Abhängigkeiten der System-Netzwerkkonfiguration
Es ist sehr einfach, die Einheitenbestellung von systemd zu beeinflussen. Andererseits müssen Sie vorsichtig sein, was eine fertige Einheit garantiert.
Konfigurieren Sie Ihren Dienst
Bei aktuellen Systemen network.target
garantiert die Bestellung nach nur, dass der Netzwerkdienst gestartet wurde, nicht, dass eine tatsächliche Konfiguration vorliegt. Sie müssen danach bestellen network-online.target
und es hineinziehen, um das zu erreichen.
[Unit]
Wants=network-online.target
After=network-online.target
Für die Kompatibilität mit älteren Systemen müssen Sie möglicherweise auch nach network.target bestellen.
[Unit]
Wants=network-online.target
After=network.target network-online.target
Das ist für die Unit-Datei Ihres Dienstes und für systemd.
Implementierung in aktuelle Softwareversionen
Jetzt müssen Sie sicherstellen, dass dies network-online.target
wie erwartet funktioniert (oder zumindest verwendet werden kann network.target
).
Die aktuelle Version von NetworkManager bietet das, NetworkManager-wait-online.service
was von network-online.target
und damit von Ihrem Dienst abgerufen wird. Dieser spezielle Dienst stellt sicher, dass Ihr Dienst wartet, bis alle Verbindungen, die für den automatischen Start konfiguriert sind, erfolgreich sind, fehlschlagen oder eine Zeitüberschreitung aufweisen.
Die aktuelle Version von systemd-networkd blockiert Ihren Dienst, bis alle Geräte wie angefordert konfiguriert sind. Es ist einfacher, da derzeit nur Konfigurationen unterstützt werden, die beim Booten angewendet werden (genauer gesagt die Startzeit von `systemd-networkd.service).
Der Vollständigkeit halber /etc/init.d/network
blockiert der Dienst in Fedora, wie von den aktuellen Versionen von systemd interpretiert, network.target
und damit indirekt auch network-online.target
Ihren Dienst. Es ist ein Beispiel für eine Skript-basierte Implementierung.
Wenn sich Ihre Implementierung, ob daemon- oder skriptbasiert, als einer der oben genannten Netzwerkverwaltungsdienste verhält, verzögert sie den Start Ihres Dienstes, bis die Netzwerkkonfiguration entweder erfolgreich abgeschlossen wurde, aus gutem Grund fehlgeschlagen ist oder nach einer angemessenen Zeit abgelaufen ist Rahmen zu vervollständigen.
Möglicherweise möchten Sie überprüfen, ob netctl auf die gleiche Weise funktioniert, und diese Informationen sind eine wertvolle Ergänzung zu dieser Antwort.
Implementierungen in älteren Softwareversionen
Ich glaube nicht, dass Sie eine ausreichend alte Version von systemd sehen werden, bei der dies nicht gut funktioniert. Aber Sie können prüfen, ob zumindest network-online.target
existiert und dass es nach geordnet wird network.target
.
Bisher garantierte NetworkManager nur, dass mindestens eine Verbindung angewendet wurde. Und selbst damit das funktioniert, müsste man das NetworkManager-wait-online.service
explizit aktivieren . Dies wurde in Fedora schon lange behoben, aber erst kürzlich im Upstream angewendet.
systemctl enable NetworkManager-wait-online.service
Hinweise zur Implementierung von network.target und network-online.target
Sie sollten nicht immer Ihre Software hängen von vornehmen müssen NetworkManager.service
oder NetworkManager-wait-online.service
noch andere spezifische Dienstleistungen. Stattdessen sollten sich alle Netzwerkverwaltungsdienste vor network.target
und optional selbst bestellen network-online.target
.
Ein einfacher skriptbasierter Netzwerkverwaltungsdienst sollte die Netzwerkkonfiguration vor dem Beenden abschließen und sich vor network.target
und damit indirekt vor dem Beenden selbst anordnen network-online.target
.
[Unit]
Before=network.target
[Service]
Type=oneshot
ExecStart=...
RemainAfterExit=yes
Ein Daemon-basierter Netzwerkverwaltungsdienst sollte sich ebenfalls vorher network.target
selbst bestellen, auch wenn dies nicht sehr nützlich ist.
[Unit]
Before=network.target
[Service]
Type=simple
ExecStart=...
Ein Dienst, der für die Daemon wartet beenden sollte sich nach dem Dienst bestellen und vor network-online.target
. Es sollte Requisite
auf dem Daemon-Dienst verwendet werden, damit es sofort fehlschlägt, wenn der entsprechende Netzwerkverwaltungsdienst nicht verwendet wird.
[Unit]
Requisite=...
After=...
Before=network-online.target
[Service]
Type=oneshot
ExecStart=...
RemainAfterExit=yes
Das Paket sollte einen Symlink zum wartenden Dienst im wants
Verzeichnis für installieren network-online.target
, damit er von Diensten abgerufen wird, die auf das konfigurierte Netzwerk warten möchten.
ln -s /usr/lib/systemd/system/... /usr/lib/systemd/system/network-online.target.wants/
Dazugehörige Dokumentation
Schlussnoten
Ich hoffe, dass ich Ihnen nicht nur bei der Beantwortung Ihrer Frage geholfen habe, sondern auch dazu beigetragen habe, die Situation in Upstream- und Linux-Distributionen zu verbessern, sodass ich jetzt eine bessere Antwort geben kann, als dies zum Zeitpunkt des Erstellens der ursprünglichen möglich war .
no-auto-default
nur dafürauto
. Haben Sie eine konkrete Frage? Meiner Meinung nach heißt es in der Manpage von nm-online eindeutig, dass damit-s
darauf gewartet wird, dass alle automatischen Verbindungen versucht werden, dh verbunden oder fehlgeschlagen sind./etc/init.d/network
oder ähnlichem erhalten, aber das funktioniert nicht universell.After
In[Unit]
Abschnitt können Sie einen Dienst definieren, der vor dem Start Ihres Dienstes gestartet werden soll. Wenn Sie beispielsweise NetworkManager verwenden, können Sie den Dienst nach dem Start von NetworkManager starten.quelle
BindsTo
ist hier nicht so angemessen, da es sich bei dem Dienst um ein einmaliges Ereignis und nicht um einen dauerhaften Dienst handelt (es sei denn, es enthält auch eineExecStop
Funktion, die ausgelöst wird, wenn das Netzwerk ausfällt).BindsTo
BindsTo
soll, z. B.,Requires
wenn der Dienst nur ausgeführt werden soll, wenn NetworkManager dies tut.After
macht das eigentlich nicht - es bedeutet nur, dass, wenn NM auch läuft, dies danach ausgeführt wird. Wenn NM nicht ausgeführt wird, wird der Dienst an einem beliebigen Punkt ausgeführt.After=foo
wird nicht dazu führen , dasfoo
Gerät zu starten , wenn es nicht bereits gestartet wird, wird es nur systemd sagen , wie die Einheiten bestellen , wenn sie beide zur gleichen Zeit gestartet . Mit beidenAfter=foo
sowieWants=foo
oderRequires=foo
die Wirkung des Ziehens in haben ,foo
wenn es nicht gestartet ist, und auch systemd um die Geräte richtig zu machen.Wenn Ihr Dienst einen Server bereitstellt, der passiv darauf warten kann, dass sich jemand mit ihm verbindet, verwenden Sie Folgendes:
Ihr Dienst sollte an die Platzhalter-Schnittstelle gebunden sein. Wenn die Socket-Aktivierung verwendet wird (empfohlen) oder wenn sie nur lokal ist, können Sie Netzwerkziele vollständig ignorieren.
Wenn Ihr Service als Client fungiert oder Peer-to-Peer ist, ist dies angemessener:
Vor systemd 213 benötigt network-online.target die erwähnte Problemumgehung Pavel (Sie müssen manuell einen Dienst aktivieren, der darauf wartet, dass das Netzwerk aktiv ist). Ab System 213 erfolgt dies standardmäßig.
systemd-networkd-wait-online
Wartet darauf, dass mindestens eine Adresse (entweder routingfähig oder verbindungslokal) auf einer Nicht-Loopback-Schnittstelle konfiguriert wird.Das Konfigurieren von systemd-networkd, NetworkManager oder einer entsprechenden Komponente ist eine eigenständige Aufgabe. DHCP (für IPv4) und NDP (für IPv6) funktionieren in der Regel sofort, Sie sollten sie jedoch so konfigurieren, dass Ihre genaue Definition von „Das Netzwerk ist aktiv“ die Auslöser sind
network-online.target
.Dokumentation:
quelle
Das hat den gegenteiligen Effekt von dem, was Sie wollen. Von
man systemd.unit
:Basierend darauf können wir sehen, dass die richtige Einheitenoption "Wants" oder "Requires" ist. Basierend auf deren Beschreibung ist "Requires" wahrscheinlich richtig, mit dem Zusatz "After", um nicht nur sicherzustellen, dass der Netzwerkdienst ausgeführt wird, sondern auch, dass er vor diesem Gerät ausgeführt wird.
Keine der Einheitenoptionen, AFAIK, kann die Bedingung enthalten, dass eine gestartete Anforderung abgeschlossen sein muss oder einen bestimmten Punkt erreicht hat (Netzwerk ist wahrscheinlich ein Daemon-Dienst), nur dass sie zuerst gestartet wird . In diesem Sinne möchten Sie möglicherweise Ihr Skript
Type=forking
erstellen und eine fehlerfreie Verzögerung (z. B. 30 Sekunden) oder eine Art Exit-On-Success-Schleife mit einer Verzögerung einleiten, um sicherzustellen, dass Sie zuerst eine DHCP-Lease haben.quelle
After
im Zusammenhang mitRequires
"Sicherstellen, dass der Netzwerkdienst nicht nur ausgeführt wird, sondern auch vor diesem Gerät" ausdrücklich erwähnt .After
arbeitet mitWants
oder aufRequires
diese Weise zusammen. Auf der anderen Seite sind explizite Verzögerungen eine schlechte Angewohnheit in abhängigkeitsbasierten Tools, insbesondere wenn es eine explizite Möglichkeit gibt, zu warten, bis das Netzwerk konfiguriert ist, wie in der Systemdokumentation angegeben. Ich muss also auf der Ablehnung bestehen.Verwenden Sie
After
in diesem[Unit]
Abschnitt, um anzugeben, was vor Ihrem eigenen Dienst gestartet werden soll. (So viel von der vorherigen Antwort ist richtig.)Verwenden Sie das Netzwerkziel, um Ihren Dienst nach dem Hochfahren des Netzwerks zu starten. Dies sollte unabhängig davon gelten, ob Sie NetworkManager, das conf.d / netctl-System in Arch oder einen anderen Dienst verwenden, der systemd bekannt ist.
Ein kurzer Blick bestätigt, dass jeder andere Dienst auf Ihrem System, der auf Netzwerkkonnektivität angewiesen ist, diese Anweisung enthält.
Es ist auch portierbar für alle Distributionen, die systemd verwenden. Ihre Unit-Datei wird dieselbe sein für Arch, Fedora, RHEL 7, zukünftige Versionen von Debian ...
Dienste , die starten eine Netzwerkverbindung, wie Arch Skripte oder eigenen, sollten angeben , damit ihre eigenen Unit - Dateien.
quelle
Wants
Teil nicht ganz, weil es Nebenwirkungen auf andere Pakete hat. Schau dir bitte meine Antwort an.Wants
onnetwork.target
hier eine gute Idee ist.Ich wollte diesem Artikel einen Punkt hinzufügen. Derzeit (Sommer 2015) in RHEL7 / CentOS 7 ist network-online.target vor dem Hochfahren des IPv6-Netzwerks falsch eingestellt
In ihrer Dienstdefinition werden auch explizit an IPv6-Adressen gebundene Dienste wahrscheinlich gestartet, bevor IPv6 ausgeführt wird, was zu einem Fehler führt.
quelle
/etc/init.d/network
. Wenn Sie das gleiche Problem auch mit NM erhalten, ist dies ein guter Grund, eine Funktionsanforderung einzureichen. Ich habe nicht bei RHEL / CentOS nachgefragt, ich kann Ihnen bei Interesse mit den Details helfen.funktioniert bei mir.
quelle
networkd
einen eigenen / wait-online / Service gibt. Das Einziehen und Nachbestellennetwork-online.target
ist der richtige Weg, um mit jedem Dienst zu beginnen, der dies unterstützt.