
Ich bin gerade dabei, einen bestehenden /etc/init.d-Dienst in systemd umzuwandeln. Es schien zu funktionieren, aber ich bin auf ein seltsames Problem gestoßen. Der systemd-Dienst startet problemlos mit dem Befehl „systemctl start service_name“ und stoppt mit „systemctl stop service_name“, aber er scheint nicht sauber zu stoppen. Die zugrunde liegende Anwendung prüft, ob sie bereits ausgeführt wird, und beendet sich in diesem Fall sofort. Das ist, was passiert.
Hier ist ein entsprechender Ausschnitt aus dem alten Skript /etc/init.d:
kill_process() {
pkill -SIGINT service_name
sleep 1
if [ -n "$(pgrep service_name)" ]; then
pkill -SIGTERM service_name
sleep 1
fi
if [ -n "$(pgrep service_name)" ]; then
pkill -SIGKILL service_name
sleep 1
fi
if [ -z "$(pgrep service_name)" ]; then
rm -f /var/lock/subsys/service_name
fi
}
start() {
action $"Starting Service: " /sbin/service_name
}
stop() {
action $"Stopping Service: " kill_process
}
restart() {
stop
start
}
Und dies ist mein erster Versuch mit dem systemd-Äquivalent:
[Unit]
Description=Service Name
[Service]
ExecStart=/sbin/service_name
[Install]
WantedBy=multi-user.target
Ich ging davon aus, dass der systemd-Dienst die Prozessbeendigung mit SIGTERM handhaben würde, habe aber mit anderen Werten für KillSignal und ExecStop experimentiert. Ich habe diesen Unterschied im Beendigungsverhalten jedoch noch nicht verstanden. Wenn ich die Anwendung manuell mit SIGINT beende, wird der Dienst außerdem auch nicht sauber beendet. Ich frage mich, ob /etc/init.d hinter den Kulissen noch etwas anderes macht.
Alle Vorschläge sind willkommen.
Antwort1
Ich wollte nur einen Schlussstrich unter diesen Beitrag ziehen, für den Fall, dass er für irgendjemand anderen von Interesse ist.
Die C-Anwendung, die als Teil des Dienstes ausgeführt wird, verwendete zuvor fork(), wenn getppid() nicht bereits 1 war (d. h. noch nicht geforkt war). Es scheint, dass die Anwendung, wenn sie von systemd ausgeführt wird, bereits eine übergeordnete PID von 1 hat. Unsere Anwendung hatte zuvor keine explizite SIGTERM-Behandlung, wurde aber ordnungsgemäß beendet, wenn sie im Kontext von /etc/init.d auf SIGINT reagierte. Ich habe einen speziellen SIGTERM-Handler hinzugefügt und der Dienst verhält sich jetzt wie erwartet.