Das Init-System Systemd, Teil 1

Seite 3: Units und Targets

Inhaltsverzeichnis

Die verschiedenen Tätigkeiten beim Systemstart – Sockets anlegen, Hardware einrichten, Datenträger einbinden, Hintergrunddienste starten und so weiter – sind in sogenannten Units organisiert. Für jede Aufgabe, die Systemd ausführen soll, benötigt man eine Unit-spezifische Konfigurationsdatei – bei einer Mount-Unit beispielsweise muss die Konfiguration lediglich die Device-Datei des Datenträgers und das Zielverzeichnis enthalten. Diese Unit-Dateien sind erheblich kürzer als traditionelle Init-Skripte. Syntaktisch ähneln sie den Ini-Dateien von Windows.

Den Typ einer Unit erkennt Systemd am Dateinamen. Dateien, die auf .service enden, legen Service-Units an; sie kümmern sich um Hintergrunddienste. Units zum Ein- und Aushängen von Dateisystemen enden auf .mount; das Suffix lautet .automount, wenn dabei der Automounter involviert ist, der Dateisysteme beim Zugriff automatisch einhängt. Units mit dem Suffix .path weisen Systemd an, die spezifizierten Dateien und Verzeichnisse via Inotify überwachen; erfolgt dort ein Zugriff, startet Systemd diese Unit.

Auf .socket endende Unit-Dateien legen einen oder mehrere Sockets für die Socket-Aktivierung an. Der zugehörige Dienst wird erst dann über eine zu der Socket-Unit gehörende Service-Unit gestartet, wenn ein anderer Prozess Daten auf den Socket schreibt. Der geöffnete Socket wird dabei an den Dienst übergeben – ähnlich wie es alte Unix-/Linux-Hasen von Inetd kennen.

Service-Units kümmern sich um Hintergrunddienste.

Die Unit-Dateien von Systemd und den Systemdiensten liegen im Verzeichnis /lib/systemd/system/; liegt eine gleichnamige Datei in /etc/systemd/system/, ignoriert Systemd die im Lib-Verzeichnis. Der Administrator kann so eine Unit-Datei von Systemd kopieren und an seine Belange anpassen, ohne fürchten zu müssen, dass sie beim nächsten Update überschrieben wird – das konnte bei Sysvinit-Distributionen passieren, wenn man eines der in /etc/rc.d/init.d/ gespeicherten Init-Skripte von Hand veränderte.

Systemd erzeugt einige Units dynamisch selbst; sie tauchen daher nicht im Dateisystem, sondern nur in der mit systemctl abrufbaren Liste der Units auf. So wird für einige Geräte wie Datenträger, PCI-Geräte und TTYs im Zusammenspiel mit Udev automatisch eine Device-Unit generiert, wenn sie in den Udev-Regeln mit TAG+="systemd" gekennzeichnet sind. Ähnlich wie beim Zweigespann aus Socket- und Service-Unit können andere Units von diesen Device-Units abhängen und so automatisch starten, wenn Geräte auftauchen, auf die sie angewiesen sind.

Dieses System kommt auch bei den .swap-Units zum Einsatz, die automatisch mit Hilfe der Angaben in /etc/fstab angelegt werden und die den Auslagerungsspeicher einbinden, sobald das spezifizierte Swap-Volume auftaucht. Systemd erzeugt auch für einige andere in /etc/fstab spezifizierte Datenträger automatisch Mount-Units, daher tauchen in der Systemctl-Liste mehr Mount-Units auf, als man Konfigurationsdateien findet.

Unit-Dateien, die auf .target enden, definieren Gruppen aus Units. Sie leisten selbst wenig, rufen vielmehr andere Units auf, die für Dienste, Dateisysteme und andere Dinge zuständig sind. So lassen sich Boot-Ziele definieren, die den klassischen Sys-V-Runlevels entsprechen. Die Unit multi-user.target etwa sorgt für den Start all jener Dienste, die ältere Fedora- und OpenSuse-Versionen im Runlevel 3 aufrufen würden – voller Multiuser-Netzwerkbetrieb ohne grafischen Anmeldemanager. Letzterer erscheint bei der Unit graphical.target, die damit das Äquivalent zum Runlevel 5 darstellt und typischerweise das Standard-Ziel ist.

Target-Units starten über Abhängigkeiten andere Units und sind mit klassischen Sys-V-Runleveln vergleichbar.

Beim Hochfahren des Systems aktiviert Systemd die spezielle Target-Unit default.target, typischerweise ein Alias eines anderen Targets wie graphical.target oder multi-user.target. Die Targets können zudem aufeinander aufbauen oder voneinander abhängen; graphical.target etwa wartet den Start von multi-user.target ab, bevor es die grafische Oberfläche startet.

Wo nötig lassen sich über die Angabe von "Wants" in den Unit-Dateien manuell Abhängigkeiten zwischen den Units definieren – wichtig beispielsweise für Dienste wie den Apache-Webserver, der beim Start eine voll konfigurierte Netzwerkumgebung erwartet. Solche Dienste sollten von network.target abhängen. Bei Diensten wie Avahi oder Bind ist eine solche Abhängigkeit nicht nötig, da diese auch mit Netzwerk-Interfaces zurechtkommen, die zur Laufzeit erscheinen oder verschwinden.