25Das Init-System

Dieses Kapitel beschreibt die Vorgänge, die vom Kernelstart bis hin zum Login stattfinden. Der Kernel startet als ersten Prozess das Programm /sbin/init. Es kümmert sich um die Basiskonfiguration des Systems, um das Einbinden von Dateisystemen und um den Start zahlloser Netzwerkdienste und -dämonen.

Wie so oft in der Linux-Welt gibt es nicht ein Init-System, sondern mehrere. Dieses Kapitel stellt die drei wichtigsten vor:

Tabelle 25.1 fasst zusammen, welches Init-System in welcher Distribution zum Einsatz kommt. Die Spalte RHEL gilt für Red Hat Enterprise Linux sowie für alle dazu kompatiblen Distributionen, also z.B. CentOS und Scientific Linux. Analog gilt dies auch für die Ubuntu-Spalte. Es ist allerdings noch nicht ganz sicher, ob alle Ubuntu-Derivate den Wechsel von Upstart auf Systemd sofort nachvollziehen werden.

Init-System

Debian

Fedora

openSUSE

RHEL

Ubuntu

Init-V

bis 7

bis 8

bis 11.4

bis 5

bis 6.04

Upstart

9 bis 13

6

6.10 bis 14.10

Systemd

ab 8

ab 14

ab 12.1

ab 7

ab 15.04

Tabelle 25.1Init-Systeme je nach Distribution und Version

Das Kapitel endet mit einer Vorstellung des Internet Service Daemons. Dieses Programm überwacht Netzwerkports. Wenn dort Anfragen eintreffen, kann es ein Programm starten, das geeignet ist, um darauf zu reagieren.

25.1Das Init-V-System

Das traditionelle Init-V-System wird bei manchen aktuellen und vielen älteren Distributionen dazu verwendet, die Systeminitialisierung durchzuführen und Netzwerkdienste zu starten. Wie das Programm /sbin/init im Einzelnen ausgeführt wird, hängt von der jeweiligen Distribution ab: In welchen Verzeichnissen befinden sich welche Init-Dateien, mit welchen Nummern oder Buchstaben sind die sogenannten Runlevel bezeichnet, welche Konfigurationsdateien werden berücksichtigt etc.?

Init-V-Grundlagen bleiben relevant!

Auch wenn viele aktuelle Distributionen Upstart oder Systemd verwenden, werden sie in diesem Abschnitt mehrfach erwähnt. Das liegt daran, dass Upstart und Systemd Init-V-kompatibel sind und daher manche Init-V-Prinzipien weiterhin gültig bleiben. Auch wenn Sie ein Script für einen eigenen Systemdienst entwickeln möchten, bietet sich das Init-V-System als kleinster gemeinsamer Nenner an. Ein Beispiel für ein derartiges Script folgt in Abschnitt 25.7, »Eigene Init-Scripts bzw. Init-Konfigurationsdateien«.

Die folgenden Punkte geben einen kurzen Überblick über einen Systemstart durch das Init-V-System:

Runlevel

Der Kernel startet /sbin/init als erstes Programm. Dabei werden alle Boot-Optionen, die der Kernel nicht kennt und daher nicht selbst verarbeiten kann, an das Init-System übergeben. Auf diese Weise kann beispielsweise erreicht werden, dass Linux im Single-User-Modus gestartet wird.

init ist also der erste laufende Prozess. Alle weiteren Prozesse werden entweder direkt von init oder indirekt durch Subprozesse von init gestartet. Führen Sie in einem Terminal pstree aus, dann erkennen Sie sofort die dominierende Rolle von init! Beim Herunterfahren des Rechners ist init der letzte noch laufende Prozess, der sich um das korrekte Beenden aller anderen Prozesse kümmert.

Für das Verständnis der System-V-Mechanismen ist der Begriff des Runlevels von zentraler Bedeutung. Der Runlevel beschreibt verschiedene Zustände, die das Betriebssystem einnehmen kann. Leider ist die Runlevel-Nummerierung je nach Distribution uneinheitlich. Die jeweilige Bedeutung der Runlevel ist in der Regel in /etc/inittab dokumentiert. Für die meisten Distributionen (aber nicht für Debian, Raspbian und Ubuntu!) gelten die folgenden Runlevel-Beschreibungen:

Auf Systemen, die zwischen den Runleveln 1 und S differenzieren, werden die Runlevel-1-Scripts ausgeführt, um von einem gewöhnlichen Runlevel (2, 3 oder 5) in den Single-User-Runlevel zu wechseln. Die Runlevel-S-Scripts kommen dagegen nur zur Anwendung, wenn der Single-User-Runlevel direkt nach dem Booten aktiviert werden soll.

Bei von Debian abgeleiteten Distributionen sind die Runlevel 2 bis 5 gleichwertig und starten jeweils ein Multiuser-System mit Netzwerk und Grafiksystem. Als Standard-Runlevel gilt 2. Der Runlevel S ist eigentlich kein eigener Level, sondern dient zur Initialisierung des Rechners unmittelbar nach dem Start, also noch bevor einer der anderen Level aktiviert wird. Die Netzwerkfunktionen werden bei Debian bzw. Ubuntu bereits während der Systeminitialisierung aktiviert und stehen daher in allen Runleveln zur Verfügung.

root kann den Runlevel im laufenden Betrieb durch das Kommando init x verändern. x ist dabei eine Runlevel-Ziffer oder ein Runlevel-Buchstabe. Beispielsweise ist es für manche Wartungsarbeiten sinnvoll, in den Single-User-Modus zu wechseln. Auch shutdown, halt, reboot bzw. (Strg)+(Alt)+(Entf) in einer Textkonsole ändern den Runlevel und führen auf diese Weise zu einem Rechnerneustart.

Wenn der reguläre Start von Linux nicht funktioniert, können Sie versuchen, das System direkt im Single-User-Modus zu starten. Dazu unterbrechen Sie den automatischen Start durch GRUB, öffnen mit (E) den Editor für den Starteintrag, suchen die mit linux beginnende Zeile und fügen am Ende dieser Zeile ein Leerzeichen und dann single hinzu. Mit (Strg)+(X) starten Sie dann Linux.

Beim klassischen Init-V-System wird der Standard-Runlevel durch die initdefault-Zeile in /etc/inittab bestimmt. Bei den meisten aktuellen Distributionen gilt 5 als Standard-Runlevel, bei Debian ist es 2.

Bei Ubuntu wird der Standard-Runlevel in /etc/init/rc-sysinit.conf festgelegt. Diese Datei ist Teil des Upstart-Systems.

Bei Distributionen, die Systemd verwenden, wird der Standard-Runlevel durch /etc/systemd/default.target festgelegt. Dieser Link zeigt auf eine der vordefinierten Target-Dateien im Verzeichnis /lib/systemd/system/.

Inittab

Beim Systemstart wird init durch die Datei /etc/inittab gesteuert. Für die Syntax der inittab-Einträge gilt folgendes Schema:

id-code:runlevel:action:command

id-code besteht aus zwei Zeichen, die die Zeile eindeutig identifizieren. Der runlevel gibt an, für welchen Runlevel der Eintrag gilt. action enthält eine Anweisung für init. command gibt an, welches Linux-Kommando oder Programm gestartet werden soll. Tabelle 25.2 zählt die wichtigsten action-Schlüsselwörter auf. Eine vollständige Beschreibung erhalten Sie mit man inittab.

Schlüsselwort

Bedeutung

ctrlaltdel

gibt an, wie init auf (Strg)+(Alt)+(Entf) reagieren soll.

initdefault

definiert den Standard-Runlevel für init (siehe oben).

once

init startet das angegebene Kommando beim Runlevel-Wechsel.

respawn

init startet das Kommando nach seinem Ende wieder neu.

sysinit

init startet das Kommando einmal während des Boot-Prozesses.

wait

init wartet auf das Ende des nachfolgenden Kommandos.

bootwait

init startet den Prozess während des Boot-Prozesses und wartet auf das Ende des nachfolgenden Kommandos.

Tabelle 25.2inittab-Schlüsselwörter (id-codes)

Das folgende Listing gibt die leicht gekürzte inittab-Datei von Debian 7 wieder. (Ab Version 8 verwendet auch Debian Systemd.) Als Standard-Runlevel gilt 2. Bei einem normalen Systemstart führt init die Script-Dateien rcS und das Kommando rc 2 aus. Schließlich wird für die Textkonsolen 1 bis 6 das Programm mingetty gestartet, das einen Login ermöglicht. (Wenn Sie mehr Textkonsolen haben möchten, ist hier der richtige Ort für Veränderungen. Beachten Sie aber, dass die Konsole 7 bei den meisten Distributionen für X reserviert ist.)

# Datei /etc/inittab bei Debian 7 sowie bei Raspbian-Versionen bis Sep. 2015 # Standard-Runlevel id:2:initdefault: # Systemkonfiguration und -initialisierung unmittelbar nach dem Rechnerstart si::sysinit:/etc/init.d/rcS # Verhalten im Single-User-Modus (Kernelparameter su) ~~:S:wait:/sbin/sulogin # Start der jeweiligen Runlevel l0:0:wait:/etc/init.d/rc 0 l1:1:wait:/etc/init.d/rc 1 l2:2:wait:/etc/init.d/rc 2 l3:3:wait:/etc/init.d/rc 3 l4:4:wait:/etc/init.d/rc 4 l5:5:wait:/etc/init.d/rc 5 l6:6:wait:/etc/init.d/rc 6 # Die folgende Zeile sollte nie erreicht werden, sie ist nur für Notfälle da. z6:6:respawn:/sbin/sulogin # Reaktion auf Strg+Alt+Entf in einer Textkonsole ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now # Reaktion auf einen Stromausfall, der von einer unterbrechungsfreien # Stromversorgung gemeldet wird pf::powerwait:/etc/init.d/powerfail start pn::powerfailnow:/etc/init.d/powerfail now po::powerokwait:/etc/init.d/powerfail stop # gettys (Terminalemulatoren) für die Textkonsolen starten 1:2345:respawn:/sbin/getty 38400 tty1 2:23:respawn:/sbin/getty 38400 tty2 3:23:respawn:/sbin/getty 38400 tty3 4:23:respawn:/sbin/getty 38400 tty4 5:23:respawn:/sbin/getty 38400 tty5 6:23:respawn:/sbin/getty 38400 tty6

Die meisten Distributionen sind so vorkonfiguriert, dass die Tastenkombination (Strg)+(Alt)+(Entf) in Textkonsolen zu einem Neustart des Rechners führt. Wenn Sie möchten, dass der Rechner stattdessen ausgeschaltet wird, geben Sie beim shutdown-Kommando in der ca:-Zeile die Option -h statt -r an. Wenn Sie diese Tastenkombination ganz deaktivieren möchten, setzen Sie vor die ca:-Zeile das Kommentarzeichen #. Beachten Sie aber, dass Änderungen in inittab nur bei solchen Distributionen zweckmäßig sind, die das Init-V-System verwenden!

Systeminitialisierung

Noch bevor die im Weiteren beschriebenen rc-Dateien die runlevel-spezifischen Dienste starten oder stoppen, wird unmittelbar nach dem Rechnerstart eine Systeminitialisierung durchgeführt (si:-Zeile in inittab). Der Name des Scripts hängt von der Distribution ab: Bei Debian bis Version 7 ist es /etc/init.d/rcS, bei RHEL 5 /etc/rc.d/rc.sysinit, bei alten SUSE-Versionen /etc/init.d/boot. Bei Debian ist rcS ein winziges Script, das seinerseits alle Script-Dateien /etc/rcS.d/S* ausführt.

Während der Systeminitialisierung werden die Dinge erledigt, die während des Rechnerstarts nur einmal getan werden müssen:

Init-V-Scripts für die Aktivierung der Runlevel

Nach der Systeminitialisierung wird der Standard-Runlevel laut /etc/inittab aktiviert. Für alle Details der Runlevel gibt es eigene Script-Dateien. Diese befinden sich je nach Distribution im Verzeichnis /etc/init.d oder in /etc/rc.d/init.d. Um eine höhere Kompatibilität zwischen den Distributionen zu erreichen, stellen meist Links sicher, dass beide Pfade gültig sind.

Zum Start der Init-V-Scripts führt init das Script /etc/rc.d/rc bzw. /etc/init.d/rc aus. An rc wird der gewünschte Runlevel n übergeben. rc führt zuerst einige Initialisierungsarbeiten durch. Dann werden alle rcn.d/K*-Script-Dateien zum Beenden laufender Prozesse ausgeführt. Schließlich werden alle rcn.d/S*-Script-Dateien zum Starten der neuen Prozesse für den jeweiligen Runlevel ausgeführt.

Der Vorteil dieses Systems besteht darin, dass es sehr einfach ist, neue Systemprozesse in den Init-V-Prozess einzubauen: Es müssen lediglich Links für die rc-Start- und -Stopp-Scripts in die richtigen Verzeichnisse eingerichtet werden – und genau das geschieht bei der Installation eines Pakets mit einem zusätzlichen Dämon. Die folgende Aufstellung zeigt, welche Script-Dateien für einige ausgewählte Runlevel ausgeführt werden:

user$ cd /etc/ user$ ls rcS.d/ rc2.d/ rc6.d/ rcS.d/: (Systeminitialisierung) K05hwclock.sh S03keyboard-setup S09mountall-bo...sh S15console-setup K12rpcbind S04mountdevsubfs.sh S10procps S16alsa-utils K13nfs-common S05checkroot.sh S10udev-mtab S16bootmisc.sh README S06checkroot-bo...sh S10urandom S16plymouth-log S01fake-hwclock S06kmod S11networking S16raspi-config S01hostname.sh S06mtab.sh S12mountnfs.sh S16x11-common S01mountkernfs.sh S07checkfs.sh S13mountnfs-bo...sh S02udev S08mountall.sh S14kbd rc2.d/: (Standard-Runlevel) K06nfs-common S01motd S02ntp S04cups K06rpcbind S01rsyslog S02radvd S04saned README S01sudo S02rsync S05samba S01bootlogs S01triggerhappy S02ssh S06plymouth S01cgroup-bin S02cron S02vsftpd S06rc.local S01dhcpcd S02dbus S03avahi-daemon S06rmnologin S01gogoc S02dphys-swapfile S03bluetooth S01ifplugd S02lirc S03lightdm rc6.d/: (Shutdown) K01alsa-utils K01lightdm K01urandom K07hwclock.sh K01bluetooth K01lirc K02avahi-daemon K07networking K01cgroup-bin K01plymouth K03sendsigs K08umountfs K01dhcpcd K01radvd K04rsyslog K09umountroot K01fake-hwclock K01samba K05umountnfs.sh K10reboot K01gogoc K01saned K06nfs-common K01ifplugd K01triggerhappy K06rpcbind

In den rcn.d-Verzeichnissen befinden sich nicht unmittelbar die Script-Dateien, sondern lediglich Links auf sie. Die eigentlichen Script-Dateien sind im Verzeichnis /etc/rc.d/init.d oder /etc/init.d gespeichert:

root# cd /etc root# ls -l rc2.d/*cups ... rc2.d/S04cups -> ../init.d/cups

Die Namen der Links sind keineswegs so willkürlich, wie sie aussehen: Der Anfangsbuchstabe gibt an, ob es sich um ein Start- oder ein Kill-Script handelt. Die S- und K-Links verweisen auf dieselbe Datei, allerdings wird das Script je nach Anfangsbuchstabe von rc mit dem Parameter start oder stop ausgeführt.

Die nachfolgende Nummer bestimmt die Reihenfolge, in der die Script-Dateien ausgeführt werden. Beispielsweise setzen die meisten Netzwerkdämonen voraus, dass schon eine Netzwerkverbindung besteht, und müssen daher nach dem Script network gestartet werden. Eine Kurzbeschreibung vieler Dämonen finden Sie in Abschnitt 14.5, »Systemprozesse (Dämonen)«.

Die Runlevel-Script-Dateien können auch manuell ausgeführt werden. Beispielsweise stoppt das folgende Kommando den Windows-kompatiblen Datei-Server Samba:

root# /etc/init.d/samba stop

Bei vielen Distributionen sind zum Starten/Stoppen von Dämonen eigene Kommandos vorgesehen, die weniger Tippaufwand bereiten. Am weitesten verbreitet ist das Kommando service. Es steht in allen in diesem Buch behandelten Distributionen unabhängig vom eingesetzten Init-System zur Verfügung.

root# service samba start

An die meisten Scripts kann einer der folgenden Parameter übergeben werden:

Verwaltung der Runlevel-Links

Viele Runlevel-Script-Dateien werden automatisch beim Rechnerstart bzw. bei einem Runlevel-Wechsel durch das rc-Script gestartet bzw. gestoppt – je nachdem, ob es im rcn.d-Verzeichnis einen S- oder K-Link auf das Init-V-Script gibt. Wenn Sie also möchten, dass eine bestimmte Funktion in Zukunft automatisch aktiviert werden soll, müssen Sie derartige Links einrichten. Entsprechend müssen Sie die Links wieder entfernen, wenn Sie in Zukunft einen automatischen Start verhindern möchten.

Die folgenden Kommandos zeigen, welche Links Sie unter Debian einrichten müssen, um das Programm samba in Zukunft bei den Runleveln 2 bis 5 automatisch zu starten:

root# cd /etc/ root# ln init.d/samba rc0.d/K01samba root# ln init.d/samba rc1.d/K01samba root# ln init.d/samba rc2.d/S20samba root# ln init.d/samba rc3.d/S20samba root# ln init.d/samba rc4.d/S20samba root# ln init.d/samba rc5.d/S20samba root# ln init.d/samba rc6.d/K01samba

Das Entfernen der Links verursacht weniger Tippaufwand:

root# rm rc?.d/*samba

In der Praxis werden Sie die obigen ln- bzw. rm-Kommandos selten manuell eintippen: Die meisten Distributionen stellen nämlich Kommandos zur Verfügung, die Ihnen diese Arbeit abnehmen, z.B. insserv ab Debian 6 sowie bei SUSE, chkconfig bei RHEL 6 und update-rc.d bei älteren Debian-Versionen sowie bei Ubuntu.

root# insserv samba (Start- und Stopp-Links einrichten) root# insserv -r samba (Start- und Stopp-Links entfernen)

Das Kommando update-rc.d ist eigentlich für die Installations-Scripts von Paketen gedacht. Es hilft bei der Installation bzw. Deinstallation von Paketen, die Runlevel-Links für das Init-V-Script des Pakets einzurichten bzw. wieder zu entfernen.

In älteren Debian-Versionen sowie unter Ubuntu können Sie das Kommando auch direkt nutzen. Beachten Sie aber, dass update-rc.d keine Änderungen an bereits vorhandenen Links durchführt! Sie müssen vorhandene Links zuerst löschen.

update-rc.d name remove entfernt alle Start- und Stopp-Links für den angegebenen Dienst. Das Kommando funktioniert allerdings nur, wenn /etc/init.d/name vorher deinstalliert wurde. Ist diese Voraussetzung nicht erfüllt, müssen Sie die Option -f (force) angeben.

update-rc.d name defaults richtet in allen Runleveln Links zum Starten (Runlevel 2–5) und Stoppen des Diensts (Runlevel 0, 1 und 6) ein. Die Link-Namen beginnen mit der durchlaufenden Zahl 30. Wenn das Script früher oder später im Start- bzw. Stopp-Prozess ausgeführt werden soll, müssen Sie die gewünschten Start- und Stopp-Werte selbst angeben – im folgenden Beispiel 30 für den Start und 1 für Stopp:

root# update-rc.d gdm defaults 30 1 /etc/rc0.d/K01gdm -> ../init.d/gdm /etc/rc1.d/K01gdm -> ../init.d/gdm /etc/rc6.d/K01gdm -> ../init.d/gdm /etc/rc2.d/S30gdm -> ../init.d/gdm /etc/rc3.d/S30gdm -> ../init.d/gdm /etc/rc4.d/S30gdm -> ../init.d/gdm /etc/rc5.d/S30gdm -> ../init.d/gdm

Um die Links wirklich für jeden Runlevel individuell einzurichten, übergeben Sie an update-rc.d Argumente in der Form name start|stop nn runlevel. Dabei ist nn die Zahl am Beginn des Runlevel-Links. Sie dürfen mehrere Runlevel und mehrere Argumentgruppen angeben. Allerdings muss jede Argumentgruppe mit einem Punkt abgeschlossen werden. Das folgende Kommando hat dieselbe Wirkung wie gdm defaults 30 1:

root# update-rc.d gdm start 30 2 3 4 5 . stop 1 0 1 6 .

Unter RHEL hilft das Kommando chkconfig bei der Verwaltung der Links auf Init-V-Scripts. Mit der Option --list gibt das Kommando eine Übersicht über alle Scripts und zeigt an, in welchem Runlevel sie gestartet werden. Sofern xinetd installiert ist, werden auch dessen Dienste aufgelistet.

Unter RHEL 7 bzw. CentOS 7 ist die Ergebnisliste kurz, weil die meisten Dienste nun ja durch Systemd verwaltet werden. chkconfig ist nur für die Dienste gedacht, für die es noch herkömmliche Init-V-Scripts gibt. Das folgende Ergebnis ist unter einer CentOS-7-Installation innerhalb von VirtualBox entstanden:

root# chkconfig --list netconsole 0:Aus 1:Aus 2:Aus 3:Aus 4:Aus 5:Aus 6:Aus network 0:Aus 1:Aus 2:Ein 3:Ein 4:Ein 5:Ein 6:Aus vboxadd 0:Aus 1:Aus 2:Ein 3:Ein 4:Ein 5:Ein 6:Aus vboxadd-service 0:Aus 1:Aus 2:Ein 3:Ein 4:Ein 5:Ein 6:Aus vboxadd-x11 0:Aus 1:Aus 2:Aus 3:Ein 4:Aus 5:Ein 6:Aus

Mit --del kann der Start eines Runlevel-Scripts generell verhindert werden:

root# chkconfig --del vboxadd-x11

chkconfig --add fügt in allen vorgesehenen Runleveln Start- und Stopp-Links für einen neuen Service ein. Die Option --add funktioniert allerdings nur, wenn die Init-V-Script-Datei Informationen darüber enthält, in welchem Runlevel das Script standardmäßig gestartet werden soll.

Bei vielen Scripts fehlen diese Informationen. Damit ein derartiges Script in Zukunft automatisch gestartet wird, müssen Sie chkconfig --level n name on/off verwenden. Im folgenden Beispiel soll ein eigenes Script zum Start eines VNC-Servers in den Runlevel 3 und 5 gestartet werden. chkconfig --list zeigt das Ergebnis an:

root# chkconfig --level 35 myvnc on root# chkconfig --list myvnc myvnc 0:Aus 1:Aus 2:Aus 3:Ein 4:Aus 5:Ein 6:Aus

Statusmeldungen während des Boot-Prozesses

Die meisten Distributionen sind so konfiguriert, dass während des Boot-Prozesses ein Hintergrundbild und eventuell ein Fortschrittsbalken oder eine andere grafische Fortschrittsanzeige zu sehen ist. Unabhängig vom Init-System ist dafür oft das Programm Plymouth verantwortlich.

Boot-Meldungen lesen

Wenn es beim Boot-Prozess Probleme gibt, ist es oft hilfreich, die Boot-Meldungen mitzuverfolgen. In der Regel müssen Sie dazu nur (Esc) drücken. Alternativ erreichen Sie die Darstellung der Boot-Meldungen auch, wenn Sie in der GRUB-Konfiguration die Boot-Option quiet entfernen.

Optimierung des Init-V-Prozesses

Der Init-V-Prozess ist sehr aufwendig: Unzählige Scripts und Programme müssen gestartet werden, und für jedes einzelne Script muss ein Script-Interpreter ausgeführt werden. All dies waren Gründe für die Entwicklung von Upstart und Systemd. Aber auch das Init-V-System selbst wurde immer weiter verbessert. Dieser Abschnitt fasst gängige Methoden zur Geschwindigkeitsoptimierung zusammen: