Das Event-gesteuerte Konzept von Upstart unterscheidet sich grundlegend von dem von SysV-Init, wo die Init-Skripte stur der lexikalischen Reihenfolge im jeweiligen Runlevel-Verzeichnis nach aufgerufen werden. Das macht Upstart sehr viel flexibler: Besteht zum Beispiel beim Start des Mail-Daemons (MTA) noch keine Netzwerkverbindung, muss man bei SysV-Init den Timeout abwarten, bevor das System weiter bootet. Bei Upstart hingegen würde der MTA erst dann gestartet, wenn die Netzwerkverbindung steht: Als Start-Event würde beim MTA-Job das Event network up konfiguriert, das der für die Netzwerkeinrichtung zuständige Dienst erst nach erfolgreicher Netzwerkkonfiguration auslöst – auf einem Notebook unterwegs im Zweifel also gar nicht.
Dadurch, dass es keine feste Startreihenfolge der Jobs gibt, kann ein System mit Upstart schneller booten als eines mit SysV-Init. Hinzu kommt, dass durchaus mehrere Jobs gleichzeitig abgearbeitet, also Initialisierungsaufgaben parallelisiert werden – auch dadurch lässt sich potenziell Zeit sparen.
Eine große Neuerung von Ubuntu 9.10 ist, dass Upstart mit Leben erfüllt und etliche Systemeinstellungen und Daemon-Aufrufe auf Upstart umgestellt wurden, darunter das Einbinden der Laufwerke, der Start von Udev und Cron sowie der grafischen Oberfläche. Allerdings ist man noch nicht so weit, gänzlich auf die alten Init-Skripte verzichten zu können, sodass es weiterhin den Wrapper-Job rc gibt, der die SysV-Init-Runlevel nachbildet und die unter /etc/init.d und /etc/rc?.d verlinkten Init-Skripte aufruft.
Kurz nachdem der Kernel gestartet und die ersten Pseudo-Dateisysteme eingebunden wurden, startet der Job /etc/init/rc-sysinit.conf. Das Start-Event des Jobs ist filesystem und seine Aufgabe ist es, das Event runlevel S zu erzeugen und somit das Äquivalent zu Runlevel S zu setzen. Anschließend läuft der Job /etc/init/rcS.conf an, der die symbolischen Links in /etc/rcS.d abarbeitet und so die Grundkonfiguration des Systems übernimmt. Anschließend wird das Signal für Runlevel 2 erzeugt, womit weitere Upstart-Jobs gekoppelt sind und die in /etc/rc2.d verlinkten Init-Skripte ausgeführt werden.
Auch die Datei /etc/inittab, die bei Systemen mit SysV-Init unter anderem den Start der Login-Konsolen zum Abschluss der Initialisierung erledigt, wurde durch mehrere Upstart-Jobs ersetzt, hier ein Auszug:
start on stopped rc RUNLEVEL=[2345]
stop on runlevel [!2345]
respawn
exec /sbin/getty -8 38400 tty1
Da der Job rc, der die Runlevel emuliert, nach dem Aufruf der Init-Skripte des jeweiligen Runlevels terminiert und nicht ständig während des emulierten Runlevels läuft, ist das Startsignal für die tty-Jobs das Beenden des rc-Jobs und nicht etwa dessen Start. Zudem sollen die Login-Konsolen beim Herunterfahren des Systems (Runlevel 0 und 6) sowie im Single-User-Modus abgeschaltet werden. Das Programm Getty selbst läuft im Vordergrund und wird, da mit dem Schlüsselwort exec aufgerufen, von Upstart überwacht. Mit dem zusätzlichen Schlüsselwort respawn wird Upstart angewiesen, den Prozess immer wieder neu zu starten, wenn er sich beendet – auf diese Weise erhält man nach dem Ausloggen wieder einen neuen Login-Prompt.
Um eine Überlastung des Systems zu verhindern, wenn ein Prozess ständig neu startet, lässt sich begrenzen, wie oft Upstart über welchen Zeitraum versuchen soll, den Dienst zu starten. Fedora 10 nutzt dieses Feature im Job prefdm zum Start der grafischen Oberfläche:
start on stopped rc5
stop on runlevel [!5]
respawn
respawn limit 10 120
exec /etc/X11/prefdm --nodaemon
Das Limit für den Neustart liegt bei 10 Versuchen innerhalb von 120 Sekunden, wobei sowohl die Angabe von respawn als auch von respawn limit erforderlich ist – respawn limit allein bewirkt noch keinen Neustart des Dienstes.
Beim Anhalten eines Jobs kümmert sich Upstart lediglich um den per exec im Vordergrund gestarteten Prozess: Er sendet ihm das Terminate-Signal (SIGTERM) und erwartet, dass er sich selbst beendet. Widerspruch duldet Upstart nicht – beendet sich der Prozess nicht, wird er wenige Sekunden später mittels Kill-Signal (SIGKILL) hart abgebrochen. Ein einmal ausgelöstes Stop-Event kann ein Dienst also weder blockieren noch verzögern oder gar rückgängig machen.
Mit Hilfe der Schlüsselwörter pre-stop und post-stop lassen sich Befehle angeben, die Upstart vor und nach dem Beenden des Dienstes ausführen soll. Dies ist für etwaige Aufräumarbeiten interessant. Hier ein Beispiel:
post-stop exec rm -f /var/run/tserv.pid
Zeitlicher Ablauf eines Upstart-Jobs
Zusätzlich gibt es noch die Schlüsselwörter pre-start und post-start, mit denen Befehle unmittelbar vor und nach dem Start eines Dienstes ausgeführt werden können, etwa um notwendige Verzeichnisse anzulegen oder nach dem Start des Dienstes bestimmte Systemeinstellungen anzupassen. Da exec erwartet, dass der Dienst im Vordergrund startet, kann Upstart mit der Ausführung von post-start nicht warten, bis der Dienst beendet wurde. Deshalb führt Upstart post-start parallel mit dem Start des Dienstes aus. Die nebenstehende Abbildung veranschaulicht den zeitlichen Ablauf beim Start und Ende eines Upstart-Jobs.
In den bisherigen Beispielen wurden Befehle stets unmittelbar per exec aufgerufen. Anstelle von exec kann jedoch auch ein Befehlsblock gesetzt werden, der von den Schlüsselwörtern script und end script eingeschlossen wird:
pre-start script
if [ ! -e /var/run/tserv ]; then
mkdir -p /var/run/tserv
fi
end script
Ersetzt man den exec-Aufruf für den Start des Dienstprogramms durch einen Befehlsblock, so muss man beachten, dass Befehle, die hinter dem Aufruf des Dienstes stehen, nur dann ausgeführt werden, wenn sich der Dienst unmittelbar beim Aufruf beendet. Wird der Dienst später mittels Terminate-Signal von Upstart regulär beendet, geschieht dies nicht.
Auf der nächsten Seite: Init-Skripte migrieren
Zum Themen-Forum Betriebssysteme
Version zum Drucken | Per E-Mail versenden
Permalink: http://heise.de/-844394