![Hintergrund](https://rvso.com/image/726372/Hintergrund.png)
Hintergrund
Ich wurde gebeten, ein systemd
Skript für einen neuen Dienst zu erstellen, foo_daemon
der manchmal in einen „schlechten Zustand“ gerät und nicht beendet wird SIGTERM
(wahrscheinlich aufgrund eines benutzerdefinierten Signalhandlers). Dies ist für Entwickler problematisch, da sie angewiesen werden, den Dienst folgendermaßen zu starten/stoppen/neu zu starten:
systemctl start foo_daemon.service
systemctl stop foo_daemon.service
systemctl restart foo_daemon.service
Problem
Manchmal müssen wir es aufgrund foo_daemon
eines schlechten Zustands gewaltsam beenden, und zwar folgendermaßen:
systemctl kill -s KILL foo_daemon.service
Frage
systemd
Wie kann ich mein Skript einrichten foo_daemon
, sodass jedes Mal, wenn ein Benutzer versucht, den Dienst zu stoppen/neu zu starten, systemd
Folgendes geschieht:
- Versuchen Sie ein ordnungsgemäßes Herunterfahren
foo_daemon
überSIGTERM
. - Warten Sie bis zu 2 Sekunden, bis das Herunterfahren/Beenden abgeschlossen ist
foo_daemon
. foo_daemon
Versuchen Sie, via zwangsweise herunterzufahren,SIGKILL
wenn der Prozess noch aktiv ist (damit wir nicht das Risiko eingehen, dass der PID wiederverwendet wird undsystemd
ProblemeSIGKILL
mit dem falschen PID auftreten). Das Gerät, das wir testen, erzeugt/verzweigt schnell zahlreiche Prozesse,Es besteht daher die seltene, aber durchaus reale Sorge, dass das PID-Recycling zu Problemen führen könnte.- Wenn ich in der Praxis einfach nur paranoid hinsichtlich der PID-Wiederverwendung bin, ist es für mich in Ordnung, wenn das Skript einfach
SIGKILL
für die PID des Prozesses ausgeführt wird, ohne mir Gedanken darüber machen zu müssen, eine wiederverwendete PID zu zerstören.
Antwort1
systemd unterstützt dies bereits standardmäßig und es iststandardmäßig aktiviert.
Das einzige, was Sie möglicherweise anpassen möchten, ist das Timeout TimeoutStopSec=
. Dies können Sie mit tun. Beispiel:
[Service]
TimeoutStopSec=2
Jetzt sendet systemd ein SIGTERM, wartet zwei Sekunden, bis der Dienst beendet wird, und sendet andernfalls ein SIGKILL.
Wenn Ihr Dienst nicht systemd-fähig ist, müssen Sie möglicherweise den Pfad zu seiner PID-Datei mit angeben PIDFile=
.
Schließlich haben Sie erwähnt, dass Ihr Daemon viele Prozesse erzeugt. In diesem Fall möchten Sie möglicherweise festlegen, KillMode=control-group
dass systemd Signale an alle Prozesse in der Kontrollgruppe sendet.
Antwort2
Da niemand die Notwendigkeit erwähnt hat Type=oneshot
, finden Sie hier ein vollständiges Beispiel, das aufgrund eines Timeout-Fehlers beendet wird.
[Unit]
Description=timeout test
[Service]
Type=oneshot
TimeoutStartSec=2
ExecStart=/bin/sleep 10