Ich habe irgendwie eine ungefähre Vorstellung davon, wie der Userspace und das Init-System (sei es das klassische Init-System sysV / upstart / systemd) beim Herunterfahren des Systems funktionieren. (Im Wesentlichen gibt es eine Befehlsfolge von "Stop!", "Bitte jetzt wirklich anhalten", "Ich muss dich umbringen, um anzuhalten" und Warten ... Dinge, die sich abspielen).
Ich bin mir sowieso nicht bewusst, wie das Herunterfahren des Systems im Kernel funktioniert (wo es sicherlich auch viel zu tun gibt)?
Ich habe versucht, in der Kernel-Dokumentation https://www.kernel.org/doc/htmldocs/ nachzuschlagen, und habe sogar mit dem Kumpelsuch-Tool der NSA versucht, herauszufinden, wie es funktioniert.
Auch ich habe auf SE U + L gesucht und nichts gefunden (habe ich es übersehen?)
Die Frage, auch wenn sie möglicherweise etwas herausfordernd ist, verdient in diesem Q & A-Netzwerk eine Antwort, da ich davon ausgehe, dass mehr Leute daran interessiert sind, eine Skizze darüber zu erhalten, was beim Herunterfahren im Linux-Kernel passiert.
Möglicherweise gibt es auch Änderungen, die auf detailliertere Erklärungen verweisen.
Eine Antwort könnte vielleicht beinhalten, welche Systemaufrufe und welche Kernsignale verwendet werden?
https://github.com/torvalds/linux/blob/b3a3a9c441e2c8f6b6760de9331023a7906a4ac6/arch/x86/kernel/reboot.c scheint die für den Neustart verwendete x86-Datei zu sein (steht schon kurz vor dem Herunterfahren, oder?)
Vielleicht kann das hier gefundene Snippet http://lxr.free-electrons.com/source/kernel/reboot.c#L176 verwendet werden, um eine Erklärung zu geben
176 void kernel_power_off (void) 177 { 178 kernel_shutdown_prepare (SYSTEM_POWER_OFF); 179 if (pm_power_off_prepare) 180 pm_power_off_prepare (); 181 migrate_to_reboot_cpu (); 182 syscore_shutdown (); 183 pr_emerg ("Ausschalten \ n"); 184 kmsg_dump (KMSG_DUMP_POWEROFF); 185 machine_power_off (); 186} 187 EXPORT_SYMBOL_GPL (kernel_power_off);
quelle
shutdown(8)
dh eine veraltete Option,-n
die meiner Meinung nach in der alten Unix-Dokumentation verwendet wurde, um " das System selbst herunterzufahren - die Kerneinheit ist ON FIRE! " würde / könnte Bits auf dem Boden verstreut lassen (oder zumindest die Dateisysteme in einem beschädigten Zustand) - man kann sich vorstellen, dass dies für ein System vom Typ Mainframe verwendet wird, bei dem jemand gerade seine Hand in einem Kühlventilator gefangen hat. 🕱Antworten:
Die wichtigsten Ressourcen zum Verständnis der Funktionsweise des Linux-Kernels sind:
In diesem Fall kann ich nichts zentral Relevantes in der Dokumentation oder auf LWN finden, so wie es LXR ist.
Der Userland-Code ruft zuletzt den
reboot
Systemaufruf auf . Es werden 4 Argumente benötigt, also suchen Sie nachSYSCALL_DEFINE4(reboot
LXR, was zu führtkernel/reboot.c
. Nach der Überprüfung des Anrufers Privilegien und die Argumente, ruft der syscall Einstiegspunkt eine von mehreren Funktionen:kernel_restart
zum Neustart,kernel_halt
um Halt auf einer engen Schleife,kernel_poweroff
zu schalten Sie das System,kernel_kexec
um den Kernel durch eine neue ersetzt werden (wenn kompiliert in) oderhibernate
um den Speicher vor dem Ausschalten auf der Festplatte zu speichern.kernel_restart
,kernel_halt
Undkernel_power_off
sind ziemlich ähnlich:reboot_notifier_list
handelt es sich um eine Liste von Hooks, die Kernel-Komponenten registrieren können , um Code beim Herunterfahren auszuführen. In dieser Phase müssen nur wenige Treiber Code ausführen, meistens Watchdogs.system_state
Variable ein.device_shutdown
an, um alle Geräte im System freizugeben oder auszuschalten. Viele Fahrer schließen sich dieser Etappe an.Beachten Sie, dass alle Dateisysteme, die zu diesem Zeitpunkt noch eingehängt sind, zwangsweise ausgehängt werden. Der Aufrufer des Systemaufrufs übernimmt die Verantwortung für ein sauberes Aushängen.
migrate_to_reboot_cpu
achtet darauf, zu einer bestimmten CPU zu wechseln und zu verhindern, dass der Scheduler Code auf anderen CPUs verteilt. Danach läuft nur noch eine CPU.syscore_shutdown
ruft dieshutdown
Methode der registrierten Syscore-Operationen auf . Ich denke, es geht hauptsächlich darum, Interrupts zu deaktivieren. wenige haken haben eineshutdown
methode.machine_restart
,machine_halt
odermachine_power_off
.Der Ruhezustand- Code durchläuft die folgenden Schritte:
kernel_restart
,kernel_halt
oderkernel_power_off
, oder einige plattformspezifische Winterschlaf - Methode.Eine andere Möglichkeit zum Herunterfahren des Systems ist
machine_emergency_restart
. Dies wird durch den magischen SysRq- SchlüsselB aufgerufen . Die OTaste funktioniert anders: Sie ruft aufkernel_power_off
.Das System kann auch zu einer Panik , dh einem nicht behebbaren Fehler, heruntergefahren werden. Beim Versuch, eine Nachricht zu protokollieren, wird in Panik versetzt. Anschließend wird das System neu gestartet (entweder über einen Hardware-Watchdog oder einen Notfall-Neustart).
quelle
syscore_shutdown
(dh, dies würde meine andere Frage lösen, unix.stackexchange.com/q/122540/24394 ). . Schritt (1) und Schritt (7) erlauben beide das Registrieren von Dingen, die beim Herunterfahren ausgeführt werden sollen, nicht sicher, was ist, + ich hatte den Eindruck, dass die Ausführungsreihenfolge dieser Rückrufe in (1) und (7) nicht beeinflusst werden kann! Ich werde die Dokumente, die Sie erwähnt haben, aber wenn Sie wissen! Vielen Dank!Dies ist nur eine Teilantwort und ich lade mit Sicherheit eine andere Antwort ein, die erschöpfender und klarer sein könnte.
Der Inhalt dieser Antwort stammt aus der
kernel/reboot.c
Datei des 3.13-Linux-Kernels (was möglicherweise nicht die erste Vermutung ist, da der Name nicht shutdown.c, sondern reboot.c lautet).Sowieso dort haben wir im Grunde drei Funktionen, die den Prozess des Herunterfahrens des Systems skizzieren
void kernel_halt(void)
// was mit einem angehaltenen System endetvoid kernel_power_off(void)
// was mit einem ausgeschalteten System endetvoid kernel_restart(char *cmd)
// was das System beendet, um es noch neu zu startenDiese Funktionen sind sehr kurz und können daher hier vollständig eingefügt werden. Ihr Code zeigt am besten, welche Schritte auf dem Weg zum Herunterfahren des Kernels unternommen werden. (Die Kommentare stammen von mir und sind möglicherweise nicht zu 100% ideal und korrekt. Prüfen Sie, ob Sie sich sicher sind. Es ist ganz einfach, es zu versuchen.
void kernel_halt(void)
Das Ganze wird mit dem
sys_reboot
Systemaufruf eingeleitet, der nicht nur einen Neustart, sondern auch ein Herunterfahren bewirkt, und der ohnehin nicht direkt mit dem Herunterfahren in Verbindung gebracht werden kann.quelle