¿Cómo funciona internamente el apagado del sistema de un kernel de Linux?


28

Tengo una idea aproximada de cómo funcionan el espacio de usuario y el sistema init (ya sea el clásico init sysV / upstart / systemd) en el apagado del sistema. (Esencialmente, hay una orden de sucesión de "¡Alto!", "¡Por favor, deténgase ahora realmente", "Proceso, necesito matarte para que pares" y esperar ... las cosas continúan).

De todos modos, no soy muy consciente de cómo funciona el apagado del sistema en el núcleo (donde seguramente también hay muchas cosas que hacer).

Traté de buscar en la documentación del kernel https://www.kernel.org/doc/htmldocs/ e incluso utilicé la herramienta de búsqueda de amigos de la NSA para ayudarme a descubrir cómo funciona.

También busqué en SE U + L y no encontré nada (¿lo pasé por alto?)

De todos modos, la pregunta, aunque potencialmente un poco desafiante, merecería una respuesta en esta red de preguntas y respuestas, ya que supongo que más personas están interesadas en obtener un boceto de lo que sucede en el kernel de Linux en el cierre.

Potencialmente, también hay cambios para vincular a algunas explicaciones más detalladas.

¿Una respuesta podría incluir qué llamadas al sistema y qué señales internas se utilizan?

https://github.com/torvalds/linux/blob/b3a3a9c441e2c8f6b6760de9331023a7906a4ac6/arch/x86/kernel/reboot.c parece ser el archivo x86 usado relacionado con el reinicio (ya está cerca del cierre, ¿eh?)

tal vez el fragmento que se encuentra aquí http://lxr.free-electrons.com/source/kernel/reboot.c#L176 se puede usar para dar una explicación

176 vacío kernel_power_off (vacío)
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 ("Apagar \ n");
184 kmsg_dump (KMSG_DUMP_POWEROFF);
185 machine_power_off ();
186}
187 EXPORT_SYMBOL_GPL (kernel_power_off);

8
que el unicornio esté contigo
Kiwy 01 de

1
@ Kiwy gracias por la sugerencia. Aceptaré después de que haya pasado un tiempo para que surjan mejores respuestas potenciales. Pero al menos ahora hay alguna respuesta.
humanityANDpeace

¡No me agradezcas, gracias el Unicornio!
Kiwy

Tenga en cuenta que hay / hubo un salto fuera de la opción de ventana , shutdown(8)es decir, la obsoleta, -n que creo que en la antigua documentación de Unix solía leer " apaguemos el sistema nosotros mismos: ¡la unidad central está ENCENDIDO! ", Efectivamente un desordenado interruptor de apagado del sistema que podría / podría dejar fragmentos esparcidos por el piso (o al menos los sistemas de archivos en un estado corrupto): uno imagina que esto se usaría para un sistema de tipo de marco principal donde alguien acaba de atrapar su mano en un ventilador de enfriamiento. 🕱
SlySven

Respuestas:


26

Los principales recursos para comprender cómo funciona el kernel de Linux son:

  1. La documentacion .
  2. Artículos de Linux Weekly News .
  3. La fuente. Esta es una bestia compleja que es un poco más fácil de comprender a través de LXR , la referencia cruzada de Linux. La variante LXR que se ejecuta en lxr.linux.no es mejor que otras, pero a menudo está inactiva .

En este caso, no puedo encontrar nada centralmente relevante en la documentación o en LWN, entonces LXR es.

Lo último que hace el código de usuario es llamar a la llamada al rebootsistema . Se necesitan 4 argumentos, así que busque SYSCALL_DEFINE4(rebooten LXR, lo que lleva a kernel/reboot.c. Después de comprobar los privilegios de la persona que llama y los argumentos, el punto de entrada de llamada al sistema llama a una de las varias funciones: kernel_restarta reiniciar, kernel_halta detenerse en un bucle estrecho, kernel_poweroffpara apagar el sistema, kernel_kexecpara reemplazar el núcleo por uno nuevo (si está compilado en), o hibernatepara guardar la memoria en el disco antes de apagarlo.

kernel_restart, kernel_haltY kernel_power_offson bastante similares:

  1. Ir a través reboot_notifier_list, que es una lista de ganchos que los componentes del kernel pueden registrar para ejecutar código en el apagado. Solo unos pocos controladores necesitan ejecutar código en esta etapa, principalmente perros guardianes.
  2. Establece la system_statevariable.
  3. Desactive usermode-helper , para asegurarse de que ya no se iniciará ningún código de usuario. (Todavía puede haber procesos existentes en esta etapa).
  4. Llame device_shutdownpara liberar o apagar todos los dispositivos en el sistema. Muchos conductores se enganchan en esta etapa.
    Tenga en cuenta que cualquier sistema de archivos que todavía esté montado en este punto se desmontará por la fuerza de manera efectiva. La persona que llama de la llamada del sistema se responsabiliza por cualquier desmontaje limpio.
  5. Solo para el apagado, si ACPI está configurado, posiblemente ejecute el código para preparar el estado ACPI S5 (apagado suave).
  6. En una máquina con múltiples CPU, el código podría ejecutarse en cualquier CPU, cualquiera que sea la llamada al sistema. migrate_to_reboot_cpuse encarga de cambiar a una CPU en particular y evitar que el programador envíe código a otras CPU. Después de este punto, solo se está ejecutando una única CPU.
  7. syscore_shutdownllama al shutdownmétodo de operaciones syscore registradas . Creo que esto se trata principalmente de desactivar interrupciones; Pocos ganchos tienen un shutdownmétodo.
  8. Registre un mensaje de información: la canción del cisne.
  9. Finalmente, descanse de alguna manera dependiente de la máquina llamando machine_restart, machine_halto machine_power_off.

El código de hibernación sigue los siguientes pasos:

  1. Iterar a través de los ganchos de administración de energía .
  2. Sistemas de archivos de sincronización.
  3. Congelar todo el código de usuario .
  4. Prevenga la conexión en caliente del dispositivo .
  5. Volcar el estado del sistema en el espacio de intercambio.
  6. Si todo tuvo éxito, hiberne el hardware . Esto puede involucrar llamadas kernel_restart, kernel_halto kernel_power_off, o algún método de hibernación específico de la plataforma.

Una forma diferente de apagar el sistema es machine_emergency_restart. Esto es invocado por la clave mágica SysRqB . La Oclave funciona de manera diferente: llamakernel_power_off .

El sistema también puede apagarse en estado de pánico , es decir, un error irrecuperable. Los intentos de pánico para registrar un mensaje, luego reiniciar el sistema (ya sea a través de un perro guardián de hardware o un reinicio de emergencia).


+1 gracias! @Gilles si desea implementar algún código que limpie / desinfecte la RAM de la máquina como un último paso, registraría una operación syscore para syscore_shutdown(es decir, eso resolvería mi otra pregunta unix.stackexchange.com/q/122540/24394 ) . El paso (1) y el paso (7) permiten registrar cosas que se ejecutarán en el apagado, no se sabe qué es lo que + tuve la impresión de que no se puede influir en el orden de ejecución de esas devoluciones de llamada en (1) y (7). ¡Haré los documentos que mencionaste, pero si lo sabes! ¡Gracias!
humanityANDpeace

Me sorprende esta pregunta y la respuesta no tiene más votos a favor.

2

Esta es solo una respuesta parcial y seguro invito a otra respuesta, que podría ser más exhaustiva y clara.

El contenido de esta respuesta se toma del kernel/reboot.carchivo 3.13 del kernel de Linux (que podría no ser la primera suposición ya que el nombre no es shutdown.c sino reboot.c)

De todos modos, tenemos básicamente tres funciones que bosquejan el proceso de apagado del sistema.

  • void kernel_halt(void) // que termina con un sistema en estado de detención
  • void kernel_power_off(void) // que termina con un sistema apagado
  • void kernel_restart(char *cmd) // que finaliza el sistema para reiniciarlo

Esas funciones son muy breves y, por lo tanto, se pueden pegar aquí en su totalidad. Su código muestra mejor qué pasos se toman para cerrar el núcleo. (los comentarios son míos y pueden no ser 100% ideales y correctos, verifíquese para estar seguro. Es un intento simple.

void kernel_halt(void)

vacío kernel_halt (vacío)
{
    // El primer paso hace:
    // a) funciones de llamada / devolución de llamada registradas para ejecutarse al reiniciar / apagar
    // b) establece system_sate en SYSTEM_HALT
    // c) detiene la interacción userspacetool
    // d) llama a la función device_shutdown ()
    kernel_shutdown_prepare (SYSTEM_HALT);

    // 2do paso: creo que esto es principalmente una necesidad para sistemas multi-CPU
    migrate_to_reboot_cpu ();

    // 3er paso:
    // syscore_shutdown - Ejecuta todas las devoluciones de llamada de cierre del sistema registradas 
    syscore_shutdown ();

    // 4tos mensajes
    pr_emerg ("Sistema detenido \ n");
    kmsg_dump (KMSG_DUMP_HALT);

    // Código de cpu-halt-call específico de la quinta llamada
    machine_halt ();
}

todo se inicia con la sys_rebootllamada al sistema que, dado que no solo se reinicia sino que también se apaga, de todos modos no es lo que se conecta directamente con el proceso de apagado.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.