Les services restent en état d'échec après l'arrêt avec systemctl

19

nous avons un simple script systemd pour démarrer un serveur MineCraft de façon service. Le SO est CentOS 7. Voici le script:

[Unit]
Description=Minecraft Server
After=syslog.target network.target

[Service]
Type=simple
WorkingDirectory=/root/Minecraft
ExecStart=/bin/java -Xmx1024M -Xms1024M -jar minecraft_server.jar nogui
Restart=on-failure

[Install]
WantedBy=multi-user.target

Le démarrage du service fonctionne correctement mais à l'arrêt, le service reste dans un état d'échec. Voir:

systemctl status minecraftd.service
minecraftd.service - Minecraft Server
   Loaded: loaded (/usr/lib/systemd/system/minecraftd.service; disabled)
   Active: active (running) since Mon 2015-06-01 16:00:12 UTC; 18s ago
 Main PID: 20975 (java)
   CGroup: /system.slice/minecraftd.service
           └─20975 /bin/java -Xmx1024M -Xms1024M -jar minecraft_server.jar nogui
systemctl stop minecraftd.service
systemctl status minecraftd.service
minecraftd.service - Minecraft Server
   Loaded: loaded (/usr/lib/systemd/system/minecraftd.service; disabled)
   Active: failed (Result: exit-code) since Mon 2015-06-01 16:01:37 UTC; 3s ago
  Process: 20975 ExecStart=/bin/java -Xmx1024M -Xms1024M -jar minecraft_server.jar nogui (code=exited, status=143)
 Main PID: 20975 (code=exited, status=143)

Une idée?

Merci

Kalise
la source

Réponses:

27

Le code de sortie 143 signifie que le programme a reçu un signal SIGTERM pour lui demander de quitter, mais il n'a pas traité le signal correctement. Cela est presque toujours dû à des erreurs de programmation et est assez courant avec les applications Java de tous types.

Vous devriez pouvoir supprimer cela en ajoutant le code de sortie dans le fichier d'unité en tant qu'état de sortie "succès":

[Service]
SuccessExitStatus=143
Michael Hampton
la source
Ça marche. Le service est maintenant dans l'état inactif, comme prévu.
kalise
4
Quelle serait la "bonne" façon de gérer le signal avec une application Java? Le plus proche que je puisse trouver serait les crochets d'arrêt, mais nulle part dans la documentation ne mentionne que les crochets d'arrêt modifient le code de sortie de l'application.
SPoage
@SPoage stackoverflow.com/q/2975248/1068283 Mais il semble que Java se termine toujours avec le code 143 dans ce cas, même si un hook d'arrêt est présent.
Michael Hampton
10

Pour compléter la réponse de Michael, le code de sortie 143 est normal ici, c'est la façon dont la machine virtuelle Java a reçu un signal SIGTERM, envoyé par systemd pour arrêter le processus. Le signal SIGTERM a une valeur numérique de 15 (voir man signal).

Maintenant, selon la spécification Posix, "l'état de sortie d'une commande qui s'est terminée parce qu'elle a reçu un signal doit être signalé comme supérieur à 128". ( http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_08_02 )

Ici, la machine virtuelle Java ajoute 128 + 15 et vous obtenez ce code de sortie de 143.

Ce code de sortie non nul a du sens, car cela permet de voir que votre programme java s'est arrêté à cause d'un signal externe, et vous avez la possibilité de savoir quel signal.

Manu
la source
Le texte de spécification POSIX référencé semble indiquer comment un shell doit se comporter et dit "Le shell est un interpréteur de langage de commande". Une machine virtuelle Java ne semble pas être couverte par cette spécification. La façon dont un shell interprète une machine virtuelle Java (ou tout autre programme) se terminant en raison de SIGTERM - qu'il devrait définir le code de sortie sur 143 - est certainement couverte par la spécification, mais je suis pratiquement sûr qu'aucun shell n'est impliqué ici.
doshea
Vous avez raison en ce que cette spécification POSIX est dirigée vers le shell UNIX, mais ici, il semble que les auteurs de la JVM aient décidé d'implémenter leur code retour de la même manière.
Manu