Warten, bis ein Dienst gestartet ist? [Gelöst]

Warum Debian und/oder eine seiner Spielarten? Was muss ich vorher wissen? Wo geht es nach der Installation weiter?
Antworten
jmar83
Beiträge: 962
Registriert: 20.06.2013 20:20:15
Wohnort: CH
Kontaktdaten:

Warten, bis ein Dienst gestartet ist? [Gelöst]

Beitrag von jmar83 » 21.11.2019 15:46:59

Hallo zusammen

Würde es gerne in einem Skript so machen, dass ich einen Dienst starten kann (über systemctl oder service..), und dann auf der nächsten Zeilen dynamisch gewartet wird (z.B. Endlosschleife) bis der Prozess wirklich existiert.

Irgendwie finde ich im Netz fast nur Beispiele welche z.B. bei Apache auf Port 80 oder bei MySQL auf Port 3306 prüfen: https://www.google.com/search?biw=1920& ... i8Q4dUDCAs

Es sollte in meinem Fall eher was sein, was generisch, also allgemein verwendbar, ist.

Vielen Dank für die Feedbacks.
Zuletzt geändert von jmar83 am 09.12.2019 16:29:00, insgesamt 2-mal geändert.
Freundliche Grüsse, Jan

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

Re: Warten, bis ein Dienst gestartet ist?

Beitrag von smutbert » 21.11.2019 17:22:08

Ganz allgemein kannst du doch mit systemd prüfen ob ein bestimmer Dienst bereits läuft. Falls das sinnvoll/notwendig ist, können die Prozesse systemd mitteilen, wenn sie einsatzbereit sind (systemd-notify). Startest du also eine service-Unit beispielsweise mit

Code: Alles auswählen

systemctl start mein-service.service
dann ist der Befehl erst fertig, wenn dieser Service gestartet und einsatzbereit ist. Das setzt natürlich voraus, dass der Service systemd darüber informiert, dass er einsatzbereit ist, was mit systemd-notify möglich ist. Ein Beispiel für eigene Dienste, die dieses Feature nutzen gibt es hier: https://askubuntu.com/questions/1120023 ... emd-notify
(Der Hauptprozess des fraglichen Dienstes sollte aber auf jeden Fall bereits existieren, wenn systemctl start ... abgeschlossen ist.)


Ansonsten habe ich behelfsweise auch schon in einer Endlosschleife auf einen Prozesse gewartet, die nicht von systemd gestartet werden. Etwa so

Code: Alles auswählen

#!/bin/bash

PROCESS_NAME=mpd

while : ; do
	pgrep "${PROCESS_NAME}" && break
	sleep 1s
done
echo "Prozess gestartet"
Keine sehr elegante Lösung, aber im Fall von mpd hat es sehr gut funktioniert und eventuell kann man die Suche mit pgrep noch mit weiteren Parametern präzisieren und damit verlässlicher machen.

jmar83
Beiträge: 962
Registriert: 20.06.2013 20:20:15
Wohnort: CH
Kontaktdaten:

Re: Warten, bis ein Dienst gestartet ist?

Beitrag von jmar83 » 22.11.2019 11:12:32

Vielen Dank!!

Code: Alles auswählen

"dann ist der Befehl erst fertig, wenn dieser Service gestartet und einsatzbereit ist. Das setzt natürlich voraus, dass der Service systemd darüber informiert, dass er einsatzbereit ist, was mit systemd-notify möglich ist."
Lässt sich das eigentlich nicht auch in der Unit-Datei (systemd) festlegen, type=... (simple, idle, fork...etc.?)
Freundliche Grüsse, Jan

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

Re: Warten, bis ein Dienst gestartet ist?

Beitrag von smutbert » 22.11.2019 23:18:03

Bei den unterschiedlichen typen fehlt mir ein bisschen der Überblick, aber bei simple, dbus und idle trifft das auf jeden Fall zu was ich gesagt habe und bei notify muss der Dienst systemd darüber informieren, dass er bereit ist.
oneshot ist insofern anders, als da der Dienst als bereit gilt, nachdem sich der Prozess beendet hat.

Den Unterschied zwischen simple und exec kapiere ich nicht und bei fork rechnet systemd damit, dass sich der gestartete Elternprozess beendet und ein bestimmter Kindprozess (idealerweise mit PID-Datei) der entscheidende ist.

jmar83
Beiträge: 962
Registriert: 20.06.2013 20:20:15
Wohnort: CH
Kontaktdaten:

Re: Warten, bis ein Dienst gestartet ist?

Beitrag von jmar83 » 25.11.2019 16:52:39

Vielen Dank für dein Feedback. Ja, das ganze ist nicht ganz trivial, und die Methode mit der Prozessüberprüfung sollte zwar allgemein verwendbar sein - diese ist aber auch eher "suboptimal"...
Freundliche Grüsse, Jan

JTH
Moderator
Beiträge: 3023
Registriert: 13.08.2008 17:01:41
Wohnort: Berlin

Re: Warten, bis ein Dienst gestartet ist?

Beitrag von JTH » 25.11.2019 20:35:38

Da du nicht verraten hast, was dein Anwendungsfall ist (evtl. gäbe es eine bessere Lösung), ein paar allgemeine, aber auch systemd-spezifische Anmerkungen dazu:

Man kann generell feststellen, ob ein Prozess (für eine bestimmte Anwendung) läuft – wie schon öfter angesprochen per pgrep, ps etc.. Das heißt aber noch lange nicht, dass die Anwendung dahinter schon „ansprechbar“ ist, z.B. ein Webserver wie oben erwähnt auf Port 80 erreichbar ist. Es könnte in dem Prozess immer noch irgendeine Art der „Vorbereitung“ laufen. Für „Ansprechbarkeit“ braucht es eigentlich immer eine spezielle Methode, 100% generisch geht das nicht.

Wenn ein Dienst, z.B. per systemctl start gestartet wird passiert folgendes: systemd (PID 1) fork()t einen neuen Prozess ab (PID x), dieser Prozess (PID x) ersetzt per execve() sich selbst mit dem zu startenden Dienst (/usr/bin/apache2, /usr/bin/mpd, /usr/sbin/whatever; weiter PID x). Erst da ganz am Ende läuft der eigentliche Dienst und kann seine eigenen „Vorbereitungen“ treffen, nach denen er „ansprechbar“ ist.

Im Normalfall (Type=simple) geht systemctl start davon aus, dass der Dienst schon nach dem fork() erfolgreich gestartet ist. Das kann aber nach dem execve() immer noch schief gehen, wenn das eigentliche Programm einen Fehler verursacht.

Beim Type=exec geht systemctl start erst nach dem execve() davon aus, dass der Dienst gestartet ist. Damit bekommt man durch das systemctl start evtl. mehr Fehler mit und der Dienst ist außerdem schon „weiter“ gestartet, als beim Type=simple. Das garantiert aber wie gesagt immer noch nicht, dass ein Dienst schon „ansprechbar“ ist.

Ein systemctl start (ohne --no-block) wartet also im Normalfall schon so lange, bis ein Dienst läuft – soweit das allgemein sinnvoll möglich ist. Genaueres braucht eine Extrawurst: sd_notify(), Aktivierung des Services über nen systemd.socket, nen PID-File etc. – hängt von der Anwendung ab.
Manchmal bekannt als Just (another) Terminal Hacker.

jmar83
Beiträge: 962
Registriert: 20.06.2013 20:20:15
Wohnort: CH
Kontaktdaten:

Re: Warten, bis ein Dienst gestartet ist?

Beitrag von jmar83 » 26.11.2019 09:05:27

Vielen Dank für deine hoch ausführliche Erklärung!! :-)
Freundliche Grüsse, Jan

Antworten