SSD Nodes Learn Hosting plans →
Anleitungen Matt ConnorVon Matt Connor · Aktualisiert 2026-08-27

Warum sich systemd gegen SysV init durchsetzte

SysV init kannte weder Dienstabhängigkeiten noch alle Prozesse eines Dienstes. Erfahren Sie, was Upstart und launchd versuchten und warum Linux in vier Jahren wechselte.

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, von welchen Komponenten 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 beschreibt, wie sich diese beiden Lösungen auf den restlichen Userland-Bereich ausweiteten. Dort begannen die Einwände, von denen mehrere berechtigt waren.

Was SysV init tatsächlich ausführte

Auf einem SysV-System las PID 1 (Prozess-ID 1, der erste vom Kernel gestartete Prozess) /etc/inittab, wählte ein Runlevel 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 in welcher Reihenfolge ausgeführt wurden. 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 bedeutet, dass dieses Skript nach S19 und vor S21 ausgeführt wird. Es erklärt nicht den Grund dafür. Daher kann niemand dies prüfen, und niemand kann zwei voneinander unabhängige Skripte sicher gleichzeitig ausführen, ohne dass ein Mensch ihre Unbedenklichkeit festlegt.

Das Programm rc führte die Skripte nacheinander aus und wartete jeweils, bis das Skript beendet war. Ein Skript, das 30 Sekunden auf eine Netzwerkadresse wartete, blockierte den gesamten Bootvorgang 30 Sekunden lang. Das galt auch für Dienste, die das Netzwerk nie verwenden.

Der LSB-(Linux Standard Base-)Header am Anfang des Skripts sollte dieses Problem von innen heraus lösen. Debian 6.0 machte 2011 insserv zum Standard: Es las Required-Start aus jedem Skript, erstellte einen Graphen und nummerierte die symbolischen Links neu. Debian konnte dadurch unabhängige Skripte mit startpar gleichzeitig ausführen. Das half, löste aber nicht das grundlegende Problem. Die Abhängigkeit bestand weiterhin darin, dass ein Skript beendet wurde. Ein Rückgabewert 0 von S20nginx bedeutet, dass eine Shell-Funktion erfolgreich zurückgegeben hat. Er bedeutet nicht, dass nginx Verbindungen akzeptiert.

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

  • Paralleler Start. Die Sortierung nach Dateinamen bildet eine vollständige Reihenfolge ü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, wenn der Daemon Anfragen verarbeiten kann. Das nächste Skript startet daher häufig zu früh.
  • Überwachung. Ein Daemon führt zweimal einen Fork aus, und sein übergeordneter Prozess wird beendet. Dadurch wird der Daemon vom Terminal getrennt und an PID 1 neu angehängt. 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-Super-Server) 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. Ein außer Kontrolle geratener Kindprozess eines Dienstes sah daher 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 Behelf: Der Daemon schrieb seine Prozess-ID nach /run/nginx.pid, und die Stop-Funktion las die Datei wieder ein. Wenn der Daemon hart beendet wurde, blieb die Datei erhalten. 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 es. Ein Prozess ersetzte init, rc, xinetd, crond und watchdogd.

Die übernehmenswerte Idee war die Socket-Aktivierung. launchd erstellt zuerst alle Listening-Sockets und startet anschließend die Daemons. Verbindet sich ein Client mit einem Daemon, der noch nicht gestartet wurde, erhält er keine Fehlermeldung „Verbindung abgelehnt“. Der Kernel hält die Verbindung in der Backlog-Warteschlange dieses Sockets, bis der Daemon accept() aufruft. Die Startreihenfolge zwischen zwei Daemons muss dadurch nicht mehr von einem Menschen festgelegt werden. Das Socket übernimmt diese Aufgabe.

launchd basiert auf Mach IPC (Inter-Process Communication). Diese Technik gehört zum XNU-Kernel von Apple und hat kein Linux-Gegenstück. Eine Portierung des Codes war 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 verwendete Upstart ebenso wie RHEL 6 und Chrome OS. Upstart ersetzte die Runlevel durch Ereignisse. 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 der Jobs traten zwei Probleme auf. Das erste betraf 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, wer ihn im nächsten Jahr benötigen wird. Das Hinzufügen eines Dienstes erforderte häufig eine Änderung an einem vorhandenen Job, damit dieser ein neues Ereignis ausgab.

Das zweite Problem war die Überwachung. Upstart verfolgte einen sich abspaltenden Daemon, indem es die Aufrufe von fork() mit ptrace zählte. Dies konfigurierten Sie als expect fork oder expect daemon. 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 äußerte sich darin, dass initctl start ohne Fehlermeldung hängen blieb. Die Job-Datei bot keine Möglichkeit, dies zu erklären.

Upstart verlangte außerdem, dass Mitwirkende das Contributor Agreement von Canonical unterzeichneten. Das war kein technischer Fehler, beeinflusste aber, wer daran mitarbeitete.

PID 1 neu gedacht, April 2010

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

  • Weniger starten. Viele Dienste können warten, bis tatsächlich eine Anfrage an sie gestellt wird.
  • 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 auf jeder 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 zur Standardeinstellung.

Warum cgroups die Überwachung zuverlässig machten

Eine cgroup (control group) ist eine Kernel-Funktion zur Gruppierung von Prozessen, die 2008 in Linux 2.6.24 aufgenommen wurde. systemd ordnet jeden Dienst einer eigenen cgroup zu. Ein Kindprozess übernimmt die cgroup seines Elternprozesses. Ein unprivilegierter Prozess kann sich nicht aus einer cgroup entfernen. Double Forking verbirgt 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 das standardmäßige KillMode=control-group.

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 erklärt das Problem mit der veralteten PID-Datei vollständig. Es gibt keine Datei, die veralten kann, weil die Liste den Zustand des Kernels wiedergibt.

Derselbe Baum enthält auch Limits, weil cgroups ursprünglich für die Abrechnung von Ressourcen entwickelt wurden, bevor sie jemand zur Prozessverfolgung einsetzte. MemoryMax=, CPUQuota= und TasksMax= bestehen jeweils aus einer Zeile. Ein hartes Speicher- und CPU-Limit für einen Dienst festlegen ist heute eine Drop-in-Datei. 2009 wäre es ein Patch für ein Shell-Skript gewesen, den niemand geschrieben hätte.

Warum jede Distribution zwischen 2011 und 2015 umstieg

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

Das RHEL-7-Datum reichte weiter als die anderen, weil CentOS 7 es neu gebaut hat. Dort begegneten die meisten Administratoren erstmals einer Unit-Datei, einem Abschnitt in der längeren Entwicklung von Red Hat Linux über CentOS bis zu Rocky und AlmaLinux.

Die Gründe waren größtenteils unspektakulär. Deshalb ging die Umstellung 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 eigenes Shell-Skript pflegen.
  • Die Sitzungsverfolgung für Desktop-Sitzungen wechselte zu systemd-logind, nachdem ConsoleKit um 2012 nicht mehr gepflegt wurde. GNOME benötigte logind. Eine Distribution ohne systemd musste daher einen Ersatz finden. Dieser Ersatz, elogind, ist 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 Prozessverfolgung und Limits pro Dienst wichtiger, da beides cgroup-Funktionen sind. Die Frage, welcher Supervisor den Prozess eines Containers besitzt, ist weiterhin relevant, wenn Sie einen Docker-Compose-Stack nach einem Reboot wieder starten lassen.

Die Entscheidung von Debian sorgte für die größten Diskussionen. 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, fair formuliert

Umfang. Ein Projekt liefert heute PID 1, den Protokollierungs-Daemon, die Verwaltung von Login-Sitzungen, den Gerätemanager, einen Daemon für die Netzwerkkonfiguration, einen DNS-Resolver (domain name system), einen NTP-Client (network time protocol), eine Container-Laufzeitumgebung 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-Baum herausgelöst wird, ist die Wahl nicht mehr frei. Genau das war mit Kopplung gemeint. Und genau das ist geschehen.

Das binäre Journal. 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 und Metadaten, die das sendende Programm nicht fälschen kann, weil journald Unit und cgroup selbst erfasst. journalctl -u nginx -p err --since "-1h" ersetzt einen grep-Aufruf durch einen regulären Ausdruck für ein Datum. Die Kosten sind ebenfalls real. Auf einem Rechner, der nicht bootet, können Sie das Protokoll aus einer Rescue-Shell nicht mit less lesen. Stattdessen geben Sie journalctl den Pfad zum eingebundenen Datenträger:

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

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

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 möchten, setzen Sie ForwardToSyslog=yes in /etc/systemd/journald.conf und lassen Sie rsyslog installiert.

Fehlersuche beim Booten. Wenn eine Unit hängt, zeigt die Konsole eine Zeile und sonst nichts:

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

Die Werkzeuge für eine weitergehende Analyse gibt es: systemctl list-jobs, solange der Vorgang hängt, danach systemd-analyze blame und systemd-analyze critical-chain sowie systemd.log_level=debug in der Kernel-Befehlszeile. Der fair formulierte Einwand lautet, dass jeder, der sh kannte, ein Init-Skript von Anfang bis Ende lesen konnte. Bei einer hängenden Unit muss man dagegen wissen, welches von einem Dutzend Befehlen erforderlich ist. Das ist ein realer Aufwand. Jeder Administrator muss ihn nur einmal lernen. Allerdings mussten ihn viele Administratoren gleichzeitig lernen.

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

Eine Standardabhängigkeit ist eine Angriffsfläche. Im März 2024 zielte die Hintertür in xz-utils auf sshd unter Debian und Ubuntu. Das OpenSSH-Upstream-Projekt verlinkt libsystemd nicht. Diese Distributionen patchten sshd so, dass es seine Bereitschaft an systemd melden konnte. Dadurch zog libsystemd liblzma als Abhängigkeit ein, und dort befand sich die Hintertür. Das Bereitschaftsprotokoll selbst besteht aus einem einzelnen Datagramm, das an den Socket aus $NOTIFY_SOCKET gesendet wird. Dafür war daher nie eine Bibliothek erforderlich. systemd reagierte, indem es Kompressionsbibliotheken mit dlopen lädt. Dadurch werden sie standardmäßig nicht mehr verlinkt. 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 der oben genannten Probleme ist jetzt eine Direktive in einer Datei, die Sie lesen können.

  • Der serielle Start wurde zu After= und Wants=, und systemd-analyze critical-chain zeigt, was Ihren Start 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. Dieser Typ schlägt mit start operation timed out. Terminating. fehl, wenn die PID-Datei nicht erscheint. Die falsche Auswahl führt dazu, dass eine Unit den Status active meldet, obwohl der gestartete Daemon bereits beendet wurde. Deshalb sollten Sie wissen, welcher Type= zur tatsächlichen Startweise Ihres Daemons passt, bevor Sie diese Zeile schreiben.
  • Die Überwachung übernimmt die cgroup. Daher ersetzt Restart=on-failure mit RestartSec= ein Wrapper-Skript, und StartLimitBurst= verhindert, dass eine Absturzschleife dauerhaft lä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 Standardstruktur 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 Voraussetzung, keine Reihenfolgeangabe: 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 verbindet sich mit einem Port, an dem noch nichts 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 schreibbaren Pfad bereit.

Am deutlichsten sehen Sie das Jahr 2005 auf einem Server aus dem Jahr 2026 bei SSH unter Ubuntu 24.04, das im August 2026 systemd 255 enthält. ssh.service wird standardmäßig über einen Socket aktiviert: ssh.socket hält den Listening-Socket, und sshd wird gestartet, 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 von der Paket-Unit geerbten Wert. Lassen Sie es weg, erhalten Sie beide Ports, weil systemd an eine Liste anhängt, statt sie zu ersetzen. Wenden Sie die Änderung anschließend an und prüfen Sie sie. Lassen Sie dabei die ganze 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 das Startdesign von launchd, zwanzig Jahre später, auf Ihrem VPS. Wenn Sie das alte Verhalten bevorzugen, erhalten Sie mit sudo systemctl disable --now ssh.socket gefolgt von sudo systemctl enable --now ssh.service einen dauerhaft laufenden sshd, der Port wieder aus seiner eigenen Konfiguration liest.

Welche dieser Details Sie vorfinden, hängt vom verwendeten Release ab. Deshalb sollten Sie den Unterschied zwischen einem LTS- und einem Interim-Release von Ubuntu kennen, bevor Sie ein Upgrade planen. Bei mehreren Rechnern ist die Tatsache, dass eine Unit-Datei überall identisch ist, der Grund dafür, dass die Verwaltung mehrerer Server von einer Stelle heute ein Konfigurationsproblem und kein Shell-Scripting-Problem mehr ist. Wenn Sie eigene Units schreiben, erledigt das Service- und Timer-Paar die Aufgabe, die Sie 2009 auf ein Init-Skript und eine 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 an. Ein Dateiname beschreibt jedoch eine Position und keine Abhängigkeit. Außerdem verlor SysV init den Überblick über Daemons, die sich vom übergeordneten Prozess 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 bestimmte das Tempo: Eine Unit-Datei funktioniert auf jeder Distribution. Daher lieferten Upstream-Projekte eine .service-Datei aus, und die Distributionsbetreuer 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 ein einziges großes Binary?

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

Kann ich Linux weiterhin ohne systemd ausführen?

Ja. Devuan liefert sysvinit aus, Gentoo verwendet standardmäßig OpenRC, Void verwendet runit, Alpine nutzt busybox init mit OpenRC, und Slackware behält Skripte im BSD-Stil bei. Der Aufwand entsteht durch die Kompatibilität. Desktop-Software, die logind voraussetzt, benötigt elogind. Dabei handelt es sich um systemds logind, das als eigenständiges Paket gepflegt wird. Außerdem liefern immer mehr Serverprogramme nur noch eine .service-Datei aus. Daher müssen Sie das Startskript selbst schreiben und pflegen.

Warum ist das Journal binär und keine reine 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 Cgroup und die tatsächliche UID selbst, statt der Logzeile zu vertrauen. Dafür benötigen Sie journalctl zum Lesen des Journals, auch von einem Rettungssystem aus. In diesem Fall geben Sie mit journalctl --directory /mnt/var/log/journal das eingehängte Laufwerk an. Wenn Sie zusätzlich Textdateien benötigen, setzen Sie ForwardToSyslog=yes in /etc/systemd/journald.conf.

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

Drop-in-Dateien. Bearbeiten Sie die Unit in /usr/lib/systemd/system/ nicht, weil 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 mit der ausgelieferten Unit zusammengeführt wird. systemctl cat nginx.service zeigt das zusammengeführte Ergebnis. systemd-delta listet alle Überschreibungen 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