- bullseye 4.10.0-1
- bullseye-backports 4.18.1-1~bpo11+1
- testing 4.18.1-1
- unstable 4.18.1-1
SYSTEMD.SERVICE(5) | systemd.service | SYSTEMD.SERVICE(5) |
BEZEICHNUNG¶
systemd.service - Dienste-Unit-Konfiguration
ÜBERSICHT¶
Dienst.service
BESCHREIBUNG¶
Eine Unit-Konfigurationsdatei, deren Name in ».service« endet, kodiert Informationen über einen von Systemd gesteuerten und überwachten Prozess.
Diese Handbuchseite listet die für diesen Unit-Typ spezifischen Konfigurationsoptionen auf. Siehe systemd.unit(5) für die gemeinsamen Optionen von allen Unit-Konfigurationsdateien. Die gemeinsamen Konfigurationselemente werden in den generischen Abschnitten »[Unit]« und »[Install]« konfiguriert. Die dienstespezifischen Konfigurationsoptionen werden im Abschnitt »[Service]« konfiguriert.
Zusätzliche Optionen sind in systemd.exec(5), das die Ausführungsumgebung, in der die Befehle ausgeführt werden und in systemd.kill(5), das die Art der Beendigung der Prozesse des Dienstes definiert und in systemd.resource-control(5), das die Ressourcensteuerungseinstellungen für die Prozesse des Dienstes konfiguriert, aufgeführt.
Falls ein Dienst unter einem bestimmten Namen angefordert wird, aber keine Unit-Konfigurationsdatei gefunden wird, schaut Systemd nach einem SysV-Init-Skript mit dem gleichen Namen (ohne die Endung .service) und erstellt dynamisch eine Dienste-Unit aus diesem Skript. Dies ist zur Kompatibilität mit SysV nützlich. Beachten Sie, dass diese Kompatibilität recht umfangreich, aber nicht 100% ist. Für Details über die Inkompatibilitäten, siehe das Dokument Inkompatibilitäten mit SysV[1].
Der Befehl erlaubt das dynamische und flüchtige Erstellen von ».service«- und ».scope«-Units auf der Befehlszeile.
DIENSTEVORLAGEN¶
systemd-Dienste können ein einzelnes Argument über die Syntax »Dienst@Argument.service« akzeptieren. Solche Dienste heißen »instanziierte« Dienste, während die Unit-Definition ohne den Parameter Argument »Vorlage« genannt wird. Eine Beispiel könnte die Dienstevorlage dhcpcd@.service sein, die eine Netzwerkschnittstelle als Parameter akzeptiert, um einen instanziierten Dienst zu formen. Innerhalb dieser Dienstedatei kann auf diesen Parameter oder den »Instanzennamen« mit Kennzeichnern »%« zugegriffen werden. Siehe systemd.unit(5) für Details.
AUTOMATISCHE ABHÄNGIGKEITEN¶
Implizite Abhängigkeiten¶
Die folgenden Abhängigkeiten werden implizit hinzugefügt:
Zusätzliche implizite Abhängigkeiten als Ergebnis der Ausführung und der gemäß systemd.exec(5) und systemd.resource-control(5) dokumentierten Ressourcen-Steuerungsparameter können hinzugefügt werden.
Standardabhängigkeiten¶
Die folgenden Abhängigkeiten werden hinzugefügt, es sei denn, DefaultDependencies=no ist gesetzt:
OPTIONEN¶
Dienstedateien müssen einen Abschnitt »[Service]« enthalten, der Informationen über den Dienst und den Prozess, den er überwacht, zusammenträgt. Eine Reihe von Optionen, die in diesem Abschnitt genutzt werden können, werden mit anderen Unit-Typen gemeinsam benutzt. Diese Optionen sind in systemd.exec(5), systemd.kill(5) und systemd.resource-control(5) beschrieben. Die für den Abschnitt »[Service]« von Dienste-Units spezifischen Optionen sind:
Type=
Es wird im Allgemeinen empfohlen, Type=simple wann immer möglich für langlaufende Dienste zu verwenden, da es die einfachste und schnellste Option ist. Da dieser Dienstetyp allerdings Fehler beim Starten nicht weiterleitet und keine Ordnung von anderen Units nach Abschluss der Initialisierung des Dienstes erlaubt (was beispielsweise für Clients sinnvoll ist, die sich mittels irgendeiner Art von IPC mit dem Dienst verbinden und der IPC-Kanal nur durch den Dienst selbst errichtet wird (statt dies vorab mittels Socket- oder Bus-Aktivierung oder ähnlichem zu erledigen)), könnte er in vielen Fällen nicht ausreichend sein. Dann sind notify oder dbus (Letzteres nur in dem Fall, in dem der Dienst eine D-Bus-Schnittstelle bereitstellt) die bevorzugten Optionen, da sie dem Diensteprogramm genau einzuplanen erlauben, wann der Dienst als erfolgreich gestartet betrachtet werden soll und wann mit den nachfolgenden Units fortgefahren werden soll. Der Dienstetyp notify benötigt explizite Unterstützung im Programmcode des Dienstes (da sd_notify() oder eine äquivalente API zum geeigneten Zeitpunkt durch den Dienst aufgerufen werden muss) — falls dies nicht unterstützt wird, ist forking eine Alternative: es unterstützt das Startprotokoll traditioneller UNIX-Dienste. Schließlich kann exec eine Option für die Fälle sein, in denen es ausreicht, sicherzustellen, dass das Diensteprogramm aufgerufen wurde und in denen das Diensteprogramm selbst keine oder nur sehr geringe Initialisierungen durchführt (und diese höchstwahrscheinlich erfolgreich sind). Beachten Sie, dass die Verwendung aller von simple verschiedenen Typen möglicherweise den Systemstartprozess verzögert, da der Diensteverwalter darauf warten muss, dass die Diensteinitialisierung abgeschlossen ist. Es wird daher empfohlen, nicht unnötigerweise von simple verschiedene Typen zu verwenden. (Es wird im Allgemeinen auch nicht empfohlen, idle oder oneshot für langlaufende Dienste zu verwenden.)
RemainAfterExit=
GuessMainPID=
PIDFile=
BusName=
ExecStart=
Es muss genau ein Befehl angegeben werden, außer Type= ist auf oneshot gesetzt. Wenn Type=oneshot verwandt wird, dürfen Null oder mehr Befehle festgelegt werden. Befehle können durch Angabe mehrerer Befehlszeilen in der gleichen Anweisung angegeben werden oder alternativ kann diese Anweisung mehr als einmal mit der gleichen Wirkung angegeben werden. Falls dieser Option die leere Zeichenketten zugewiesen wird, wird die Liste der zu startenden Befehle zurückgesetzt und vorhergehende Zuweisungen zu dieser Option haben keinen Effekt. Falls kein ExecStart= angegeben ist, dann muss der Dienst RemainAfterExit=yes und mindestens eine gesetzte ExecStop=-Zeile haben. (Dienste, denen sowohl ExecStart= als auch ExecStop= fehlt, sind nicht gültig.)
Für jeden der festgelegten Befehle muss das erste Argument entweder ein absoluter Pfad zu einem Programm oder ein einfacher Dateiname ohne Schrägstriche sein. Optional kann dem Dateinamen eine Reihe von besonderen Zeichen vorangestellt werden:
Tabelle 1. Besondere Präfixe für
Programme
Präfix | Effekt |
"@" | Falls dem Programmpfad ein »@« vorangestellt wird, wird der zweite angegebene Parameter als »argv[0]« (statt des tatsächlichen Dateinamens) an den ausgeführten Prozess übergeben, gefolgt von den weiteren angegebenen Argumenten. |
"-" | Falls dem Programmpfad ein »-« vorangestellt ist, wird ein Exit-Code, der normalerweise als Fehlschlag betrachtet wird (d.h. ein von Null verschiedener Exit-Status oder ein abweichender Exit aufgrund eines Signals), aufgezeichnet, hat aber weiter keine Wirkung und wird äquivalent zum Erfolg betrachtet. |
":" | Falls dem Programmpfad ein »:« vorangestellt ist, erfolgt keine Umgebungsvariablenersetzung (wie in dem nachfolgenden Abschnitt »Befehlszeilen« beschrieben). |
"+" | Falls dem Programmpfad ein »+« vorangestellt ist, wird der Prozess mit vollen Privilegien ausgeführt. In diesem Modus werden die mit User=, Group=, CapabilityBoundingSet= oder den verschiedenen Dateisystemnamensraumoptionen (wie PrivateDevices=, PrivateTmp=) konfigurierten Privilegienbeschränkungen für die aufgerufene Befehlszeile nicht angewandt (betreffen aber weiterhin jede andere ExecStart=-, ExecStop=-, … -Zeilen). |
"!" | Ähnlich zum oben besprochenen Zeichen »+« ermöglicht dieser den Aufruf von Befehlszeilen mit erweiterten Privilegien. Anders als »+« ändert das Zeichen »!« exklusiv den Effekt von User=, Group= und SupplementaryGroups=, d.h. nur die Absätze, die Benutzer- und Gruppenberechtigungen betreffen. Beachten Sie, dass diese Einstellung mit DynamicUser= kombiniert werden darf, womit ein dynamisches Benutzer-/Gruppenpaar vor dem Aufruf des Befehls reserviert wird, aber die Änderung der Berechtigungen dem ausgeführten Prozess selbst überlassen bleibt. |
"!!" | Dies ist sehr ähnlich zum Voranstellen von »!«, es wirkt allerdings nur auf Systemen, denen die Unterstützung für Umgebungsprozess-Capabilities fehlt, d.h. ohne Unterstützung für AmbientCapabilities=. Es ist für Unit-Dateien gedacht, die von Umgebungs-Capabilities profitieren, um wann immer möglich Prozesse mit minimalen Privilegien auszuführen, und gleichzeitig kompatibel zu Systemen bleiben sollen, denen die Unterstützung für Umgebungs-Capabilities fehlt. Beachten Sie, dass alle konfigurierten Absätze SystemCallFilter= und CapabilityBoundingSet= implizit modifiziert werden, wenn »!!« verwandt wird und erkannt wird, dass dem System die Unterstützung für Umgebungs-Capabilities fehlt, um zu erlauben, dass erzeugte Prozesse Berechtigungen und Capabilities selbst abgeben können, selbst falls konfiguriert wurde, dass dies nicht erlaubt ist. Desweiteren wird AmbientCapabilities= übersprungen und nicht angewandt, falls dies vorangestellt ist und ein System erkannt wird, dem die Unterstützung für Umgebungs-Capabilities fehlt. Auf Systemen, die Umgebungs-Capabilities unterstützen, hat »!!« keinen Effekt und ist redundant. |
»@«, »-«, »:« und eines aus »+«/»!«/»!!« können zusammen verwandt werden und in jeder Reihenfolge auftauchen. Allerdings darf nur einer von »+«, »!«, »!!« gleichzeitig benutzt werden. Beachten Sie, dass diese Zeichen auch den anderen Befehlzeileneinstellungen vorangestellt werden dürfen, d.h. ExecStartPre=, ExecStartPost=, ExecReload=, ExecStop= und ExecStopPost=.
Falls mehr als ein Befehl angegeben ist, werden die Befehle der Reihe nach in der Reihenfolge, in der sie in der Unit-Datei auftauchen, ausgeführt. Falls einer der Befehle fehlschlägt (und ihm kein »-« vorangestellt ist) werden die anderen Zeilen nicht ausgeführt und die Unit wird als fehlgeschlagen betrachtet.
Außer falls Type=forking gesetzt ist, wird der über die Befehlszeile gestartete Prozess als Hauptprozess des Daemons betrachtet.
ExecStartPre=, ExecStartPost=
Falls einer dieser Befehle (dem nicht »-« vorangestellt ist) fehlschlägt, wird der Rest nicht ausgeführt und die Unit als fehlgeschlagen betrachtet.
ExecStart=-Befehle werden nur ausgeführt, nachdem alle ExecStartPre=-Befehle, denen kein »-« vorangestellt wurde, sich erfolgreich beendet haben.
ExecStartPost=-Befehle werden nur ausgeführt, nachdem die in ExecStart= festgelegten Befehle erfolgreich gestartet wurden, wie durch Type= festgelegt (d.h. der Prozess wurde für Type=simple oder Type=idle gestartet, der letzte ExecStart=-Prozess hat sich erfolgreich für Type=oneshot beendet, der anfängliche Prozess hat sich für Type=forking erfolgreich beendet, »READY=1« ist für Type=notify gesetzt oder der BusName= ist für Type=dbus genommen worden.
Beachten Sie, dass ExecStartPre= nicht zum Starten von langlaufenden Prozessen verwandt werden darf. Alle von mittels ExecStartPre= aufgerufenen Prozesse mittels Fork gestarteten Prozesse werden getötet, bevor der nächste Diensteprozess ausgeführt wird.
Beachten Sie, dass falls einer der in ExecStartPre=, ExecStart= oder ExecStartPost= festgelegten Prozesse fehlschlägt (und ihm kein »-« vorangestellt wurde, siehe oben) oder seine Zeit abgelaufen ist, bevor der Dienst vollständig hochgekommen ist, die Ausführung mit den in ExecStopPost= festgelegten Komponenten fortgefahren wird und die Befehle in ExecStop= übersprungen werden.
Beachten Sie, dass die Ausführung von ExecStartPost= zum Zwecke der Before=/After= Ordnungsbeschränkungen berücksichtigt wird.
ExecCondition=
Das Verhalten ist wie ein ExecStartPre= und die Bedingungsprüfung erfolgt hybrid: wenn sich ein ExecCondition=-Befehl mit Exit-Code 1 bis 254 (einschließlich) beendet, werden die verbleibenden Befehle übersprungen und die Unit wird nicht als fehlgeschlagen markiert. Falls sich allerdings ein ExecCondition=-Befehl mit 255 oder unnormal (z.B. wegen einer Zeitüberschreitung, durch ein Signal getötet) beendet, wird die Unit als fehlgeschlagen betrachtet (und die verbliebenen Befehle übersprungen). Exit-Code 0 oder solche, die auf SuccessExitStatus= passen, führen zur Ausführung des oder der nächsten Befehle.
Die gleiche Empfehlung, keine langlaufenden Prozesse in ExecStartPre= auszuführen, gilt auch für ExecCondition=. ExecCondition= wird, falls eine Beendigung nicht Null oder unnormal erfolgt, beim Stoppen des Dienstes auch die in ExecStopPost= aufgeführten Befehle ausführen, wie die oben beschriebenen.
ExecReload=
Eine zusätzliche, besondere Umgebungsvariable wird gesetzt: falls bekannt, wird $MAINPID auf den Hauptprozess des Daemons gesetzt und kann für Befehlszeilen wie der folgenden benutzt werden:
ExecReload=kill -HUP $MAINPID
Beachten Sie, dass das Neuladen eines Daemons durch Senden eines Signals (wie in dem obigen Beispiel) normalerweise keine gute Wahl ist, da dies eine asynchrone Aktion und daher nicht dazu geeigent ist, das Neuladen von mehreren Diensten untereinander zu sortieren. Es wird nachdrücklich empfohlen, ExecReload= auf einen Befehl zu setzen, der nicht nur das Neuladen des Daemons auslöst, sondern auch synchron darauf wartet, dass dies abgeschlossen wird. Beispielsweise verwendet dbus-broker(1) Folgendes:
ExecReload=busctl call org.freedesktop.DBus \
/org/freedesktop/DBus org.freedesktop.DBus \
ReloadConfig
ExecStop=
Beachten Sie, dass es normalerweise nicht ausreicht, einen Befehl für diese Einstellung festzulegen, der nur um das Beenden des Dienstes bittet (beispielsweise durch Senden einer Art von Signal an es), aber dann nicht darauf wartet, dass es auch passiert. Da die verbleibenden Prozesse des Dienstes, direkt nachdem der Befehl sich beendet hat, gemäß den oben beschriebenen KillMode= und KillSignal= oder RestartKillSignal= getötet werden, kann dies zu einem unsauberen Stopp führen. Der angegebene Befehl sollte daher eine synchrone Aktion und nicht eine asynchrone sein.
Beachten Sie, dass die in ExecStop= festgelegten Befehle nur ausgeführt werden, wenn der Dienst zuerst erfolgreich gestartet wird. Sie werden nicht aufgerufen, falls der Dienst überhaupt nie gestartet wurde oder im Falle, dass das Starten fehlschlug, beispielsweise weil einer der in ExecStart=, ExecStartPre= oder ExecStartPost= festgelegten Befehle fehlschlug (oder ihm kein »-« vorangestellt wurde, siehe oben) oder eine Zeitüberschreitung erfolgte. Verwenden Sie ExecStopPost=, um Befehle aufzurufen, wenn ein Dienst nicht korrekt startete und wieder heruntergefahren wird. Beachten Sie auch, dass die Stopp-Aktion immer durchgeführt wird, wenn der Dienst erfolgreich startete, selbst falls die Prozesse in dem Dienst sich von alleine beendeten oder getötet wurden. Der Stopp-Befehl muss für diesen Fall vorbereitet sein. $MAINPID wird nicht gesetzt sein, falls Systemd weiß, das sich der Hauptprozess zum Zeitpunkt des Aufrufs des Stopp-Befehls beendet hat.
Diensteneustartanfragen sind als Stopp-Aktionen gefolgt von Start-Aktionen implementiert. Dies bedeutet, dass während einer Diensteneustartaktion ExecStop= und ExecStopPost= ausgeführt werden.
Es wird empfohlen, diese Einstellung für Befehle zu verwenden, die mit dem Dienst kommunizieren, die das saubere Beenden erbitten. Für Post-mortem-Bereinigungsschritte verwenden Sie stattdessen ExecStopPost=.
ExecStopPost=
Es wird empfohlen, diese Einstellung für Aufräumaktionen zu verwenden, die ausgeführt werden sollen, selbst wenn das korrekte Starten des Dienstes fehlschlug. Befehle, die mit dieser Einstellung konfiguriert sind, müssen in der Lage sein, zu funktionieren, selbst falls der Dienst mitten im Starten fehlschlug und unvollständig initialisierte Daten hinterließ. Da alle Prozesse des Dienstes bereits beendet wurden, wenn die mit dieser Einstellung festgelegten Befehle ausgeführt werden, sollten sie nicht versuchen, mit ihnen zu kommunizieren.
Beachten Sie, dass alle mit dieser Einstellung konfigurierten Befehle mit dem Ergebnis-Code des Dienstes sowie dem Exit-Code und -Status des Hauptprozesses, gesetzt auf die Umgebungsvariablen $SERVICE_RESULT, $EXIT_CODE und $EXIT_STATUS, aufgerufen werden, siehe systemd.exec(5) für Details.
Beachten Sie, dass die Ausführung von ExecStopPost= zum Zwecke der Before=/After= Ordnungsbeschränkungen berücksichtigt wird.
RestartSec=
TimeoutStartSec=
Falls ein Dienst vom Type=notify »EXTEND_TIMEOUT_USEC=…« sendet, kann dies dazu führen, dass die Startzeit sich über TimeoutStartSec= hinauszieht. Der erste Empfang dieser Nachricht muss auftreten, bevor TimeoutStartSec= überschritten wird und sobald die Startzeit sich über TimeoutStartSec= hinausgezogen hat, wird der Diensteverwalter dem Dienst die Weiterführung des Startens erlauben, vorausgesetzt, der Dienst wiederholt »EXTEND_TIMEOUT_USEC=…« innerhalb des festgelegten Intervalls, bis der Dienstestart durch »READY=1« abgeschlossen ist (siehe sd_notify(3)).
TimeoutStopSec=
Falls ein Dienst vom Type=notify »EXTEND_TIMEOUT_USEC=…« sendet, kann dies dazu führen, dass die Stoppzeit sich über TimeoutStopSec= hinauszieht. Der erste Empfang dieser Nachricht muss auftreten, bevor TimeoutStopSec= überschritten wird und sobald die Stoppzeit sich über TimeoutStopSec= hinausgezogen hat, wird der Diensteverwalter dem Dienst die Weiterführung des Stoppens erlauben, vorausgesetzt, der Dienst wiederholt »EXTEND_TIMEOUT_USEC=…« innerhalb des festgelegten Intervalls oder beendet sich (siehe sd_notify(3)).
TimeoutAbortSec=
Akzeptiert einen Wert ohne Einheit in Sekunden oder einen Zeitdauerwert wie »5min 20s«. Übergeben Sie einen leeren Wert, um die Handhabung der zugeordneten Watchdog-Zeitüberschreitung zu überspringen und auf TimeoutStopSec= zurückzufallen. Übergeben Sie »infinity«, um die Zeitüberschreitungslogik zu überspringen. Standardmäßig DefaultTimeoutAbortSec= aus der Verwalterkonfigurationsdatei (siehe systemd-system.conf(5)).
Falls ein Dienst vom Type=notify SIGABRT selber handhabt (statt sich auf den Kernel zum Schreiben eines Speicherauszuges zu verlassen), kann er »EXTEND_TIMEOUT_USEC=…« senden, um die Abbruchzeit über TimeoutAbortSec= hinaus zu verlängern. Der erste Empfang dieser Nachricht muss auftreten, bevor TimeoutAbortSec= überschritten wird und sobald die Abbruchzeit sich über TimeoutAbortSec= hinausgezogen hat, wird der Diensteverwalter dem Dienst die Weiterführung des Abbrechens erlauben, vorausgesetzt, der Dienst wiederholt »EXTEND_TIMEOUT_USEC=…« innerhalb des festgelegten Intervalls oder beendet sich (siehe sd_notify(3)).
TimeoutSec=
TimeoutStartFailureMode=, TimeoutStopFailureMode=
Falls terminate gesetzt ist, wird der Dienst sauber beendet, indem ihm das in KillSignal= festgelegte Signal (standardmäßig SIGTERM, siehe systemd.kill(5)) gesandt wird. Falls sich der Dienst nicht beendet, dann wird FinalKillSignal= nach TimeoutStopSec= gesendet. Falls abort gesetzt ist, wird stattdessen WatchdogSignal= gesandt und TimeoutAbortSec= gilt bevor FinalKillSignal= gesandt wird. Diese Einstellung kann zur Analyse von Diensten verwandt werden, die beim Hoch- oder Runterfahren zeitweilig fehlschlagen. Durch Verwendung von kill wird der Dienst sofort durch Senden von FinalKillSignal= beendet, ohne weitere Zeitüberschreitungen. Diese Einstellung kann zur Beschleunigung des Herunterfahrens von fehlgeschlagenen Diensten verwandt werden.
RuntimeMaxSec=
Falls ein Dienst vom Type=notify »EXTEND_TIMEOUT_USEC=…« sendet, kann dies dazu führen, dass die Laufzeit sich über RuntimeMaxSec= hinauszieht. Der erste Empfang dieser Nachricht muss auftreten, bevor RuntimeMaxSec= überschritten wird und sobald die Laufzeit sich über RuntimeMaxSec= hinausgezogen hat, wird der Diensteverwalter dem Dienst die Weiterführung des Laufens erlauben, vorausgesetzt, der Dienst wiederholt »EXTEND_TIMEOUT_USEC=…« innerhalb des festgelegten Intervalls, bis das Herunterfahren durch »STOPPING=1« (oder die Beendigung) erreicht wird (siehe sd_notify(3)).
WatchdogSec=
Restart=
Akzeptiert no, on-success, on-failure, on-abnormal, on-watchdog, on-abort oder always. Falls auf no (die Vorgabe) gesetzt, wird der Dienst nicht neu gestartet. Falls auf on-success gesetzt, wird er nur neu gestartet, wenn sich der Diensteprozess sauber beendet. In diesem Kontext bedeutet das saubere Beenden einen Exit-Code 0 oder eines der Signale SIGHUP, SIGINT, SIGTERM oder SIGPIPE und zusätzlich in SuccessExitStatus= festgelegte Exit-Stati und Signale. Falls auf on-failure gesetzt, wird der Dienst neu gestartet, wenn der Prozess sich mit einem von Null verschiedenen Exit-Code beendet, durch ein Signal beendet wird (einschließlich eines Speicherauszuges, aber ausschließlich der vorher genannten Signale), wenn eine Aktion (wie das Neuladen eines Dienstes) in eine Zeitüberschreitung läuft und wenn die konfigurierte Watchdog-Zeitüberschreitung ausgelöst wird. Falls auf on-abnormal gesetzt, wird der Dienst neu gestartet, wenn der Prozess durch ein Signal beendet wird (einschließlich eines Speicherauszuges, aber ausschließlich der vorher genannten Signale), wenn eine Aktion in eine Zeitüberschreitung läuft und wenn die konfigurierte Watchdog-Zeitüberschreitung ausgelöst wird. Falls auf on-abort gesetzt, wird der Dienst nur neu gestartet, falls sich der Dienst aufgrund eines nicht abgefangenen Signals, das nicht als sauberer Exit-Status festgelegt ist, beendet hat. Falls auf on-watchdog gesetzt, wird der Dienst nur neu gestartet, wenn die Watchdog-Zeitüberschreitung für den Dienst abläuft. Falls auf always gesetzt, wird der Dienst neu gestartet, unabhängig davon, ob er sauber beendet wurde oder nicht, abnormal durch ein Signal beendet wurde oder in eine Zeitüberschreitung lief.
Tabelle 2. Exit-Gründe und der Effekt der
Einstellung Restart=
darauf
Neustart-Einstellung/Exit-Grund | no | always | on-success | on-failure | on-abnormal | on-abort | on-watchdog |
Sauberer Exit-Code oder -Signal | X | X | |||||
Unsauberer Exit-Code | X | X | |||||
Unsauberes Signal | X | X | X | X | |||
Zeitüberschreitung | X | X | X | ||||
Watchdog | X | X | X | X |
Als Ausnahme zu den obigen Einstellungen wird der Dienst nicht neu gestartet, falls der Exit-Code oder das Exit-Signal in RestartPreventExitStatus= (siehe unten) festgelegt ist oder der Dienst mit systemctl stop oder einer äquivalenten Aktion gestoppt wird. Auch wird der Dienst immer neu gestartet, falls der Exit-Code oder das Exit-Signal in RestartForceExitStatus= (siehe unten) festgelegt ist.
Beachten Sie, dass der Diensteneustart der mit StartLimitIntervalSec= und StartLimitBurst= konfigurierten Unit-Startratenbegrenzung unterliegt, siehe systemd.unit(5) für Details. Ein neugestarteter Dienst tritt in den Fehlerzustand nur ein, nachdem die Startratenbegrenzungen erreicht wurden.
Für langlaufende Dienste wird empfohlen, dies auf on-failure zu setzen, um die Zuverlässigkeit zu erhöhen, indem die automatische Wiederherstellung bei Fehlern versucht wird. Für Dienste, die sich nach eigenen Kriterien beenden (und sofortige Neustarts vermeiden) können, ist on-abnormal eine alternative Wahl.
SuccessExitStatus=
Beachten Sie, dass diese Einstellung nicht die Zuordnung zwischen numerischen Exit-Stati und ihren Namen ändert, d.h. unabhängig von der Verwendung dieser Einstellung wird 0 immer »SUCCESS« (und in der Ausgabe von Werkzeugen typischerweise als »0/SUCCESS« angezeigt) und 1 »FAILURE« zugeordnet (und daher typischerweise als »1/FAILURE« angezeigt) wird, und so weiter. Dies steuert nur, was als Auswirkung auf diese Exit-Stati passiert, und wie sie zum Zustand des Dienstes als Ganzes weitergeleitet wird.
Falls diese Option mehr als einmal auftaucht, wird die Liste der erfolgreichen Exit-Stati zusammengeführt. Falls dieser Option die leere Zeichenkette zugewiesen wird, wird diese Liste zurückgesetzt und alle vorherigen Zuweisungen zu dieser Option haben keinen Effekt.
Beispiel 1. Ein Dienst mit der Einstellung SuccessExitStatus=
SuccessExitStatus=TEMPFAIL 250 SIGKILL
Exit-Status 75 (TEMPFAIL), 250 und das Beendigungssignal wird SIGKILL als saubere Dienstebeendigung betrachtet.
Beachten Sie: systemd-analyze exit-codes kann zur Auflistung der Exit-Stati und zur Übersetzung zwischen numerischen Code-Werten und Namen verwandt werden.
RestartPreventExitStatus=
RestartPreventExitStatus=1 6 SIGABRT
Dies stellt sicher, dass die Exit-Codes 1 und 6 und das Beendigungssignal SIGABRT nicht zu einem automatischen Diensteneustart führen. Wenn diese Option mehr als einmal auftaucht, werden die Neustart-verhindernden Status zusammengeführt. Falls dieser Option die leere Zeichenkette zugewiesen wird, wird diese Liste zurückgesetzt und alle vorherigen Zuweisungen zu dieser Option haben keinen Effekt.
Beachten Sie, dass diese Einstellung keine Auswirkung auf mittels ExecStartPre=, ExecStartPost=, ExecStop=, ExecStopPost= oder ExecReload= konfigurierte Prozesse hat, sondern nur auf den Hauptdiensteprozess, d.h. entweder den mittels ExecStart= aufgerufenen oder (abhängig von Type=, PIDFile=, …) den anderweitig konfigurierten Hauptprozess.
RestartForceExitStatus=
RootDirectoryStartOnly=
NonBlocking=
NotifyAccess=
Beachten Sie, dass sd_notify()-Benachrichtigungen nur Units korrekt zugeordnet werden können, falls entweder der sendende Prozess noch zu dem Zeitpunkt vorhanden ist, zu dem PID 1 die Nachricht verarbeitet oder falls der sendende Prozess explizit vom Diensteverwalter laufzeitverfolgt ist. Letzteres ist der Fall, falls der Diensteverwalter den Prozess ursprünglich mit fork erzeugte, d.h. bei allen Prozessen, die auf NotifyAccess=main oder NotifyAccess=exec passen. Umgekehrt, falls ein Hilfsprozess einer Unit eine sd_notify()-Nachricht sendet und sich sofort beendet, könnte der Diensteverwalter nicht in der Lage sein, die Nachricht korrekt der Unit zuzuordnen und wird sie daher ignorieren, selbst falls NotifyAccess=all für sie gesetzt ist.
Um daher alle Ressourcenwettläufe, die mit Nachschlagen von Units des Clients verknüpft sind, zu beseitigen und Benachrichtigungen Units richtig zuzuordnen, kann sd_notify_barrier() verwandt werden. Dieser Aufruf dient als Synchronisationspunkt und stellt sicher, dass alle Benachrichtigungen gesendete werden, bevor dieser Aufruf vom Diensteverwalter aufgenommen wird, wenn er erfolgreich zurückkehrt. Die Verwendung von sd_notify_barrier() wird für Clients benötigt, die nicht durch den Diensteverwalter aufgerufen werden, andernfalls ist dieser Synchronisationsmechanismus zur Zuordnung von Benachrichtigungen zu Units unnötig.
Sockets=
Beachten Sie, dass der gleiche Socket-Dateideskriptor simultan an mehrere Prozesse übergeben werden kann. Beachten Sie auch, dass ein anderer Dienst auf eingehenden Socket-Verkehr aktiviert werden kann als derjenige, der schließlich konfiguriert ist, den Socket-Dateideskriptor zu erben. Oder mit anderen Worten: Die Einstellung Service= von .socket-Units muss nicht auf das Inverse der Einstellung Sockets= von .service, auf die es sich bezieht, passen.
Falls diese Option mehr als einmal auftaucht, wird die Liste der Socket-Units zusammengeführt. Beachten Sie, dass das Bereinigen der Liste (beispielsweise durch Zuweisung der leeren Zeichenkette zu dieser Option) nicht unterstützt wird, sobald die Option einmal gesetzt wurde.
FileDescriptorStoreMax=
USBFunctionDescriptors=
USBFunctionStrings=
OOMPolicy=
Verwenden Sie die Einstellung OOMScoreAdjust=, um zu konfigurieren, ob Prozesse der Unit als bevorzugte oder weniger bevorzugte Kandidaten für die Beendigung durch die Linux-OOM-Killer-Logik betrachtet werden sollen. Siehe systemd.exec(5) für Details.
Lesen Sie systemd.exec(5) und systemd.kill(5) für weitere Einstellungen.
BEFEHLSZEILEN¶
Dieser Abschnitt beschreibt die Auswertung der Befehlszeile und Variablen- und Kennzeichnerersetzung für die Optionen ExecStart=, ExecStartPre=, ExecStartPost=, ExecReload=, ExecStop= und ExecStopPost=.
Mehrere Befehlszeilen können in eine einzelne Anweisung zusammengefasst werden, indem sie mit Semikola (die als separate Wörter übergeben werden müssen) getrennt werden. Einzelne Semikola können als »\;« maskiert werden.
Jede Befehlszeile wird bei Leerraumzeichen aufgeteilt, wobei das erste Objekt der auszuführende Befehl und die nachfolgenden Objekte dessen Argumente sind. Doppelte ("…") und einfache Anführungszeichen ('…') können zum Einhüllen eines ganzen Objekts verwandt werden (das öffnende Anführungszeichen darf nur am Anfang oder nach Leerraumzeichen, die nicht in Anführungszeichen sind, erscheinen und dem schließenden Anführungszeichen muss Leerraumzeichen oder das Zeilenende folgen), dabei wird alles bis zum nächsten passenden Anführungszeichen Teil des gleichen Arguments. Die Anführungszeichen selbst werden entfernt. C-artige Maskierungen werden auch unterstützt. Die nachfolgende Tabelle enthält die Liste der bekannten Maskiermuster. Nur Maskiermuster, die auf die Syntax in der Tabelle passen, sind erlaubt; andere Muster können in der Zukunft hinzugefügt werden und unbekannte Muster führen zu einer Warnung. Insbesondere sollten alle Rückwärtsschrägstriche verdoppelt werden. Schließlich kann ein abschließender Rückwärtsschrägstrich (»\«) zum Zusammenführen von Zeilen verwandt werden.
Diese Syntax ist von der Shell-Syntax inspiriert, aber nur die in den nachfolgenden Absätzen beschriebenen Metazeichen und Erweiterungen werden verstanden und die Expansion von Variablen unterscheidet sich. Insbesondere werden Umleitungen mittels »<«, »<<«, »>« und »>>«, Pipes mittels »|«, das Ausführen von Programmen im Hintergrund und andere Elemente der Shell-Syntax nicht unterstützt.
Der auszuführende Befehl darf Leerzeichen enthalten, aber Steuerzeichen sind nicht erlaubt.
Die Befehlszeile akzeptiert wie in systemd.unit(5) beschrieben »%s«-Kennzeichner.
Grundlegende Umgebungsvariablenersetzung wird unterstützt. Verwenden Sie auf der Befehlszeile »${FOO}« als Teil des Worts oder als einzelnes Wort, das dann gelöscht und genau durch den Wert der Umgebungsvariablen (falls vorhanden), einschließlich sämtlichen darin enthaltenen Leerraums, ersetzt und immer genau zu einem einzelnen Argument wird. Verwenden Sie »$FOO« als ein separates Wort auf der Befehlszeile, das durch den Wert der Umgebungsvariablen, getrennt an den Leerraumzeichen, ersetzt wird und zu Null oder mehr Argumenten führt. Für diese Art von Expansion werden Anführungszeichen beim Trennen in Wörter berücksichtigt und anschließend entfernt.
Falls der Befehl kein kompletter (absoluter) Pfad ist, wird er mittels eines festen, zum Zeitpunkt der Kompilierung bestimmten Suchpfades zu einem kompletten Pfad aufgelöst. Suchverzeichnisse sind unter anderem /usr/local/bin/, /usr/bin/, /bin/ auf Systemen, die getrennte Verzeichnisse /usr/bin/ und /bin/ verwenden, und ihre sbin/-Gegenstücke auf Systemen, die getrennte bin/ und sbin/ verwenden. Es ist daher sicher, nur den Programmnamen zu verwenden, falls das Programm sich in einem der »Standard«-Verzeichnisse befindet. Für andere Fälle muss ein absoluter Pfad verwandt werden. Es wird empfohlen, einen absoluten Pfad zu verwenden, um Mehrdeutigkeiten zu vermeiden. Tipp: Dieser Suchpfad kann mit systemd-path search-binaries-default abgefragt werden.
Beispiel:
Environment="EINS=eins" 'ZWEI=zwei zwei' ExecStart=echo $EINS $ZWEI ${ZWEI}
Dies führt /bin/echo mit vier Argumenten aus: »eins«, »zwei«, »zwei« und »zwei zwei«.
Beispiel:
Environment=EINS='eins' "ZWEI='zwei zwei' auch" DREI= ExecStart=/bin/echo ${EINS} ${ZWEI} ${DREI} ExecStart=/bin/echo $EINS $ZWEI $DREI
Dies führt dazu, dass /bin/echo zweimal aufgerufen wird, das erste Mal mit den Argumenten »'eins'«, »'zwei zwei' auch« »« und das zweite Mal mit den Argumenten »eins«, »zwei zwei«, »auch«.
Um ein wörtliches Dollarzeichen zu übergeben, verwenden Sie »$$«. Variablen, deren Wert zum Expansionszeitpunkt nicht bekannt ist, werden als leere Zeichenkette behandelt. Beachten Sie, dass das erste Argument (d.h. das auszuführende Programm) keine Variable sein darf.
Variablen, die auf diese Art verwandt werden, können mittels Environment= und EnvironmentFile= definiert werden. Zusätzlich können Variablen, die im Abschnitt »Umgebungsvariablen in erzeugten Prozessen« in systemd.exec(5), die als »statische Konfiguration« betrachtet werden, verwandt werden (dies schließt beispielsweise $USER, aber nicht $TERM ein).
Beachten Sie, dass Shell-Befehlszeilen nicht direkt unterstützt werden. Falls Shell-Befehlszeilen verwandt werden sollen, müssen sie explizit an eine Art von Shell-Implementierung übergeben werden. Beispiel:
ExecStart=sh -c 'dmesg | tac'
Beispiel:
ExecStart=echo eins ; echo "zwei zwei"
Dies wird echo zwei Mal ausführen, jedes Mal mit einem Argument: »eins« bzw. »zwei zwei«. Da zwei Befehle angegeben sind, muss Type=oneshot verwandt werden.
Beispiel:
ExecStart=echo / >/dev/null & \; \ ls
Dies wird echo mit fünf Argumenten ausführen: »/«, »>/dev/null«, »&«, »;« und »ls«.
Tabelle 3. In Befehlszeilen und
Umgebungsvariablen unterstützte
C-Maskierungen
Wortsinn | Tatsächlicher Wert |
"\a" | Glockenton |
"\b" | Rückschritt (»backspace«) |
"\f" | Seitenvorschub |
"\n" | Zeilenumbruch |
"\r" | Wagenrücklauf |
"\t" | Tabulator |
"\v" | Vertikaler Tabulator |
"\\" | Rückschrägstrich (»backslash«) |
"\"" | doppeltes englisches Anführungszeichen |
"\'" | einfaches englisches Anführungszeichen |
"\s" | Leerzeichen |
"\xxx" | Zeichen Nummer xx in hexadezimaler Kodierung |
"\nnn" | Zeichen Nummer nnn in oktaler Kodierung |
BEISPIELE¶
Beispiel 2. Einfacher Dienst
Die folgende Unit-Datei erstellt einen Dienst, der /usr/sbin/foo-daemon ausführt. Da kein Type= angegeben ist, wird die Vorgabe Type=simple angenommen. Systemd wird annehmen, dass die Unit sofort nach Beginn der Ausführung des Programmes gestartet werden soll.
[Unit] Description=Foo [Service] ExecStart=/usr/sbin/foo-daemon [Install] WantedBy=multi-user.target
Beachten Sie, dass Systemd hier annimmt, dass der durch Systemd gestartete Prozess läuft, bis der Dienst beendet wird. Falls das Programm sich selbst zum Daemon macht (d.h. Fork ausführt), verwenden Sie bitte stattdessen Type=forking.
Da kein ExecStop= angegeben wurde, wird Systemd SIGTERM an alle von diesem Dienst gestarteten Prozesse senden und nach einer Zeitüberschreitung auch SIGKILL. Dieses Verhalten kann verändert werden, siehe systemd.kill(5) für Details.
Beachten Sie, dass dieser Unit-Typ keine Art von Benachrichtigung, wenn der Dienst seine Initialisierung abgeschlossen hat, enthält. Dafür sollten Sie andere Unit-Typen, wie Type=notify, falls der Dienst das Benachrichtigungsprotokoll von Systemd versteht, Type=forking, falls der Dienst sich selbst in den Hintergrund bringen kann oder Type=dbus, falls der Dienst einen DBus-Namen erlangt, sobald die Initialisierung abgeschlossen ist, in Betracht ziehen. Siehe unten.
Beispiel 3. Oneshot-Dienst
Manchmal sollen Units einfach eine Aktion ausführen, ohne aktive Prozesse zu behalten, wie beispielsweise eine Dateisystemüberprüfung oder eine Aufräumaktion beim Systemstart. Dafür existiert Type=oneshot. Units dieser Art werden warten, bis der festgelegte Prozess sich beendet hat und dann auf einen inaktiven Status zurückfallen. Die folgende Unit wird eine Aufräumaktion durchführen:
[Unit] Description=Bereinigung alter Foo-Daten [Service] Type=oneshot ExecStart=/usr/sbin/foo-cleanup [Install] WantedBy=multi-user.target
Beachten Sie, dass Systemd die Unit im Status »starting« betrachten wird, bis sich das Programm beendet hat, daher werden Ordnungsabhängigkeiten auf die Beendigung des Programms warten, bevor sie sich selbst starten. Die Unit wird zum Zustand »inactive« nach dem Abschluss der Ausführung zurückkehren und niemals den Zustand »active« erreichen. Das bedeutet, dass eine weitere Anfrage, die Unit zu starten, die Aktion erneut ausführen wird.
Nur Units mit Type=oneshot dürfen mehr als ein ExecStart= festgelegt haben. Für Units mit mehreren Befehlen (Type=oneshot) werden alle Befehle erneut ausgeführt.
Für Type=oneshot sind Restart=always und Restart=on-success nicht erlaubt.
Beispiel 4. Beendbarer Oneshot-Dienst
Ähnlich zum Oneshot-Dienst gibt es manchmal Units, die ein Programm ausführen müssen, um etwas einzurichten, und dann ein anderes, um es herunterzufahren, aber es bleibt kein Prozess aktiv, während diese als »started« betrachtet werden. Netzwerkkonfiguration kann manchmal in diese Kategorie fallen. Ein anderer Anwendungsfall ist, falls ein Oneshot-Dienst nicht jedesmal, wenn er als Abhängigkeit hereingezogen wird, ausgeführt werden soll, sondern nur beim ersten Mal.
Dafür kennt Systemd die Einstellung RemainAfterExit=yes, die dazu führt, dass Systemd die Unit als aktiv betrachtet, falls die Startaktion sich erfolgreich beendet hat. Diese Anweisung kann mit allen Typen verwandt werden, ist aber mit Type=oneshot und Type=simple am nützlichsten. Mit Type=oneshot wird Systemd warten, bis die Startaktion abgeschlossen ist, bevor es die Unit als aktiv betrachtet, daher starten Abhängigkeiten erst nachdem die Startaktion erfolgreich war. Mit Type=simple werden die Abhängigkeiten sofort nach dem Absetzen der Startaktion gestartet. Die nachfolgende Unit stellt ein Beispiel für eine einfache statische Firewall bereit.
[Unit] Description=Einfache Firewall [Service] Type=oneshot RemainAfterExit=yes ExecStart=/usr/local/sbin/simple-firewall-start ExecStop=/usr/local/sbin/simple-firewall-stop [Install] WantedBy=multi-user.target
Da die Unit als laufend betrachtet wird, nachdem sich die Start-Aktion beendet hat, wird der Aufruf von systemctl start auf dieser Unit zu keiner Aktion führen.
Beispiel 5. Traditioneller forkender Dienst
Viele traditionelle Daemons/Dienste bringen sich selbst in den Hintergrund (d.h. forken, daemonisieren sich), wenn sie starten. Setzen Sie Type=forking in der Unit-Datei des Dienstes, um diesen Betriebsmodus zu unterstützen. Systemd wird den Dienst im Prozess der Initialisierung betrachten, während das ursprüngliche Programm noch läuft. Sobald es sich erfolgreich beendet und mindestens ein Prozess verbleibt (und RemainAfterExit=no), wird der Dienst als gestartet betrachtet.
Oft besteht ein traditioneller Daemon nur aus einem Prozess. Daher wird Systemd diesen Prozess als den Hauptprozess des Dienstes betrachten, falls nur ein Prozess nach Beendigung des ursprünglichen Prozesses verbleibt. In diesem Fall wird die Variable $MAINPID in ExecReload=, ExecStop= usw. verfügbar sein.
Falls mehr als ein Prozess verbleibt, wird Systemd nicht in der Lage sein, den Hauptprozess zu bestimmen und wird daher annehmen, dass es keinen gibt. In diesem Fall wird $MAINPID nicht auf etwas expandiert. Falls allerdings der Prozess entscheidet, eine traditionelle PID-Datei zu schreiben, wird Systemd in der Lage sein, die Haupt-PID von dort zu bestimmen. Bitte setzen Sie PIDFile= entsprechend. Beachten Sie, dass der Daemon diese Datei schreiben sollte, bevor er seine Initialisierung abschließt. Andernfalls könnte Systemd versuchen, die Datei zu lesen, bevor sie existiert.
Das folgende Beispiel zeigt einen einfachen Daemon, der forkt und einfach einen Prozess im Hintergrund startet:
[Unit] Description=Ein einfacher Daemon [Service] Type=forking ExecStart=/usr/sbin/my-simple-daemon -d [Install] WantedBy=multi-user.target
Bitte lesen Sie systemd.kill(5) für Details, wie Sie die Art, wie Systemd die Dienste beendet, beeinflussen können.
Beispiel 6. DBus-Dienste
Für Dienste, die einen Namen auf dem DBus-Systembus erlangen, verwenden Sie Type=dbus und setzen BusName= entsprechend. Der Dienste sollte nicht forken (daemonisieren). Systemd wird den Dienst als initialisiert betrachten, sobald der Name auf dem Systembus erlangt wurde. Das folgende Beispiel zeigt einen typischen DBus-Dienst:
[Unit] Description=Einfacher DBus-Dienst [Service] Type=dbus BusName=org.example.simple-dbus-service ExecStart=/usr/sbin/simple-dbus-service [Install] WantedBy=multi-user.target
Für Bus-aktivierbare Dienste nehmen Sie keinen Abschnitt »[Install]« in der Systemd-Dienstedatei auf, sondern verwenden die Option SystemdService= in der entsprechenden DBus-Dienstedatei, beispielsweise (/usr/share/dbus-1/system-services/org.example.simple-dbus-service.service):
[D-BUS Service] Name=org.example.simple-dbus-service Exec=/usr/sbin/simple-dbus-service User=root SystemdService=simple-dbus-service.service
Bitte lesen Sie systemd.kill(5) für Details, wie Sie die Art, wie Systemd die Dienste beendet, beeinflussen können.
Beispiel 7. Dienste, die Systemd über ihre Initialisierung benachrichtigen
Type=simple-Dienste sind wirklich einfach zu schreiben, haben aber den großen Nachteil, dass Systemd nicht feststellen kann, wann die Initialisierung des gegebenen Dienstes abgeschlossen ist. Aus diesem Grund unterstützt Systemd ein einfaches Benachrichtigungsprotokoll, das es Daemons erlaubt, Systemd darüber in Kenntnis zu setzen, dass sie initialisiert sind. Verwenden Sie dafür Type=notify. Eine typische Dienste-Datei für solch einen Daemon sähe wie folgt aus:
[Unit] Description=Einfacher Benachrichtigungsdienst [Service] Type=notify ExecStart=/usr/sbin/simple-notifying-service [Install] WantedBy=multi-user.target
Beachten Sie, dass der Daemon das Benachrichtigungsprotokoll von Systemd unterstützen muss, da ansonsten Systemd glauben wird, dass der Dienst noch nicht gestartet wurde und ihn nach einer Zeitüberschreitung töten wird. Für ein Beispiel, wie transparent ein Daemon aktualisiert wird, um dieses Protokoll zu unterstützen, schauen Sie in sd_notify(3). Systemd wird die Unit im Zustand »starting« betrachten, bis eine Bereitschaftsbenachrichtigung angekommen ist.
Bitte lesen Sie systemd.kill(5) für Details, wie Sie die Art, wie Systemd die Dienste beendet, beeinflussen können.
SIEHE AUCH¶
systemd(1), systemctl(1), systemd-system.conf(5), systemd.unit(5), systemd.exec(5), systemd.resource-control(5), systemd.kill(5), systemd.directives(7), systemd-run(1)
ANMERKUNGEN¶
- 1.
- Inkompatibilitäten mit SysV
- 2.
- USB FunctionFS
ÜBERSETZUNG¶
Die deutsche Übersetzung dieser Handbuchseite wurde von Helge Kreutzmann <debian@helgefjell.de> erstellt.
Diese Übersetzung ist Freie Dokumentation; lesen Sie die GNU General Public License Version 3 oder neuer bezüglich der Copyright-Bedingungen. Es wird KEINE HAFTUNG übernommen.
Wenn Sie Fehler in der Übersetzung dieser Handbuchseite finden, schicken Sie bitte eine E-Mail an die Mailingliste der Übersetzer.
systemd 247 |