Login
Newsletter
Werbung

So, 10. Juli 2005, 00:00

Freundliche Helfer

Daemonen und SysvInit in Linux

Daemonen und die Systeminitialisierung

Wenn man von Daemonen spricht, muß zwangsläufig auch die Systeminitialisierung ins Spiel kommen, denn wie wir oben bemerkt haben, werden viele Daemonen bereits beim Systemstart gestartet. Als Anwender merkt man dies aber höchstens an den komischen Meldungen auf dem Bildschirm während des Bootvorgangs:

"Starte syslog... OK"

rc-Dateien

Wir wollen jetzt einmal genauer beleuchten, was beim Systemstart so abläuft. Die folgende Darstellung ist in manchen Dingen nicht exakt bis ins kleinste Detail. Insbesondere sind die Pfade in den meisten Systemen anders als die hier angegebenen. Der Grund dafür ist einfach: Es gibt soviele Varianten von rc-Dateien, wie es Distributionen gibt (böse Zungen behaupten, sogar noch einige mehr).

Linux startet als ersten Prozeß nach dem Booten das Programm init, das meist in /sbin/init zu finden ist. Init liest eine Konfigurationsdatei, meist /etc/inittab, die definiert, welche weiteren Programme gestartet werden sollen. Wir wollen hier die etwas kryptische Syntax von /etc/inittab beiseite lassen. Wichtig zu wissen ist, daß Init mit dem Konzept der Runlevel arbeitet. Ein Runlevel wird mit einem einzelnen Zeichen bezeichnet. Am häufigsten werden S und die Ziffern 0-6 verwendet. Es gibt noch weitere, die aber selten benutzt werden.

Und wofür sind die Runlevel gut? Sie definieren, welche Programme automatisch gestartet werden. Das ist für jeden Runlevel frei konfigurierbar und geschieht eben in der /etc/inittab.

Obwohl die Runlevel frei konfigurierbar sind, hat sich doch ein gewisser Standard herauskristallisiert. Beschränken wir uns auf die normalerweise verwendeten Runlevel, so ist die folgende Liste eine typische Definition, wie sie auch von der Linux Standard Base (LSB) in Kapitel 8.5 (in LSB 2.1) vorgeschlagen wird:

S Single User Systeminitialisierung (vor Runlevel 1)
0 Halt Wechseln in diesen Runlevel fährt das System herunter. Die Wirkung ist dieselbe wie bei Eingabe von "halt" oder "shutdown -h now".
1 Single User Systeminitialisierung. Entgegen dem Namen können sich in diesem Level auch andere User außer root anmelden, doch laufen in diesem Level keine der normalerweise vorhandenen Daemonen. Dieser Level wird während des Hochfahrens durchlaufen, wird aber auch zur Systemreparatur oder -wartung benutzt.
2 Multiuser In diesem Level stehen alle Dienste außer den Netzwerkdiensten zur Verfügung.
3 Multiuser mit Netzwerk In diesem Level stehen alle Dienste zur Verfügung. Der Unterschied zu Level 5 ist, daß X11 nicht automatisch gestartet wird. Aber es ist natürlich möglich, X11 mit startx zu starten.
4 unbenutzt kann mit Runlevel 3 identisch sein
5 X11 In diesem Level stehen alle Dienste zur Verfügung. Zusätzlich wird X11 (genauer: das Programm xdm) automatisch gestartet.
6 Reboot Wechseln in diesen Runlevel bootet das System neu. Die Wirkung ist dieselbe wie bei Eingabe von "reboot" oder "shutdown -r now".

Offensichtlich muß es auch eine Möglichkeit geben, den Runlevel zu wechseln. Dies geschieht mit einem Aufruf von /sbin/init (oder /sbin/telinit), dem man den gewünschten Runlevel mitgibt. Init sorgt dann für den Wechsel des Runlevels, indem es alle Programme abschießt, die in dem neuen Runlevel nicht laufen sollen, und Programme startet, die in dem neuen Runlevel laufen sollen, aber im alten Runlevel nicht vorhanden waren. So ist es beispielsweise möglich, durch Eingabe von init 6 (natürlich nur als root) das System neu zu booten, als Alternative zum Befehl reboot, der auf manchen Systemen nicht vorhanden ist.

Doch zurück zum eigentlichen Thema. Wir wissen nun, daß Daemonen von init gestartet werden. Doch wie es genau funktioniert, haben wir noch nicht gesehen. Denn init startet keine Daemonen direkt. Stattdessen wird in jedem Runlevel ein Programm gestartet, das beispielsweise /etc/rc.d/rc heißt. Dieses Programm ist nichts weiter als ein Shell-Skript. Es ruft typischerweise weitere Skripte auf, z.B. rc.boot oder rc.local. Darüber hinaus sucht es ein Verzeichnis namens rcX.d auf, wobei das X durch den vorhergehenden Runlevel ersetzt wird. Dann führt es alle Programme (wiederum Shell-Skripte) aus, die in diesem Verzeichnis enthalten sind und deren Name mit K beginnt. Die Reihenfolge der Ausführung ist alphabetisch, was für das einwandfreie Funktionieren sehr bedeutsam ist. Dann macht das Skript das gleiche für alle Skripte, die mit S beginnen und im Verzeichnis rcY.d liegen, wobei Y der neue Runlevel ist.

Das alles klingt recht komplex und rätselhaft. Fangen wir an mit dem Erklären: das K steht für Kill und das S für Start. Skripte, die mit K beginnen, killen Programme oder Daemonen, während solche, die mit S beginnen, diese starten. Doch hier kommt schon wieder eine Hürde zum Verständnis: Die Skripte existieren eigentlich gar nicht. Es handelt sich um symbolische Links, die auf Skripte in einem speziellen Verzeichnis verweisen, beispielsweise /etc/rc.d/init.d oder /etc/init.d. Das ganze ist mit einer Abbildung sicher besser zu verstehen. Hier sehen wir ein Beispiel für die Init-Skripte, die zum Syslog-Daemon gehören.

/etc/rc.d
	init.d
		syslog*
	rc0.d
		K70syslog -> ../init.d/syslog*
	rc1.d
		K70syslog -> ../init.d/syslog*
	rc2.d
		S30syslog -> ../init.d/syslog*
	rc3.d
		S30syslog -> ../init.d/syslog*
	rc4.d
		S30syslog -> ../init.d/syslog*
	rc5.d
		S30syslog -> ../init.d/syslog*
	rc6.d
		K70syslog -> ../init.d/syslog*

Nun muß man nur noch wissen, daß diese Skripte immer mit einem Argument aufgerufen werden, beispielsweise stop (zum Killen von Programmen) oder start (eben dieses). Das ist das sogenannte System V Init in seiner ganzen Häßlichkeit (das V steht für Five). Häßlich deshalb, weil so ein Wald von symbolischen Links nicht gerade angenehm zu verwalten ist. Zu diversen Frontends für diesen Zweck kommen wir später.

Der Vorteil dieser Init-Skripte ist allerdings, daß man jeden Daemon separat, auch von Hand, starten und stoppen kann. Wäre das nicht möglich, müßte man zum Stoppen die Befehlssequenz ps ax zum Finden der Prozeß-ID und kill mit der richtigen Prozeß-ID anwenden. Was nicht so einfach ist, wie es sich anhört, da man den Namen des Prozesses kennen muß, und ein einfaches kill nicht immer hilft. Zum Starten des Prozesses müßte man dann wiederum den Namen und alle benötigten Argumente wissen - sehr umständlich. Mit den Init-Skripten geht es einfacher:

/etc/init.d/syslog stop
/etc/init.d/syslog start

Die Skripte enthalten also die ganze "Intelligenz", um die Unterschiede zwischen den Daemonen hinter einer einheitlichen Fassade zu verbergen. Dieses "Information Hiding", das Verstecken von Information, ist nicht etwa Böswilligkeit, sondern eines der Grundprinzipien der Software-Entwicklung, oder allgemein der Entwicklung von modularen Systemen.

Kommentare (Insgesamt: 0 )
Pro-Linux
Pro-Linux @Facebook
Neue Nachrichten
Werbung