Upline: Infos & Dokus Administration Linux Linux manpages

man init, telinit


Mit dem Linux-Befehl init kann man das Runlevel des Systems ändern. Dies wird z.B. häufig dazu genutzt, um vom Konsolenlogin in die grafische Oberfläche zu kommen oder andersherum, um die grafische Oberfläche KDE/Gnome oder was auch immer (meist auf Runlevel 5) zu beenden und zum einfachen Konsolenlogin zu kommen. Die Runlevels 0 (Herunterfahren), 1 (Single-User-Modus) und 6 (Neustart) sind vordefiniert und bewirken bei allen Unix-/Linux-Derivaten das selbe Verhalten. Im Gegensatz dazu können die Runlevels 2-5 frei genutzt werden und viele Distributionen nutzen diese daher auch sehr unterschiedlich. Was in welchem Runlevel gestartet bzw. gestoppt wird, kann man aus folgenden Verzeichnissen entnehmen: rc0.d, rc1.d, rc2.d, rc3.d, rc4.d, rc5.d, rc6.d und rcS.d.
Nicht für besondere Zwecke genutzte Runlevels werden (meist) identisch zum jeweils höheren Runlevel-Inhalt belegt. So sind z.B. bei einem Debian Sarge ohne grafische Oberfläche die Start- und Stopscripte in den Runlevels 2-5 identisch. Diese Scripte liegen physikalisch unter /etc/init.d/ und verweisen aus den Runlevel-Verzeichnissen nur per Symlink (weicher/symbolischer Link) auf die original Startscripte. Bei der Namensgebung der Runlevel-Links ist zu beachten, dass ein mit "S" beginnender Link zum Aufruf als Startscript und ein mit "K" beginnender Link als Stopscript bzw Killscript dient. Die Scripte selbst sind zwar identisch, werden aber durch Parameter gesteuert sowohl zum Starten als auch zum Stoppen bestimmter Prozesse (Daemons) verwendet. Hinter dem Anfangsbuchstaben "S" bzw. "K" folgt eine zweistellige Zahl, die die Reihenfolge des Startens bzw. Stoppens der Prozesse festlegt. Grundsätzlich sollte die Stopreichenfolge entgegengesetzt zur Startreihenfolge sein.
Nachfolgend kommt die unter der GPL stehende und von mir nochmals überarbeitete Original-Version der Manpage zum Befehl init.

Name

init, telinit - Initialisierung der Kontrolle über Prozesse und Runlevel

Übersicht

/sbin/init [-t sec] [0123456SsQq]
/sbin/telinit [-t sec] [0123456SsQq]

Beschreibung und Optionen

init

Init ist der Vater aller Prozesse. Seine Hauptaufgabe besteht darin, Prozesse nach einem Skript in der Datei /etc/inittab zu erzeugen (siehe auch inittab(5)). Diese Datei hat normalerweise bestimmte Einträge, die init dazu veranlassen, auf jeder Leitung gettys zu erzeugen, auf der sich ein Benutzer einloggen kann. Er kontrolliert auch alle autonomen Prozesse, die von einem bestimmten System benötigt werden.

Runlevel

Ein Runlevel ist ein Softwarezustand des Systems, der es nur einer bestimmten Gruppe von Prozessen erlaubt, ausgeführt zu werden. Die Prozesse, die von init für jeden dieser Runlevel erzeugt werden, sind in der Datei /etc/inittab definiert. Init kann sich in einem von acht Runleveln befinden: 0-6 und S bzw. s. Init wechselt den Runlevel, wenn ein privilegierter Benutzer das Programm /sbin/telinit startet, welches init bestimmte Signale sendet, die ihm sagen, in welchen Runlevel gewechselt werden soll.
Die Runlevel 0, 1 und 6 sind reserviert. Der Runlevel 0 wird dazu verwendet, das System anzuhalten, der Runlevel 6 wird genutzt, um das System neu zu starten, und der Runlevel 1 wird dafür verwendet, das System in den Single-User-Modus herunterzufahren. Der Runlevel S wird normalerweise nicht direkt angesprungen, sondern dient nur als Zwischenstufe für die Skripte, die ausgeführt werden, wenn in den Runlevel 1 übergegangen wird. Weitere Informationen darüber finden Sie in den Handbuchseiten zu shutdown(8) und inittab(5).
Die Runlevel 7-9 sind ebenfalls gültig, jedoch nicht wirklich dokumentiert. Das liegt daran, dass die "traditionellen" UNIX-Varianten diese nicht benutzen. Manche werden sich vielleicht auch wundern, dass es zwischen den Runlevel S und s keinen ersichtlichen Unterschied gibt. Tatsächlich sind beide Optionen lediglich ein Alias für ein und den selben Runlevel.

Systemstart

Wenn init im letzten Schritt des Bootprozesses aufgerufen wird, sucht er nach der Datei /etc/inittab und sieht nach, ob es dort einen initdefault-Eintrag gibt (siehe inittab(5)). initdefault bestimmt den Anfangs-Runlevel des Systems. Falls es dort keine derartige Eintragung gibt oder gar keine inittab-Datei existiert, so muss an der Systemkonsole der runlevel eingegeben werden.
Die runlevel S und s bringen das System in den Single-User-Modus und benötigen keine /etc/inittab-Datei. Im Single-User-Modus wird auf /dev/console /sbin/sulogin aufgerufen.
Wenn das System in den Single-User-Modus übergeht, liest init die ioctl(2)-Zustände der Konsole in /etc/ioctl.save. Existiert diese Datei nicht, dann initialisiert init die Leitung mit 9600 BAUD und mit CLOCAL-Einstellungen. Wenn init den Single-User-Modus verläßt, schreibt es die ioctl-Einstellungen in diese Datei, so dass diese Einträge bei der nächsten Single-User-Sitzung wiederverwendet werden können.
Wenn init das erste mal in einen Multi-User-Modus eintritt, führt er die boot- und bootwait-Einträge der Datei /etc/inittab aus, die es erlauben, dass die Dateisysteme gemountet werden können, bevor sich ein Benutzer einloggen kann. Danach werden alle die runlevel betreffenden Einträge ausgeführt.
Immer wenn init einen neuen Prozeß startet, schaut das Programm erst nach, ob die Datei /etc/initscript existiert. Wenn es sie gibt, benutzt init das Skript dieser Datei, um den Prozeß zu starten.
Jedesmal, wenn ein Kindprozeß terminiert, hält init diese Tatsache und den Grund, weshalb der Kindprozeß gestorben ist, in den Dateien /var/run/utmp und /var/log/wtmp fest, falls diese Dateien existieren.

Runlevel-Änderungen

Sobald alle vorgesehenen Prozesse erzeugt worden sind, wartet init darauf, dass ein Kindprozeß stirbt, auf ein Stromausfallsignal oder auf eine Anweisung von /sbin/telinit, in welchen runlevel er wechseln soll. Wenn eine der drei oben genannten Bedingungen erfüllt ist, untersucht init nochmals die /etc/inittab-Datei, da dieser Datei jederzeit neue Einträge hinzugefügt werden können. Man kann den schlafenden init-Prozeß auch mit den Kommandos Q oder q aufwecken, was ihn dazu veranlaßt, nochmals die /etc/inittab-Datei zu examinieren.
Wenn init sich nicht im Single-User-Modus befindet und ein Stromausfallsignal (SIGPWR) empfängt, liest es die Datei /etc/powerstatus. Anschließend wird ein Befehl anhand des Inhalts der Datei gestartet:
  • F(AIL) Strom fällt aus, die USV versorgt den Rechner mit Strom. Die powerwait- und powerfail-Einträge werden ausgeführt.
  • O(K) Strom wurde wiederhergestellt, es werden die powerokwait-Einträge ausgeführt.
  • L(OW) Strom wird knapp und die USV geht auf dem Zahnfleisch. Die powerfailnow-Einträge werden ausgeführt.
Wenn /etc/powerstatus nicht existiert oder etwas anderes enthält als die Buchstaben F, O oder L, wird init sich so verhalten, als hätte es den Buchstaben F gelesen.
Die Verwendung von SIGPWR und /etc/powerstatus werden nicht empfohlen. Wenn etwas mit init interagieren möchte, sollte der Kontrollkanal /dev/initctl verwendet werden - siehe Quellcode des sysvinit-Pakets für mehr Dokumentation darüber.
Wenn init angewiesen wird den runlevel zu wechseln, wird das Warnsignal SIGTERM an alle Prozesse geschickt, die nicht in der Datei /etc/inittab für den neuen runlevel vorgesehen sind. Init wartet dann 5 Sekunden, bevor er diese Prozesse mit dem kill-Signal SIGKILL gewaltsam terminiert. Achtung: init nimmt an, dass alle diese Prozesse (und deren Nachfahren) in derselben Prozeßgruppe verblieben sind, die init ursprünglich für sie erzeugt hat (siehe setpgrp(2)). Wenn irgendeiner dieser Prozesse seine Prozeßguppenzugehörigkeit geändert hat, wird er diese Signale nicht erhalten! Solche Prozesse müssen einzeln terminiert werden!

telinit

Das Programm /sbin/telinit ist auf /sbin/init gelinkt. Er wird mit Argumenten, die aus nur einem Buchstaben bestehen gesteuert und sendet init Anweisungen (Signale), welche Aktionen dieses auszuführen hat. Die folgenden Argumente dienen als Anweisungen für telinit:
  • 0,1,2,3,4,5 oder 6 befehlen init in den angegebenen Runlevel zu wechseln.
  • a, b, c befehlen /sbin/init nur die Einträge der Datei /etc/inittab auszuführen, die den Runlevel a, b oder c haben.
  • Q oder q befehlen /sbin/telinit nocheinmal die Datei /etc/inittab einzulesen.
  • S oder s befehlen /sbin/telinit in den Single-User-Modus zu schalten.
/sbin/telinit kann den init-Prozeß auch anweisen, wieviel Zeit dieser zwischen dem Senden des TERM und des KILL Signals warten soll; die Standardeinstellung ist 5 Sekunden, kann jedoch durch die Option -t sec verändert werden.
/sbin/telinit kann nur von Benutzern mit einer entsprechenden Berechtigung aufgerufen werden.
Das init-Programm überprüft, ob es als init oder telinit gestartet wurde, indem es auf seine Prozeß-ID schaut; die reelle Prozeß-ID von init ist immer 1. Von daher darf man einfach auch init anstelle von telinit verwenden oder eines Aliases.

Umgebung

Init setzt folgende Umgebungsvariablen für alle seine Kindprozesse:
  • PATH Wird standarmäßig auf /usr/local/sbin:/sbin:/bin:/usr/sbin:/usr/bin gesetzt.
  • INIT_VERSION Wie der Name schon sagt. Nützlich, wenn ein Skript direkt von init ausgeführt werden soll.
  • RUNLEVEL Der augenblickliche Runlevel des Systems.
  • PREVLEVEL Der vorherige Runlevel (nützlich nach einer Änderung des Runlevels).
  • CONSOLE Die System-Konsole. Diese wird tatsächlich vom Kernel vererbt; wenn sie jedoch nicht gesetzt ist, wird init sie auf /dev/console setzen als Voreinstellung.

Bootsignale

Es ist möglich init eine Reihe von Bootsignalen (bootflags) vom Bootmonitor aus (d.h. vom LILO aus) zu übergeben. Init akzeptiert folgende Signale:
  • -s, S, single Bootet im Single-User-Modus. In diesem Modus wird zuerst die Datei /etc/inittab eingelesen; danach werden, noch bevor die Single-User-Shell gestartet wird, die Bootskripte der Datei /sbin/init.d/boot ausgeführt.
  • 1, 2, 3, 4 oder 5 Weist init an, in welchen Runlevel gebootet werden soll.
  • -b, emergency Gibt init die Anweisung direkt in den Single-User-Modus zu booten, ohne irgendwelche Startup-Skripte auszuführen.
  • -a, auto Der LILO-Bootloader fügt das Wort an den Kernel. init ist in der Lage, es zu lesen.
  • -z xxx Das Argument zu -z wird irgnoriert. Sie können es benutzen, um die Komandozeile etwas zu verlängern, damit sie etwas mehr Platz auf dem Stack reserviert. Init kann anschließend die Komandozeile derart modifizieren, dass ps(1) den aktuellen Runlevel anzeigt.

Schnittstelle

Init lauscht auf einem Fifo in /dev, /dev/initctl, auf Nachrichten. Telinit benutzt diesen, um mit init zu kommunizieren. Die Schnittstelle ist noch nicht sehr ausführlich dokumentiert. Wer interessiert ist, möge die Datei initreq.h im Quellcode von init studieren.

Signale

Init reagiert auf verschiedene Signale:
  • SIGHUP Init sucht nach /etc/initrunlvl und /var/log/initrunlvl. Wenn eine dieser Dateien existiert und einen ASCII-Runlevel enthält, wechselt init in den neuen Runlevel. Dieses existiert nur für Abwärtskompatibilität! In normalen Fällen (wenn die Dateien nicht existieren) verhält sich init, als wenn telinit q ausgeführt wurde.
  • SIGUSR1 Beim Emfang dieses Signals schließt init sein Kontroll-Fifo /dev/initctl und öffnet ihn wieder. Das ist sinnvoll für Boot-Skripte, wenn /dev neu gemountet wird.
  • SIGINT Normalerweise sendet der Kernel dieses Signal an init, wenn CTRL-ALT-DEL gedrückt wurde. Es aktiviert die ctrlaltdel-Aktion.
  • SIGWINCH Der Kernel sendet dieses Signal, wenn die KeyboardSignal-Taste gedrückt wurde. Es aktiviert die kbdrequest-Aktion.

Konform zu

Init ist kompatibel zum System V init. Er arbeitet eng mit den Skripten zusammen, die in den Verzeichnissen /sbin/init.d und /sbin/init.d/rc{runlevel 1-6}.d untergebracht sind. Wenn das System dieser Konvention folgt, sollte sich in diesem Verzeichnis eine README-Datei befinden, die erklärt wie diese Skripte funktionieren.

Dateien

/etc/inittab
/etc/initscript
/dev/console
/etc/ioctl.save
/var/run/utmp
/var/log/wtmp
/dev/initctl

Warnungen

Init geht davon aus, dass alle Prozesse und Kindprozesse in der selben Prozessgruppe verbleiben, die ursprünglich für sie eingerichtet worden ist. Wenn einer dieser Prozesse in eine andere Gruppe wechselt, kann init ihn nicht mehr beenden, und es kann passieren, dass man in einem Zustand landet, in dem zwei Prozesse von einer Terminalleitung Befehle einlesen wollen.

Diagnose

Wenn init herausfindet, dass es kontinuierlich einen Eintrag öfter als 10 mal in 2 Minuten neu erzeugt, wird es annehmen, dass ein Fehler in der Befehlszeile vorliegt, einen Fehler erzeugen, Meldungen auf die Systemkonsole erstatten und sich weigern, den Eintrag auszuführen, bis 5 Minuten vergangen sind oder es ein Signal empfängt. Dieses verhindert, dass Systemresourcen verschwendet werden, wenn jemand einen Tippfehler in /etc/inittab einbaut oder das zum Eintrag gehörende Programm löscht.

AUTOR

Miquel van Smoorenburg miquels@cistron.nl, ursprüngliche Manpage von Michael Haardt u31b3hs@pool.informatik.rwth-aachen.de, Übersetzung Martin Okrslar okrslar@informatik.uni-muenchen.de und Überarbeitung von Martin Schulze joey@infodrom.north.de und proteino.de ;)

Siehe auch

getty(8), login(1), sh(1), who(1), shutdown(8), kill(2), inittab(5), utmp(5)
11 February 2000 INIT(8)