web-dev-qa-db-fra.com

Configurer le service buggy systemd pour qu'il se termine via SIGKILL

Contexte

On m'a demandé de créer un script systemd pour un nouveau service, foo_daemon, qui entre parfois dans un "mauvais état" et ne mourra pas via SIGTERM (probablement en raison du gestionnaire de signal personnalisé). Cela est problématique pour les développeurs, car ils sont invités à démarrer/arrêter/redémarrer le service via:

  • systemctl start foo_daemon.service
  • systemctl stop foo_daemon.service
  • systemctl restart foo_daemon.service

Problème

Parfois, en raison de foo_daemon entrer dans un mauvais état, nous devons le tuer de force via:

  • systemctl kill -s KILL foo_daemon.service

Question

Comment configurer mon script systemd pour foo_daemon de sorte que, chaque fois qu'un utilisateur tente d'arrêter/redémarrer le service, systemd:

  • Essayez d'arrêter gracieusement foo_daemon via SIGTERM.
  • Accordez jusqu'à 2 secondes pour l'arrêt/la fin de foo_daemon compléter.
  • Tenter un arrêt forcé de foo_daemon via SIGKILL si le processus est toujours en cours (nous n'avons donc pas de risque de recyclage du PID et systemd émet SIGKILL contre le mauvais PID). L'appareil que nous testons génère/opère rapidement de nombreux processus, il y a donc une préoccupation rare mais très réelle concernant le recyclage PID qui cause un problème.
  • Si, dans la pratique, je suis juste paranoïaque à propos du recyclage des PID, je suis d'accord avec le script qui émet simplement SIGKILL contre le PID du processus sans se soucier de tuer un PID recyclé.

20
Cloud

systemd prend déjà cela en charge, et c'est activé par défaut .

La seule chose que vous voudrez peut-être personnaliser est le délai d'expiration, que vous pouvez faire avec TimeoutStopSec=. Par exemple:

[Service]
TimeoutStopSec=2

Maintenant, systemd enverra un SIGTERM, attendra deux secondes que le service se termine, et si ce n'est pas le cas, il enverra un SIGKILL.

Si votre service n'est pas compatible avec systemd, vous devrez peut-être fournir le chemin d'accès à son fichier PID avec PIDFile=.

Enfin, vous avez mentionné que votre démon engendre de nombreux processus. Dans ce cas, vous souhaiterez peut-être définir KillMode=control-group et systemd enverront des signaux à tous les processus du groupe de contrôle.

27
Michael Hampton

Puisque personne n'a mentionné avoir besoin de Type=oneshot, voici un exemple complet qui se termine en raison d'un échec de temporisation.

[Unit]
Description=timeout test

[Service]
Type=oneshot
TimeoutStartSec=2
ExecStart=/bin/sleep 10
1
Evidlo