Was ist in systemd der Unterschied zwischen After = und Requires =?

53

Ich erstelle eine systemd .service-Datei und brauche Hilfe, um den Unterschied zwischen Requires=und zu verstehen After=. Die Manpage besagt: Requires="Konfiguriert Anforderungsabhängigkeiten von anderen Einheiten." und After="Konfiguriert Bestellabhängigkeiten zwischen Einheiten." Was ist der Unterschied?

TomOnTime
quelle

Antworten:

43

After=Konfiguriert den Serviceauftrag (mache X erst nach Y), während die Requires=Zustandsabhängigkeiten. Wenn Sie keinen Auftrag angeben, wird ein von einem anderen abhängiger Dienst gleichzeitig mit dem Dienst gestartet, von dem er abhängt. Außerdem ist die Art und Weise, wie ich es verstehe (obwohl ich das jetzt nicht testen kann und keinen Verweis finde), After=eine "lose Kopplung", und ein Dienst mit einer solchen Anweisung würde immer noch ausgeführt, wenn der in der After=Zeile genannte nicht ist überhaupt nicht gestartet, während Require=verhindern würde, dass es gestartet wird, wenn die Anforderung nicht erfüllt ist.

Unter Angabe von https://www.freedesktop.org/software/systemd/man/systemd.unit.html :

Benötigt =

Konfiguriert Anforderungsabhängigkeiten von anderen Einheiten. Wenn dieses Gerät aktiviert wird, werden auch die hier aufgeführten Geräte aktiviert. Wenn eine der anderen Einheiten deaktiviert wird oder ihre Aktivierung fehlschlägt, wird diese Einheit deaktiviert. Diese Option kann mehrmals angegeben werden, oder es können mehrere durch Leerzeichen getrennte Einheiten in einer Option angegeben werden. In diesem Fall werden Anforderungsabhängigkeiten für alle aufgelisteten Namen erstellt. Beachten Sie, dass Anforderungsabhängigkeiten keinen Einfluss auf die Reihenfolge haben, in der Dienste gestartet oder gestoppt werden. Dies muss unabhängig mit den Optionen After = oder Before = konfiguriert werden. Wenn eine Einheit foo.service eine mit Requires = konfigurierte Einheit bar.service benötigt und keine Bestellung mit After = oder Before = konfiguriert ist, werden beide Einheiten gleichzeitig und ohne Verzögerung zwischen ihnen gestartet, wenn foo.service aktiviert ist. Häufig,

und

Vorher =, Nachher =

Eine durch Leerzeichen getrennte Liste von Einheitennamen. Konfiguriert die Reihenfolge der Abhängigkeiten zwischen Einheiten. Wenn eine Einheit foo.service eine Einstellung Before = bar.service enthält und beide Einheiten gestartet werden, wird der Start von bar.service verzögert, bis foo.service gestartet wird. Beachten Sie, dass diese Einstellung unabhängig von und orthogonal zu den Anforderungsabhängigkeiten ist, die mit Requires = konfiguriert wurden. Es ist ein gängiges Muster, einen Einheitennamen in die Optionen After = und Requires = aufzunehmen. In diesem Fall wird die aufgelistete Einheit vor der Einheit gestartet, die mit diesen Optionen konfiguriert ist. Diese Option kann mehrmals angegeben werden. In diesem Fall werden Ordnungsabhängigkeiten für alle aufgelisteten Namen erstellt. After = ist die Umkehrung von Before =, dh während After = sicherstellt, dass die konfigurierte Einheit nach Beendigung des Hochfahrens der aufgelisteten Einheit gestartet wird, stellt Before = das Gegenteil sicher, d. H dass das konfigurierte Gerät vollständig gestartet ist, bevor das aufgelistete Gerät gestartet wird. Beachten Sie, dass beim Herunterfahren von zwei Einheiten, zwischen denen eine Abhängigkeit von der Reihenfolge besteht, die Umkehrung der Startreihenfolge angewendet wird. dh wenn eine Einheit mit After = auf einer anderen Einheit konfiguriert ist, wird die erstere vor der letzteren gestoppt, wenn beide heruntergefahren werden. Bei zwei Einheiten, zwischen denen eine Abhängigkeit von der Reihenfolge besteht, wird die Abschaltung vor dem Start angeordnet, wenn eine Einheit heruntergefahren und die andere gestartet wird. Es spielt keine Rolle, ob die Bestellabhängigkeit After = oder Before = ist. Es ist auch egal, welche der beiden heruntergefahren wird, solange eine heruntergefahren und die andere hochgefahren wird. Die Abschaltung wird in jedem Fall vor der Inbetriebnahme angeordnet. Wenn zwischen zwei Einheiten keine Ordnungsabhängigkeiten bestehen, werden sie gleichzeitig heruntergefahren oder gestartet.

Sven
quelle
7
Was ist eine Abhängigkeit, wenn keine Auftragsbestätigung? (im Ernst ... ich verstehe den Unterschied nicht)
TomOnTime
Siehe meine Bearbeitung. Mein Verständnis: After=Xwürde bedeuten "Mach das nach X, wenn X fertig ist", während Require=Xwürde bedeuten "mach das überhaupt nicht, wenn du X nicht kannst".
Sven
Der Before=Abschnitt der Manpage scheint dies zu bestätigen. 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 So wie ich das verstehe, würde die Bestellung nicht erzwungen werden, wenn sie bar.serviceohnehin nicht gestartet wird und foo.servicenormal starten würde.
Sven
9

Einer der Hauptunterschiede ist,

  • After Überprüft nur, ob die Einheit bereits aktiviert ist, und aktiviert die angegebenen Einheiten nicht explizit.
  • Die in aufgelisteten Einheiten Requireswerden zusammen mit der Einheit aktiviert. Wenn eine der erforderlichen Einheiten nicht startet, wird die Einheit nicht aktiviert.

Angenommen, ich habe eine Unit-Datei test-app.service,

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

Folgendes passiert, wenn diese Anweisung ausgeführt wird:

  • Afterprüft ob network-online.target.
  • Wird es network-online.targetnicht gestartet, wartet es.
  • test-appstartet erst nachdem network-online.targetaktiv ist

Wenn ich Requiresstattdessen hätte,

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

Folgendes passiert, wenn diese Anweisung ausgeführt wird:

  • network-online.targetund test-appwerden gemeinsam aktiviert
  • Wenn network-online.targetnicht gestartet test-appwird, wird nicht aktiviert.
Sufiyan Ghori
quelle
2

systemd ist ein Jobmanager. Die Manpage ist nicht sehr genau, wie die Dinge funktionieren.

Wenn Sie booten, erstellt systemd eine Transaktion, die aus Jobs für den Ankerjob besteht (dh start job for default.target). All diese Abhängigkeiten und Beziehungen definieren, wie und welche Jobs ausgelöst werden. Durch die Bestellung wird festgelegt, auf welche (n) Job (s) jeder andere Job wartet. Die default.target-Einheit steht daher im Mittelpunkt all dessen, weshalb Sie beim Aktivieren von Einheiten eine umgekehrte Abhängigkeit verwenden, die durch systemctl enable eine symbolische Dateisystemverknüpfung erzeugt, die eine Vorwärtsabhängigkeit anzeigt, der systemd folgen kann (auch, warum Sie Dateisystemverknüpfungen in der Datei benötigen) erster Platz). Ähnlich ist es, wenn Sie eine Einheit manuell starten, diese Einheit dann Anker ist und die Transaktion für sie berechnet wird.

Ich gehe nicht zu sehr ins Detail und erkläre, was Requires = und After = tun.

Requires = veranlasst systemd, einen Startjob für die erforderliche Einheit auszulösen, wenn Sie einen Startjob ausgelöst bekommen (explizit oder durch eine Abhängigkeit: es gibt intern keine Unterscheidung). Es hat auch die Eigenschaft, einen Stoppjob bei Ihnen auszulösen, wenn dieses Gerät gestoppt (Hinweis: gestoppt, nicht von selbst heruntergefahren) oder neu gestartet wird. Dies bedeutet, dass Sie auch stoppen / neu starten, wenn Abhängigkeiten / systemctl dazu führen, dass sie gestoppt / neu gestartet werden. Wenn es jedoch von selbst ausfällt, werden Sie nicht aufhören, da es keinen Job gab und der Zustandswechsel ohne die Beteiligung von systemd stattfand. Hier würden Sie BindsTo = verwenden (ähnlich wie Geräteeinheiten, die aus offensichtlichen Gründen ohne die Beteiligung von systemd inaktiv werden können).

Jetzt wird die Verwendung von After = empfohlen, da Requires = allein für die jeweiligen Aufgaben von großer Bedeutung ist: Brechen Sie das Require ab, wenn der Startjob fehlschlägt. Dieser Abbruch funktioniert jedoch nur für Aufträge, dh wenn die andere Einheit keine Reihenfolge definiert, löst systemd beides parallel aus, und wenn der Startauftrag endet, bevor der Startauftrag fehlschlägt, wird er nicht abgebrochen (er kann tatsächlich nicht abgebrochen werden). . Die Verwendung von After = bedeutet, dass ein anderer Job so lange wartet, bis der Startjob der gewünschten Einheit beendet ist. Je nach Ergebnis wird der wartende Startjob Ihrer Einheit mit dem Jobergebnis JOB_DEPENDENCY abgebrochen (warum Sie gelb verwenden [DEPEND]). beim Booten für solche Fälle). Daher ist dieser Invalidierungseffekt ohne die Verwendung von After = undeterministisch.

Dies ist der Grund, warum die Verwendung von Wants = ohne After = in Ordnung ist, wenn Sie nicht auf den Start der anderen Einheit warten möchten: Da dort keine Ungültigkeitserklärung vorliegt, gibt es kein Rennen. In diesem Fall handelt es sich lediglich um einen Synchronisationsmechanismus.

Sie können auch beide beim Booten aktivieren und einander nicht benötigen und nur die Reihenfolge definieren. In diesem Fall werden beide im Rahmen derselben Transaktion abgerufen und sortiert (oder wenn der Auftrag für den anderen ausgelöst wird) Während der Job für die Einheit ausgeführt wird, nach der er ausgeführt werden soll, wartet er zunächst transaktionsübergreifend darauf, dass er beendet wird.

Wenn jetzt kein Auftrag vorhanden ist, hat die Bestellung keine Auswirkung auf das betreffende Gerät. In der Regel gibt es jedoch einen Job, da Abhängigkeiten wie Requires = und Wants = verwendet werden oder beide gleichzeitig abgerufen werden und eine bestimmte Reihenfolge definieren. In diesem Fall warten sie auf den Job bzw. die Jobs einer anderen Einheit.

Jonathan Kowalski
quelle