Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 31/08/2016, à 12:59

Compte supprimé

Faire en sorte que SystemD attende la fin d'un Script

(Pt'être pas dans la bonne catégorie, non ?)

Booonjooour à tous !
Bref, hier, je me suis mis difficilement à SystemD.
Ce qui m'as fait découvrir que j'étais schizophrène ! (Confère ceci : http://forum.ubuntu-fr.org/viewtopic.php?id=1995715 ) big_smile

Bon, en fait, ça fonctionne pas totalement.
J'vous explique : J'ai un script qui gére le démarrage et l'arrêt d'un serveur Minecraft. Pour que tout ça soit automatique, je l'ai mis en service, et voici ma configuration (En suivant un peu ce tutoriel : https://doc.ubuntu-fr.org/creer_un_service_avec_systemd ) :

# Minecraft systemd service file

[Unit]
Description=Minecraft
After=network.target local_fs.target remote_fs.target screen-cleanup.service

[Service]
RemainAfterExit=true

ExecStart=/etc/init.d/minecraft start
ExecStop=/etc/init.d/minecraft stop
ExecReload=/etc/init.d/minecraft restart

[Install]
WantedBy=multi-user.target

Bon, ça démarre impec' Minecraft, mais au shutdown, SystemD n'attend pas la fin de mon script, ce qui coupe l'OS au nez de Java. C'est un peu c**, parce que ça n'attend pas que les données soient enregistrées.

J'ai essayé pleins de trucs déjà, seuls ou un peu mélangés dans tous les sens, en fonction de ce que je trouvais sur Internet :
• TimeoutStopSec=0
• TimeoutStopSec=1min            # Une minute est peut être un peu exagéré, il faut en vrai 12 secondes.
• TimeoutStopSec=60s
• ExecStartPost=/bin/sleep 60
• KillMode=none
• Type=oneshot
• Nice=-20

Et rien à faire, ça ne fonctionne pas. Le script quant à lui marche impeccable, il est, au passage, programmé pour attendre la fin du shutdown de Minecraft avant de se terminer. Donc le but que je cherche ici est de faire en sorte que SystemD attende la fin du script.
Vous devinez surement ma question : Quelqu'un as des idées ?

Voilà voilà, merci beaucoup, et bonne journée !


PS : Ce qui est marrant, c'est que avec la commande systemctl stop minecraft, ça à l'air de bien attendre que Minecraft soit coupé. Enfin, d'après les logs de SystemD (systemctl status minecraft) et celles de Minecraft.

PPS : Et j'ai pas trouvé d'indices là dedans, mais on sait jamais... Voici l'erreur dans logs du serveur Minecraft lorsque tout s'arrête pas proprement :

[13:25:24] [Thread-4/INFO]: Stopping server
[13:25:24] [Server console handler/ERROR]: Exception handling console input
java.io.IOException: Erreur d'entrée/sortie
    at java.io.FileInputStream.readBytes(Native Method) ~[?:1.8.0_101]
    at java.io.FileInputStream.read(FileInputStream.java:255) ~[?:1.8.0_101]
    at java.io.BufferedInputStream.fill(BufferedInputStream.java:246) ~[?:1.8.0_101]
    at java.io.BufferedInputStream.read(BufferedInputStream.java:265) ~[?:1.8.0_101]
    at org.bukkit.craftbukkit.libs.jline.internal.NonBlockingInputStream.read(NonBlockingInputStream.java:169) ~[Spigot.jar:git-Spigot-078e2f8-7f9fbe5]
    at org.bukkit.craftbukkit.libs.jline.internal.NonBlockingInputStream.read(NonBlockingInputStream.java:137) ~[Spigot.jar:git-Spigot-078e2f8-7f9fbe5]
    at org.bukkit.craftbukkit.libs.jline.internal.NonBlockingInputStream.read(NonBlockingInputStream.java:246) ~[Spigot.jar:git-Spigot-078e2f8-7f9fbe5]
    at org.bukkit.craftbukkit.libs.jline.internal.InputStreamReader.read(InputStreamReader.java:261) ~[Spigot.jar:git-Spigot-078e2f8-7f9fbe5]
    at org.bukkit.craftbukkit.libs.jline.internal.InputStreamReader.read(InputStreamReader.java:198) ~[Spigot.jar:git-Spigot-078e2f8-7f9fbe5]
    at org.bukkit.craftbukkit.libs.jline.console.ConsoleReader.readCharacter(ConsoleReader.java:2145) ~[Spigot.jar:git-Spigot-078e2f8-7f9fbe5]
    at org.bukkit.craftbukkit.libs.jline.console.ConsoleReader.readLine(ConsoleReader.java:2349) ~[Spigot.jar:git-Spigot-078e2f8-7f9fbe5]
    at net.minecraft.server.v1_10_R1.DedicatedServer$2.run(DedicatedServer.java:84) [Spigot.jar:git-Spigot-078e2f8-7f9fbe5]

A noter que nous avons le message "Stopping server" alors que la commande d'arrêt par le script n'a pas encore été exécutée ! Euh... Oui, je viens de me rendre compte, c'est bête, le problème ne viendrais donc pas de mon Service SystemD mais de autre chose. Non ? Toi qui lit ces lignes, tu en pense quoi ? Hein ? Parce que là, je me sens un peu perdu...

Dernière modification par Bloufit (Le 31/08/2016, à 14:17)

#2 Le 18/09/2016, à 17:49

Zakhar

Re : Faire en sorte que SystemD attende la fin d'un Script

Et en mettant le script pour stopper minecraft dans un autre script, histoire de pouvoir logger ce qu'il se passe ?

Genre:

ExecStop=/etc/init.d/debug_minecraft_stop.sh

Lequel contient

#? /bin/sh

LOGFILE="/path/file"

echo "Debug stopping minecraft" >>"$LOGFILE"
/etc/init.d/minecraft stop
echo "Minecraft stopped" >>"$LOGFILE"
sleep 30
echo "Done sleeping" >>"$LOGFILE"

... ou tout ce que tu veux d'autre de pertinent pour logger ce qu'il se passe dans ton serveur

Dernière modification par Zakhar (Le 18/09/2016, à 17:50)


"A computer is like air conditioning: it becomes useless when you open windows." (Linus Torvald)

Hors ligne

#3 Le 20/02/2017, à 22:26

Compte supprimé

Re : Faire en sorte que SystemD attende la fin d'un Script

Plop.
Et non ! Je ne suis pas mort.
Bref. Merci beaucoup de ta réponse, et désolé pour ces mois d'abandons de ma part sur ce problème... Je crois que j'ai battu un record là !

Enfin voilà. Le bug existe toujours, et il va pas se régler tout seul.

J'ai essayé ton truc, et ça ne fait absolument rien. Rien dans logs qu'on lui demande de créer, juste un petit message au shutdown. En fait, le système n'attend pas la fin du script...
Ou alors il arrête Java avant ? J'ai pas trouvé de service relatif à Java en fait.
Ou alors la screen ? Ou alors la session ? Parce que mon truc utilise les deux.

Bon par contre, j'ai trouvé autre chose : Quand j'installe mon script, j'ai ce joli message d'amour :

insserv: warning: current start runlevel(s) (empty) of script `minecraft' overrides LSB defaults (2 3 4 5).
insserv: warning: current stop runlevel(s) (0 1 2 3 4 5 6) of script `minecraft' overrides LSB defaults (0 1 6).

Chouette... Euh... Je vois pas le problème en fait.

Bon et puis, dans mes bidouillages désespérés, il y a ça :

[Unit]
Description=Minecraft
After=network.target local_fs.target remote_fs.target screen-cleanup.service firewall.service
Requires=firewall.service
RequiresMountsFor=/home
Wants=network.target
Before=network.target shutdown.target network-online.target reboot.target halt.target systemd-halt.service systemd-poweroff.service systemd-reboot.service systemd-kexec.service
Conflicts=shutdown.target

[Service]
Type=forking
RemainAfterExit=true
KillMode=none

ExecStart=/etc/init.d/minecraft start
ExecStop=/etc/init.d/minecraft stop

TimeoutStopSec=30s

[Install]
WantedBy=multi-user.target

Enfin bref. Je vais dormir parce que ça me donne mal à la tête ces histoires.

Si quelqu'un a une idée, n'hésitez pas ! wink
Sur ce, bonne soirée !

PS : Aussi cette page est sympa ! Vous en pensez quoi d'ajouter "Wants=minecraft.service" dans le "multi-user.target" ? Si je trouve ce "multi-user.target", parce que la commande d'édition ne donne rien...

PPS : Et puis aussi, nouvelle attraction : Le serveur met 10 minutes à s'éteindre... Ou alors le noyau met 10 minutes à s'allumer... Je sais pas en fait. La première ligne du "journalctl" est dite affichée 10 minutes plus tard.


Edit : Etant donné que c'était bien le bazar dans ma config, je vous la remet propre ici, tel qu'elle est maintenant :

# Minecraft systemd service file

[Unit]
Description=Minecraft

After=local_fs.target remote_fs.target screen-cleanup.service
Before=local_fs.target remote_fs.target shutdown.target reboot.target halt.target

Requires=network.target

Wants=network.target
Conflicts=shutdown.target

[Service]
Type=simple

RemainAfterExit=true
KillMode=none

RequiresMountsFor=/home

ExecStart=/etc/init.d/minecraft start
ExecStop=/etc/init.d/minecraft stop

ExecReload=/etc/init.d/minecraft restart

[Install]
WantedBy=multi-user.target

Dernière modification par Bloufit (Le 21/02/2017, à 17:59)

#4 Le 22/02/2017, à 11:36

DonutMan75

Re : Faire en sorte que SystemD attende la fin d'un Script

Hello Bloufit,
ton problème m'intéresse beaucoup !
Je ne suis hélas pas très familier de systemd mais peut être quelques pistes pour voir d'où vient le problème :

1) Remplacer le script d'arrêt par un script super simple qui  :
- écrit "script arrêt lancé a XXX heure" dans un fichier de log de ton choix
- sleep pendant 2 minutes
- écrit "script arrêt terminé à XXX heure" dans ce même fichier de log

Si les deux lignes sont bien écrites, c'est que le problème ne vient sans doute pas de systemd mais de ton script minecraft

2) Complexifier ensuite ce même script en exécutant ces mêmes lignes dans un screen : retrouvons-nous le même comportement attendu ?

3) Peux-tu nous mettre le détail de ton script minecraft (stop/start/restart) ?

Je suis curieux d'avoir la réponse à ce problème. Bon courage en tout cas smile

Donut.

Hors ligne

#5 Le 22/02/2017, à 12:45

Compte supprimé

Re : Faire en sorte que SystemD attende la fin d'un Script

Hello !
Merci de ta réponse ! Et content que ça t’intéresse. Moi ça commence un peu à me barber (Depuis 6 mois) ! big_smile

Bref. J'ai donc (ré)essayé de faire ce genre de script, mais comme celui de Zakhar, SystemD l'arrête en plein milieu. Il log juste le premier message, et se fait arrêter en plein milieu du "sleep". Un peu comme le script original en fait, sauf que là, il ne fait quasiment rien !

D'ailleurs, un sleep mis dans le fichier de configuration du service, dans "ExecPostStop=", ne fonctionne pas.

Mon script est celui-ci : https://github.com/superjamie/minecraft … /minecraft.
Bien que je l'ai pas mal simplifié, mais pour la fonction "stop", c'est la même chose.

Ce qui est bizzare d'ailleurs, ce quand je fais "service minecraft stop", SystemD attend bien avant de me redonner la ligne de commande.

Et au passage, mon fichier "minecraft.service" ressemble à ça actuellement :

# Minecraft systemd service file

[Unit]
Description=Minecraft

After=local_fs.target remote_fs.target screen-cleanup.service

Requires=network.target mysql.service ssh.service 

Conflicts=shutdown.target reboot.target halt.target

RequiresMountsFor=/home

[Service]
Type=simple

RemainAfterExit=true
KillMode=none

ExecStart=/etc/init.d/minecraft start
ExecStop=/home/user/stop.sh

ExecReload=/etc/init.d/minecraft restart

TimeoutStopSec=1min

[Install]
WantedBy=multi-user.target

J'ai viré les "Before=", car ce sont les programmes qui doivent se lancer après le lancement de ce service, et non après qu'il soit éteint. Et aussi le "Want=", car il revient au même que le "Require=", mais en plus facultatif.
Bref, les heures passées sur la doc de SystemCtl n'ont pas étés inutiles ! smile

Voilà voilà voilà ! Si tu as des idées, je suis preneur !
En attendant, bonne journée !

Dernière modification par Bloufit (Le 29/10/2018, à 18:15)

#6 Le 22/02/2017, à 13:01

Compte supprimé

Re : Faire en sorte que SystemD attende la fin d'un Script

Je rectifie !
(Oui je sais, je devrais faire un "Edit" de mon message précédent, mais vu que celui-ci est mal écrit, ça sera plus compréhensible de mettre ça ici)
Quand je lance le script de stop qu'on a créé manuellement, il fonction à merveille et log bien tout ce qu'on lui demande de logger, mais quand je lance "service minecraft stop", le système ne fait rien, et ne lance même pas le script ! Même si je le met sur un autre service...
C'est quand même un peu embêtant, parce que le vrai script se fait effectivement attendre... Beuh... Qui créé ces programmes à la noix ? big_smile

Dernière modification par Bloufit (Le 22/02/2017, à 13:12)