Wie Upstart Ubuntu-basierte Systeme bootet

Start me up

Als Ersatz für das alte System-V-Init wirft Upstart viele geliebte wie gehasste Konzepte über Bord: Statt verwirrender Runlevel gibt es jetzt Jobs und Ereignisse, während parallel startende Dienste den Bootvorgang beschleunigen sollen. Dennoch ist die Konfiguration fast ein Kinderspiel.
Wer sein System permanent überwacht, hat den Grundstein dafür gelegt Engpässe zu vermeiden und Fehler frühzeitig zu erkennen. Neben dem Platzhirsch Nagios ... (mehr)

Sobald der Linux-Kernel die Hardware in Beschlag genommen und alle Treiber geladen hat, übergibt er die Kontrolle an das kleine Programm »init« . Ihm kommt die Aufgabe zu, den Rest des Systems einzurichten und hochzufahren. Bis vor wenigen Jahren nutzten noch fast alle Linux-Distributionen das so genannte System-V-Init mit seinem geliebten wie gehassten Runlevel-Konzept. Es startete brav einen Dienst nach dem anderen, was zu teilweise recht langen Bootzeiten führte.

Bei Canonical begann man deshalb 2006 mit der Entwicklung eines flotteren Ersatzes. Das Ergebnis namens Upstart fährt seitdem vor allem bei Ubuntu-Distributionen sowie Red Hat Enterprise Linux (RHEL) 6 die Dienste hoch.

Gegenüber dem alten System-V-Init versucht Upstart alle notwendigen Dienste und Programme möglichst parallel zu starten. Darüber hinaus kann es auf bestimmte Ereignisse reagieren, beispielsweise wenn man während des Betriebs eine Festplatte einstöpselt oder austauscht. Schließlich beobachtet es auf Wunsch ohne umständliche Krücken die gestarteten Prozesse und startet sie bei einem Absturz automatisch neu. Um das alles leisten zu können, bricht es vollständig mit dem alten Runlevel-Konzept. Wer damit noch arbeiten muss, sollte im Folgenden kurz sein altes Wissen vergessen.

Um ein Linux-System vollständig hochzufahren, muss Upstart verschiedene Aufgaben durchführen – wie etwa das Netzwerk aktivieren oder den Webserver »httpd« starten. Jede dieser Aufgaben bezeichnet Upstart als Job, den es allerdings immer nur dann bearbeitet, wenn zuvor ein passendes Ereignis eingetreten ist. Ein solches Ereignis könnte beispielsweise "Netzwerk aktiviert" oder "Druckerdaemon gestartet" sein. Gibt es zu einem Ereignis mehrere Jobs, so versucht Upstart, sie parallel zu bearbeiten. Das alles erfolgt vollautomatisch: Ein Webserver muss Upstart nur mitteilen, dass er gerne beim Ereignis "Netzwerk aktiviert" starten möchte. Um alles andere kümmert sich Upstart.

Jeder Job besitzt im Unterverzeichnis »/etc/init« eine eigene Konfigurationsdatei mit der Endung ».conf« . So finden sich beispielsweise in »cups.conf« alle Informationen, die Upstart zum Aktivieren des Cupps-Druckerdaemon kennen muss. Der Dateiname ohne Endung ist gleichzeitig der offizielle Name des Jobs.

Tod oder Leben

Bester Freund des Administrators ist das zu Upstart gehörende Werkzeug »initctl« . Es kontrolliert und verwaltet sämtliche Jobs. Beispielsweise listet der Befehl

initctl list

sämtliche Jobs und ihren aktuellen Status auf ( Abbildung 1 ). In jeder Zeile steht ganz vorne der Name eines Jobs. Der Begriff vor dem Schrägstrich verrät, ob der Job zuletzt gestartet ( »start« ) oder angehalten ( »stop« ) wurde. Nach dem Schrägstrich folgt sein aktueller Zustand. Sofern ein Job beziehungsweise der durch ihn gestartete Dienst läuft, steht am Ende auch gleich noch seine Prozess-ID. Einen laufenden Job beendet

Abbildung 1: initctl list
initctl stop jobname

Damit man sich nicht immer die Finger wund tippen muss, darf man alternativ auch einfach nur

stop jobname

aufrufen. »stop« ist schlicht ein Wrapper-Skript für »initctl stop« , das ebenfalls zum Upstart-Paket gehört und normalerweise in »/sbin« liegt. In jedem Fall sendet Upstart dem betroffenen Prozess zunächst ein SIGTERM-Signal und wartet dann standardmäßig fünf Sekunden. Wenn der Dienst danach immer noch laufen sollte, beendet Upstart ihn umgehend mit dem SIGKILL-Signal. Ein einmal ausgesprochenes »initctl stop« ist somit endgültig.

Neben »stop« gibt es natürlich auch noch »start« und »restart« , die einen Job starten beziehungsweise neustarten. Tabelle 1 fasst die wichtigsten »initctl« -Befehle zusammen (zu den noch unbekannten Befehlen gleich noch mehr). Apropos »/sbin« : Darin liegt auch Upstart selbst unter dem Namen »init« , damit Linux es auch garantiert findet.

Wer einen eigenen Dienst beim Booten hochfahren lassen möchte, braucht eine neue Job-Datei. Im einfachsten Fall besteht diese aus lediglich einer einzigen Zeile:

exec /usr/bin/messd --log=/var/log/laerm/messung.log

Hinter »exec« steht schlicht das Programm beziehungsweise der Dienst, den Upstart ausführen soll. Hier im Beispiel nimmt ein Lärmmessprogramm seine Arbeit auf, das unablässig über entsprechende Hardware den Schallpegel misst und seine gesammelten Messergebnisse in der angegebenen Logdatei ablegt. Sobald man die obige Zeile in einer Datei wie beispielsweise »messen.conf« verstaut und diese bei ihren Kolleginnen unter »/etc/init« geparkt hat, kann man die Messsoftware bereits als Administrator per

sudo start messen

hochfahren beziehungsweise via

sudo stop messen

beenden. In der Regel möchte man den Dienst automatisch beim Booten starten. In diesem Fall muss man die Job-Datei wie in Listing 1 noch etwas erweitern.

Listing 1

Beispiel für eine einfache Job-Datei

 

Kommentare beginnen wie von Shellskripten gewohnt mit einem Hash (#). Hinter »start on« steht der Name eines Ereignisses. Sobald es eintritt, aktiviert Upstart automatisch den Dienst. Anstelle von »exec« darf man übrigens auch ein Skript einbinden:

script
# kleines Bash-Skript:
if [...]; then
...
fi
end script

Upstart führt dann nicht ein Programm aus, sondern arbeitet die Shellbefehle zwischen »script« und »end script« ab. Die Job-Dateien selbst sind übrigens reine Textdateien und sollten möglichst nicht ausführbar sein.

Günstige Gelegenheit

Die Upstart-Ereignisse, auf die ein Job warten kann, können aus mehreren Quellen stammen. Sobald Upstart die Arbeit aufnimmt, erzeugt es automatisch selbst ein Ereignis mit dem Namen »startup« . Ein Dienst, der mit der Anweisung

start on startup

nur auf dieses Ereignis wartet, kann daher weder mit einem funktionierenden Netzwerk noch mit einem vorhandenen Dateisystem rechnen. Im Weiteren entsteht immer dann ein Ereignis, wenn irgendein Job startet oder stoppt. Mit der Zeile

start on starting rsyslog

würde Upstart etwa das Lärmmessprogramm gleichzeitig mit »rsyslog« starten. Möchte man sicherstellen, dass »rsyslog« schon läuft, nutzt man »started« :

start on started rsyslog

Damit würde das Lärmmessprogramm erst nach »rsyslog« loslegen – wann genau, lässt sich nicht vorhersagen. Man muss folglich damit rechnen, dass möglicherweise »rsyslog« noch nicht vollständig funktioniert. Schließlich kann Upstart den Job auch anwerfen, sobald sich ein anderer Dienst beendet beziehungsweise nicht läuft:

start on stopped rsyslog

Eine weitere Ereignisschleuder sind Systemdienste, allen voran der Gerätemanager »udev« . Beim Einstöpseln eines neuen Gerätes erzeugt er ein Ereignis der Form » sub -device- action « . » sub « steht dabei für das entsprechende Udev-Subsystem und » action « für die ausgeführte Aktion. Ein neu angeschlossener Datenträger löst beispielsweise das Ereignis »block-device-added« aus.

Eine unvollständige Liste mit den grundlegenden und zumindest in jedem Ubuntu-System vorhandenen Ereignissen liefert die Manpage »man upstart-events« ( Abbildung 3 ). Eine weitere Quelle sind die schon vorhandenen Job-Dateien unter »/etc/init« .

Abbildung 3: Die Manpage zu

Abschließend kann ein Administrator mit »initctl« ein eigenes Ereignis auslösen:

initctl emit meinereignis

Diesen Befehl darf natürlich auch ein Skript in der Job-Datei aufrufen. Damit es nicht Upstarts Planungen durcheinanderwürfelt, muss man die Job-Datei dann noch mit der Zeile

emit meinereignis

würzen. Sie kündigt formal an, dass der Job irgendwann das Ereignis »meinereignis« auslöst. Sofern ein Job mehrere Ereignisse absetzen möchte, führt man sie jeweils in einer eigenen Zeile auf, wie etwa:

emit start-messung
emit ende-messung

Die »emit« -Angaben benötigt übrigens auch zwingend »initctl check-config« , um die Abhängigkeiten zwischen den Jobs korrekt überprüfen zu können (siehe Kasten "Troubleshooting" ).

Ähnliche Artikel

comments powered by Disqus
Einmal pro Woche aktuelle News, kostenlose Artikel und nützliche ADMIN-Tipps.
Ich habe die Datenschutzerklärung gelesen und bin einverstanden.

Konfigurationsmanagement

Ich konfiguriere meine Server

  • von Hand
  • mit eigenen Skripts
  • mit Puppet
  • mit Ansible
  • mit Saltstack
  • mit Chef
  • mit CFengine
  • mit dem Nix-System
  • mit Containern
  • mit anderer Konfigurationsmanagement-Software

Ausgabe /2023