web-dev-qa-db-fra.com

SystemCtL montre inactif / mort, mais le service est en cours d'exécution

Je souhaite gérer un serveur TeamSpeak 3 avec SystemD (SystemCtL).

Lorsque je démarre/arrête/redémarrez le serveur TeamSpeak 3 à l'aide de la commande SystemCtL, SystemCtl renvoie le statut correct:

$ systemctl status ts3server.service
● ts3server.service - TeamSpeak 3 Server
   Loaded: loaded (/etc/systemd/system/ts3server.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2019-02-12 23:15:18 CET; 1min 11s ago
 Main PID: 842 (ts3server)
   CGroup: /system.slice/ts3server.service
           └─842 ./ts3server inifile=ts3server.ini

Feb 12 23:15:18 hostname.local systemd[1]: Starting TeamSpeak 3 Server...
Feb 12 23:15:18 hostname.local ts3server_startscript.sh[838]: Starting the TeamSpeak 3 server
Feb 12 23:15:18 hostname.local ts3server_startscript.sh[838]: TeamSpeak 3 server started, for details please view the log file
Feb 12 23:15:18 hostname.local systemd[1]: Started TeamSpeak 3 Server.

Mais lorsque le service est arrêté sinon (par exemple, dans un processus de mise à jour automatisé), puis a recommencé - sans SystemCtL - le systemctl status La commande renvoie un statut incorrect:

$ systemctl status ts3server.service
● ts3server.service - TeamSpeak 3 Server
   Loaded: loaded (/etc/systemd/system/ts3server.service; enabled; vendor preset: enabled)
   Active: inactive (dead) since Mon 2019-02-11 03:15:16 CET; 1 day 19h ago
Condition: start condition failed at Mon 2019-02-11 03:15:16 CET; 1 day 19h ago
           └─ ConditionPathExists=!/home/teamspeak/.update.lock was not met
  Process: 21740 ExecStop=/home/teamspeak/ts3server_startscript.sh stop (code=exited, status=0/SUCCESS)
  Process: 29220 ExecStart=/home/teamspeak/ts3server_startscript.sh start (code=exited, status=0/SUCCESS)
 Main PID: 29224 (code=exited, status=0/SUCCESS)

Warning: Journal has been rotated since unit was started. Log output is incomplete or unavailable.

Le fichier PID existe en ce moment:

$ stat /home/teamspeak/ts3server.pid
  File: /home/teamspeak/ts3server.pid
  Size: 4              Blocks: 8          EA Block: 4096   regular file
Device: ca01h/51713d     Inode: 534471      Symbolic Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 1001/teamspeak)   Gid: ( 1001/teamspeak)
Access    : 2019-02-12 23:15:09.192927211 +0100
Modified: 2019-02-12 23:15:09.188927218 +0100
Changed   : 2019-02-12 23:15:09.188927218 +0100
 Birth    : -

Le processus avec ce PID est en cours d'exécution et je peux me connecter à ce serveur TeamSpeak 3.

/home/teamspeak/.update.lock existe alors que le processus de mise à jour automatisé est en cours d'exécution. Après la mise à jour, le fichier est supprimé/supprimé et n'existe plus.

systemctl montre le statut correct, lorsque je tue le service d'exécution PID comme systemctl redémarre le service à l'aide de SystemD correct ultérieurement.

Voici mon /etc/systemd/system/ts3server.service déposer:

[Unit]
Description=TeamSpeak 3 Server
After=network.target mysqld.service
ConditionPathExists=!/home/teamspeak/.update.lock

[Install]
WantedBy=multi-user.target
Alias=ts3server.service

[Service]
User=teamspeak
Group=teamspeak
WorkingDirectory=/home/teamspeak/
ExecStart=/home/teamspeak/ts3server_startscript.sh start
ExecStop=/home/teamspeak/ts3server_startscript.sh stop
ExecReload=/home/teamspeak/ts3server_startscript.sh restart
PIDFile=/home/teamspeak/ts3server.pid
Restart=always
Type=forking

Pourquoi systemctl _ ne pas renvoyer l'état correct, bien que le serveur TeamSpeak 3 soit démarré correctement de manière différente?

3
user2966991

Vous devriez changer le Type à simple dans votre fichier d'unité et cela fonctionnera. IIRC forking nécessite un appel explicite de fork() méthode, tandis que vous le démarrez à partir d'un script Bash et il n'y a tout simplement pas fork() appel.

2
Gothrek

La réponse à votre question "pourquoi" est que SystemD recherche le PID qu'il sait (842 dans votre exemple de sortie ci-dessus), il ne suit pas les informations de PID du service. Si ce processus ne fonctionne plus, SystemD n'a aucune idée de ce qui se passe avec le processus. Il ne peut pas non plus le redémarrer (car les ports seraient déjà liés à la nouvelle instance).

Probablement un moyen plus propre de faire la mise à niveau est

  1. Utilisez SystemCtL pour arrêter le service
  2. Effectuer la mise à jour, puis
  3. Utilisez SystemCTL Démarrer le processus.
1
Kevin Colagio

L'astuce consiste à spécifier Type=oneshot et RemainAfterExit=yes et ne spécifiez pas PIDFile=

Exemple minimal:

[Unit]
Description=service that is restarted by externalities.

[Service]
Type=oneshot
RemainAfterExec=yes
ExecStart=/startup.sh
ExecStop=/stop.sh

[Install]
WantedBy=multi-user.target

La documentation l'appelle " SERVICE ONESHOT STOPPABLE "

De la même manière que les services ONESHOT, il existe parfois des unités qui doivent exécuter un programme pour configurer quelque chose, puis l'exécuter une autre pour la fermer, mais aucun processus reste actif pendant qu'ils sont considérés comme "démarrages".

Mais ils ne considèrent pas le cas d'utilisation où le programme qui est démarré modifie les valeurs de PID, même si cela fonctionne aussi pour cela.

0
Metta Crawler