Poste normalerweise nicht hier, aber ich reiße mir die Haare darüber aus. Ich besitze ein Python-Skript, das beim Start abgefragt wird und für das Starten einer Reihe anderer Prozesse verantwortlich ist. Dieses Skript wurde früher beim Start über sysvinit gestartet, aber kürzlich habe ich ein Upgrade auf Debian Jessie durchgeführt und es so angepasst, dass es über systemd gestartet werden kann.
Leider stoße ich auf ein Problem, das ich nicht lösen kann. Wenn Sie das Skript direkt in einer Benutzershell starten, werden die untergeordneten Prozesse ordnungsgemäß gestartet, und wenn das Skript beendet wird, werden die untergeordneten Prozesse verwaist und weiterhin ausgeführt.
Wenn der übergeordnete Prozess über systemd gestartet wird, werden auch alle untergeordneten Prozesse beendet. (Nun, der Bildschirm, den sie starten, wird als tot angezeigt. ???)
Idealerweise muss ich in der Lage sein, das übergeordnete Skript neu zu starten, ohne alle untergeordneten Prozesse zu beenden. Fehlt mir etwas?
Vielen Dank!
[Unit]
Description=Server commander
After=network.target
[Service]
User=serveruser
Type=forking
PIDFile=/var/Server/Server.pid
ExecStart=/var/Server/Server.py
ExecStop=/bin/kill -s TERM $MAINPID
[Install]
WantedBy=multi-user.target
Bearbeiten: Es ist wahrscheinlich relevant für mich, darauf hinzuweisen, dass das Python-Skript im Wesentlichen ein "Controller" für seine untergeordneten Prozesse ist. Es startet und stoppt Server in Gnu-Bildschirmen, wie von einem zentralen Server angefordert. Es läuft normalerweise immer, es spawnt keine Dienste und beendet sich nicht. Es gibt jedoch Fälle, in denen ich das Skript neu laden möchte, ohne untergeordnete Prozesse zu beenden, auch wenn dies bedeutet, dass die Prozesse auf PID 1 verwaist sind. Tatsächlich spielt es keine Rolle, ob das Python-Skript Prozesse als gestartet hat ein übergeordneter Prozess, wenn das überhaupt möglich ist.
Eine bessere Erklärung, wie es funktioniert:
- Systemd erzeugt /Server.py
- Server.py gibt die PID-Datei für Systemd aus und schreibt sie
- Server.py erzeugt dann Serverprozesse auf dem Gnu-Bildschirm basierend auf seinen Anweisungen
- Server.py wird weiterhin ausgeführt, um alle vom Server angeforderten Neustarts durchzuführen
Wenn Server.py ohne Systemd gestartet wird, kann es neu gestartet werden, und die von ihm gestarteten Gnu-Bildschirme sind nicht betroffen. Beim Starten mit Systemd werden beim Herunterfahren von Server.py diese Bildschirmprozesse nicht auf PID 1 verwaist, sondern beendet.
quelle
Server.py
Code und eine Beschreibung darüber zu haben, wie die gestarteten Dienste gegabelt werden (wenn sie gegabelt werden). Im Allgemeinen handelt es sich jedoch um ein Problem mit der Nichtübereinstimmung des Bereitschaftsprotokolls .ExecStop=
nicht benötigt. Die Standardaktion von systemd beim Stoppen ist das Abbrechen von Prozessen. Vielleicht möchten Sie einen Blick in die Dokumentation zurKillMode=
Direktive werfen .simple
oderforking
tatsächlich), wäre der letzte Ausweg seinType=oneshot
,RemainAfterExit=yes
undKillMode=control-group
.Antworten:
Ich habe es geschafft, dies einfach zu beheben, indem ich KillMode so eingestellt habe, dass es anstelle der Kontrollgruppe verarbeitet wird (Standardeinstellung). Vielen Dank an alle
quelle
Was darauf hinweist, dass Sie es falsch machen. Mehr dazu gleich.
Dies ist kein korrektes Verhalten. Wenn der "Haupt" -Prozess - in diesem Fall das von Ihnen angegebene
Type=forking
untergeordnete Element - beendet wird, betrachtet systemd den Dienst als deaktiviert und beendet alle anderen noch laufenden Prozesse (in der Kontrollgruppe), um aufzuräumen .Manchmal ist die Konvertierung von System 5-
rc
Skripten nach systemd nicht einfach, da die richtige Vorgehensweise unter systemd ganz anders ist. Der richtige Weg, OpenVPN, OpenStack oder OSSEC HIDS in systemd auszuführen, ist nicht derselbe wie mit einemrc
Skript. Die Tatsache, dass Sie ein Skript haben, das gegabelt wird, dann eine ganze Menge von Enkelprozessen erzeugt und dann damit fertig wird, dass diese Enkelkinder weiterlaufen, zeigt an, dass Sie die gleiche Art von Horror begehen wieossec-control
, wenn auch mit zwei Stufen weniger gegabelt wird. Wenn Sie feststellen, dass Sie ein "Master" -Skript schreiben, das "enable" -Flags überprüft und untergeordnete Prozesse für die "enabled" -Teile Ihres Systems ausführt, machen Sie den gleichen Fehler wie die horrendenossec-control
.Bei systemd sind keine solchen hausgemachten Mechanismen erforderlich. Es ist bereits ein Service Manager. Laut /unix//a/200365/5132 besteht der richtige Weg, dies in systemd zu tun, nicht darin, einen Dienst zu haben, der einen verrückten und verwirrten Versuch hervorruft, "Unterdienste" zu haben. Es ist wichtig, dass jedes untergeordnete Element als eigenständiger systemd-Dienst fungiert. Dann aktiviert und deaktiviert und startet und stoppt man die verschiedenen Teile des Systems unter Verwendung der normalen systemd-Steuerelemente. Wie Sie im OSSEC HIDS-Fall sehen können, deckt eine einfache Vorlagenserviceeinheit fast alle Dienste ab (eine Ausnahme ist /ubuntu//a/624871/43344 ), sodass Sie beispielsweise
systemctl enable [email protected]
eine optionale Serviceeinheit aktivieren könnenagentlessd
Service, ohne den fürchterlichen "Master-Script" -Mechanismus zu benötigen, der mit System 5 benötigt wurderc
.Es gibt viele Fälle, die vielleicht nicht so extrem sind wie OSSEC HIDS, in denen ein solches Umdenken erforderlich ist. MTSes wie exim und sendmail sind zwei davon. Möglicherweise gab es ein einzelnes
rc
Skript, das einen Warteschlangenläufer, ein SMTP-Submission-Dæmon und ein SMTP-Relay-Dæmon erzeugte, mit einer Reihe von Ad-hoc-Shell-Variablen in einer Konfigurationsdatei, um genau zu steuern, welche ausgeführt werden. Der richtige Weg, dies mit systemd zu tun, besteht darin, drei richtige Service-Einheiten (von denen zwei zugeordnete Socket-Einheiten haben ) und überhaupt keine Ad-hoc-Dinge zu haben, sondern nur die regulären Mechanismen des Service-Managers.quelle
Sie könnten einfach die Eltern schlafen und warten, bis systemd sie zum Stoppzeitpunkt beendet hat.
quelle