Ich erstelle eine Linux-Distribution und brauche jetzt ein Init-Programm. Ich kann sehr gut in c programmieren und kenne mich ziemlich gut mit Linux aus (nicht sehr viel, aber ich verwende Arch Linux seit 4 Jahren für die Entwicklung). Deshalb dachte ich, ich sollte versuchen, mein eigenes Init-Skript in C zu schreiben Ich frage mich nur, welche Aufgaben hat init, um das System für eine einfache Shell einzurichten? (Wenn ich frage "Was macht init?", Weiß ich, was init ist und wofür es ist. Ich weiß nur nicht, welche Aufgaben es tut.)
Ich brauche Code nicht und ich tun , möglicherweise nicht einmal brauchen grundlegende Befehle , aber ich kann die Reihenfolge müssen , dass sie in ausgeführt werden .
Antworten:
System 5
init
wird Ihnen nur einen kleinen Teil der Geschichte erzählen.Es gibt eine Art Kurzsichtigkeit, die die Linux-Welt betrifft. Die Leute denken, dass sie ein Ding namens "System 5
init
" verwenden, und das ist sowohl das, was traditionell ist, als auch der beste Ausgangspunkt. Weder ist in der Tat der Fall.Tradition ist eigentlich nicht das, was solche Leute sagen. System 5
init
und System 5rc
datieren auf AT & T UNIX System 5, das fast so weit nach dem ersten UNIX war, wie wir es jetzt (etwa) nach der ersten Version von Linux-Mandrake sind.Erstausgabe hatte nur UNIX
init
. Es hatte nichtrc
. Die erste Ausgabe der Assemblerspracheinit
( Code derer wurde restauriert und zur Verfügung gestellt von Warren Toomey et al. ) Direkt hervorgebracht und respawned 12getty
Prozesse, 3 montiert fest verdrahtet Dateisysteme von einem eingebauten Tisch und lief ein Programm direkt aus dem Home - Verzeichnis einer benutzernamemel
. Diegetty
Tabelle befand sich auch direkt im Programmabbild.Es war ein weiteres Jahrzehnt nach UNIX System 5, als das sogenannte "traditionelle" Linux-Init-System auf den Markt kam. 1992 schrieb Miquel van Smoorenburg ein Linux
init
+rc
und die dazugehörigen Tools (neu), die heute als "System 5init
" bezeichnet werden, obwohl es sich eigentlich nicht um die Software von UNIX System 5 handelt (und das nicht nur)init
).System 5
init
/rc
ist nicht der beste Ausgangspunkt, und selbst wenn man Kenntnisse über systemd hinzufügt, die nicht die Hälfte des Wissens abdecken. Auf dem Gebiet des Init-Systemdesigns (für Linux und die BSDs) wurde allein in den letzten zwei Jahrzehnten viel Arbeit geleistet. Alle möglichen technischen Entscheidungen wurden diskutiert, getroffen, entworfen, implementiert und umgesetzt. Auch die Commercial Unices haben viel getan.Bestehende Systeme zum Lernen und Lernen
Hier ist eine unvollständige Liste einiger der wichtigsten Init-Systeme außer diesen beiden und einem oder zwei ihrer (mehreren) hervorstechenden Punkte:
init
losgeht.getty
Zombies) in einen separaten Service-Manager verlagert wird und nur betriebssystemspezifische "API" -Geräte / Symlinks / Verzeichnisse und Systemereignisse verarbeitet werden./bin/rc.init
wessen Aufgabe es ist, Programme zu starten, das Dateisystem zu mounten usw. Hierfür können Sie so etwas wie minirc verwenden .Darüber hinaus gab es vor ungefähr 10 Jahren eine Diskussion unter Daemontools-Anwendern und anderen über die Verwendung
svscan
als Prozess 1, die zu Projekten wie Paul Jarcs Svscan als Prozess 1-Studie , Gerrit Papes Ideen und Laurent Bercots Svscan als Prozess 1 führte .Das bringt uns zu dem, was die Programme von Prozess 1 leisten.
Welchen Prozess # 1 Programme tun
Vorstellungen davon, was der Prozess Nr. 1 "tun soll", sind ihrer Natur nach subjektiv. Ein aussagekräftiges objektives Entwurfskriterium ist das, was Prozess 1 mindestens leisten muss . Der Kernel stellt verschiedene Anforderungen an ihn. Und es gibt immer einige betriebssystemspezifische Dinge verschiedener Art, die es zu tun hat. Wenn es darum geht, was Prozess Nr. 1 traditionell getan hat, dann sind wir nicht bei diesem Minimum und haben es nie wirklich getan.
Es gibt einige Dinge, die verschiedene Betriebssystemkerne und andere Programme von Prozess 1 verlangen, denen man sich einfach nicht entziehen kann.
Die Leute werden Ihnen sagen, dass
fork()
die Hauptfunktion von Prozess 1 darin besteht , Dinge zu erledigen und als Eltern verwaister Prozesse zu agieren. Ironischerweise ist das nicht wahr. Der Umgang mit verwaisten Prozessen ist (bei neueren Linux-Kerneln, wie unter https://unix.stackexchange.com/a/177361/5132 erläutert ) ein Teil des Systems, den man in anderen Prozessen, wie z ein engagierter Service-Manager . All dies sind Service-Manager, die nicht mit Prozess 1 konfrontiert sind:srcmstr
Programm, der System Resource Controllerrunsvdir
von runitsvscan
von daemontools, Adam Sampsonsvscan
von freedt , Bruce Guentersvscan
von daemontools-encore und Laurent Bercots6-svscan
von s6perpd
von perpservice-manager
von noshEbenso muss, wie unter https://superuser.com/a/888936/38062 erläutert , die gesamte
/dev/initctl
Idee nicht in der Nähe von Prozess 1 liegen. Ironischerweise ist es das stark zentralisierte System, das zeigt, dass es aus Prozess 1 herausbewegt werden kann.Umgekehrt ist für die obligatorischen Dinge
init
, in der Regel , dass die Menschen in ihrem off-the-top-of-the-Kopf - Design vergessen, sind Dinge wie HandhabungSIGINT
,SIGPWR
,SIGWINCH
und so weiter aus dem Kernel gesendet und die verschiedenen Systemstatusänderungsanforderungen erlassen gesendet von Programmen, die "wissen", dass bestimmte Signale, um # 1 zu verarbeiten, bestimmte Dinge bedeuten. (Zum Beispiel: Wie unter https://unix.stackexchange.com/a/196471/5132 erläutert , "wissen" BSD-Toolsets, dassSIGUSR1
sie eine bestimmte Bedeutung haben.)Es gibt auch einmalige Initialisierungs- und Finalisierungsaufgaben, denen man sich nicht entziehen kann oder die sehr unter Umständen nicht ausgeführt werden, z. B. das Mounten von "API" -Dateisystemen oder das Leeren des Dateisystem-Cache.
Die Grundlagen des Umgangs mit "API" -Dateisystemen unterscheiden sich kaum von der Funktionsweise von
init
Unix der ersten Edition: Man hat eine Liste mit Informationen, die fest im Programm verankert sind, und man hat einfachmount()
alle Einträge in der Liste. Sie werden diesen Mechanismus in Systemen finden, die so unterschiedlich sind wie BSD (sic!)init
, Von noshsystem-manager
bis systemd."Richten Sie das System für eine einfache Shell ein"
Wie Sie bereits bemerkt haben, werden
init=/bin/sh
"API" -Dateisysteme nicht gemountet, stürzen in ungünstiger Weise ohne Cache-Flush ab, wenn ein Typexit
( https://unix.stackexchange.com/a/195978/5132 ) eingibt , und lassen es im Allgemeinen an den (Super-) Benutzer, die Aktionen, die das System minimal nutzbar machen, manuell durchzuführen.Um zu sehen, was man eigentlich keine andere Wahl hat, als in den Programmen Nr. 1 zu arbeiten, und Sie so auf einen guten Kurs für Ihr erklärtes Designziel zu bringen, ist es Ihre beste Option, die Überschneidungen in der Funktionsweise von Gerrit Papes runit, Felix von, zu untersuchen Leitners Minit und das
system-manager
Programm aus dem Nosh-Paket. Die beiden ersteren zeigen zwei Versuche, minimalistisch zu sein und dennoch mit den Dingen umzugehen, die man nicht vermeiden kann.Letzteres ist nützlich, ich schlage vor, für seine umfangreiche manuelle Eingabe für das
system-manager
Programm, die genau angibt, welche "API" -Dateisysteme eingehängt sind, welche Initialisierungsaufgaben ausgeführt werden und welche Signale behandelt werden; in einem System , das durch Design der Systemmanager nur laichen drei andere Dinge (die Service - Manager, ein Begleitlogger und das Programm ausführen , um die Zustandsänderungen) und nur tun , um die unvermeidlich in Prozess # 1 hat.quelle
launchd
. Manchmal vergessen die Leute gänzlich, dass OSX ein (großartiges) Mitglied der großen * nix-Familie ist.System V init unter Debian (es gibt andere Varianten und Variationen) führt Folgendes aus:
/etc/rcX.d/S*
in alphanumerischer Reihenfolge aufgerufen, wobeiX
es sich um den Runlevel handelt. Diese Skripte sollten den Runlevel einrichten. Das typische Setup startet Daemons und führt Setup-Aufgaben für diese Ausführungsebene aus. Dies ist eine einmalige Aktion, wenn Sie das Runlevel betreten./etc/inittab
als aktiv aufgeführt sind und während dieser Ausführung aktiv sein müssen. Wenn diese Daemons nicht mehr ausgeführt werden, werden sie neu gestartet. Während Sie einen beliebigen Dämon verwalten lassen können, benötigen Sieinit
mindestens einigegetty
, damit Sie sich anmelden können.getty
Wird nach Abschluss der Anmeldung beendet und anschließendinit
neu gestartet, wobei eine neue Anmeldeaufforderung angezeigt wird.init
automatisch versucht, es am Laufen zu halten. Sie müssen dies separat in der Tabelle angeben/etc/inittab
./etc/rcX.d/K*
in alphanumerischer Reihenfolge aufgerufen, wobeiX
der Runlevel angegeben ist. Eine Möglichkeit zum Implementieren des Herunterfahrens oder Neustarts besteht darin, einen Runlevel für diese Ereignisse zu definieren und die letzte ausgeführte Task zum Befehlhalt
oder zu machenreboot
.Sie können also
init
als rudimentärer Service-Manager fungieren, aber es ist heutzutage die Hauptaufgabe, diegetty
verfügbaren zu behalten , damit sich ein Benutzer anmelden und Runlevel-Übergänge starten kann.Irgendwas du willst. Unter Debian befindet sich in jedem
/etc/rcX.d
Verzeichnis ein Symlink zu einem Skript,/etc/init.d
und Sie können diese Skripte vollständig anpassen oder entfernen. Die Reihenfolge wird durch vor jedem Skript mit einem etablierten00
,01
usw.Sie können auch eine
-b
Option angebeninit
(z. B. über die Kernel-Befehlszeile), wenn Sie nurinit
eine Shell erzeugen möchten . Wenn Sie die Shell verlassen,init
stirbt und wenninit
stirbt, gerät der Kernel in Panik.quelle
Das absolute Minimum, das init tun muss, ist, mindestens ein anderes Programm auszuführen und es niemals zu beenden. Wenn init beendet wird, stürzt das System ab. Ich nehme an, dass das Ausführen eines anderen Programms nicht unbedingt erforderlich ist, aber wenn Sie dies nicht tun, müsste init dafür verantwortlich sein, alles zu tun, was vom System erwartet wird, oder es wäre nicht sehr nützlich.
quelle
init
kann machen was du willstinit ist eine beliebige ausführbare Datei, die vom Linux-Kernel am Ende des Startvorgangs aufgerufen wird (und die einzige solche ausführbare Datei).
Es wird normalerweise als ausführbare ELF-Datei implementiert, kann aber auch ein Shell-Skript mit
chmod +x
: Init als Shell-Skript seinTypische Implementierungen wie sysemd lesen Konfigurationsdateien
/etc/initrc
und geben dann eine Reihe von Userland-Prozessen aus, die auf diesen Konfigurationen basieren, um verschiedene Aspekte des Systems zu implementieren.Dies ist jedoch vollständig implementierungsspezifisch. Daher kann Ihre Frage nicht beantwortet werden, ohne eine bestimmte Implementierung anzugeben. Ich habe zum Beispiel mit einem
init
Prozess gespielt, der einfach einenreboot
Systemaufruf für Bildungszwecke ausführt.Der Linux-Kernel sucht
/init
standardmäßig nach der ausführbaren Datei im Pfad , diese kann jedoch mit deminit=
Befehlszeilenparameter des Linux-Kernels überschrieben werden.Eine großartige Möglichkeit zum Herumspielen
init
ist die Verwendung von QEMU, da Sie die Kernel-Befehlszeilenparameter mit der-append
Option von der QEMU-Befehlszeile an QEMU übergeben können , ohne befürchten zu müssen, Ihren Desktop zu beschädigen.Hier ist mein minimales vollautomatisches Buildroot + QEMU-Setup , das es sehr einfach macht, mit Ihren eigenen Inits herumzuspielen, um die Angelegenheit zu entmystifizieren.
quelle
Wenn Sie sich dem modularen Prinzip "Mach eins und mach es gut" verschrieben haben,
init
sollte ein Programm Prozesse starten.Prozesse starten
Sie sollte ausgeführt werden, sobald der Kernel erfolgreich dekomprimiert wurde, und sich um alle grundlegenden Aufgaben kümmern, die mit der Initialisierung aller anfänglichen Prozesse verbunden sind, die ein System zum Betrieb benötigt (z. B. das Mounten von Laufwerken in / etc / fstab, das Aufrufen von Netzwerkschnittstellen und bald).
Da der Vorgang des Hochfahrens und Herunterfahrens im Wesentlichen umgekehrt ist, stellt ein Init-Programm häufig auch sicher, dass Prozesse bei einem Befehl zum Herunterfahren gestoppt werden.
Prozesse stoppen
Dies bedeutet, dass Prozesse gemäß der Manpage dieses Prozesses gestoppt werden müssen (mit anderen Worten, nicht nur ein offensichtlicher
kill -9
Prozess, sondern der Prozess sollte so heruntergefahren werden, wie er beendet werden soll), die Bereitstellung von Laufwerken aufgehoben und schließlich der endgültige Befehl zum Herunterfahren ausgegeben werden muss .Verweise
Eine gute Referenz dafür, wie dies von anderen gemacht wird, sind die /etc/rc.d-Skripte von Slackware und ein einfaches Init-System, das bereits existiert, wie ninit (ein Nachfolger von minit). Es verfügt über eine Prozessüberwachung (dh, wenn ein Prozess stirbt, wird er neu gestartet), was wohl nicht die Aufgabe von init ist, aber dennoch recht einfach und verständlich ist, insbesondere anhand der Beispielskripte des Autors.
quelle