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

12

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 MYSERVICEvous devez arrêter 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

En conséquence, startet restarttravailler, mais reloaddonne 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?

TomOnTime
la source
Est-ce que cela a vraiment besoin d'être ajouté au rechargement , où il ne correspond pas tout à fait exactement? Ne pouvez-vous pas faire en sorte que le démon se comporte de manière sensée?
Michael Hampton
Merci @MichaelHampton, mais ce n'est pas une situation où je peux réécrire le programme. J'apprécie votre suggestion utile. Cela dit, je suis sûr que c'est un cas d'utilisation systémique commun et une réponse canonique pourrait aider beaucoup de gens.
TomOnTime
1
Je suis sûr qu'une réponse pourrait aider quelqu'un, j'ai donc voté pour la question. Je ne suis tout simplement pas sûr que ce soit un cas d'utilisation courant. Après avoir utilisé systemd pendant cinq ans environ, presque depuis le jour où il a été déclenché dans le monde, c'est la première fois que je me souviens avoir entendu parler de quelqu'un qui tentait ce genre de scénario. Il est possible que je me méprenne sur quelque chose à cause de détails manquants.
Michael Hampton

Réponses:

16

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 fait pas changer le PID du service. En d'autres termes, systemd ne veut que refléter les fonctionnalités existantes.

Au lieu de cela, vous devez utiliser systemctl reload-or-restartce 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 MYSERVICEet, (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.

TomOnTime
la source
3

La philosophie de systemd reloadest facultative et l'utilisateur de systemd devrait savoir, pour chaque service, s'il doit l'appeler reloadou 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 PID du service. 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 si je pouvais implémenter un "faux" rechargement en permettant ExecReloadde tuer et de redémarrer le service? Ensuite, je pourrais utiliser systemctl reload FOOpour tous mes services et je n'aurais pas à me rappeler lesquels le prennent en charge 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 s'il reloadexiste 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'en a pas reloadet par défaut, tue et redémarre 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 d'espace de noms tout-en-mon-couche. 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.)

TomOnTime
la source
1
Il y systemctl reload-or-restarten a qui rechargera le service s'il le prend en charge et le redémarrera s'il ne le fait pas. Aucune idée pourquoi Puppet fait cette hypothèse.
Michael Hampton