Bewertung: 2


Die Kandidaten sollten in der Lage sein, Systemstart-Scripte angemessen zu editieren, um die Standard Runlevel und den Boot-Prozess einzustellen. Dieses Prüfungsziel beinhaltet Interaktion mit den Runlevels und das Erstellen von eigenen initrd Images, je nach Anforderung.

Schlüsseldateien, Begriffe und Hilfsmittel beinhalten:

  • /etc/init.d
  • /etc/inittab
  • /etc/rc.d
  • mkinitrd (beide, Debian und RedHat basierte Modelle)

Dieser Abschnitt beschäftigt sich hauptsächlich mit den Startprozessen eines Linux-Systems und natürlich den Möglichkeiten, sie zu konfigurieren. Dazu gehört natürlich zuerst einmal das Verständnis des Bootprozesses selbst, um dann die Überlegungen anzustellen, wo hier Eingriffsmöglichkeiten liegen.

Überblick über den Bootvorgang

Der Vorgang des Systemstarts bei Linux beginnt immer mit dem Laden des Kernels. Dieser Ladeprozeß ist abhängig davon, wie das System eingerichtet wurde, er kann auf verschiedenste Art stattfinden. Die üblichsten Formen sind:

  • Booten von einer Bootdisk
  • Booten über syslinux
  • Booten über einen Bootmanager (z.B. lilo)
  • Booten über ein vorher gestartetes DOS mit loadlin

In jedem Fall wird durch den eigentlichen Bootprozess ein komprimiertes Kernelimage in den Speicher geladen und dort entkomprimiert. Hier finden wir bereits die erste Eingriffsmöglichkeit, indem wir dem Kernel selbst Parameter mitgeben, die seine Initialisierung beeinflussen. Bei diesen Kernelparametern handelt es sich um verschiedene Eingabemöglichkeiten, die hauptsächlich die folgenden Aufgaben haben:

  • Einstellungen, die den Kernel selbst betreffen wie etwa die initiale Ramdisk, das init-Programm oder die verwendete Wurzelpartition.
  • Einstellungen für in den Kernel eingebaute Gerätetreiber wie IRQs, DMA oder IO-Adressen einzelner Geräte.

Ist der Kernel dann einmal geladen und entpackt, so wird er gestartet (schließlich ist auch der Kernel „nur“ ein Programm). Zuerst überprüft und initialisiert er die gefundene Hardware, für die er eingebaute Treiber besitzt. Dazu werden evt. eingegebene Kernelparameter benutzt.

Als nächsten Schritt muß der Kernel ein Wurzeldateisystem laden. Dabei kommt es zu dem schon geschilderten Problem, wenn für den Zugriff auf das Dateisystem oder das Laufwerk, auf dem es gespeichert ist, Module benötigt werden, die eventuell eben auf diesem Dateisystem gespeichert sind. Aus diesem Grund muß hier evt. eine initiale Ramdisk geladen werden, wie schon in Kapitel 2.201.2 geschildert. Das ist aber nur dann nötig, wenn tatsächlich Module für den Zugriff auf das Wurzeldateisystem benötigt werden.

Sind die Module dann geladen, so wird das „echte“ Wurzeldateisystem gemountet und weitere Module geladen. Standardmäßig wird das Wurzeldateisystem übrigens zunächst im ReadOnly Modus eingehängt. Wenn alle Module geladen sind, der Kernel also komplett ist und das Wurzeldateisystem eingehängt ist, wird der erste Prozess gestartet, der sich dann weiter um die Initialisierung des Systems kümmert. Sinnigerweise heißt das gestartete Programm auch – fals nichts anderes angegeben wurde – init. Dieser Prozess hat immer die ProzessID 1. Hier finden wir die nächste Möglichkeit der Einflußnahme, das Programm init wird über die Datei /etc/inittab konfiguriert.

Bevor jedoch das init-Programm seine Konfiguration einließt, startet es zunächst einmal im sogenannten Single User Mode, einem Modus, in dem sich niemand außer dem Systemverwalter einloggen kann. In diesem Modus werden jetzt noch einige Einstellungen von init vorgenommen wie etwa die Konfiguration der seriellen Schnittstellen oder ähnliches. Auch werden hier alle Dateisysteme, die gemountet werden sollen, einer Überprüfung unterzogen, die im Bedarfsfall das Programm fsck (filesystemcheck) auf ein fehlerhaftes oder zu häufig gemountetes Dateisystem anwendet. Danach werden jetzt alle weiteren Partitionen (Dateisysteme) gemountet, auch das Wurzeldateisystem wird jetzt ReadWrite eingehängt.

Der nächste Schritt von init ist der Wechsel in den voreingestellten Runlevel (der wiederum in /etc/inittab eingestellt ist) und die Abarbeitung aller angegebenen Befehle für diesen Runlevel. Dazu zählen insbesondere die Aktivierung der getty-Prozesse, die den Login über die angeschlossenen Terminals ermöglichen. Wenn hier die Rede von den angegebenen Befehlen ist, so bezieht sich das auch wieder auf die in /etc/inittab angegebenen Befehle für einen Runlevel.

Einstellungen in /etc/inittab

Die genaue Syntax der Datei /etc/inittab ist auf einer eigenen Seite dargestellt. Die entscheidenden Einstellungen in dieser Datei sind:

  • Die Angabe, welcher Runlevel der voreingestellte Runlevel sein soll (initdefault).
  • Die Angabe welche Terminals in welchem Runlevel aktiv sein sollen (gettys).
  • Die Angabe, welches Script für welchen Runlevel abgearbeitet werden soll (rc-Scripts)

In früheren Unix-Systemen fand sich in dieser Datei immer auch eine Liste der zu startenden Server-Programme. Diese Programme sind heute aber wesentlich mehr geworden und man will vermeiden, dass wegen jedem neuen Dienst erneut die Datei /etc/inittab editiert werden muß. Aus diesem Grund hat Linux hier eine Erweiterung des System V übernommen, die anfangs etwas verkopft aussieht, jedoch sehr mächtig und einfach zu verwalten ist.

In der /etc/inittab findet sich in praktisch allen Distributionen für jeden Runlevel eine Zeile, die ein Script rc mit der Nummer des Runlevels als Parameter ausführt. Diese Zeilen sehen etwa wie folgt aus:

  l2:2:wait:/etc/init.d/rc 2
  l3:3:wait:/etc/init.d/rc 3
  l4:4:wait:/etc/init.d/rc 4

Bei einem Wechsel in den Runlevel 2 wird also das Programm /etc/init.d/rc ausgeführt und zwar mit dem Parameter 2. Entsprechendes gilt für alle anderen Runlevels. Ob das Script rc jetzt in /etc/init.d oder an einer anderen Stelle des Systems abgelegt ist, kann von Distribution zu Distribution anders sein, wichtig ist das Prinzip.

Das Script /etc/init.d/rc führt jetzt viele andere Scripts aus, die jeweils einen Dienst starten. Diese Scripts liegen meistens auch in /etc/init.d, manchmal auch unter /etc/rc.d. Aus diesem Grund werden wir uns im Anschluß mit eben diesem Verzeichnis beschäftigen.

Der wesentliche Vorteil dieser Technik ist es, dass jeder Dienst, der auf einem Linux-Rechner installiert wird, automatisch in dieses Verzeichnis ein Script ablegen kann (und soll), das ihn entsprechend richtig startet (und evt. auch wieder stoppt).

Das Verzeichnis /etc/init.d

In diesem Verzeichnis finden sich jetzt also viele Scripts, die alle dafür gedacht sind, bestimmte Dienste (oder auch andere Konfigurationen) zu starten oder zu stoppen. Meist heißen die Scripts wie jeweilig die zu startenden Dienste.

Jedes dieser Scripts erwartet immer genau einen Parameter, dabei kennen die Scripts die folgenden:

  • start
    Wird das Script mit dem Parameter start aufgerufen, so wird der entsprechende Dienst gestartet.
  • stop
    Wird das Script mit dem Parameter stop aufgerufen, so wird der entsprechende Dienst beendet.
  • restart
    Wird das Script mit dem Parameter restart aufgerufen, so wird der entsprechende Dienst beendet und dann neu gestartet.

In manchen Fällen gibt es noch weitere Parameter (status, reload o.ä.) Wichtig sind die beiden ersten, also start und stop.

Natürlich ist mit diesen Scripts jetzt noch nicht festgelegt, welche Dienste in welchem Runlevel tatsächlich gestartet werden sollen und welche nicht. Dazu bedient sich Linux jetzt einer sehr eleganten Methode. Es existieren für jeden Runlevel ein eigenes Verzeichnis, das entweder in /etc selbst oder auch in /etc/init.d liegt und den Namen rcX.d trägt. Das X wird dabei durch die Nummer des Runlevels ersetzt. Wir finden also mindestens die folgenden Verzeichnisse dort:

  • rc0.d
  • rc1.d
  • rc2.d
  • rc3.d
  • rc4.d
  • rc5.d
  • rc6.d
  • rcS.d

Diese Verzeichnisse enthalten jetzt symbolische Links auf die Scripts in /etc/init.d. Die Namen dieser Links beginnen entweder mit einem K (kill) oder einem S (start) dem eine Nummer und dann der Name des Scripts folgt.

Das Programm /etc/init.d/rc, das ja in der Datei /etc/inittab aufgerufen wurde, wechselt jetzt in eben das Verzeichnis rcRunlevelnummer.d und führt alle Scripts dort mit dem Parameter start aus, die mit S beginnen. Die Nummer nach dem S dient einfach der Festlegung der Reihenfolge dieser Aufrufe. Je niedriger die Nummer, um so früher wird das Script ausgeführt. Genau genommen werden die Scripts einfach in alphabetischer Reihenfolge ausgeführt, was durch die Nummern dann zu diesem Effekt führt.

Beim Wechsel in einen anderen Runlevel werden entsprechend dann die Scripts ausgeführt, die mit einem K beginnen und zwar mit dem Parameter stop.

Über diesen Mechanismus ist es also sehr einfach möglich, festzulegen, in welchem Runlevel welche Dienste gestartet werden sollen. Es muß ja nur ein entsprechender Link im jeweiligen rc.x.d Verzeichnis angelegt werden.

Zusammenfassung der Steuerungsmöglichkeiten

Alles in Allem haben wir also die verschiedensten Möglichkeiten, den Bootablauf zu steuern, um unser System zu konfigurieren. Hier nochmal alle Möglichkeiten im Überblick, in der Reihenfolge des Abarbeitens: Angabe von Kernelparametern Bereits beim Booten selbst können wir dem Kernel schon Parameter mitgeben, die entweder die fest im Kernel eingebauten Gerätetreiber konfigurieren, oder Angaben über Speichergröße, verwendetes init-Programm oder ähnliches einstellen können. Im nächsten Kapitel werden wir mehr darüber hören. Die Datei /etc/inittab Der erste Prozess des Systems ist der init-Prozess (PID 1). Seine Aktionen werden in der Datei /etc/inittab eingestellt. Typischerweise wird hier festgelegt, was in welchem Runlevel gestartet werden soll, insbesondere die Frage, auf welchen Terminalleitungen getty-Prozesse laufen sollen, also ein Einloggen möglich ist. Die Verzeichnisse /etc/init.d und /etc/rcx.d Im Verzeichnis /etc/init.d liegen Shellscripts, die zum Starten der Dienste benutzt werden, für jeden Runlevel existiert ein Verzeichnis /etc/rcRunlevelnummer.d in dem Symlinks auf die Scripts in /etc/init.d liegen. In jedem Runlevel werden alle diese Links abgearbeitet und damit die entsprechenden Dienste gestartet.

Natürlich sind all diese Einstellungen nur für die Konfiguration des Systems selbst gedacht. Die persönlichen Einstellungen der User des Systems sind hier noch nicht enthalten, sie werden über andere Mechanismen gesteuert.