Provided by: manpages-de_4.27.0-1_all bug

BEZEICHNUNG

       systemd-soft-reboot.service - Neustartaktion im Anwendungsraum

ÜBERSICHT

       systemd-soft-reboot.service

BESCHREIBUNG

       systemd-soft-reboot.service ist ein Systemdienst, der von soft-reboot.target hereingezogen wird und für
       die Durchführung einer Neustartaktion rein im Anwendungsraum verantwortlich ist. Beim Aufruf wird er ein
       Signal SIGTERM an alle noch laufenden Prozesse senden (aber wartet nicht darauf, dass sich die Prozesse
       beenden) und folgt dann mit SIGKILL. Falls das Verzeichnis /run/nextroot/ existiert (dies kann ein
       normales Verzeichnis, ein Verzeichnis-Einhängepunkt oder ein Symlink auf diese sein), dann wird es die
       Dateisystemwurzel dorthin umschalten. Es führt dann den Diensteverwalter von dem (jetzt möglicherweise
       neuen) Wurzeldateisystem erneut aus, wodurch eine neue Systemstarttransaktion in die Warteschlange kommt,
       wie bei einem normalen Systemneustart.

       Solch eine reine Neustartaktion im Anwendungsraum erlaubt das Aktualisieren oder Zurücksetzen der
       Gesamtheit des Anwendungsraums mit minimaler Ausfallzeit, da die Neustartaktion nicht folgende Punkte
       durchlaufen muss:

       •   Die zweite Phase des regulären Herunterfahrens, wie von systemd-shutdown(8) implementiert.

       •   Die dritte Phase des regulären Herunterfahrens, d.h. der Rückkehr in den Initrd-Kontext.

       •   Die Hardware-Neustart-Aktion.

       •   Die Firmware-Initialisierung.

       •   Die Initialisierung des Systemstartprogramms.

       •   Die Kernel-Initialisierung.

       •   Die Initrd-Initialisierung.

       Allerdings hat diese Art des Neustarts auch Nachteile:

       •   Die Betriebssystemaktualisierung bliebt unvollständig, da der Kernel nicht zurückgesetzt wird und
           weiter läuft.

       •   Kerneleinstellungen (wie die Einstellungen in /proc/sys/, bekannt auch als »sysctl«- oder
           /sys/-Einstellungen) werden nicht zurückgesetzt.

       Diese Beschränkungen können mit verschiedenen Mitteln adressiert werden, die außerhalb des Umfangs dieser
       Dokumentation sind, wie beispielsweise dem Live-Patchen des Kernels und hinreichend umfangreichen Dateien
       in /etc/sysctl.d/.

RESSOURCEN-WEITERGABE

       Verschiedene Laufzeit-Betriebssystem-Ressourcen können von einer Systemlaufzeit zu der nächsten über die
       Neustartaktion im Anwendungsraum hinweg weitergegeben werden. Konkret:

       •   Dateideskriptoren, die im Dateideskriptorspeicher von Diensten abgelegt sind, die bis zum
           allerletzten Ende aktiv bleiben, werden zum nächsten Start weitergegeben, wo sie in dem
           Dateideskriptorspeicher der gleichen Unit abgelegt werden. Damit dies funktioniert, müssen Units
           DefaultDependencies=no deklarieren (und ein manuelles Conflicts=shutdown.target und ähnliches
           vermeiden), um sicherzustellen, dass sie nicht normal während der Herunterfahraktion des Systems
           beendet werden. Alternativ können Sie FileDescriptorStorePreserve= verwenden, um dem
           Dateideskriptorspeicher zu erlauben, festgehalten zu werden, selbst wenn die Unit heruntergefahren
           ist. Siehe systemd.service(5) zu Details des Dateideskriptorspeichers.

       •   Entsprechend bleiben Dateideskriptoren offen (auch verbindbar), die .socket-Units zugeordnet sind,
           falls die Units nicht während des Übergangs gestoppt werden. (Dies wird durch DefaultDependencies=no
           erreicht.)

       •   Das Dateisystem /run/ bleibt eingehängt und gefüllt und kann zur Übergabe von Zustandsinformationen
           zwischen Neustartzyklen im Anwendungsraum verwandt werden.

       •   Diensteprozesse können über den Übergang hinweg, hinter den weichen Neustart und in die nächste
           Sitzung hinein laufen, falls sie in Diensten abgelegt sind, die bis zum allerletzten Ende des
           Herunterfahrens aktiv bleiben (was wiederum durch DefaultDependencies=no erreicht wird). Sie müssen
           auch so eingerichtet werden, dass sie das Beenden mit den vorher erwähnten SIGTERM und SIGKILL
           mittels SurviveFinalKillSignal=yes vermeiden und auch so konfiguriert sein, dass sie das Stoppen beim
           Isolieren mittels IgnoreOnIsolate=yes vermeiden. Sie müssen auch so konfiguriert sein, dass sie beim
           normalen Herunterfahren, Neustarten oder im Wartungsmodus angehalten werden. Schließlich müssen sie
           nach basic.target angeordnet sein, um die korrekte Sortierung beim Systemstart sicherzustellen. Falls
           irgendwelche neuen oder angepassten Units zum Hineinisolieren verwandt werden oder diese eine
           äquivalente Herunterfahrfunktionalität bereitstellen, dann müssen diese Prozesse auch manuell für die
           korrekte Sortierung und Konflikte konfiguriert sein. Beispiel:

               [Unit]
               Description=Mein überlebender Dienst
               SurviveFinalKillSignal=yes
               IgnoreOnIsolate=yes
               DefaultDependencies=no
               After=basic.target
               Conflicts=reboot.target kexec.target poweroff.target halt.target rescue.target emergency.target
               Before=shutdown.target rescue.target emergency.target

               [Service]
               Type=oneshot
               ExecStart=sleep infinity

       •   Ergänzend zu obigen benötigen instanziierte Units auch eine Konfigurationsdatei für ihre Scheibe, da
           sie standardmäßig eine Scheibe verwenden, die nach dem Vorlagenteil der Unit benannt ist. Für eine
           Instanz foo@test.service könnte beispielsweise eine Unit system-foo.slice mit dem folgenden Inhalt
           hinzugefügt werden:

               [Unit]
               SurviveFinalKillSignal=yes
               IgnoreOnIsolate=yes
               DefaultDependencies=no

       •   Dateisystemeinhängungen können während des Übergangs eingehängt bleiben und komplexe Speichersysteme
           angehängt, falls sie so konfiguriert wurden, dass sie bis zum allerletzten Ende des
           Herunterfahrprozesses aktiv bleiben. (Dies wird auch mittels DefaultDependencies=no und dem Vermeiden
           von Conflicts=umount.target erreicht.)

       •   Falls die Unit einen Dienst über D-Bus veröffentlicht, muss die Verbindung nach einem weichen
           Neustart neu etabliert werden, da der D-Bus-Vermittler gestoppt und dann wieder gestartet wird. Unter
           Verwendung der Bibliothek sd-bus(3) kann dies durch Anpassung des folgenden Beispiels erfolgen.

               /* SPDX-License-Identifier: MIT-0 */

               /* Ein D-Bus-Dienst, der sich automatisch neu verbindet, wenn der Systembus neu gestartet wird.
                *
                * Kompilieren Sie mit »cc sd_bus_service_reconnect.c $(pkg-config --libs --cflags libsystemd)«
                *
                * Um dem Programm zu erlauben, die Eigentümerschaft des Namen »org.freedesktop.ReconnectExample« anzunehmen,
                * fügen Sie folgendes als /etc/dbus-1/system.d/org.freedesktop.ReconnectExample.conf hinzu
                * und laden Sie den Verwalter mit »systemctl reload dbus« neu:

               <?xml version="1.0"?> <!--*-nxml-*-->
               <!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
                 "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
               <busconfig>
                 <policy user="root">
                   <allow own="org.freedesktop.ReconnectExample"/>
                   <allow send_destination="org.freedesktop.ReconnectExample"/>
                   <allow receive_sender="org.freedesktop.ReconnectExample"/>
                 </policy>

                 <policy context="default">
                   <allow send_destination="org.freedesktop.ReconnectExample"/>
                   <allow receive_sender="org.freedesktop.ReconnectExample"/>
                 </policy>
               </busconfig>

                *
                * Um die Eigenschaften mittel busctl zu erlangen:
                *
                * $ busctl --user get-property org.freedesktop.ReconnectExample \
                *                              /org/freedesktop/ReconnectExample \
                *                              org.freedesktop.ReconnectExample \
                *                              Example
                * s "example"
                */

               #include <errno.h>
               #include <stdio.h>
               #include <stdlib.h>
               #include <systemd/sd-bus.h>

               #define _cleanup_(f) __attribute__((cleanup(f)))

               static int log_error(int r, const char *str) {
                 fprintf(stderr, "%s schlug fehl: %s\n", str, strerror(-r));
                 return r;
               }

               typedef struct object {
                 const char *example;
                 sd_bus **bus;
                 sd_event **event;
               } object;

               static int property_get(
                               sd_bus *bus,
                               const char *path,
                               const char *interface,
                               const char *property,
                               sd_bus_message *reply,
                               void *userdata,
                               sd_bus_error *error) {

                 object *o = userdata;

                 if (strcmp(property, "Example") == 0)
                   return sd_bus_message_append(reply, "s", o->example);

                 return sd_bus_error_setf(error,
                                          SD_BUS_ERROR_UNKNOWN_PROPERTY,
                                          "Unbekannte Eigenschaft »%s«",
                                          property);
               }

               /* https://www.freedesktop.org/software/systemd/man/sd_bus_add_object.html */
               static const sd_bus_vtable vtable[] = {
                 SD_BUS_VTABLE_START(0),
                 SD_BUS_PROPERTY(
                   "Example", "s",
                   property_get,
                   0,
                   SD_BUS_VTABLE_PROPERTY_CONST),
                 SD_BUS_VTABLE_END
               };

               static int setup(object *o);

               static int on_disconnect(sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
                 int r;

                 r = setup((object *)userdata);
                 if (r < 0) {
                   object *o = userdata;
                   r = sd_event_exit(*o->event, r);
                   if (r < 0)
                     return log_error(r, "sd_event_exit()");
                 }

                 return 1;
               }

               /* Sicherstellen, dass sich die Ereignisschleife mit einem klaren Fehler beendet, falls das Erlangen des gut bekannten Dienstenamens fehlschlägt */
               static int request_name_callback(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
                 int r;

                 if (!sd_bus_message_is_method_error(m, NULL))
                   return 1;

                 const sd_bus_error *error = sd_bus_message_get_error(m);

                 if (sd_bus_error_has_names(error, SD_BUS_ERROR_TIMEOUT, SD_BUS_ERROR_NO_REPLY))
                   return 1; /* Der Bus ist nicht verfügbar, später erneut versuchen */

                 fprintf(stderr, "Fehlschlag beim Anfragen des Namens: %s\n", error->message);
                 object *o = userdata;
                 r = sd_event_exit(*o->event, -sd_bus_error_get_errno(error));
                 if (r < 0)
                   return log_error(r, "sd_event_exit()");

                 return 1;
               }

               static int setup(object *o) {
                 int r;

                 /* Falls es eine Neuverbindung ist, muss das Busobjekt geschlossen, abgehängt von
                  * der Ereignisschleife und neu erstellt werden.
                  * https://www.freedesktop.org/software/systemd/man/sd_bus_detach_event.html
                  * https://www.freedesktop.org/software/systemd/man/sd_bus_close_unref.html
                  */
                 if (*o->bus) {
                   r = sd_bus_detach_event(*o->bus);
                   if (r < 0)
                     return log_error(r, "sd_bus_detach_event()");
                   *o->bus = sd_bus_close_unref(*o->bus);
                 }

                 /* Einrichten eines neuen Busobjekts für den Systembus, dessen Konfiguration, auf die Verfügbarkeit
                  * des D-Busses zu warten, statt bei Nichtverfügbarkeit fehlzuschlagen und ihn zu starten. Alle
                  * folgenden Aktionen sind asyncron und blockieren nicht beim Warten auf die Verfügbarkeit des D-Bus.
                  * https://www.freedesktop.org/software/systemd/man/sd_bus_new.html
                  * https://www.freedesktop.org/software/systemd/man/sd_bus_set_address.html
                  * https://www.freedesktop.org/software/systemd/man/sd_bus_set_bus_client.html
                  * https://www.freedesktop.org/software/systemd/man/sd_bus_negotiate_creds.html
                  * https://www.freedesktop.org/software/systemd/man/sd_bus_set_watch_bind.html
                  * https://www.freedesktop.org/software/systemd/man/sd_bus_set_connected_signal.html
                  * https://www.freedesktop.org/software/systemd/man/sd_bus_start.html
                  */
                 r = sd_bus_new(o->bus);
                 if (r < 0)
                   return log_error(r, "sd_bus_new()");
                 r = sd_bus_set_address(*o->bus, "unix:path=/run/dbus/system_bus_socket");
                 if (r < 0)
                   return log_error(r, "sd_bus_set_address()");
                 r = sd_bus_set_bus_client(*o->bus, 1);
                 if (r < 0)
                   return log_error(r, "sd_bus_set_bus_client()");
                 r = sd_bus_negotiate_creds(*o->bus, 1, SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_EFFECTIVE_CAPS);
                 if (r < 0)
                   return log_error(r, "sd_bus_negotiate_creds()");
                 r = sd_bus_set_watch_bind(*o->bus, 1);
                 if (r < 0)
                   return log_error(r, "sd_bus_set_watch_bind()");
                 r = sd_bus_start(*o->bus);
                 if (r < 0)
                   return log_error(r, "sd_bus_start()");

                 /* Veröffentlicht eine Schnittstelle auf dem Bus unter Angabe des gut bekannte Objektzugriffspfades
                    und des öffentlichen Schnittstellennamens.
                  * https://www.freedesktop.org/software/systemd/man/sd_bus_add_object.html
                  * https://dbus.freedesktop.org/doc/dbus-tutorial.html
                  */
                 r = sd_bus_add_object_vtable(*o->bus,
                                              NULL,
                                              "/org/freedesktop/ReconnectExample",
                                              "org.freedesktop.ReconnectExample",
                                              vtable,
                                              o);
                 if (r < 0)
                   return log_error(r, "sd_bus_add_object_vtable()");
                 /* Standardmäßig ist dem Dienst nur ein flüchtiger Name zugewiesen. Der gut bekannte
                  * wird hinzugefügt, damit Clients ihn für den Aufruf kennen. Dies muss asynchron erfolgen
                  * da der D-Bus noch nicht verfügbar sein könnte. Der Rückruf wird prüfen, ob der Fehler
                  * erwartet wurde oder nicht, falls er fehlschlägt.
                  * https://www.freedesktop.org/software/systemd/man/sd_bus_request_name.html
                  */
                 r = sd_bus_request_name_async(*o->bus,
                                               NULL,
                                               "org.freedesktop.ReconnectExample",
                                               0,
                                               request_name_callback,
                                               o);
                 if (r < 0)
                   return log_error(r, "sd_bus_request_name_async()");
                 /* Wenn der D-Bus abgetrennt wird, wird dieser Rückruf aufgerufen, der die Verbindung
                  * erneut einrichtet. Dies muss asynchron erfolgen, da der D-Bus noch nicht verfügbar
                  * sein könnte.
                  * https://www.freedesktop.org/software/systemd/man/sd_bus_match_signal_async.html
                  */
                 r = sd_bus_match_signal_async(*o->bus,
                                               NULL,
                                               "org.freedesktop.DBus.Local",
                                               NULL,
                                               "org.freedesktop.DBus.Local",
                                               "Disconnected",
                                               on_disconnect,
                                               NULL,
                                               o);
                 if (r < 0)
                   return log_error(r, "sd_bus_match_signal_async()");
                 /* Das Bus-Objekt an die Ereignisschleife anhängen, so dass Aufrufe und Signale verarbeitet
                  * werden.
                  * https://www.freedesktop.org/software/systemd/man/sd_bus_attach_event.html
                  */
                 r = sd_bus_attach_event(*o->bus, *o->event, 0);
                 if (r < 0)
                   return log_error(r, "sd_bus_attach_event()");

                 return 0;
               }

               int main(int argc, char **argv) {
                 /* Der Bus sollte aufgegeben werden, bevor sich das Programm beendet. Die
                  * Aufräumattribute ermöglichen es, dass dies beim Verlassen des Blocks nett
                  * und sauber erfolgt.
                  */
                 _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
                 _cleanup_(sd_event_unrefp) sd_event *event = NULL;
                 object o = {
                   .example = "example",
                   .bus = &bus,
                   .event = &event,
                 };
                 int r;

                 /* Erzeugt eine Ereignisschleifen-Datenstruktur mit Standard-Parametern.
                  * https://www.freedesktop.org/software/systemd/man/sd_event_default.html
                  */
                 r = sd_event_default(&event);
                 if (r < 0)
                   return log_error(r, "sd_event_default()");

                 /* Standardmäßig wird sich die Ereignisschleife beenden, wenn alle Quellen verschwunden
                  * sind, daher muss sie »belegt« bleiben. Dafür wird Signalverarbeitung registriert.
                  * https://www.freedesktop.org/software/systemd/man/sd_event_add_signal.html
                  */
                 r = sd_event_add_signal(event, NULL, SIGINT|SD_EVENT_SIGNAL_PROCMASK, NULL, NULL);
                 if (r < 0)
                   return log_error(r, "sd_event_add_signal(SIGINT)");

                 r = sd_event_add_signal(event, NULL, SIGTERM|SD_EVENT_SIGNAL_PROCMASK, NULL, NULL);
                 if (r < 0)
                   return log_error(r, "sd_event_add_signal(SIGTERM)");

                 r = setup(&o);
                 if (r < 0)
                   return EXIT_FAILURE;

                 /* Eintreten in die Hauptschleife, sie wird nur bei Sigint/Sigterm verlassen.
                  * https://www.freedesktop.org/software/systemd/man/sd_event_loop.html
                  */
                 r = sd_event_loop(event);
                 if (r < 0)
                   return log_error(r, "sd_event_loop()");

                 /* https://www.freedesktop.org/software/systemd/man/sd_bus_release_name.html */
                 r = sd_bus_release_name(bus, "org.freedesktop.ReconnectExample");
                 if (r < 0)
                   return log_error(r, "sd_bus_release_name()");

                 return 0;
               }

       Obwohl die Weitergabe von Ressourcen von einem weichen Neustartzyklus zum nächsten auf diese Art möglich
       ist, empfehlen wir nachdrücklich, diese Funktionalität nur restriktiv zu verwenden, da sie zu fragileren
       Systemen führt, da Ressourcen von verschiedenen Versionen des Betriebssystems und Anwendungen mit
       unvorhergesehenen Konsequenzen gemischt werden. Insbesondere wird empfohlen zu vermeiden, es Prozessen zu
       erlauben, die weiche Neustartaktion zu überleben, da dies bedeutet, dass Code-Aktualisierungen
       notwendigerweise unvollständig sind und Prozesse typischerweise verschiedene andere Ressourcen festhalten
       (wie das ihnen zugrundeliegende Dateisystem), wodurch der Speicherverbrauch erhöht wird (da zwei
       Versionen des Betriebssystems/der Anwendung/des Dateisystems im Speicher verbleiben können). Das
       Weiterlaufen von Prozessen während einer weichen Neustartaktion benötigt die umfassende Abtrennung des
       Dienstes vom Betriebssystem, d.h. die Minimierung von IPC und die Reduktion der gemeinsamen Verwendung
       von Ressourcen mit dem Rest des Betriebssystems. Ein möglicher Mechanismus, dies zu erreichen, ist das
       Konzept des Portablen Dienstes[1]. Stellen Sie aber sicher, dass keine Ressource vom
       Betriebssystem-Dateisystem des Hauptsystems mittels BindPaths= oder ähnlichen Unit-Einstellungen
       festgehalten wird. Andernfalls verbleibt das alte, ursprüngliche Dateisystem eingehängt, solange die Unit
       läuft.

ANMERKUNGEN

       Beachten Sie, dass auch die Programme in /usr/lib/systemd/system-shutdown/ nicht ausgeführt werden, da
       systemd-shutdown(8) nicht ausgeführt wird.

       Beachten Sie, dass systemd-soft-reboot.service (und zugehörige Units) niemals direkt ausgeführt werden
       sollten. Lösen Sie stattdessen das Herunterfahren des Systems mit Befehlen wie »systemctl soft-reboot«
       aus.

       Falls ein neues Wurzeldateisystem unter »/run/nextroot/« eingerichtet wurde, beachten Sie, dass ein
       soft-reboot durchgeführt wird, wenn der Befehl reboot aufgerufen wird.

SIEHE AUCH

       systemd(1), systemctl(1), systemd.special(7), systemd-poweroff.service(8), systemd-suspend.service(8),
       bootup(7)

ANMERKUNGEN

        1. Portable Dienste
           https://systemd.io/PORTABLE_SERVICES

Ü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: debian-l10n-german@lists.debian.org.

systemd 257.6                                                                     SYSTEMD-SOFT-REBOOT.SERVICE(8)