13 votes

Qu'est-ce qui peut faire que l'arrêt d'un service systemd se termine par l'annulation d'un travail ?

Occasionnellement, lors de l'arrêt d'un service systemd avec systemctl stop test-server il échouera en mentionnant que le travail a été annulé :

Unable to stop service test-server: Job for test-server.service canceled.

Qu'est-ce qui pourrait entraîner l'annulation de l'arrêt du service ?

Note : L'arrêt est en fait initié à partir d'un playbook Ansible, mais je ne vois pas en quoi cela est lié.

10voto

Jonathan Kowalski Points 356

Chaque unité de systemd dispose d'un slot de job en interne, et il ne peut y avoir qu'un seul job installé pour l'unité à la fois. Les tâches encapsulent les demandes de changement d'état pour les unités en général, mais leurs effets varient en fonction du type d'unité. Dans les services, ils peuvent initier une demande de changement d'état, mais l'action peut être exécutée même si vous annulez le job installé (ou si vous l'annulez et le remplacez par un autre type de job, ce qui maintiendra l'autre dans l'état d'attente jusqu'à ce que l'opération soit terminée, puisque les fonctions unit_start/stop internes peuvent également décider quand un certain job peut être exécuté).

À titre d'exemple, si une action d'arrêt prend beaucoup de temps, l'appel de start pendant que la tâche d'arrêt est en cours annulera, avec le mode de travail par défaut (replace), la tâche d'arrêt installée/en cours d'exécution et installera une tâche de start dans l'emplacement de travail de l'unité. Puisque unit_stop a précédemment initié une transition vers la désactivation (et ce qui correspond au sous-état interne du service - stop, stop-sigterm, stop-sigkill, stop-final, stop-final-sigterm, stop-final-sigkill), unit_start retournera maintenant -EAGAIN, ce qui amène systemd à mettre le job de démarrage dans l'état JOB_WAITING, et au prochain changement d'état, il sera ajouté à la file d'attente d'exécution, on vérifiera s'il peut être exécuté à nouveau, et selon le résultat, il sera exécuté ou mis en attente à nouveau (à partir de unit_notify). Chaque fois qu'un travail est exécuté, il est supprimé de la file d'attente. C'est la raison pour laquelle systemctl start reste en attente pendant tout ce temps (si vous n'utilisez pas --no-block).

Il s'agissait d'une vue d'ensemble de certains éléments en mouvement. Il y a trois choses à garder à l'esprit en ce qui concerne les emplois : Ils ont un type (démarrer, arrêter, redémarrer, recharger, etc.), un résultat (délai, terminé, annulé, dépendance, ignoré, etc.) et un mode (remplacer, isoler, vider, etc.). Les modes s'appliquent à l'ensemble d'une transaction (le travail demandé et son exigence, ainsi que les travaux dépendants de manière propagative appliqués ensemble de manière cohérente), et il existe une documentation sur ce que chacun d'eux fait.

Dans votre cas particulier, il semble que lorsque vous effectuez un arrêt systemctl, un autre travail arrive et remplace votre travail d'arrêt, et le client systemctl se déconnecte car le travail qu'il avait mis en file d'attente a été annulé. Cela peut être dû à une dépendance, ou à autre chose (comme ExecStop= qui appelle systemctl start unit (qui ne fonctionne que la première fois) ou quelque chose de similaire, ou une unité qui veut/exige/se lie à la même unité qui démarre, déclenchant un travail de démarrage qui remplace le travail d'arrêt que vous avez déclenché, etc). Il peut s'agir d'un service qui est activé par une socket et qui, en raison d'une connexion occupée, est redéclenché, mettant en file d'attente un travail de démarrage en raison de la dépendance Triggers= dans l'unité de socket, ce qui annule votre travail d'arrêt. Il peut également s'agir d'un minuteur ou d'autre chose : en bref, la tâche d'arrêt est remplacée par une autre tâche qui vient la remplacer.

Bien sûr, comme vous le notez, tout ceci est sujet à des courses, cela peut arriver ou ne pas arriver, donc cela arrive occasionnellement dans votre cas. Il serait bon de revoir votre configuration pour éviter ces problèmes.

4voto

nh2 Points 716

Dans mon cas, j'ai obtenu

[root@server:~]# systemctl start nginx
Job for nginx.service canceled.

et la raison en est que j'avais défini nginx pour qu'il ait une fonction BindsTo= d'avoir un autre service, de sorte qu'il s'exécute exactement quand cet autre service s'exécute.

En raison d'un bogue, l'autre service a un jour commencé à se terminer immédiatement, ce qui a amené systemd à annuler la tâche de démarrage de nginx.

Malheureusement, systemd ne semble pas donner d'autres indications sur la façon dont le système doit être utilisé. raison de l'annulation - j'ai l'impression que ce serait beaucoup mieux si c'était le cas (et j'ai déjà eu l'occasion de le faire). fonctionnalité demandée il).

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X