J'ai en quelque sorte une idée approximative de la façon dont l'espace utilisateur et le système init (que ce soit le sysV / upstart / systemd classique init) fonctionnent à l'arrêt du système. (Essentiellement, il y a une succession d'ordres "Stop!", "S'il vous plaît, arrêtez vraiment maintenant", "Processus dont j'ai besoin pour vous tuer pour arrêter" et attendez ... que les choses se passent).
Je ne sais pas comment fonctionne l'arrêt du système dans le noyau (où il y a sûrement aussi beaucoup de choses à faire)?
J'ai essayé de consulter la documentation du noyau https://www.kernel.org/doc/htmldocs/ et j'ai même utilisé l' outil de recherche de copains de la NSA pour me donner une longueur d'avance sur la façon de savoir comment cela fonctionne.
De plus, j'ai cherché sur SE U + L et je n'ai rien trouvé (l'ai-je oublié?)
Quoi qu'il en soit, la question, bien que potentiellement un peu difficile, mériterait une réponse dans ce réseau de questions / réponses, car je suppose que plus de gens sont intéressés à obtenir un croquis de ce qui se passe dans le noyau Linux à l'arrêt.
Potentiellement, il y a aussi un changement pour établir un lien avec des explications plus détaillées.
Une réponse pourrait peut-être inclure quels appels système et quels signaux kernal sont utilisés?
https://github.com/torvalds/linux/blob/b3a3a9c441e2c8f6b6760de9331023a7906a4ac6/arch/x86/kernel/reboot.c semble être le fichier x86 utilisé lié au redémarrage (déjà proche de l'arrêt, hein?)
peut-être que l'extrait trouvé ici http://lxr.free-electrons.com/source/kernel/reboot.c#L176 peut être utilisé pour donner une explication
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 ("Mise hors tension \ n"); 184 kmsg_dump (KMSG_DUMP_POWEROFF); 185 machine_power_off (); 186} 187 EXPORT_SYMBOL_GPL (kernel_power_off);
la source
shutdown(8)
dire celle obsolète-n
qui, je pense, dans la vieille documentation Unix utilisée pour lire " arrêter le système nous-mêmes - l'unité centrale est EN FEU! " laisserait / pourrait laisser des morceaux éparpillés sur le sol (ou au moins les systèmes de fichiers dans un état corrompu) - on imagine que cela serait utilisé pour un système de type cadre principal où quelqu'un vient de prendre la main dans un ventilateur de refroidissement. 🕱Réponses:
Les principales ressources pour comprendre le fonctionnement du noyau Linux sont:
Dans ce cas, je ne trouve rien de centralement pertinent dans la documentation ou sur LWN, donc LXR c'est le cas.
La dernière chose que fait le code userland est l'appel
reboot
système . Il faut 4 arguments, alors recherchezSYSCALL_DEFINE4(reboot
sur LXR, ce qui conduit àkernel/reboot.c
. Après avoir vérifié les privilèges de l' appelant et les arguments, le point d'entrée de syscall appelle une de plusieurs fonctions:kernel_restart
au redémarrage,kernel_halt
à l' arrêt sur une boucle serrée,kernel_poweroff
à la mise hors tension du système,kernel_kexec
pour remplacer le noyau par un nouveau (si compilé), ouhibernate
pour sauvegarder la mémoire sur le disque avant de mettre hors tension.kernel_restart
,kernel_halt
Etkernel_power_off
sont assez similaires:reboot_notifier_list
, qui est une liste de hooks que les composants du noyau peuvent enregistrer pour exécuter du code à la mise hors tension. Seuls quelques pilotes ont besoin d'exécuter du code à ce stade, principalement des chiens de garde.system_state
variable.device_shutdown
pour libérer ou éteindre tous les périphériques du système. Beaucoup de pilotes se connectent à cette étape.Notez que tous les systèmes de fichiers qui sont encore montés à ce stade sont effectivement démontés de force. L'appelant de l'appel système est responsable de tout démontage propre.
migrate_to_reboot_cpu
prend soin de basculer vers un processeur particulier et d'empêcher le planificateur de distribuer du code sur d'autres processeurs. Après ce point, un seul processeur est en cours d'exécution.syscore_shutdown
appelle lashutdown
méthode des opérations syscore enregistrées . Je pense qu'il s'agit principalement de désactiver les interruptions; quelques crochets ont uneshutdown
méthode.machine_restart
,machine_halt
oumachine_power_off
.Le code d' hibernation passe par les étapes suivantes:
kernel_restart
,kernel_halt
oukernel_power_off
, ou une méthode d'hibernation spécifique à la plate-forme.Une manière différente d'arrêter le système est
machine_emergency_restart
. Ceci est invoqué par la clé magique SysRqB . La Oclé fonctionne différemment: elle appellekernel_power_off
.Le système peut également s'arrêter en panique , c'est-à-dire une erreur irrécupérable. La panique tente d'enregistrer un message, puis de redémarrer le système (via un chien de garde matériel ou un redémarrage d'urgence).
la source
syscore_shutdown
(c'est-à-dire qui résoudrait mon autre question unix.stackexchange.com/q/122540/24394 ) . L'étape (1) et l'étape (7) permettent toutes deux d'enregistrer des choses à exécuter à l'arrêt, pas de dire ce qui est quoi + J'ai eu l'impression que l'ordre d'exécution de ces rappels en (1) et (7) ne peut pas être influencé! Je vais les documents que vous avez mentionnés, mais si vous savez! Merci!Ceci n'est qu'une réponse partielle et j'invite à coup sûr d'autres réponses, qui pourraient être plus exhaustives et claires.
Le contenu de cette réponse est tiré du
kernel/reboot.c
fichier du noyau Linux 3.13 (qui pourrait ne pas être la première supposition car le nom n'est pas shutdown.c mais reboot.c)Quoi qu'il en soit, nous avons essentiellement trois fonctions qui décrivent le processus de fermeture du système
void kernel_halt(void)
// qui se termine par un système en état d'arrêtvoid kernel_power_off(void)
// qui se termine par un système hors tensionvoid kernel_restart(char *cmd)
// qui termine le système pour le redémarrerCes fonctions sont très brèves et peuvent donc être collées ici dans leur intégralité. Leur code montre le mieux les étapes à suivre pour arrêter le noyau. (Les commentaires sont de moi et ne sont peut-être pas 100% idéaux et corrects, vérifiez-vous pour en être sûr. C'est simple à essayer.
void kernel_halt(void)
le tout est initié avec l'
sys_reboot
appel système qui, étant donné qu'il ne redémarre pas seulement mais aussi l'arrêt, pas la chose directe pour se connecter au processus d'arrêt de toute façon.la source