Upstart
Archivierte Anleitung
Dieser Artikel wurde archiviert. Das bedeutet, dass er nicht mehr auf Richtigkeit überprüft oder anderweitig gepflegt wird. Der Inhalt wurde für keine aktuell unterstützte Ubuntu-Version getestet. Wenn du Gründe für eine Wiederherstellung siehst, melde dich bitte in der Diskussion zum Artikel. Bis dahin bleibt die Seite für weitere Änderungen gesperrt.
Anmerkung: Upstart 🇬🇧 war ein Ubuntu-Projekt, welches den Systemstart von Ubuntu bzw. allgemein Linux beschleunigt. Es war geplant, dass Upstart mittel- bis langfristig auch noch weitere Aufgaben bei Linux-Systemen übernehmen sollte. Nach hitzigen Debatten bei Debian und einer Entscheidung für die Alternative systemd gab Mark Shuttleworth Anfang 2014 bekannt, dass auch Ubuntu ab 14.10 nach und nach umgestellt werde: Losing graciously 🇬🇧. Die weitere Entwicklung von Upstart wurde daher eingefroren.
Zum Verständnis dieses Artikels sind folgende Seiten hilfreich:
Wie Upstart arbeitet¶
Beim Systemstart werden eine Reihe von Programmen und Diensten gestartet (z.B. der XServer für die Grafik, der CUPS-Daemon zum Drucken etc.), bevor man mit dem System arbeiten kann. Traditionell werden diese Programme bzw. Dienste über eine in den "run levels" des klassischen SysVinit-Systems festgelegte Reihenfolge geladen. Das Laden erfolgt dabei sequentiell, d.h. ein Dienst nach dem anderen.
Upstart verwendet einen neuen Ansatz, um den Systemstart zu beschleunigen. Programme und Dienste werden ereignisbasiert geladen und gestartet, wodurch mehrere – voneinander unabhängige – Dienste parallel gestartet werden können. Hierdurch wird die Startgeschwindigkeit erhöht.
Upstart unter Ubuntu¶
Seit Ubuntu 6.10 ist Upstart fester Bestandteil von Ubuntu und wird standardmäßig zum Systemstart eingesetzt (wobei 6.10 die erste Linux-Distribution überhaupt war, in der Upstart eingesetzt wurde). In Ubuntu 7.04 wurde eine verbesserte Version von Upstart eingesetzt, mit Ubuntu 9.04 wurde der Bootvorgang durch eine optimierte Hardwareerkennung und eine teilweise Parallelisierung der Startskripte deutlich beschleunigt. Anfang März 2011 wurde Upstart 1.0 veröffentlicht.
Systemstart¶
Upstart ersetzt das klassische SysVinit-System und damit auch die Start-/Stop-Mechanismen von Diensten. Allerdings sind noch lange nicht alle Dienste auf Upstart umgestellt, sondern vorrangig die zum Systemstart ("Init-Jobs") erforderlichen. Die Datei /etc/inittab entfällt. Wann ein Init-Job aktiv wird, legen Konfigurationsdateien im Ordner /etc/init/ fest. Alle Dateien in diesem Ordner werden automatisch gestartet. Man braucht also z.B. neue Skripte nicht mehr umständlich zu aktivieren, wie es früher der Fall war.
Das zentrale Werkzeug ist nun initctl, das Init-Jobs startet oder stoppt, Signale verschickt und den Status abfragt. So gibt beispielsweise der Befehl [1]:
initctl list
eine Liste aller Init-Jobs und ihres Status aus:
mountall-net stop/waiting rc stop/waiting rsyslog start/running, process 10856 tty4 start/running, process 1132 udev start/running, process 10894 upstart-udev-bridge start/running, process 389 ureadahead-other stop/waiting avahi-daemon start/running, process 11169 hwclock-save stop/waiting tty5 start/running, process 1140 apport stop/waiting atd start/running, process 1169 dbus start/running, process 683 failsafe-x stop/waiting control-alt-delete stop/waiting hwclock stop/waiting network-manager start/running, process 824 usplash stop/waiting module-init-tools stop/waiting cron start/running, process 1170 gdm start/running, process 836 mountall stop/waiting acpid start/running, process 1161 rcS stop/waiting ufw start/running hal stop/waiting rc-sysinit stop/waiting anacron stop/waiting tty2 start/running, process 1156 udevtrigger stop/waiting rsyslog-kmsg start/running, process 556 tty3 start/running, process 1157 udev-finish stop/waiting hostname stop/waiting mountall-reboot stop/waiting mountall-shell stop/waiting network-interface (lo) start/running network-interface (eth0) start/running tty1 start/running, process 1370 udevmonitor stop/waiting dmesg stop/waiting networking stop/waiting procps stop/waiting tty6 start/running, process 1159 ureadahead stop/waiting
Dementsprechend werden mit
sudo initctl [start | stop] Init-Job
Init-Jobs gestartet bzw. beendet.
Trotz Upstart ist Ubuntu nicht frei von klassischen SysVinit-Skripten. Diese werden ebenfalls von Upstart aufgerufen. Weitere Informationen zu diesem Thema findet man im Artikel Dienste.
Verhalten von Upstart beeinflussen¶
Möchte man bestimmte Init-Jobs abändern, so muss man die entsprechende Konfigurationsdatei im Verzeichnis /etc/init/ editieren.
Achtung!
Änderungen bitte mit Bedacht, entsprechenden Vorsichtsmaßnahmen und nie ohne vorherige Datensicherung vornehmen. Schlimmstenfalls droht ein nicht mehr startendes System.
Run-Level ändern¶
Um zu verhindern, dass ein Dienst in einem bestimmten Run-Level gestartet wird, öffnet man die entsprechende .conf-Datei und editiert die Zeile
start on runlevel [2345]
Die Zahlen in den eckigen Klammern, repräsentieren dabei die Runlevel.
Entsprechend sollte auch die Zeile
stop on runlevel [!2345]
geändert werden. Das Ausrufezeichen in der Stop-Anweisung bedeutet, dass der Dienst gestoppt wird, wenn sich der Run-Level außerhalb der Aufzählung befindet. Upstart überwacht die Konfigurationsdateien mittels inotify
, so dass man beim Testen der Änderungen folgende Meldung erhält:
initctl: Unknown job: Init-Job
Erst mit einem Neustart liest Upstart die geänderten Dateien ein. Schneller (und ohne Rechner-Neustart) geht es mit folgendem Befehl:
sudo initctl reload-configuration
Abhängigkeiten von anderen Prozessen steuern¶
Wie die unten aufgeführten Beispiele zeigen, kann Upstart ein Programm oder einen Prozess entweder mit "exec
" ausführen oder über ein Skript starten. Dieses Skript befindet sich dann in den Zeilen zwischen den Schlüsselwörtern "script
" und "end script
". Wenn es nötig ist, dass ein Prozess erst nach einem bestimmten Ereignis startet, dann gibt es prinzipiell zwei Wege:
Entweder erstellt man sich ein eigenes Upstart-Skript und fügt dessen erfolgte Ausführung als weitere Start-Bedingung in die oben beschriebene "start on"-Zeile der abhängigen Datei /etc/init/JOBNAME.conf ein. Hierbei sind auch komplexe logische Verknüpfungen 🇬🇧 möglich, was beispielsweise innerhalb der Datei gdm.conf (hier am Beispiel von Ubuntu 10.04) sehr anschaulich zu sehen ist:
# gdm - GNOME Display Manager # # The display manager service manages the X servers running on the # system, providing login and auto-login services description "GNOME Display Manager" author "William Jon McCann <mccann@jhu.edu>" start on (filesystem and started dbus and (drm-device-added card0 PRIMARY_DEVICE_FOR_DISPLAY=1 or stopped udevtrigger)) stop on runlevel [016] emits starting-dm env XORGCONFIG=/etc/X11/xorg.conf script if [ -n "$UPSTART_EVENTS" ] then [ ! -f /etc/X11/default-display-manager -o "$(cat /etc/X11/default-display-manager 2>/dev/null)" = "/usr/sbin/gdm" ] || { stop; exit 0; } # Check kernel command-line for inhibitors for ARG in $(cat /proc/cmdline) do case "${ARG}" in text|-s|s|S|single) plymouth quit || : # We have the ball here exit 0 ;; esac done fi if [ -r /etc/default/locale ]; then . /etc/default/locale export LANG LANGUAGE elif [ -r /etc/environment ]; then . /etc/environment export LANG LANGUAGE fi export XORGCONFIG exec gdm-binary $CONFIG_FILE end script
Dabei ist aber zu beachten, dass nur das Schlüsselwort "starting
" den Moment bezeichnet, an dem der Referenzprozess gestartet wird, und das im Beispiel gezeigte Schlüsselwort "started
" einen (beliebigen) Moment, nachdem der Referenzprozess gestartet worden ist. "started
" wartet also nicht so lange, bis der referenzierte Prozess fertig abgearbeitet ist.
Alternativ kann man auch in die betreffende JOBNAME.conf ein "pre-start script
" einfügen, wie es in der Datei mysql.conf (auch wieder am Beispiel von Ubuntu 10.04) schön zu sehen ist:
# MySQL Service description "MySQL Server" author "Mario Limonciello <superm1@ubuntu.com>" start on (net-device-up and local-filesystems and runlevel [2345]) stop on runlevel [016] respawn env HOME=/etc/mysql umask 007 pre-start script #Sanity checks [ -r $HOME/my.cnf ] [ -d /var/run/mysqld ] || install -m 755 -o mysql -g root -d /var/run/mysqld # Load AppArmor profile if aa-status --enabled 2>/dev/null; then apparmor_parser -r /etc/apparmor.d/usr.sbin.mysqld || true fi LC_ALL=C BLOCKSIZE= df --portability /var/lib/mysql/. | tail -n 1 | awk '{ exit ($4<4096) }' end script exec /usr/sbin/mysqld post-start script for i in `seq 1 30` ; do /usr/bin/mysqladmin --defaults-file="${HOME}"/debian.cnf ping && { exec "${HOME}"/debian-start # should not reach this line exit 2 } sleep 1 done exit 1 end script
Das Pre-Start-Skript wird erst komplett abgearbeitet, bevor der "exec
"-Befehl ausgeführt wird.
Möchte man beispielsweise sicherstellen, dass ein Dateiserver oder NAS nach dessen Wake-On-LAN bereits online ist, bevor man sich am Client anmelden kann (bspw. damit die Netzlaufwerke während des Startprozesses korrekt eingebunden werden können), dann kann man das durch ein entsprechendes Pre-Start-Skript, das man in die gdm.conf einfügt, erreichen (Beispiel). Die Folge ist, dass die Anmelde-Maske erst dann erscheint, wenn der Dateiserver oder NAS erfolgreich mit ping erreicht werden konnten.
Deaktivieren von Init-Jobs¶
Wenn man Init-Jobs dauerhaft deaktivieren möchte, kann man entweder
die Datei /etc/init/jobname.conf umbenennen bzw. deren Endung .conf entfernen oder
innerhalb der Datei jobname.conf die Zeile mit "
start on
" auskommentieren
Zum Reaktivieren diese Änderungen rückgängig machen.
Ab Upstart 1.3 bzw. Ubuntu 11.10 existiert noch eine dritte Variante: .override-Dateien. Beispiele:
echo "manual" | sudo tee /etc/init/jobname.override
oder
sudo sh -c "echo 'manual' > /etc/init/jobname.override"
Der Vorteil gegenüber den ersten beiden Varianten ist, dass die Originaldatei /etc/init/jobname.conf nicht verändert wird. Möchte man einen Init-Job wieder aktivieren, löscht man einfach die .override-Datei (oder entfernt das Schlüsselwort "manual
" in dieser Datei).
Beispiele¶
Wer ein eigenes Upstart-Skript schreiben möchte, braucht neben guten Englisch-Kenntnissen auch Beispiele. Nachfolgend ein erster Versuch, abzuspeichern als /etc/init/hallo_welt.conf:
# Meine ersten Schritte mit Upstart description "simples Upstart-Beispiel" # wann starten bzw. stoppen? start on runlevel [2345] stop on runlevel [!2345] env text_variable="Hallo Welt" exec echo "$text_variable $(date)" > /var/log/hallo_welt.log
Hiermit wird einfach der Text "Hallo Welt" und das aktuelle Datum in die Datei /var/log/hallo_welt.log geschrieben. Wie auch schon in den beiden Skripten weiter oben, wird auch im Beispiel eine Variable mit einem vorangestelltem "env
" deklariert. Diese Variable ist dann in allen Abschnitten des Skripts verfügbar. Natürlich bringt ein solches Beispiel keinen konkreten Nutzen, aber vielleicht erleichtert es den Einstieg in Upstart.
Ein weiteres Beispiel aus dem Artikel Trackpoint (Abschnitt „Einstellungen-permanent-machen-ab-Ubuntu-9-10“) zeigt das Ändern von Werten im Sysfs:
description "Trackpoint-Einstellungen" start on virtual-filesystems env TPDIR=/sys/devices/platform/i8042/serio1/serio2 script while [ ! -f $TPDIR/sensitivity ]; do sleep 2 done echo -n 200 > $TPDIR/sensitivity echo -n 150 > $TPDIR/speed echo -n 1 > $TPDIR/press_to_select end script
Kritik¶
So bestechend die Idee von Upstart bei mobilen und Desktop-Rechnern ist, gibt es insbesondere beim Einsatz auf Servern auch Probleme. Zum einen werden diese im Regelfall eher selten neu gestartet, so dass ein schnellerer Bootvorgang nur eine untergeordnete Rolle spielt. Zum anderen hat sich das klassische SysVinit-System in der Praxis seit Jahrzehnten bewährt, auch wenn es definitiv nicht mehr zeitgemäß ist. Durch die Parallelisierung von Upstart lassen sich viele Dienste nicht mehr so einfach wie beim hierarchischen "Step-by-Step" aufeinander abstimmen bzw. erfordern einen höheren Konfigurationsaufwand.
Bei mancher Hardware kann es bei einer etwas unglücklichen Konfiguration beim Starten zu "Race Conditions" kommen, d.h. es wird versucht irgend etwas zu machen, noch bevor das benötigte dafür bereit ist – in sehr seltenen Fällen kann das dann schon mal sporadisch ("nur so") vorkommen. Schuld sind meistens Bemühungen, den Startprozess zu stark zu optimieren.
Zur Beschleunigung des Startvorgangs gibt es mit systemd einen ernsthaften Konkurrenten. Bisher setzte Ubuntu exklusiv auf Upstart, während beispielsweise Arch Linux, Fedora und OpenSuse systemd präferieren. Bei den Versionen nach Ubuntu 14.04 wird daher auch Ubuntu schrittweise zu systemd wechseln. Ab 14.10 kann systemd bereits als alternatives Init-System installiert werden, ab 15.04 ist systemd auch bei Ubuntu vorinstalliert.
Problembehebung¶
Job unbekannt¶
Nach Änderungen an bestehenden Skripten oder bei eigenen Skripten erscheint trotz Einlesen der neuen Konfiguration die Fehlermeldung:
"initctl: Unknown job: hallo_welt"
Eventuell liegt ein Fehler in der Syntax vor. Das Skript lässt sich ab Ubuntu 12.04 mit folgendem Befehl prüfen:
init-checkconf /etc/init/hallo_welt.conf
rc.local¶
Vom asynchronen Systemstart sind auch Anweisungen betroffen, die via /etc/rc.local ausgeführt werden sollen. Obwohl ein eigenes Upstart-Skript die bessere und zukunftssichere Lösung wäre, kann man betroffene Dienste oder Programme auch einfach zeitverzögert (neu) starten. Wie das konkret geht, ist im Artikel rc.local (Abschnitt „Probleme-und-Loesungen“) beschrieben.
Logdateien¶
Upstart legt für viele Dienste Logdateien in /var/log/upstart/ an.
Links¶
Projektseite 🇬🇧
Upstart Wiki 🇬🇧 - offizielle Spezifikation und Dokumentation zu Upstart
Upstart Intro, Cookbook and Best Practises 🇬🇧 - Einführung, Referenz und Beispiele zur Verwendung von Upstart (auch als PDF ⮷ verfügbar)
ReplacementInit 🇬🇧 - Ubuntu Wiki-Eintrag zu Upstart; stellt sehr schön die Beweggründe dar, warum Upstart entwickelt wurde.
Schneller booten mit Upstart 🇩🇪 - aktualisierte Version eines c't Artikels auf heise Open Source, 10/2009
Controlling Ubuntu's and Fedora's Upstart (the init replacement) 🇬🇧 - LinuxPlanet 05/2009
Ubuntu's Success Story: the Upstart Startup Manager (Linux Boot Camp p.2) 🇬🇧 - LinuxPlanet, 04/2010