Hintergrund

Hintergrund

Hintergrund

Ich wurde gebeten, ein systemdSkript für einen neuen Dienst zu erstellen, foo_daemonder 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_daemoneines schlechten Zustands gewaltsam beenden, und zwar folgendermaßen:

  • systemctl kill -s KILL foo_daemon.service

Frage

systemdWie kann ich mein Skript einrichten foo_daemon, sodass jedes Mal, wenn ein Benutzer versucht, den Dienst zu stoppen/neu zu starten, systemdFolgendes geschieht:

  • Versuchen Sie ein ordnungsgemäßes Herunterfahren foo_daemonüber SIGTERM.
  • Warten Sie bis zu 2 Sekunden, bis das Herunterfahren/Beenden abgeschlossen ist foo_daemon.
  • foo_daemonVersuchen Sie, via zwangsweise herunterzufahren, SIGKILLwenn der Prozess noch aktiv ist (damit wir nicht das Risiko eingehen, dass der PID wiederverwendet wird und systemdProbleme SIGKILLmit 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 SIGKILLfü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-groupdass 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

verwandte Informationen