SSD Nodes Learn 🎉 VPS ab $5.50/Monat
Anleitungen Matt ConnorVon Matt Connor · Aktualisiert 2026-08-13

Warum sich systemd durchsetzte: Die Geschichte

SysV init konnte Abhängigkeiten und Prozesse nicht sauber verfolgen. Lesen Sie, was Upstart und launchd versuchten, warum systemd in vier Jahren gewann und welche Kritik berechtigt war.

Warum sich systemd durchsetzte

Die Geschichte von systemd beginnt mit zwei Aufgaben, die SysV init nicht erfüllen konnte. SysV init (System V init, das von AT&T Unix übernommene Startsystem von Linux) konnte weder beschreiben, wovon ein Dienst abhängt, noch feststellen, welche Prozesse nach dem Start zu einem Dienst gehören. systemd löste beide Probleme mit Kernel-Funktionen, die ein Shell-Skript nicht nutzen kann: Control Groups zur Nachverfolgung von Prozessen und vorab geöffnete Listening-Sockets zur Steuerung der Startreihenfolge. Der weitere Verlauf zeigt, wie sich diese beiden Lösungen auf den übrigen Userland-Bereich ausbreiteten. Dort begannen die Einwände. Mehrere dieser Einwände waren berechtigt.

Was SysV init tatsächlich tat

Auf einem SysV-System las PID 1 (Prozess-ID 1, der erste vom Kernel gestartete Prozess) /etc/inittab, wählte ein Runlevel aus und führte die Skripte für dieses Runlevel aus. Die Skripte lagen in /etc/init.d/. Symbolische Links in /etc/rc3.d/ legten fest, welche Skripte ausgeführt wurden und in welcher Reihenfolge. Daher verwies /etc/rc3.d/S20nginx auf /etc/init.d/nginx und wurde mit dem Argument start aufgerufen.

#!/bin/sh
### BEGIN INIT INFO
# Provides:          nginx
# Required-Start:    $local_fs $remote_fs $network $syslog
# Required-Stop:     $local_fs $remote_fs $network $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
### END INIT INFO

case "$1" in
  start)
    start-stop-daemon --start --quiet --pidfile /run/nginx.pid \
      --exec /usr/sbin/nginx
    ;;
  stop)
    start-stop-daemon --stop --quiet --retry TERM/30/KILL/5 \
      --pidfile /run/nginx.pid
    ;;
esac

Das 20 in S20nginx ist eine Position, keine Abhängigkeit. Es besagt, dass dieses Skript nach S19 und vor S21 ausgeführt wird. Es erklärt nicht den Grund dafür. Deshalb kann niemand dies prüfen, und niemand kann zwei voneinander unabhängige Skripte sicher gleichzeitig ausführen, ohne dass ein Mensch dies als unbedenklich einstuft.

Das Programm rc führte die Skripte nacheinander aus und wartete jeweils auf deren Beendigung. Ein Skript, das dreißig Sekunden lang auf eine Netzwerkadresse wartete, blockierte den gesamten Bootvorgang dreißig Sekunden lang. Das galt auch für Dienste, die das Netzwerk nie verwenden.

Der LSB-Header (Linux Standard Base) am Anfang dieses Skripts sollte dieses Problem von innen heraus lösen. Debian 6.0 machte insserv im Jahr 2011 zum Standard: Es las Required-Start aus jedem Skript, erstellte daraus einen Graphen und nummerierte die symbolischen Links neu. Debian konnte unabhängige Skripte anschließend mit startpar gleichzeitig ausführen. Das war hilfreich, löste aber nicht das grundlegende Problem. Die Abhängigkeit bestand weiterhin darin, dass ein Skript beendet wurde. Wenn S20nginx den Wert 0 zurückgibt, bedeutet das, dass eine Shell-Funktion zurückgekehrt ist. Es bedeutet nicht, dass nginx Verbindungen annimmt.

Die fünf Dinge, die kein Init-Skript beheben konnte

  • Paralleler Start. Die Reihenfolge anhand des Dateinamens bildet eine vollständige Ordnung über alle Dienste auf dem Rechner. Dadurch dauert der Bootvorgang so lange wie die Summe aller Einzelstarts.
  • Bereitschaft. Ein Startskript wird beendet, sobald es den Daemon per Fork gestartet hat, nicht erst dann, wenn der Daemon Anfragen verarbeiten kann. Deshalb startet das nächste Skript häufig zu früh.
  • Überwachung. Ein Daemon führt zweimal einen Fork aus, und sein Elternprozess wird beendet. Dadurch wird der Daemon vom Terminal gelöst und dem Prozess mit PID 1 neu zugeordnet. init sieht, dass ein Kindprozess beendet wurde, und hat keine zuverlässige Verbindung zu dem Prozess, der weiterläuft.
  • Start bei Bedarf. inetd, der Internet-Superserver, konnte einen Daemon starten, sobald eine Verbindung einging. Er war jedoch ein separates System mit einer eigenen Konfigurationsdatei und regelte nicht die Reihenfolge der übrigen Starts beim Booten.
  • Ressourcensteuerung. Mit einem Init-Skript ließ sich weder der Speicher eines Dienstes begrenzen noch sein Anteil an der CPU festlegen. ulimit wirkte auf einen einzelnen Prozess, und nice beeinflusste nur den Scheduler. Daher sah ein außer Kontrolle geratener Kindprozess eines Dienstes wie jeder andere Prozess auf dem Rechner aus.

Die Lücke bei der Überwachung war im täglichen Betrieb besonders problematisch. Die PID-Datei war der übliche Workaround: Der Daemon schrieb seine Prozess-ID nach /run/nginx.pid, und die Stop-Funktion las diese Datei wieder ein. Wenn der Daemon hart beendet wurde, blieb die Datei zurück. Der Kernel verwendete diese Nummer anschließend für einen anderen Prozess, und start-stop-daemon --stop --pidfile sendete ein Signal an den Prozess, dem sie nun gehörte. Eine veraltete PID-Datei führt dazu, dass ein Init-Skript den falschen Prozess beendet.

launchd löste das Socket-Problem zuerst

Apple veröffentlichte launchd 2005 mit Mac OS X 10.4. Dave Zarzycki schrieb die Software. Ein Prozess ersetzte init, rc, xinetd, crond und watchdogd.

Die übernehmenswerte Idee war die Socket-Aktivierung. launchd erstellt zuerst jedes Listening-Socket und startet danach die Daemons. Verbindet sich ein Client mit einem noch nicht gestarteten Daemon, erhält er keine Verbindungsablehnung. Der Kernel hält die Verbindung in der Backlog-Warteschlange dieses Sockets, bis der Daemon accept() aufruft. Die Reihenfolge zwischen zwei Daemons muss dadurch nicht mehr von einem Menschen festgelegt werden. Das Socket übernimmt diese Aufgabe.

launchd basiert auf Mach IPC (Interprozesskommunikation). Diese gehört zum XNU-Kernel von Apple und hat unter Linux kein Gegenstück. Eine Portierung des Codes war daher nie realistisch. Die Idee setzte sich trotzdem durch.

Upstart machte Ereignisse zur Arbeitseinheit

Canonicals Upstart, entwickelt von Scott James Remnant, wurde im Oktober 2006 mit Ubuntu 6.10 veröffentlicht. Fedora 9 bis Fedora 14 verwendeten es ebenso wie RHEL 6 und Chrome OS. Upstart ersetzte den Runlevel durch ein Ereignis. Ein Job legte fest, welche Ereignisse ihn starten und stoppen sollten.

# /etc/init/example.conf
start on filesystem and net-device-up IFACE!=lo
stop on runlevel [!2345]
respawn
respawn limit 10 5
exec /usr/local/bin/exampled

Mit wachsender Anzahl von Jobs traten zwei Probleme auf. Das erste Problem war die Richtung. Ein Job sagt: „Starte mich, wenn dies geschieht.“ Dadurch steht das Wissen über Abhängigkeiten in der falschen Datei: Ein Dienst weiß, was er benötigt, kann aber nicht wissen, welcher andere Dienst ihn im nächsten Jahr benötigen wird. Das Hinzufügen eines Dienstes bedeutete häufig, einen vorhandenen Job zu bearbeiten, damit dieser ein neues Ereignis ausgibt.

Das zweite Problem war die Überwachung. Upstart verfolgte einen sich per Fork aufspaltenden Daemon, indem es fork()-Aufrufe mit ptrace zählte. Dies wurde als expect fork oder expect daemon konfiguriert. Wenn die Anzahl der Forks falsch angegeben war, überwachte Upstart entweder einen Prozess, der bereits beendet war, oder wartete auf einen Fork, der bereits erfolgt war. Das Symptom ist ein hängendes initctl start ohne Fehlermeldung. Die Jobdatei bietet keine Möglichkeit, dies zu erklären.

Upstart verlangte außerdem von Mitwirkenden, Canonicals Contributor Agreement zu unterzeichnen. Das war kein technischer Fehler. Es beeinflusste jedoch, wer daran mitarbeitete.

Neubewertung von PID 1, April 2010

Am 30. April 2010 veröffentlichte Lennart Poettering einen Beitrag mit dem Titel „Rethinking PID 1“. Kay Sievers arbeitete mit ihm an dem Projekt. Die Argumentation bestand aus vier Teilen.

  • Weniger starten. Viele Dienste können warten, bis sie tatsächlich angefordert werden.
  • Keine Reihenfolge deklarieren, wenn ein Socket sie implizieren kann. Alle Sockets in einem Durchlauf öffnen und anschließend alles gleichzeitig starten.
  • Prozesse mit Control Groups statt mit PID-Dateien verfolgen.
  • Einen Dienst in einer deklarativen Datei beschreiben, damit eine Beschreibung für jede Distribution funktioniert.

Die erste Veröffentlichung folgte noch im selben Jahr. Fedora 14 veröffentlichte systemd im November 2010 als Option, und Fedora 15 machte es im Mai 2011 zum Standard.

Warum cgroups die Überwachung zuverlässig machten

Eine cgroup (control group) ist eine Kernel-Funktion zum Gruppieren von Prozessen, die 2008 in Linux 2.6.24 integriert wurde. systemd ordnet jeden Dienst einer eigenen cgroup zu. Ein Kindprozess übernimmt die cgroup seines Elternprozesses. Ein Prozess ohne ausreichende Berechtigungen kann sich nicht aus einer cgroup entfernen. Doppelte Forks verbergen daher nichts: PID 1 kennt jederzeit exakt die Menge der Prozesse, die zu einer Unit gehören. Einen Dienst zu stoppen bedeutet, alle Prozesse in seiner cgroup zu beenden. Genau das bewirkt KillMode=control-group standardmäßig.

systemctl status gibt diese Gruppe aus:

● nginx.service - A high performance web server and a reverse proxy server
     Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; preset: enabled)
     Active: active (running) since Tue 2026-08-11 09:14:22 UTC; 3min ago
   Main PID: 1042 (nginx)
      Tasks: 3 (limit: 4653)
     Memory: 6.1M (peak: 7.4M)
     CGroup: /system.slice/nginx.service
             ├─1042 "nginx: master process /usr/sbin/nginx"
             ├─1043 "nginx: worker process"
             └─1044 "nginx: worker process"

Dieser Block liefert die vollständige Erklärung für die veraltete PID-Datei. Eine PID-Datei kann nicht veralten, weil die Liste im Kernel-Zustand enthalten ist.

Derselbe Baum enthält auch die Ressourcenlimits, weil cgroups ursprünglich für die Abrechnung entwickelt wurden, bevor sie jemand zur Nachverfolgung von Prozessen verwendete. MemoryMax=, CPUQuota= und TasksMax= bestehen jeweils aus einer Zeile. Ein hartes Speicher- und CPU-Limit für einen Dienst festlegen bedeutet heute, eine Drop-in-Datei anzulegen. 2009 hätte dafür ein Patch für ein Shell-Skript erstellt werden müssen, das niemand geschrieben hatte.

Warum jede Distribution zwischen 2011 und 2015 umstieg

  • Fedora 15, Mai 2011.
  • openSUSE 12.1, November 2011.
  • Mageia 2, Mai 2012.
  • Arch Linux, Standard für neue Installationen ab Oktober 2012.
  • RHEL 7, Juni 2014.
  • SLES 12, Oktober 2014.
  • Debian 8, April 2015.
  • Ubuntu 15.04, April 2015.

Die Gründe waren überwiegend unspektakulär. Deshalb erfolgte der Wechsel schnell.

  • Eine Unit-Datei funktioniert auf jeder Distribution. Daher begannen Upstream-Projekte, eine .service-Datei auszuliefern. Die Distributionen mussten dadurch nicht mehr pro Paket und Release ein Shell-Skript pflegen.
  • Die Nachverfolgung von Desktop-Sitzungen wechselte zu systemd-logind, nachdem ConsoleKit etwa 2012 nicht mehr gepflegt wurde. GNOME benötigte logind. Eine Distribution ohne systemd musste daher einen Ersatz finden. Dieser Ersatz ist elogind. Dabei handelt es sich um systemd's logind, das herausgelöst und separat gepflegt wird.
  • udev, der Gerätemanager, wurde im April 2012 in den systemd-Quellbaum integriert. Distributionen, die udev auslieferten, verfolgten nun das Repository von systemd. Gentoo forkte daraufhin eudev.
  • Container machten eine zuverlässige Prozessnachverfolgung und Limits pro Dienst wichtiger, da beides Funktionen von cgroups sind. Die Frage, welcher Supervisor einen Containerprozess verwaltet, stellt sich weiterhin, wenn Sie einen Docker-Compose-Stack nach einem Reboot wieder starten lassen wollen.

Die Entscheidung von Debian sorgte für die größte Aufmerksamkeit. Das Technical Committee stimmte im Februar 2014 ab. Die Abstimmung endete unentschieden. Der Vorsitzende Bdale Garbee gab daraufhin die entscheidende Stimme für systemd ab. Ubuntu kündigte wenige Tage später an, Debian zu folgen, statt Upstart weiterzuverwenden. Eine Gruppe von Debian-Entwicklern forkte die Distribution im November 2014 als Devuan und veröffentlichte Devuan 1.0 im Mai 2017.

Die Einwände, sachlich dargestellt

Umfang. Ein einziges Projekt liefert inzwischen PID 1, den Logging-Daemon, die Verwaltung von Anmeldesitzungen, den Gerätemanager, einen Daemon für die Netzwerkkonfiguration, einen DNS-Resolver (Domain Name System), einen NTP-Client (Network Time Protocol), einen Container-Runner und einen Bootloader. Die übliche Verteidigung, dass es sich um separate Binärdateien handelt, die Sie nicht installieren müssen, ist zwar richtig, beantwortet den Einwand aber nicht. Sobald ein Desktop logind benötigt und logind aus dem systemd-Quellbaum stammt, ist die Entscheidung nicht mehr frei. Genau das war mit Kopplung gemeint. Und genau das ist passiert.

Das Binärjournal. journald schreibt ein indiziertes Binärformat statt Klartext. Dadurch erhalten Sie Funktionen, die Klartext nie geboten hat: Filterung nach Unit und Priorität, strukturierte Felder sowie Metadaten, die das sendende Programm nicht fälschen kann, weil journald Unit und cgroup selbst erfasst. journalctl -u nginx -p err --since "-1h" ersetzt ein grep durch einen regulären Ausdruck für ein Datum. Die Kosten sind ebenfalls real. Auf einem Rechner, der nicht bootet, können Sie das Journal mit less nicht aus einer Rescue-Shell lesen. Stattdessen geben Sie den Pfad zur eingehängten Festplatte an journalctl:

sudo journalctl --directory /mnt/var/log/journal --boot -1 --priority err

Hier gibt es eine zweite Falle, die viele einmal übersehen. journald speichert Logs in /run/log/journal, also im Arbeitsspeicher, sofern /var/log/journal nicht existiert. Auf einem Rechner, auf dem das nicht vorhanden ist, hat journalctl -b -1 nach einem Reboot nichts anzuzeigen. Das ist genau der Zeitpunkt, an dem Sie die Logs benötigen. Prüfen und korrigieren Sie die Einstellung:

journalctl --disk-usage
sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journald

journalctl --disk-usage sollte nun archivierte Journale unter /var/log/journal melden. Wenn Sie zusätzlich Klartext benötigen, setzen Sie ForwardToSyslog=yes in /etc/systemd/journald.conf und lassen Sie rsyslog installiert.

Debugging des Bootvorgangs. Wenn eine Unit hängt, zeigt die Konsole eine einzige Zeile und sonst nichts:

[  *** ] A start job is running for Wait for Network to be Configured (1min 32s / no limit)

Die erforderlichen Werkzeuge sind vorhanden: systemctl list-jobs, solange der Vorgang hängt, systemd-analyze blame und systemd-analyze critical-chain danach sowie systemd.log_level=debug in der Kernel-Befehlszeile. Sachlich formuliert lautet der Einwand, dass jeder, der sh kannte, ein Init-Skript von oben bis unten lesen konnte, während Sie bei einer hängenden Unit wissen müssen, welches von einem Dutzend Kommandos Sie verwenden müssen. Das ist ein realer Nachteil. Jeder Administrator bezahlt ihn einmal. Viele Administratoren mussten ihn gleichzeitig bezahlen.

Eine Vorgabe, die für alle geändert wird. systemd 230 änderte 2016 die Vorgabe von logind, sodass verbliebene Benutzerprozesse beim Abmelden beendet wurden. Getrennte tmux- und screen-Sitzungen wurden beendet, sobald die Sitzung endete, die sie gestartet hatte. Distributionen lieferten KillUserProcesses=no in /etc/systemd/logind.conf aus. Die unterstützte Lösung lautet loginctl enable-linger <user>. Eine Vorgabe in einem einzigen Projekt änderte eine Gewohnheit, auf die sich Millionen Menschen verlassen hatten. Genau das bedeutet „zu viel Userland an einer Stelle“ in der Praxis.

Eine Standardabhängigkeit ist eine Angriffsfläche. Im März 2024 zielte die Hintertür in xz-utils auf sshd in Debian und Ubuntu. Das OpenSSH-Upstream-Projekt linkt nicht gegen libsystemd. Diese Distributionen integrierten die erforderliche Unterstützung, damit sshd seine Bereitschaft an systemd melden konnte. Dadurch zog libsystemd liblzma als Abhängigkeit hinzu, wo sich die Hintertür befand. Das Bereitschaftsprotokoll selbst besteht aus einem einzelnen Datagramm, das an den in $NOTIFY_SOCKET genannten Socket gesendet wird. Dafür war daher niemals eine Bibliothek erforderlich. systemd reagierte darauf, Komprimierungsbibliotheken mit dlopen zu laden, sodass sie standardmäßig nicht mehr gelinkt werden. Eine verwandte Fehlerklasse zeigt dasselbe Muster: 2017 wurde ein User=-Wert, der mit einer Ziffer begann, als ungültig behandelt. Die Unit lief dadurch als root, statt fehlzuschlagen. Ein Tippfehler wurde so zu einer Rechteausweitung. Spätere Versionen verweigern den Start der Unit.

Historie an der eigenen systemctl-Eingabeaufforderung

Jedes oben genannte Problem ist jetzt eine Direktive in einer Datei, die Sie lesen können.

  • Der serielle Bootvorgang wurde zu After= und Wants=, und systemd-analyze critical-chain zeigt, was Ihren Bootvorgang tatsächlich aufgehalten hat.
  • Die Bereitschaft wurde zu Type=notify. Darin schreibt der Dienst READY=1 nach $NOTIFY_SOCKET, sobald er Anfragen verarbeiten kann. Type=forking mit PIDFile= gibt es für alte Daemons weiterhin. Dabei handelt es sich um den Typ, der mit start operation timed out. Terminating. fehlschlägt, wenn die PID-Datei nie angelegt wird.
  • Die Überwachung übernimmt die cgroup. Daher ersetzt Restart=on-failure mit RestartSec= ein Wrapper-Skript, und StartLimitBurst= verhindert, dass eine Absturzschleife endlos weiterläuft.
  • Aus inetd wurde eine .socket-Unit neben der .service-Unit.
  • Aus ulimit wurden MemoryMax=, CPUQuota= und TasksMax=.
  • Die su - appuser -c-Zeile in einem Init-Skript wurde zu User=, NoNewPrivileges=yes und ProtectSystem=strict. Dadurch ist das Ausführen eines Dienstes als nicht privilegierter Benutzer die standardmäßige Struktur einer Unit und keine zusätzliche Arbeit.
[Unit]
Description=Example API
Wants=network-online.target
After=network-online.target postgresql.service
Requires=postgresql.service

[Service]
Type=notify
ExecStart=/usr/local/bin/exampled
Restart=on-failure
RestartSec=2
MemoryMax=512M
CPUQuota=50%
TasksMax=128
User=exampled
NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=strict
StateDirectory=exampled

[Install]
WantedBy=multi-user.target

Eine Zeile in dieser Datei ist der Fehler, den jeder einmal macht. Requires=postgresql.service ist eine Abhängigkeit, keine Reihenfolgevorgabe. Die Direktive besagt, dass Ihre Unit fehlschlägt, wenn Postgres fehlschlägt. Sie besagt nicht, dass Postgres zuerst gestartet wird. Ohne After=postgresql.service starten beide zum selben Zeitpunkt, und Ihr Dienst versucht, eine Verbindung zu einem Port herzustellen, an dem noch kein Prozess lauscht. Die beiden Direktiven sind absichtlich getrennt, weil Sie manchmal nur eine davon benötigen. ProtectSystem=strict bindet das Dateisystem für diesen Dienst schreibgeschützt ein. Deshalb ist StateDirectory= vorhanden: Die Direktive stellt dem Dienst unter /var/lib einen beschreibbaren Pfad bereit.

Am deutlichsten sehen Sie das Verhalten von 2005 auf einem Server aus 2026 bei SSH unter Ubuntu 24.04, das im August 2026 systemd 255 ausliefert. ssh.service wird standardmäßig über einen Socket aktiviert: ssh.socket hält den Listening-Socket, und sshd startet, sobald eine Verbindung eintrifft. Daher hat Port 2222 in /etc/ssh/sshd_config keine Wirkung, weil nicht sshd den Port geöffnet hat. Die Änderung gehört in die Socket-Unit.

sudo systemctl edit ssh.socket
[Socket]
ListenStream=
ListenStream=2222

Das leere ListenStream= löscht den Wert, der von der mitgelieferten Unit geerbt wurde. Lassen Sie es weg, erhalten Sie beide Ports, weil systemd eine Liste erweitert, statt sie zu ersetzen. Wenden Sie die Änderung anschließend an und prüfen Sie sie. Lassen Sie dabei die gesamte Zeit eine zweite SSH-Sitzung geöffnet:

sudo systemctl daemon-reload
sudo systemctl restart ssh.socket
sudo ss -lntp | grep 2222

ss sollte einen Socket auf Port 2222 auflisten, der systemd gehört, nicht sshd. Das ist 20 Jahre später das launchd-Design auf Ihrem VPS. Wenn Sie das frühere Verhalten bevorzugen, erhalten Sie mit sudo systemctl disable --now ssh.socket und anschließend sudo systemctl enable --now ssh.service einen dauerhaft laufenden sshd, der Port wieder aus seiner eigenen Konfiguration liest.

Welche dieser Details für Sie relevant sind, hängt vom verwendeten Release ab. Daher sollten Sie den Unterschied zwischen einem LTS- und einem Interim-Release von Ubuntu kennen, bevor Sie ein Upgrade planen. Auf mehreren Rechnern ist die Tatsache, dass eine Unit-Datei überall identisch ist, der Grund dafür, dass die Verwaltung mehrerer Server von einer Stelle aus heute ein Konfigurationsproblem und kein Shell-Scripting-Problem mehr ist. Wenn Sie eigene Units schreiben, übernimmt das Paar aus Service und Timer die Aufgabe, die Sie 2009 zwischen einem Init-Skript und einer Cron-Zeile aufgeteilt hätten.

FAQ

Warum haben Linux-Distributionen SysV init durch systemd ersetzt?

Dafür gab es zwei technische und einen Wartungsgrund. SysV init ordnete Dienste nach Dateinamen. Das ist eine Position und keine Abhängigkeit. Außerdem verlor SysV init den Überblick über Daemons, die sich von ihrem Elternprozess abspalteten. Deshalb konnten veraltete PID-Dateien den falschen Prozess beenden. systemd löste die Reihenfolge mit Socket-Aktivierung und Abhängigkeitsdirektiven. Die Prozessüberwachung wurde mit Control Groups gelöst. Der Wartungsgrund gab letztlich den Ausschlag für die Geschwindigkeit: Eine Unit-Datei funktioniert auf jeder Distribution. Deshalb lieferten Upstream-Projekte eine .service-Datei aus, und die Distributionsmaintainer mussten nicht mehr für jedes Paket ein Shell-Skript schreiben. Fedora 15 wechselte im Mai 2011. Ubuntu 15.04 war im April 2015 der letzte große Nachzügler.

Ist systemd eine einzige große Binärdatei?

Nein. Der Quellbaum erstellt viele separate Programme. PID 1 ist /usr/lib/systemd/systemd. journald, logind und udevd sind dagegen separate Prozesse mit eigenen Binärdateien. Mit ls /usr/lib/systemd/ können Sie sie auf Ihrem eigenen System anzeigen. Die anhaltende Kritik bezieht sich eher auf die Kopplung der Releases als auf die Größe der Binärdatei: Diese Programme werden gemeinsam veröffentlicht und verwenden private Schnittstellen. Deshalb übernehmen Distributionen sie meist als Paket. Software wie GNOME erwartete außerdem zunehmend speziell logind.

Kann ich Linux weiterhin ohne systemd ausführen?

Ja. Devuan liefert sysvinit aus, Gentoo verwendet standardmäßig OpenRC, Void verwendet runit, Alpine verwendet busybox init mit OpenRC, und Slackware behält Skripte im BSD-Stil bei. Der Aufwand besteht in der Kompatibilität. Desktop-Software, die logind erwartet, benötigt elogind. Dabei handelt es sich um systemds logind als separat verwaltetes Paket. Außerdem wird zunehmend Serversoftware ausschließlich mit einer .service-Datei ausgeliefert. Das Startskript müssen Sie dann selbst schreiben und warten.

Warum ist das Journal binär und keine einfache Textdatei?

Weil journald strukturierte Felder mit einem Index speichert. Dadurch sind Filterung nach Unit und Priorität sowie Metadaten möglich, die das sendende Programm nicht fälschen kann. journald erfasst die Unit, die Control Group und die tatsächliche UID selbst, statt der Logzeile zu vertrauen. Der Nachteil ist, dass Sie zum Lesen journalctl benötigen, auch von einem Rettungssystem aus. Dort geben Sie mit journalctl --directory /mnt/var/log/journal die eingebundene Festplatte an. Wenn Sie zusätzlich Textausgabe benötigen, setzen Sie ForwardToSyslog=yes in /etc/systemd/journald.conf.

Was ersetzt das Bearbeiten meines /etc/init.d-Skripts?

Drop-in-Dateien. Bearbeiten Sie die Unit in /usr/lib/systemd/system/ nicht, da ein Paket-Upgrade sie überschreibt. Führen Sie sudo systemctl edit nginx.service aus. systemd erstellt dann /etc/systemd/system/nginx.service.d/override.conf, das über die bereitgestellte Unit gelegt wird. systemctl cat nginx.service zeigt das zusammengeführte Ergebnis an. systemd-delta listet alle Overrides auf dem System auf. Führen Sie nach jeder manuellen Änderung sudo systemctl daemon-reload aus. Andernfalls gibt der nächste Befehl Warning: The unit file, source configuration file or drop-ins of nginx.service changed on disk. aus.

#systemd#linux#init#sysvinit#history