UNIX Systemstart und Shutdown
Willemers Informatik-Ecke

Der Artikel behandelt in erster Linie die klassischen UNIX-Bootvorgänge. Linux Boot-Probleme werden auf der Linux-Seite aktueller behandelt.

Systemstart

Der Start einer UNIX-Maschine ist normalerweise einem durchschnittlich intelligenten Menschen binnen Sekunden erklärt: man drückt auf den Hauptschalter und wartet auf die Aufforderung zum Einloggen.

Haltestelle Bootprompt

Vom Start zum Login machen einige Maschinen an zwei markanten Punkten eine kurze Rast. Die erste Position ist der boot-Prompt. Hier hat man die Möglichkeit, der Maschinen Bootparameter mitzugeben oder das Medium zu nennen, von dem gebootet werden soll. In den meisten Fällen wird der Bootvorgang nach einigen Sekunden von selbst fortgesetzt. Ansonsten bedarf es eines Returns oder des Wortes boot gefolgt von Return.

Single User Modus

Der zweite Halt erfolgt im Single User Modus. Hier wird man entweder nach dem root-Kennwort gefragt oder steht direkt in der root-Shell. Geht es hier nicht von selbst weiter, reicht ein Ausloggen durch ctrl-D, exit oder logout. Der Single User Modus hat bei der Wartung einer UNIX-Maschine besondere Bedeutung. Hier kann beispielsweise die Konsistenz eingebundener Platten geprüft und gegebenenfalls wieder hergestellt werden. Sollte der Start der Maschine trotz Ausloggens nicht weiter gehen, gilt es, die Meldungen sehr genau zu lesen und nach den Problemursachen zu suchen.

Eine bootende UNIX-Maschine erschlägt den Zuschauer mit Meldungen. Die Hardware wird aufgelistet und initialisiert, die verschiedenen Betriebssystembestandteile melden ihre Vollendung. Während diese Meldungen im Anfang verwirrend wirken, bekommt man bei häufigerer Beobachtung ein Gefühl dafür, welche Systembestandteile wann starten und welche Zusammenhänge existieren. Wenn es dann einmal ein Fehlverhalten gibt, kann man es leicht erkennen und vielleicht sogar die Ursache analysieren.

Bootprompt

Der Bootvorgang einer Maschine beginnt damit, dass in einem ROM ein kleines Programm steht, das die Maschine anweist, den ersten Block der Platte zu laden und auszuführen. In diesem ersten Block steht ein etwas umfangreicheres Programm, das bereits in der Lage ist, ein UNIX Dateisystem zu lesen und so den eigentlichen Betriebssystemkern in den Speicher zu laden und durchzustarten.

Moderne Computer sind weitgehend konfigurierbar. Eine Maschine soll von der Platte, von der CD-ROM, aus dem Netz oder gar vom Bandlaufwerk booten. Diese Information wird in einem RAM abgelegt, das durch einen Akku oder eine Batterie gesichert wird. Bei Suns Workstations nennen sich die entsprechenden Bausteine NVRAM. Sie enthalten den Speicher inklusive der Batterie. Wenn deren Batterie leer ist, vergessen die Maschinen alles, bis hin zu ihrer Ethernet- und Rechnernummer. Erst recht wissen sie nicht mehr, von welchem Medium sie booten sollen. Stellt man erstes Schwächeln beim Booten fest, sollte man genaue Aufzeichnungen über alle Informationen haben, die bei einem Ausfall der Batterie wichtig sind. Für weitere Informationen zu diesem Thema gibt es eine FAQ (Frequently Asked Questions):

http://www.squirrel.com/squirrel/sun-nvram-hostid.faq.html

Bootkonfiguration: lilo

Lilo als Bootmanager

Während eine reine UNIX-Maschine darauf ausgelegt ist, einen UNIX Kernel zu booten, muss auf einem PC ein Bootmanager eingerichtet werden, der nach dem Start des BIOS (das ist das Boot ROM eines PCs) vom Master Boot Record einer Platte geladen wird und von dort aus dem Dateisystem des UNIX den Kernel startet. Auf der anderen Seite müssen diese Bootprogramme auch so flexibel sein, andere Betriebssysteme auf dem Rechner zu starten oder sich von anderen Bootmanagern starten zu lassen. Eines der ausgereiftesten Programme dieser Art ist sicher das Programm lilo (linux loader) für Linux. lilo wird durch die Datei /etc/lilo.conf gesteuert.

image = /boot/vmlinuz.suse
  root = /dev/hda5
  label = Linux
 
other = /dev/hda1
  label = windows
  table = /dev/hda

lilo.conf

In der Datei werden die einzelnen Partitionen, die durch Lilo gestartet werden sollen, aufgezählt. Der Eintrag für eine Linuxpartition wird durch das Schlüsselwort image eingeleitet und zeigt auf den Pfad des Kernels. Andere Betriebssysteme, wie hier MS-Windows, werden durch das Schlüsselwort other eingeleitet. Mehrfachnennungen sind möglich. Der Name, unter dem das gewählte Betriebssystem startet, steht hinter Schlüsselwort label. Auch Bootparameter, die für das Starten von Linux bei bestimmter Hardware benötigt wird, können hier hinterlegt werden.

Nach der Erstellung der lilo.conf wird einmal der Befehl lilo aufgerufen, um die Einträge zu übernehmen. Dabei wird eine Liste der Optionen angezeigt. Die mit einem Stern versehene Partition wird dabei automatisch gestartet.

Lilo kann man von MS-DOS oder MS-Windows aus durch den Aufruf von FDISK /MBR wieder entfernen.

Andere Bootmanager

Für den PC gibt es diverse andere Bootmanager. Aber selbst wenn ein solcher eingesetzt wird, wird Lilo gebraucht. Er wird dann auf der Bootpartition selbst installiert, um dem Bootmanager vorzutäuschen, dass sich Linux genau wie MS-Windows oder MS-DOS verhält.

Durchlaufen der Runlevel

Der allererste Prozess ist der Kernel. Dieser findet sich an wohlbekannter Stelle im Verzeichnisbaum. Er hat die Prozessnummer 0. Da das Betriebssystem schlecht gleichzeitig Prozess sein kann, startet er als erstes den Prozess init, der damit die Prozessnummer 1 erhält. Dieser liest bei System V die Datei /etc/inittab. Diese enthält typischerweise die Informationen über das Durchlaufen der Runlevel.

Runlevel Zustand
0 Maschine steht (halt)
S Singleuser
1 Multiuser ohne Netzwerk
2 Multiuser mit Netzwerk
3 Multiuser mit Netzwerk und grafischem Login
6 Reboot

BSD: /etc/rc

Das Starten der Systemumgebung wird im BSD durch das Ausführen der Datei /etc/rc bestimmt. Diese Datei startet nacheinander die relevanten Startdateien, die sich typischerweise ebenfalls im Verzeichnis /etc befinden und mit rc. beginnen.

Zuvor werden die Dateien rc.conf in den Verzeichnissen etc/default und /etc gestartet. Sie besetzen Umgebungsvariablen mit Werten, die von den rc-Dateien verwendet werden, um die Dämonen zu konfigurieren. Das heißt, dass Änderungen der Konfiguration, wie beispielsweise der Rechnername hier zu geschehen hat.

System V: init.d

Für den Start von Systemprozessen befinden sich je nach System im Verzeichnis /etc/init.d oder in /sbin/init.d die Skripten. die beim Systemstart ausgeführt werden. Dabei handelt es sich ausnahmslos um Shellskripten, deren Kommandos mit einem normalen Editor bearbeitet werden können. So ist es möglich, hier mit Hilfe des Kommandos grep nach dem Start von bestimmten Prozessen zu suchen.

Runlevelverzeichnisse enthalten Links

Um die Runlevel zu initialisieren, gibt es für jeden ein eigenes Verzeichnis rcX.d, dabei steht X für den jeweiligen Runlevel. In jedem der Runlevelverzeichnisse befinden sich ausschließlich symbolische Links auf die eben betrachteten Startskripten. Dabei befindet sich immer dann ein symbolischer Link, wenn beim Übergang in den jeweiligen Runlevel der Skript ausgeführt werden soll. Dabei haben alle Links einen Präfix S oder K, gefolgt von zwei Ziffern. S soll die Prozesse starten und K soll sie beenden (K wie kill). Die Ziffern bewirken eine Reihenfolge, damit die Prozesse in der richtigen Reihenfolge gestartet werden. Beispielsweise heißen die Links in rc2.d für apache, den Webserver, S20apache und K20apache. Der erste wird beim Eintreten in den Runlevel 2 und der andere beim Verlassen des Runlevels gerufen. Die Nummer 20 dient der Reihenfolge. S19 wird beispielsweise vor S20apache aufgerufen.

Aussehen eines Startskripts

Man schreibt einen Startskript, der als Parameter die Worte start und stop verarbeitet. Einige dieser Skripte verarbeiten auch das Kommando restart. Ein solcher Skript, den man zunächst im Verzeichnis init.d ablegt, besteht aus einer großen case Anweisung. Als Beispiel soll der Dienst unfug gestartet werden. Der Dienst unfug wird durch das Programm unfugd gestartet. Als Startskript erstellt man eine Datei namens unfug und stellt sie in das Verzeichnis /sbin/init.d.

#! /bin/sh
test -f /usr/bin/unfugd || exit 0
case "$1" in
    start)
        echo "Starte Unfug-Daemon"
        /usr/bin/unfugd
        ;;
    stop)
        echo "Stoppe Unfug-Daemon"
        kill `cat /var/run/unfugd.pid`
        ;;
    restart)
        echo "Restart Unfug"
        kill `cat /var/run/unfugd.pid`
        /usr/bin/unfugd
        ;;
    *)
        echo "usage: $0 start | stop | restart"
        exit 1
        ;;
esac

Existiert unfugd?

In der ersten Zeile wird angewiesen, dass dieser Skript von der einfachen Bourne Shell gestartet wird. Die zweite Zeile testet, ob es das Programm unfugd im Verzeichnis /usr/bin überhaupt gibt. Ist das nicht der Fall, endet der Skript hier mit der Fehlernummer 0. Es ist ja kein wirklicher Fehler aufgetreten. Es gibt nur einfach nichts zum Starten. Der case untersucht die Variable $1, die für den ersten Parameter steht und verteilt auf start, stop, restart oder auf den Stern, mit dem alle anderen möglichen Werte gemeint sind.

Start und Stop des Dämons

Bei start gibt es eine kurze Meldung und dann wird das Programm unfugd gestartet. Dämonen haben die Eigenart von selbst in den Hintergrund zu gehen. Darum ist an dieser Stelle ein & nicht erforderlich. Des weiteren schreibt unfugd seine Prozess-ID in die Datei /var/run/unfugd.pid. Das macht es beim Herunterfahren einfacher, den Prozess wieder zu beenden. Beim stop wird nämlich genau dort das Argument für den kill Befehl ausgelesen. Beim restart wird erst beendet und dann neu gestartet. Bei vielen Dämonen hätte auch ein kill -SIGHUP ausgereicht. restart wird nicht für das Booten oder Herunterfahren gebraucht, ist aber sehr praktisch, wenn man den Dämon konfigurieren will. Der Stern sorgt einfach dafür, dass wer den Skript falsch aufruft auch einen Hinweis bekommt, was falsch ist.

Startskripten sollten sehr sorgfältig erstellt werden. Dabei ist ein Zusammenbruch nicht so tragisch. Falls aber ein Startskript hängen bleibt oder in einer Endlosschleife verharrt, bleibt der Rechner beim Booten stehen. In einer solchen Situation brauchen Sie eine Möglichkeit, den Computer von einem anderen Bootmedium zu starten. Anschließend binden Sie die Platte per mount ein und können dann den Skript löschen oder sogar bearbeiten.

Will man die Datei beim Systemstart hochfahren, muss man zunächst überlegen, in welchem Runlevel sie gestartet werden sollen und dann mit den Links vergleichen, zu welchem Zeitpunkt sie gestartet werden müssen.

Setzen der Links

Nachdem nun der Skript unfug in init.d liegt, muss man ihn noch mit chmod 755 ausführbar machen. Zuletzt wird er an passender Stelle in ein rcX.d-Verzeichnis verlinkt. Der Unfug soll erst nach dem apache starten und vor diesem herunterfahren. Also verwendet man das Verzeichnis rc2.d und erzeugt einen Link mit S21 und einen mit K19.

cd rc2.d
ln -s ../unfug S21unfug
ln -s ../unfug K19unfug

Die Ausgabemeldungen des letzten Bootprozesses werden normalerweise in einer eigenen Datei protokolliert. Unter HP-UX ist das /etc/rc.log, unter Linux /var/log/boot.msg.

Startup des MacOS X

Im MacOS X werden statt der typischen rc-Dateien im Verzeichnis /System/Library/StartupItems/ je ein Verzeichnis für jedes Startobjekt angelegt. Hierin werden die Startmodule abgestellt. Dazu kommt eine Datei namens StartupParameters.plist. Dabei handelt es sich um eine Textdatei, die das Verhalten der Erweiterung bestimmt. Im Beispiel wird das Accounting gezeigt:

{
   Description     = "system usage accounting";
   Provides        = ("Accounting");
   OrderPreference = "Last";
   Messages =
   {
     start = "Starting accounting";
     stop  = "Stopping accounting";
   };
}

Dieser Mechanismus setzt auf dem unter BSD üblichen Startmechanismus mit den rc-Dateien auf.

Konfigurationsdateien

Während ein Systemadministrator in früheren Jahren die rc-Skripte auf die Gegebenheiten seines Systems anpasste, wird heute oft mit sehr allgemeinen rc-Skripten gearbeitet, die ihre Informationen über Konfigurationsdateien erhalten. Unter BSD finden Sie das in den bereits erwähnten Dateien rc.config im Verzeichnis /etc/default und /etc.

HP-UX legt diese Konfigurationsdateien ins Verzeichnis /etc/rc.config.d. Hierin befinden sich dann viele kleine Dateien, die manchmal nur eine Information enthalten, die in den rc-Skripten direkt verwendet werden.

S.u.S.E. und rc.config

Die SuSE-Distribution verwendet eine Datei namens /etc/rc.config, über die Umgebungsvariablen verändert werden, die von den rc-Skripten gelesen werden. Diese Datei wird vom Administrationstool yast gepflegt, kann aber auch mit einem normalen Editor bearbeitet werden. Damit von Hand eingetragene Änderungen darin übernommen werden, muss man anschließend SuSEconfig aufrufen. Bei Änderungen durch yast erledigt das Tool diese Aufgabe automatisch.

Herunterfahren: shutdown

Der Befehl zum Herunterfahren einer UNIX Maschine ist shutdown. Er wird mit den Optionen -h für Abschalten und -r für Neustarten gegeben. Im Allgemeinen akzeptiert der Befehl auch eine Zeitverzögerung, in der den angemeldeten Usern eine Meldung gegeben wird, dass sie sich ausloggen sollen. Alternativ verwenden einige Systeme die Befehle halt und reboot. Überall funktioniert auch init 0.

root-Rechte erforderlich

Allen diesen Möglichkeiten ist gemeinsam, dass der Administrator root das Herunterfahren veranlassen muss. Das ist durchaus sinnvoll, da ein Produktionsserver nicht einfach von jedem heruntergefahren werden darf. Anders ist die Lage bei Workstations. Da kommt es häufiger mal vor, dass der Anwender auch seine Maschine herunterfahren muss. Hier kann man mit sudo arbeiten oder einen Login einrichten, der zum Herunterfahren der Maschine führt.

Notwendigkeit

Es gibt nur wenig Gründe, einen UNIX-Server herunterzufahren. Üblicherweise passiert dies ausschließlich bei der Installation von Hardware, die man nicht im laufenden Betrieb wechseln kann. Aufgrund einer Konfigurationsänderung ist ein Neustart im Normalfall nicht erforderlich. Es gibt Fälle, wo ein Neustart schneller und vielleicht sogar verlässlicher ist, als der reguläre Weg.

Alles bereit zum Sterben?

Terminalanmeldungen kontrollieren

Wenn ein UNIX-Server heruntergefahren wird, ist das keine Privatangelegenheit des Systemadministrators, sondern kann nur erfolgen, wenn niemand mehr an der Maschine arbeitet. Ein einfacher Befehl finger oder who gibt Auskunft, ob die Terminals alle abgemeldet sind. Auch Anmeldungen über virtuelle Terminals können so erkannt werden. Virtuelle Terminals sind Netzwerkverbindungen, die den Charakter von Terminalsitzungen haben. Man erkennt diese daran, dass sie sich mit /dev/pty-Devices angemeldet haben.

Netzverbindungen kontrollieren

Schwieriger wird es, wenn auf der Maschine echte Client-Server Applikationen laufen. Hier helfen Befehle wie lsof, der die offenen Dateien anzeigt oder netstat, der Netzverbindungen anzeigt.

Wechsel in den Single-User Modus

Der Single-User Modus hat für die Wartung einer UNIX-Maschine eine besondere Bewandnis. Hier kann man sicher sein, dass nichts im Hintergrund passiert. Das heißt, dass die Platten auch nicht von Hintergrundprozessen bearbeitet werden. Man kann also in aller Ruhe Festplatten testen oder sonstige Arbeiten durchführen, die die Störung fremder Prozesse nicht vertragen. Das Herunterfahren in den Single-User Modus ist aus Sicht der Benutzer allerdings nichts anderes als ein normales Herunterfahren. Entsprechend muss man auch hier schauen, dass man niemandem die Prozesse abbricht. Der Wechsel selbst geht einfach durch Aufruf von

init 1

Zurück in den bisherigen Modus kommt man durch Schließen der Shell mit ctrl-D oder durch init 2 bzw. init 3.

Diese Seite basiert auf Inhalten aus dem Buch Arnold Willemer: Wie werde ich UNIX-Guru?