Das braucht man nicht unbedingt.
Wenn die C
Dienste warten müssen, S
bis sie bereit sind, damit sie eine Socket-Verbindung herstellen können, muss dies nicht unbedingt der Fall sein. Vielmehr kann man das frühzeitige Öffnen der Hörbuchse durch Service-Manager nutzen.
Einige Systeme, darunter Laurent Bercots s6 , mein Nosh-Toolset und systemd, bieten Möglichkeiten, wie ein Abhörsockel frühzeitig geöffnet werden kann. Dies ist das allererste, was beim Einrichten des Dienstes erforderlich ist . Sie alle umfassen etwas anderes als das Serviceprogramm, das die Listening-Sockets öffnet, und das Serviceprogramm, das beim Aufrufen die Listening-Sockets als bereits geöffnete Dateideskriptoren empfängt.
Insbesondere mit systemd erstellt man eine Socket-Einheit , die den Listening-Socket definiert. systemd öffnet die Socket-Einheit und richtet sie so ein, dass das Kernel-Netzwerksubsystem auf Verbindungen wartet. und übergibt es als offenen Dateideskriptor an den eigentlichen Dienst, wenn es darum geht, die Prozesse zu erzeugen, die Verbindungen zum Socket verarbeiten. (Es kann dies auf zwei Arten tun, genau wie es inetd
könnte, aber eine Diskussion der Details von Accept=true
versus Accept=false
Diensten geht über den Rahmen dieser Antwort hinaus.)
Der wichtige Punkt ist, dass man nicht unbedingt mehr Bestellung braucht. Der Kernel stapelt Clientverbindungen in einer Warteschlange, bis das Serviceprogramm initialisiert ist, und ist bereit, sie zu akzeptieren und mit Clients zu sprechen.
Wenn man das tut, sind Bereitschaftsprotokolle das Richtige.
systemd verfügt über eine Reihe von Bereitschaftsprotokollen , die von Dienst zu Dienst mit der Type=
Einstellung in der Serviceeinheit angegeben werden. Das hier interessierende besondere Bereitschaftsprotokoll ist das notify
Bereitschaftsprotokoll. Damit wird systemd angewiesen, Nachrichten vom Dienst zu erwarten, und wenn der Dienst bereit ist, sendet es eine Nachricht, die die Bereitschaft kennzeichnet. systemd verzögert die Aktivierung der anderen Dienste, bis die Bereitschaft markiert ist.
Dies zu nutzen beinhaltet zwei Dinge:
- Ändern Sie den Code von
S
so, dass er so etwas wie die notify_systemd()
Funktion von Pierre-Yves Ritschard oder die Funktion von Cameron T Norman aufruft notify_socket()
.
- Einrichten der Serviceeinheit für den Service mit
Type=notify
und NotifyAccess=main
.
Die NotifyAccess=main
Einschränkung (dies ist die Standardeinstellung) besteht darin, dass systemd wissen muss, dass Nachrichten von schelmischen (oder einfach nur fehlerhaften) Programmen ignoriert werden, da jeder Prozess im System Nachrichten an den Benachrichtigungssocket von systemd senden kann.
Man verwendet den Code von Pierre-Yves Ritschard oder Cameron T Norman als Präferenz, da er die Möglichkeit nicht ausschließt, diesen Mechanismus unter UbuntuBSD, Debian FreeBSD, tatsächlichem FreeBSD, TrueOS, OpenBSD usw. zu haben. was der von den systemd-Autoren bereitgestellte Code ausschließt.
Eine zu vermeidende Falle ist das systemd-notify
Programm. Es gibt mehrere Hauptprobleme, nicht zuletzt, dass mit ihm gesendete Nachrichten unbearbeitet von systemd weggeworfen werden können. Das größte Problem in diesem Fall ist, dass es nicht als "Haupt" -Prozess des Dienstes ausgeführt wird, sodass die Bereitschaftsbenachrichtigungen für den Dienst S
für jeden Prozess auf dem System mit geöffnet werden müssen NotifyAccess=all
.
Eine weitere zu vermeidende Falle ist die Annahme, dass das forking
Protokoll einfacher ist. Es ist nicht. Um es richtig zu machen , muss das übergeordnete Element erst dann gegabelt und beendet werden, wenn (zum einen) alle Arbeitsthreads des Programms ausgeführt werden. Dies entspricht nicht der Tatsache, dass die überwiegende Mehrheit der Dæmons, die sich gabeln, tatsächlich gabelt.
Weiterführende Literatur
systemd.service(5)
,NotifyAccess=all
akzeptieren Nachrichten von allen Mitgliedern der Kontrollgruppe Dienst , die sie nicht nur irgendeinen Schurken Prozess auf dem System bedeuten. Dies ist für die meisten Anwendungsfälle sicher genug. Auch Ihre Bedenken hinsichtlich der Portabilität auf andere Betriebssysteme sind für OP nicht relevant, da wir uns hier bereits mit dem Thema Systemd befassen.Unter Bezugnahme auf die Handbuchseite
systemd.service(5)
, insbesondere auf den Abschnitt über Type = , hat jeder Diensttyp eine andere Möglichkeit für Systemd, festzustellen, ob es bereit ist, anderen Diensten Funktionen anzubieten:In diesem
Type=simple
Fall sollten die Kommunikationskanäle vor dem Start des Dämons installiert werden (z. B. von systemd eingerichtete Sockets über Socket-Aktivierung).Wenn dies
Type=forking
der Fall ist, wird erwartet, dass der übergeordnete Prozess beendet wird, wenn der Start abgeschlossen ist und alle Kommunikationskanäle eingerichtet sind.Wenn
Type=dbus
dies der Fall ist, wird erwartet, dass der Dämon einen Namen auf dem D-Bus-Bus erhält. An diesem Punkt fährt systemd mit dem Starten der Folgeeinheiten fort.Wenn
Type=notify
dies der Fall ist, wird erwartet, dass der Dämon nachsd_notify(3)
Abschluss des Startvorgangs eine Benachrichtigungsnachricht über oder einen entsprechenden Anruf sendet . systemd fährt mit dem Starten der Folgeeinheiten fort, nachdem diese Benachrichtigung gesendet wurde.Für die letzte Option (Senden einer Nachricht über
sd_notify
) können Sie dassystemd-notify
Dienstprogramm verwenden und daran denken, ihm Zugriff zu gewährenNotifyAccess=all
.Da Sie die Kontrolle über den Service haben
S
, können Sie die beste Option für Ihren Anwendungsfall oder einfach die am einfachsten zu implementierende auswählen.quelle
so was:
S.service
C0.service
C1.service
C9.service
Wobei / usr / bin / myBinary einen sd_notify READY = 1- Aufruf ausführt , wenn die Initialisierung abgeschlossen ist.
Abhängig davon, wie sich die Abhängigkeit verhalten soll, können Sie PartOf, Requires oder BindsTo oder andere verwenden .
quelle