Dans systemd, quelle est la différence entre After = et REQUIS =?

55

Je crée un fichier .service systemd et j’ai besoin d’aide pour comprendre la différence entre Requires=et After=. La page de manuel indique que Requires="Configure les dépendances des exigences sur d'autres unités". et After="Configure les dépendances de commande entre les unités." Quelle est la différence?

TomOnTime
la source

Réponses:

45

After=configure l'ordre de service (faire X seulement après Y), tout en Requires=dépendances d'état. Si vous ne spécifiez pas de commande, un service dépendant d'un autre sera démarré en même temps que celui sur lequel il dépend. De plus, la façon dont je le comprends (bien que je ne puisse pas le tester maintenant et ne pas trouver de référence), After=est un "couplage lâche", et un service avec une telle déclaration serait toujours exécuté si celui qui est nommé dans la After=ligne isn pas commencé du tout, alors que Require=cela empêcherait son démarrage si la condition requise n'est pas remplie.

Citant https://www.freedesktop.org/software/systemd/man/systemd.unit.html :

Nécessite =

Configure les dépendances des exigences sur d'autres unités. Si cette unité est activée, les unités listées ici le seront également. Si l'une des autres unités est désactivée ou si son activation échoue, cette unité sera désactivée. Cette option peut être spécifiée plusieurs fois ou plusieurs unités séparées par des espaces peuvent être spécifiées dans une option, auquel cas des dépendances des exigences pour tous les noms répertoriés seront créées. Notez que les dépendances des exigences n'influencent pas l'ordre dans lequel les services sont démarrés ou arrêtés. Ceci doit être configuré indépendamment avec les options Après = ou Avant =. Si un foo.service d'unité nécessite un service bar.service configuré avec Requiert = et qu'aucun ordre n'est configuré avec Après = ou avant =, les deux unités seront démarrées simultanément et sans aucun délai entre elles si foo.service est activé. Souvent,

et

Avant =, Après =

Une liste de noms d'unités séparés par des espaces. Configure les dépendances de commande entre les unités. Si une unité foo.service contient un paramètre Avant = bar.service et que les deux unités sont en cours de démarrage, le démarrage de bar.service est différé jusqu'au démarrage de foo.service. Notez que ce paramètre est indépendant et orthogonal aux dépendances des exigences telles que configurées par Requiert =. Il est courant d'inclure un nom d'unité à la fois dans les options Après = et Requises =, auquel cas l'unité répertoriée sera démarrée avant l'unité configurée avec ces options. Cette option peut être spécifiée plusieurs fois. Dans ce cas, des dépendances de classement sont créées pour tous les noms répertoriés. After = est l'inverse de Before =, c'est-à-dire while After = garantit que l'unité configurée est démarrée une fois que l'unité listée a fini de démarrer, Before = garantit l'inverse, c'est-à-dire l’unité configurée est complètement démarrée avant celle de la liste. Notez que lorsque deux unités avec une dépendance d'ordre entre elles sont arrêtées, l'inverse de l'ordre de démarrage est appliqué. c'est-à-dire si une unité est configurée avec After = sur une autre unité, la première est arrêtée avant la dernière si les deux sont éteintes. Si deux unités sont dépendantes l'une de l'autre, si une unité est arrêtée et que l'autre est démarrée, l'arrêt est commandé avant le démarrage. Peu importe que la dépendance à l'ordre soit Après = ou Avant =. Peu importe également lequel des deux est arrêté, du moment que l’un est arrêté et que l’autre est démarré. L'arrêt est commandé avant le démarrage dans tous les cas. Si deux unités n'ont aucune dépendance d'ordre entre elles, elles sont éteintes ou démarrées simultanément,

Sven
la source
7
Qu'est-ce qu'une dépendance si ce n'est une déclaration d'ordre? (sérieusement ... je ne comprends pas la différence)
TomOnTime
Voir mon édition. Ma compréhension: After=Xsignifierait "Faites ceci après X si X est terminé", alors Require=Xque signifierait "ne le faites pas du tout si vous ne pouvez pas faire X".
Sven
La Before=section de la page de manuel semble le confirmer. If a unit foo.service contains a setting Before=bar.service and both units are being started, bar.service's start-up is delayed until foo.service is started up Si j'ai bien compris, la commande ne serait pas exécutée si elle bar.servicen'était pas lancée de toute façon et foo.servicequ'elle commencerait normalement.
Sven
10

Une des différences majeures est,

  • After vérifie uniquement si l'unité est déjà activée et n'active pas explicitement les unités spécifiées.
  • Les unités listées dans Requiressont activées avec l'unité. Si l'une des unités requises ne parvient pas à démarrer, l'unité n'est pas activée.

Considérer que j'ai un fichier d'unité test-app.service,

[Unit]
Description=test app
After=network-online.target

Voici ce qui se passera quand cette déclaration sera exécutée,

  • Aftervérifie si network-online.target.
  • si network-online.targetpas commencé, ça va attendre.
  • test-appcommence seulement après network-online.targetest actif

Si j'avais à la Requiresplace,

[Unit]
Description=test app
Requires=network-online.target

Voici ce qui se passera quand cette déclaration sera exécutée,

  • network-online.targetet test-appsont activés ensemble
  • si network-online.targetne parvient pas à démarrer test-appne sera pas activé.
Soufiyan Ghori
la source
2

Systemd est un gestionnaire d'emploi. La page de manuel n’est pas très précise sur le fonctionnement des choses.

Lorsque vous démarrez, ce que systemd construit est une transaction comprenant des travaux pour le travail d'ancrage (par exemple, le travail de démarrage pour default.target). Toutes ces dépendances et relations définissent comment et quels travaux seront déclenchés. La commande définit le ou les travaux que chaque travail attendra. L'unité default.target est donc au centre de tout cela. C'est pourquoi, lorsque vous activez des unités, vous utilisez une dépendance inverse qui, via systemctl, crée un lien symbolique du système de fichiers dénotant une dépendance directe que systemd peut suivre (également pourquoi vous avez besoin de première place). De même, lorsque vous démarrez manuellement une unité, cette unité est ancre et la transaction est calculée.

Sans trop entrer dans les détails, je vais expliquer ce que requiert = et après =.

Requiert = oblige systemd à déclencher un travail de démarrage pour l'unité requise lorsque vous déclenchez un travail de démarrage (explicitement ou par le biais d'une dépendance: il n'y a pas de distinction en interne). Il a également la propriété de déclencher un travail d’arrêt sur vous lorsque cette unité est arrêtée (remarque: arrêtée, ne tombe pas en panne seule) ou redémarrée. Cela signifie que si une dépendance / systemctl provoque son arrêt / redémarrage, vous allez également arrêter / redémarrer. Cependant, si cela se produit tout seul, vous ne vous arrêterez pas, car il n'y avait pas de travail, et le changement d'état a eu lieu sans l'implication de systemd. C'est là que vous utiliseriez BindsTo = (similaire aux unités de périphériques, qui peuvent passer en mode inactif sans la participation de systemd, pour des raisons évidentes).

Maintenant, l'utilisation de After = est recommandée car Requise = alone est racé pour ce qu'elle fait: annulez l'exigence si le travail de démarrage échoue. Cette annulation ne fonctionne cependant que sur les tâches. En d’autres termes, si l’autre unité ne définit pas la commande, Systemd les déclenche en parallèle et si sa tâche de démarrage se termine avant l’échec de votre tâche de démarrage, elle ne sera pas annulée (elle ne peut pas être annulée, en fait). . L'utilisation de After = signifie qu'un autre travail continue à attendre jusqu'à ce que le travail de démarrage de l'unité requise soit terminé. Selon le résultat, en cas d'échec, le travail de démarrage en attente de votre unité est annulé avec le résultat du travail JOB_DEPENDENCY (pourquoi vous utilisez jaune [DEPEND] au démarrage pour de tels cas). Par conséquent, cet effet d'invalidation est indéterministe sans l'utilisation de After =.

C’est pourquoi utiliser Wants = without After = convient si vous ne souhaitez pas attendre le démarrage de l’autre unité: il n’y a pas d’invalidation, il n’ya donc pas de course. Dans ce cas, il ne s’agit que d’un mécanisme de synchronisation.

En outre, vous pouvez également activer les deux au démarrage, sans vous imposer, et définir uniquement un ordre. Dans ce cas, lorsque les deux sont extraits dans le cadre de la même transaction, ils sont commandés (ou si le travail de l'autre est déclenché tant que le travail de l'unité pour laquelle il souhaite s'exécuter est en cours d'exécution, il attendra d'abord qu'il se termine, à travers les transactions).

Maintenant, s'il n'y a pas de travail, la commande n'a aucun effet pour ladite unité. Cependant, il existe généralement un travail résultant des dépendances telles que Requiert = et Wants =, ou les deux sont arrêtés à la fois et définissent un ordre, auquel cas ils attendent sur le ou les travaux d'une autre unité.

Jonathan Kowalski
la source