Ich habe einen systemd-Dienst, um ein Überwachungs-Bash-Skript auszuführen, das von einem systemd-Timer gestartet wird. Ich habe das verwendet, Type=oneshot
was am geeignetsten erscheint. Manchmal muss das Skript jedoch ein anderes Programm aufrufen, das sich dann aufspaltet. Sobald dies geschieht, ist das Skript fertig und wird beendet. Sobald das Skript beendet ist, beendet systemd jedoch alle verbleibenden untergeordneten Prozesse.
Ich könnte KillMode=process
dies verhindern, aber dann besteht das Risiko, dass in anderen Pfaden durch das Skript andere Prozesse (die sich nicht verzweigen) nach dem Beenden weiter ausgeführt werden könnten.
Wie geht man damit am besten um?
Das Forking-Programm ist übrigens dhcpcd, aber ich denke, die Frage ist allgemeiner Natur. dhcpcd wurde ursprünglich von ifplugd gestartet und dieses Skript ist eine Ausfallsicherung für den Fall, dass das System in einen Zustand gerät, in dem dhcpcd nicht mehr läuft.
Antwort1
Prozesse werden beendet, weil sie zu einer Kontrollgruppe (cgroup) gehören, die dem Dienst zugeordnet ist, z. B. hier (für Systemdienste):
/sys/fs/cgroup/systemd/system.slice/your-service.service
Um einen Prozess aus der Kontrollgruppe zu verschieben,Weisen Sie es einer anderen Kontrollgruppe zu. Die "übergeordnete Kontrollgruppe" scheint richtig zu sein. Für einen Systemdienst sieht es so aus:
echo <PID> > /sys/fs/cgroup/systemd/system.slice/tasks
# or even to the general systemd cgroup
echo <PID> > /sys/fs/cgroup/systemd/tasks
Um einen Befehl von Anfang an in dieser Kontrollgruppe auszuführen, führen Sie eine Shell aus, die sich selbst der Kontrollgruppe zuordnet, und exec
wechseln Sie dann zum eigentlichen Befehl:
sh -c 'echo "$$" > /sys/fs/cgroup/systemd/tasks; exec /the/forking/program'
/the/forking/program
ersetzt die Shell, die sich bereits in der neuen Kontrollgruppe befindet. Wenn sie sich aufspaltet, befindet sich die aufgespaltene Instanz in der neuen Kontrollgruppe. Wenn das Hauptskript beendet wird, beendet systemd Prozesse in der Kontrollgruppe, die mit dem Dienst verknüpft ist, aber das betreffende Programm ist nicht darunter.
Vielleicht gibt es eine bessere Möglichkeit, Ihr Problem zu lösen, mit Unit-Dateien oder so. Ich weiß es aber nicht.