Experimentieren mit Upstart unter Debian 5.0 Lenny

Diese Anleitung ist als Hilfe zum Einstieg für eigene Experimente mit Upstart auf einem Rechner mit Debian 5.0 Lenny gedacht.

Upstart ist ein Ersatz für SysV-Init, das Programm das nach dem Laden des Linux-Kernel als
erstes gestartet wird und direkt oder indirekt alle anderen Programme startet.

Achtung! In dieser Anleitung werden essentielle Systemprogramme ersetzt.
Es ist möglich, das der Rechner anschließend nicht mehr bis zum Anmeldebildschirm startet.
Daher ist diese Anleitung ausschließlich an erfahrene Anwender gerichtet.

Upstart übersetzen und installieren

Leider ist Upstart bei Debian erst in der momentanen Test-Distribution Squeeze enthalten. Ich nehme daher die Quellen von dort und übersetze Upstart selbst.

Als erstes nehme ich die Quellpakete von Debian Squeeze in /etc/apt/sources.list auf

$ sudo vim /etc/apt/sources.list


In dieser Datei füge ich die folgende Zeile hinzu, falls sie nicht schon enthalten ist.
deb-src http://ftp.de.debian.org/debian/ testing main non-free contrib
Als nächstes installiere ich einige Programme, die ich für das Übersetzen von Debian-Paketen im Allgemeinen benötige und noch ein paar, die für Upstart notwendig sind.

$ sudo aptitude install dpkg-dev fakeroot debhelper
$ sudo aptitude install quilt libdbus-1-dev

Das Übersetzen der für Upstart notwendigen Debian-Pakete ist dann recht einfach.

$ apt-get source --build upstart


Etwas problematischer ist die Installation, da Upstart ein Ersatz für SysV-Init ist und letzteres - ein essentielles Programm - dafür entfernt werden muss. Das Paketsystem von Debian ist darauf ausgerichtet, unerfahrene Anwender vor sich selbst zu schützen und daher muss ich dem Programm dpkg mit der Option --force-remove-essential mitteilen, dass ich SysV-Init wirklich ersetzen will.

$ sudo dpkg --force-remove-essential -i *.deb


Bluetooth auf Start durch Upstart umstellen

Da momentan noch recht wenig Software auf die Verwaltung durch Upstart umgestellt ist, hat es außer dem Lerneffekt wenig Sinn die oben genannten Schritte durchzugehen und die Stabilität seines Systems auf's Spiel zu setzen. Wenn man nicht die Vorteile von Upstart wirklich nutzen will.

Auf meinem Netbook wird Bluetooth automatisch mit gestartet damit es beim Anstecken des Bluetoothsticks gleich verfügbar ist. Das kostet bei jedem Start etwa eine Sekunde bevor der Anmeldebildschirm da ist. Daher war das Bluetooth-System für mich die erste Software, die ich auf Upstart umgestellt habe.

Bei der Umstellung von Bluetooth habe ich mich von einem Artikel in der Zeitschrift c't [1] inspirieren lassen.

Zunächst benötigen wir eine Regel für udev, mit deren Hilfe wir Ereignisse für Upstart generieren, wenn ein USB-Bluetoothstick angesteckt oder abgezogen wird.

sudo vim /etc/udev/rules.d/bluetooth.rule


Die Datei sieht bei mir wie folgt aus:
SUBSYSTEM=="bluetooth", SUBSYSTEMS=="usb", ACTION=="add", RUN+="/sbin/initctl --quiet emit --no-wait -e UDEV_KERNEL=$kernel -e UDEV_DEVPATH=$devpath bluetooth-device-add"
SUBSYSTEM=="bluetooth", SUBSYSTEMS=="usb", ACTION=="add", RUN+="/usr/bin/logger -- /sbin/initctl --quiet emit --no-wait -e UDEV_KERNEL=$kernel -e UDEV_DEVPATH=$devpath bluetooth-device-add" SUBSYSTEM=="usb", ACTION=="remove", RUN+="/sbin/initctl --quiet emit --no-wait -e UDEV_DEVPATH=$devpath device-remove" SUBSYSTEM=="usb", ACTION=="remove", RUN+="/usr/bin/logger -- /sbin/initctl --quiet emit --no-wait -e UDEV_DEVPATH=$devpath device-remove"
Die zweite und vierte Zeile (die mit /usr/bin/logger können entfallen, sind nur zum Zwecke der Fehlersuche da.

Als nächstes erzeugen wir eine Steuerdatei in /etc/event.d/, die die Ereignisse die von der udev-Regeldatei kommen, auswertet und daraus die Ereignisse bluetooth-start und bluetooth-stop generiert.

$ sudo vim /etc/event.d/bluetooth-device


Diese Datei sieht bei mir so aus:
# Start VDR only when at least one dvb device is present
env RUNDIR=/var/run/bluetooth start on bluetooth-device-add start on device-remove emits bluetooth-start bluetooth-stop script logger "upstart: bluetooth-device: $UPSTART_EVENT: $UDEV_KERNEL - $UDEV_DEVPATH" case "$UPSTART_EVENT" in bluetooth-device-add) if [ -n "$UDEV_KERNEL" -a -n "UDEV_DEVPATH" ]; then mkdir -p $RUNDIR # echo ${UDEV_DEVPATH%/dvb/dvb*.dvr0} > $RUNDIR/$UDEV_KERNEL echo ${UDEV_DEVPATH%/bluetooth/${UDEV_KERNEL}} > $RUNDIR/$UDEV_KERNEL logger "/sbin/initctl --quiet emit --no-wait bluetooth-start" /sbin/initctl --quiet emit --no-wait bluetooth-start fi ;; device-remove) if [ -d $RUNDIR ]; then logger "device-remove: UDEV_DEVPATH=$UDEV_DEVPATH" for d in $RUNDIR/*; do if [ -f $d ]; then read basedev < $d logger "device-remove: $d: basedev=$basedev" if [ -z "$basedev" -o "${UDEV_DEVPATH#${basedev}}" != "${UDEV_DEVPATH}" ]; then : else rm -f $d fi fi done rmdir --ignore-fail-on-non-empty $RUNDIR if [ ! -d $RUNDIR ]; then logger "/sbin/initctl --quiet emit --no-wait bluetooth-stop" /sbin/initctl --quiet emit --no-wait bluetooth-stop fi fi ;; esac end script
Auch hier sind die Zeilen mit logger entbehrlich. Zur Funktionsweise der Datei siehe [1]
Als nächstes erzeugen wir eine Steuerdatei in /etc/event.d/ mit der das Bluetooth-System gestartet und beendet wird.

$ sudo vim /etc/event.d/bluetooth


Diese Datei sieht bei mir so aus:
# Starts Bluetooth
start on bluetooth-start stop on bluetooth-stop stop on runlevel 0 stop on runlevel 1 stop on runlevel 6 script logger "upstart: bluetooth: $UPSTART_EVENT" stop () { /etc/init.d/bluetooth stop } trap stop 15 case "$UPSTART_EVENT" in bluetooth-start) /etc/init.d/bluetooth start while true; do sleep 10000; done ;; # bluetooth-stop) # /etc/init.d/bluetooth stop # ;; esac end script
Upstart erwartet, dass ein gestarteter Dienst im Vordergrund bleibt im Gegensatz zu SysV-Init, welches erwartet, das sich ein via rc gestartetes Script aus /etc/init.d/ beendet, wenn der Dienst initialisiert ist. Beim Beenden eines Dienstes sendet Upstart diesem lediglich ein SIGTERM bzw. SIGKILL, wenn der Dienst sich nicht schnell genug beendet, während SysV-Init das gleiche Script wie zum Starten mit dem Parameter stop aufruft.

Da ich nicht das gesamte Script /etc/init.d/bluetooth nachprogrammieren wollte, adaptiere ich das Verhalten des Scripts für Upstart. Nachdem das Script /etc/init.d/bluetooth sich beendet hat, halte ich das Upstart-Script mit der while-Schleife am Leben. Wenn dieses Script ein SIGTERM-Signal erhält, wird via trap die Funktion stop() und darüber das SysV-Init-Script mit dem Parameter stop aufgerufen.

Bleibt als letztes, Bluetooth aus der Verwaltung durch die SysV-Init-Scripts zu entlassen.

$ sudo update-rc.d -f bluetooth remove


Literatur, Verweise

  1. Mirko Dölle; Bitzstarter; c't Magazin für Computertechnik 2009, Heft 9, S. 176ff

0 Kommentar(e)

Zum Posten von Kommentaren bitte