web-dev-qa-db-fra.com

Comment configurer systemd pour tuer et redémarrer un démon lors du rechargement?

J'ai un démon à l'ancienne que je veux contrôler en utilisant systemd. Lorsque son fichier de configuration change, il doit être tué et redémarré. En d'autres termes, après avoir modifié le fichier de configuration, systemctl reload MYSERVICE devrait tuer le processus et le redémarrer.

Tentative 1: essayez les valeurs par défaut. Cela indique à systemd comment démarrer le démon, mais pas comment le recharger.

[Service]
ExecStart=/usr/bin/MYSERVICE
Type=simple

Par conséquent, start et restart fonctionnent, mais reload donne cette erreur:

# systemctl reload MYSERVICE
Failed to reload MYSERVICE.service: Job type reload is not applicable for unit MYSERVICE.service.

Tentative 2: dites-lui comment tuer le processus. Cela tue le processus mais systemd ne le redémarre pas pour moi.

[Service]
ExecStart=/usr/bin/MYSERVICE
Type=simple
ExecReload=/bin/kill -HUP $MAINPID

...suivi par...

# systemctl daemon-reload
# systemctl reload MYSERVICE

... tue le processus mais il n'est pas redémarré automatiquement.

Tentative 3: utilisez également ExecReload pour redémarrer le processus. Cela échoue pour plusieurs raisons:

ExecReload=/bin/kill -HUP $MAINPID ; /usr/bin/MYSERVICE

... le message d'erreur que j'obtiens ...:

# systemctl daemon-reload
# systemctl reload MYSERVICE
Job for MYSERVICE.service failed because the control process exited with error code. See "systemctl status MYSERVICE.service" and "journalctl -xe" for details.

Je m'attendrais à ce qu'il y ait un ReloadType = kill_and_restart ou quelque chose mais pas de chance.

Comment dire à systemd de tuer et de redémarrer un démon lors du rechargement?

12
TomOnTime

La réponse est "non"! Mais nous avons de bonnes nouvelles.

la philosophie de systemd est que le rechargement est facultatif et ne doit pas être défini s'il n'y a pas de véritable fonctionnalité de rechargement. Je définirais la "véritable fonctionnalité de rechargement" comme un rechargement qui ne tue pas et ne redémarre pas le service, ou ne modifie pas son PID. En d'autres termes, systemd ne veut que refléter les fonctionnalités existantes.

Au lieu de cela, vous devez utiliser systemctl reload-or-restart qui fera un rechargement s'il existe, et un redémarrage si ce n'est pas le cas.

Depuis la page de manuel ...

   reload-or-restart PATTERN...
       Reload one or more units if they support it. If not, restart them
       instead. If the units are not running yet, they will be started.

   reload-or-try-restart PATTERN...
       Reload one or more units if they support it. If not, restart them
       instead. This does nothing if the units are not running. Note that,
       for compatibility with SysV init scripts, force-reload is
       equivalent to this command.

Par conséquent: (1) laissez ExecReload vide, (2) utilisez systemctl reload-or-restart MYSERVICE et, (3) vous devriez être prêt.

Si vous essayez d'utiliser ExecReload pour définir un moyen de tuer et de redémarrer le service, il aura un nouveau PID et systemd serait confus.

16
TomOnTime

la philosophie de systemd est que reload est facultatif et que l'utilisateur de systemd devrait savoir, pour chaque service, s'il doit appeler reload ou le simuler en appelant restart.

Par conséquent, la réponse à votre question est: "Cela ne fonctionne pas et cela ne devrait pas. Veuillez résoudre ce problème au niveau supérieur suivant."

En d'autres termes, systemd veut que vous n'implémentiez " reload " que si le service sous-jacent prend en charge une véritable fonctionnalité de rechargement ... c'est-à-dire un rechargement qui ne tue pas et ne redémarre pas le service, ou ne change pas le service. PID. En d'autres termes, systemd ne veut que refléter les fonctionnalités existantes.

Vous vous demandez peut-être: mais ne serait-il pas plus facile de mettre en œuvre un "faux" rechargement en permettant à ExecReload de tuer et de redémarrer le service? Ensuite, je pourrais utiliser systemctl reload FOO pour tous mes services et je n'aurais pas à me rappeler lesquels le soutiennent et lesquels ne le sont pas?

Oui, ce serait plus facile, mais ce ne serait pas la voie de Systemd. Systemd veut que l'appelant soit la chose qui sait si reload existe pour le service. Systemd veut être une interface commune avec les fonctionnalités existantes, il ne veut pas être responsable de combler les lacunes.

Par exemple, marionnette suppose qu'un service piloté par systemd n'a pas de reload et par défaut pour tuer et redémarrer le processus . Si le type Service [] a ajouté un moyen de spécifier que le rechargement existe et qu'il doit être utilisé lors de la notification, il devra savoir quels services ont ou n'ont pas un rechargement natif. Chef et tous les autres systèmes devraient également apprendre la même chose car systemd veut que cela soit résolu au niveau de cette couche. (MiniRant: pour démarrer un système de processus, il semble que ce soit le système omniscient, à montage complet et à personnalisation de tout-espace de nommage. Par conséquent, je ne peux pas vous dire pourquoi il ne fonctionne pas étendre cette philosophie au rechargement. Peut-être que l'un des auteurs peut sonner ici.)

3
TomOnTime