dependency based boot

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
king-crash
Beiträge: 739
Registriert: 08.08.2006 12:07:56
Lizenz eigener Beiträge: MIT Lizenz

dependency based boot

Beitrag von king-crash » 16.11.2017 17:33:24

Ich habe eine grundsätzliche Frage zum Starten von von einander abhängigen Diensten.
Nehmen wir an, ich habe einen Dienst A der mit einem Server kommuniziert. Dieser Server ist nur via VPN -> Dienst B, erreichbar.

Folglich darf Dienst A erst nach Dienst B starten.
Woher ist beispielsweise einer Init wie systemd bekannt wann in diesem Fall Dienst B eine Verbindung aufgebaut hat und er mit der Bootschleife (Dienst A) weiter machen kann?

TomL

Re: dependency based boot

Beitrag von TomL » 16.11.2017 17:52:00

Systemd weiss nur, dass eine Netzwerkverbindung etabliert wurde. Wenn ein bestimmter Server verfügbar sein muss, musst Du Dir eine eigene service-unit und ein kleines Script schreiben, die die Erreichbarkeit prüft. Das ist eigentlich eine einfache Sache....

Andersrum, die reine Reihenfolge von Units legt man mit After und Before-Statements fest. Damit ist es aber nicht möglich, die tatsächliche Erreichbarkeit eines Servers zu prüfen.

Benutzeravatar
king-crash
Beiträge: 739
Registriert: 08.08.2006 12:07:56
Lizenz eigener Beiträge: MIT Lizenz

Re: dependency based boot

Beitrag von king-crash » 18.11.2017 11:47:01

Hm war jetzt möglicherweise ein schlechtes Beispiel.
Ich versuche es anderst. Ein fork-exec um einen neuen Dienst zu starten dauert wenige Millisekunden. So gesehen müssten, wenn es keine andere Rückmeldung gibt, voneinander abhängige Dienste in viel zu kurzer Zeit starten.

Mit "systemd-analyze blame" habe ich aber Sachen wie "2.401s openvpn@bla.service".
Der Dienst läuft ab Start die ganze Zeit. Die 2.401s sind wie ich vermute die Zeit, bis eine Verbindung aufgebaut wurde.
Woher ist systemd das bekannt? Gibt der VPN eine Rückmeldung, "verbindung aufgebaut"?

Wenn ich das jetzt nachstellen wollte: Ich erstelle einen Testdienst, der permanent laufen und nach 2 Sekunden signalisieren soll er habe gestartet. Wie würde ich das anstellen?

Benutzeravatar
smutbert
Beiträge: 8342
Registriert: 24.07.2011 13:27:39
Wohnort: Graz

Re: dependency based boot

Beitrag von smutbert » 18.11.2017 11:59:37

Es gibt network-online.target, das die vershiedenen Tools zum Konfigurieren des Netzwerks nutzen können um bekannt zu geben ob eine Netzwerkverbindung besteht. Der network-manager bringt dazu zum Beispiel die Datei »/lib/systemd/system/NetworkManager-wait-online.service« und erzeugt einen Link in »/etc/systemd/system/network-online.target.wants/NetworkManager-wait-online.service«.

Diverse openvpn-Units, unter anderem openvpn@.service haben eine Abhängigkeit von network-online.target.


Auf ganz ähnliche Art kann openvpn das Starten weiterer Dienste hinauszögern, so habe ich zum Beispiel in openvpn@.service

Code: Alles auswählen

Before=systemd-user-sessions.service
gefunden. Der Typ notify, der sich in dieser Unit findet, bedeutet obendrein, dass dieser Dienst ein Signal an systemd sendet, wenn er bereit ist
Das heißt Benutzer können sich erst anmelden wenn openvpn bereits läuft

Benutzeravatar
king-crash
Beiträge: 739
Registriert: 08.08.2006 12:07:56
Lizenz eigener Beiträge: MIT Lizenz

Re: dependency based boot

Beitrag von king-crash » 18.11.2017 12:38:01

Danke, es wird heller.

Was ich noch gefunden habe https://www.freedesktop.org/software/sy ... rvice.html
Ich fasse das Zusammen. Wie systemd weiß ob ein service gestartet ist hängt von der Option "Type" in der config ab:

Type=notify -> Der service kommuniziert mit Systemd mittels einer library https://www.freedesktop.org/software/sy ... otify.html

Type=simple -> Es wird sofort nach Start mit der Bootreihenfolge weiter gemacht. Evtl kann systemd sockets zuvor selbst anlegen? Stichwort "socket activation"?

Type=forking -> Systemd geht davon aus, dass der von ihm gestartete Prozess sich nach der Initialisierung selbst beendet und zuvor einen Kindprozess anlegt, der die Arbeit zur Laufzeit erledigt. Welche PID dieser Kindprozess hat muss derselbe in die Datei die mit Option "PIDFile=" schreiben. systemd liest diese und kann so die Zuordnung herstellen.

Type=oneshot -> Es wird auf die Beendigung des Dienstes gewartet bevor weiter gemacht wird. Z.B. für Initialisierungen wie iptables.

Type=dbus -> Systemd wartet bis sich ein Teilnehmer am dbus anmeldet der den Namen der mit der Option "BusName=" angegeben wird hat

Antworten