- Die Abhängigkeiten der Runlevel-Skripte untereinander. Das
hergebrachte System kann die Reihenfolge steuern, in der es die
Skripte eines Runlevels abarbeitet. Es kennt aber keinen
Mechanismus, der es daran hindern würde, viel Zeit mit
aussichtslosen Startversuchen zu verplempern, nachdem Dienste am
Anfang einer Abhängigkeitskette keinen Erfolg hatten. Die
darauf aufbauenden Services bemerken die fehlenden Voraussetzungen
nicht und mühen sich daher auf verlorenem Posten, bis ein
Timeout sie erlöst. - Die Geschwindigkeit des Bootvorgangs. System-V-Init arbeitet
streng seriell und absolviert einen Schritt nach dem anderen
(Abbildung 1). Das ist dort, wo ein Dienst auf einem anderen
aufbaut, auch nötig – voneinander unabhängige
Dienste könnten aber gleichzeitig anlaufen, was einen
großen Zeitgewinn brächte. - Die Überwachung einmal gestarteter Dienste. Das
traditionelle Init-System gibt die Verantwortung für einen
Dienst ab, sobald es sein Startskript ausgeführt hat. Die
einzige kleine Ausnahme sind jene Dienste, die
»/etc/inittab« startet, etwa die
»getty«-Prozesse. Für sie ist ein automatischer
Neustart möglich (Respawning). - Die Flexibilität beim Booten, zum Beispiel durch die
Verwendung von Profilen, die an verschiedene Einsatzszenarien
angepasst sind. Die einzige Möglichkeit, die
Systemkonfiguration mit Hilfe von System-V-Init vor dem Booten zu
bestimmen, ist die Wahl eines bestimmten Runlevels. Deren
Granularität ist aber sehr gering.
Abhilfe in allen Punkten verspricht eine ganze Reihe von Lösungen, die im einfachsten Fall nur darauf abzielen, die Skripte zu verbessern, die das klassische »init« ausführt. Schon dieser Ansatz reicht aus, um zumindest bestehende Abhängigkeiten besser zu verwalten.
Etliche Linux-Distributionen gehen diesen Weg. Auf der Habenseite verbuchen sie dabei die Kompatibilität mit dem hergebrachten System. Die meisten Alternativen streben allerdings die Parallelisierung der Startvorgänge an und sind daher zu einem viel radikaleren Schnitt gezwungen. Sie ersetzen den zentralen Systemstarter »init« komplett.
Runit
Runit [2] ist ein Init-Ersatz, der von den Daemontools [3] des bekannten amerikanischen Kryptologen und Methematikers D. J. Bernstein inspiriert ist. Die umstrittenen Lizenzbedingungen verhinderten allerdings ihre Integration in Debian – für Gerrit Pape einer der Gründe, im November 2001 das Konzept in einem eigenen Projekt erneut aufzugreifen.
So entstand Runit, das sein Programmierer dem Linux-Magazin als einen Service-Supervisor erklärt, der sich “nicht nur beim Booten um seine Dienste kümmert, sondern während der ganzen Laufzeit des Systems. Das ist ein eigenes Konzept für die Behandlung der Systemdienste: Sie werden nicht gestartet und dann sich selbst überlassen, sondern durch ein kleines Programm überwacht, das dem Administrator ein Interface für die Verwaltung bietet. Auf diese Weise lassen sich die Daemons starten, neu starten und beenden, Signale versenden oder Statusinformationen abfragen.”

Abbildung 1: Das grafische Protokoll eines herkömmlichen Bootvorgangs auf einem minimalistischen Testsystem, erstellt mit »bootchart«. Gut zu erkennen ist die streng serielle Arbeitsweise beim Starten der Dienste.
Den Bootvorgang gliedert Runit in drei Stadien (Stages): Das erste absolviert alle One-Time-Tasks nacheinander. Das betrifft vor allem die Initialisierung der Hardware sowie das Überprüfen und Mounten der lokalen Filesysteme. In Stage 2 startet Runit weitere Dienste parallel. Jedem Service ist für diesen Zweck in einem Runlevel-Verzeichnis (siehe Abbildung 2) unterhalb von »/etc/runit/runsvdir« ein eigenes Unterverzeichnis zugeordnet. Es muss mindestens ein Skript namens »run« enthalten, das den Dienst startet. Stage 3 schließlich kontrolliert den Shutdown.
Für eventuelle Abhängigkeiten von anderen Diensten ist jedes Startskript selbst verantwortlich: Stellt es fest, dass ihm Voraussetzungen fehlen, beendet es sich wieder mit einem Fehler-Returncode. Der Supervisor-Daemon wird es später, wenn die noch fehlenden Dienste wahrscheinlich laufen, erneut automatisch zu starten versuchen.

Abbildung 2: Das Heimatverzeichnis eines Service unter Runit. Neben den beiden Startskripten »run« und »finish« sammelt ein Unterverzeichnis Meta-Informationen.
Runit kann sich sowohl dem System-V-Init unterordnen und, selbst vom klassischen Init gestartet, nur das Service-Monitoring übernehmen als auch selber System-V-Bootskripte respektive ganze Runlevel nach altem Vorbild starten.
In der Umstellungsphase ist diese Flexibilität ein großer Vorteil. Doch hält der Mischbetrieb auch Stolperstellen parat: So kreiert Runit beispielsweise nicht die Fifo »/dev/initctl«, die »telinit« beim Wechsel des Runlevels zur Kommunikation mit »init« verwendet. Will der Admin ein mit Runit gebootetes System etwa mit »reboot« neu starten, muss er dies via »-f« erzwingen, sonst bricht das Kommando ab, da es den erwarteten Kommunikationskanal nicht findet. Ein Problem, das Runit mit etlichen Konkurrenten teilt.
Alle Bootskripte sind neu zu erstellen. Sie fallen jedoch viel einfacher aus als ihre System-V-Vorbilder, weil sie sich nur noch auf den Start ihrer Prozesse zu konzentrieren brauchen. Die vergleichsweise gute Dokumentation enthält einen großen Fundus an Beispielen.




