Für alle, die mit MacOS vertraut sind, lassen sich die Runlevels wohl am ehesten mit verschiedenen Sets im Kontrollfeld Erweiterungen ein/aus vergleichen. Wie dort kann man mit Hilfe von Runlevels verschiedene Gruppen von Diensten[1] ein und ausschalten. Natürlich ist das ganze anders organisiert als bei MacOS. Aber fangen wir klein an.
Zu jedem Dienst[1],
der über die Runlevel gesteuert werden soll, muss ein Init-Skript
existieren[2].
Diese Init-Skripte sind normale (Bourne-) Shell-Skripte und
liegen im Verzeichnis /etc/rc.d/init.d/
(bzw. bei der SuSE[3] direkt in /etc/rc.d/
).
Aufgerufen werden diese Skripte immer mit einem Parameter, mit dem bestimmt wird, was dieses Skript tun soll.
Grundsätzlich immer dabei sind start
zum Starten eines Dienstes und stop
zum Anhalten des Dienstes. Daneben bieten einige Skripte auch noch restart
(zum Neustarten des Dienstes), reload
(bewirkt das der Dienst seine Konfiguration neu einliest,
z.B. nachdem dort etwas geändert wurde) oder status
(ist der Dienst aktiv).
Nun ein Runlevel ist nun eine Zusammenstellung von Diensten, ähnlich verschiedener Sets im
MacOS-Kontrollfeld Erweiterungen ein/aus (aber das hatte wir ja schon).
Wenn der Runlevel gewechselt wird, werden alle (d.h. alle bei denen es darauf ankommt) Dienste
des alten Runlevels angehalten. Dazu werden die entsprechenden Initskript mit dem Parameter stop
aufgerufen. Danach werden alle Dienste des neuen Runlevels gestartet, indem die passenden Init-Skripte
mit start
aufgerufen werden.
Die Runlevel selbst haben leider keine so schönen Namen wie unter MacOS, sondern nur eine
Zahl oder einen Buchstaben als Bezeichnung, und auch nicht irgendeinen Buchstaben
sondern einen von diesen hier:
0123456SsQqAaBbCcUu
. Diese Auswahl kommt aus der Historie von UNIX. Die Ziffer des
Runlevels bezeichnet eine immer umfangreiche Funktionalität, d.h. System bewegt sich also
auf einer "höheren" Ebene, die der Einfachheit halber durch eine Zahl ausgedrückt wird.
Für spezielle Situationen (z.B. den Single-User-Mode wurden auch spezielle Runlevel eingeführt,
bei der SuSE z.B. das 'S'). Auch dürfte der vielfältig und mitunter verwirrenden Stammbaum
von UNIX einige heute nicht mehr gebräuchliche Runlevel beigesteuert haben.
Bei LinuxPPC werden folgenden Runlevel üblich[4]
verwendet:
0 | halt (Do NOT set initdefault to this) bewirkt das Abschalten des Rechners |
1 | Single user mode Der Single-User-Mode ist gewissermassen ein Wartungmode in dem nur der Systemadministrator (also root) Zugriff hat. |
2 | Multiuser, without NFS normaler textorientierter Multi-User-Modus, aber ohne die Möglichkeit des "Filesharings". Andere Netzwerkfunktionen sind aber aktiv. |
3 | Full multiuser mode wie 2, nur das jetzt auch noch das "Filesharings"über das NFS (Network File System) unter UNIX/Linux-Maschinen möglich ist. |
4 | unused |
5 | X11 wie 3. Nun läuft aber endlich auch die graphische Oberfläche X-Window (oder kurz X11). |
6 | reboot bewirkt einen Neustart. |
Wofür ein bestimmter Runlevel steht sollte in der Datei /etc/inittab
zu finden sein.
Dort kann man auch einstellen, in welchen Runlevel
das System beim Booten gehen soll. Dazu muss man nur in der Zeile
id:5:initdefault:
die unterstrichene Zahl durch die des gewünschten Runlevels ersetzen werden.
Aber Achtung, man sollte hier nicht
die Runlevel für halt oder shutdown (bei LinuxPPC 0) oder reboot (bei LinuxPPC 6) hier eintragen.
Wie weiß aber das System, welcher Dienst in welchem Runlevel laufen soll?
Dazu gibt es zu jedem Runlevel im Verzeichnis /etc/rc.d
ein Verzeichnis, das rc?.d
heisst. Dabei steht das '?' für die Nummer des jeweiligen Runlevels
(also z.B. /etc/rc.d/rc5.d/
.
In jedem dieser Verzeichnisse liegt nun eine Sammlung symbolischer Links
auf einzelne Init-Skript. Diese symbolischen folgen dabei einer Namenskonvention (an die man sich auch
halten muss): Sie beginnen mit einem 'S' oder einem 'K', gefolgt von einer Zweistelligen Zahl und dem
Namen des Skriptes auf das sie verweisen, also z.B. S85httpd
.
Die S-Links (S wie Start) werden beim Starten eines Runlevels aufgerufen, die 'K'-Links bei Verlassen
(K wie Kill, also Abschießen eines Dienstes).
Die S-Links werden dabei immer mit dem Parameter start
aufgerufen, die 'K'-Links immer mit
stop
.
Nun gibt es Dienste, die erste gestartet werden können wen andere schon laufen, z.B. kann NFS erst gestartet werden, wenn das Netzwerk schon läuft. Auch sollte erst NFS abgeschaltet werden und dann das Netzwerk. Daher sind die Links nummeriert. Bei Betreten oder Verlassen des Runlevels werden die Links in numerischer Reihenfolge aufgerufen (bei gleicher Nummer in alphabetischer). Deshalb ist es wichtig jedem Link eine passende Nummer zu geben.
Das Booten findest in zwei Stufen statt. Zunächst lädt und initialisiert sich der Kernel. Dabei erkennt er die Hardware usw. Danach startet der Init-Prozess. Dieser startet seinerseits ein Reihe von Skripten. Der genaue Ablauf dabei ist leider von Distribution zu Distribution unterschiedlich Bei LinuxPPC 1999 sieht es so aus:
init startet das Skript /etc/rc.d/rc.sysinit
. Dieses sorgt u.a.
dafür, dass die Partitionen überprüft und gemountet werden, kümmert sich um Sound
und RAIDs etc.
Danach folgen die Init-Skripte des default-Runlevels, wie er in der /etc/inittab
angebeben ist.
Es werden natürlich nur die 'S'-Links ausgeführt, da das System ja vorher in keinem
Runlevel war.
Am Ende wir noch das Skript /etc/rc.d/rc.local
ausgeführt. Hier kann
ein Systemadministrator relativ gefahrlos Kleinigkeiten, die nur einmal beim Booten getan werden müssen
(z.B. die Systemuhr nach einer Timeserver nachstellen), hinzufügen
Wenn man einen Dienst starten oder stoppen will muss man dazu nicht gleich den ganzen Runlevel stoppen.
Es reicht, wenn man den Dienst über sein Skript in /etc/rc.d/init.d
direkt anspricht.
Man sollte nur aufpassen, ob nicht andere Dienste laufe, die von diesem Dienst abhängen
Also nicht das Netzwerk stoppen, wenn man noch NFS laufen hat. SuSE-Linux macht es einem
noch einfacher. Dort gibt es zu jedem Init-Skript ein Link im /sbin
-Verzeichnis,
der wie das Skript mit vorangestelltem rc heisst.
Dadurch kann, z.B. AppleTalk durch:
rcatalk start
starten. Bei LinuxPPC heisst das äquivalent:
/etc/rc.d/init.s/atalk start
Da man jeden Dienst direkt starten kann, ist in der Regel unnötig den Rechner neu zu starten, wenn man einen Dienst hinzugefügt hat. Im Gegenteil, man kann u.U. sogar den neuen Dienst so besser austesten.
Wenn man nun einen neuen Dienst installiert hat und diesen beim Booten auch aktivieren will, so reicht es selbst symbolische Links in den Verzeichnissen, der gewünschten Runlevel anzulegen. Man sollte dabei nur auf die Abhängigkeiten zwischen den Diensten achten, d.h. zum Beispiel wenn man Appletalk hinzufügen will, muss der 'S'-Link hinter dem 'S'-Link des Netzwerkes liegen. Der 'K'-Link jedoch davor. Auch sollte man die 'K'-Links in den Runleveln 0 und 6 (shutdown und reboot) nicht vergessen, vor allem dann wenn es um Filesharing, wie bei AppleTalk geht.
/etc/rc.d/rc.local
.
Leider hat sich bei Linux noch kein einheitliche Schema für Pfade von Systemdateien
durchgesetzt (Abgesehen von Grundkonventionen, wie Konfigurationsfiles in /etc
u.ä.
SuSE-Linux (zumindest im x86-Fall) benutzt ein abweichendes Runlevel-Schema:
0 | is halt |
S | is single-user |
1 | is multi-user without network |
2 | is multi-user with network |
3 | is multi-user with network and xdm |
6 | is reboot |