¿Qué hace exactamente init?


43

Estoy creando una distribución de Linux y ahora necesito un programa init. Puedo codificar en c muy bien y sé bastante sobre Linux (no mucho, pero he estado usando Arch Linux para el desarrollo durante 4 años), así que pensé que debería intentar escribir mi propio script de inicio básico en C. Estaba Me pregunto, ¿qué tareas hace init para configurar el sistema para un shell simple? (Cuando pregunto "¿qué hace init?", Sé qué es init y para qué sirve. Simplemente no sé qué tareas hace).

No necesito código y posiblemente ni siquiera necesito comandos básicos, pero necesito el orden en que se ejecutan.


1
Puede usar el intérprete que desee para los scripts de inicio de estilo SysV, incluidos Perl, awk, bash, (t) csh, binarios nativos, ... Bash se usa normalmente porque está prácticamente garantizado que esté disponible en el sistema donde se encuentran dichos scripts. desplegado en el punto relevante del proceso de arranque, no porque haya algún acoplamiento entre SysVinit y bash. SysVinit define el contrato y cada script es libre de implementar ese contrato de cualquier manera que su desarrollador lo considere conveniente.
un CVn

Respuestas:


53

El sistema 5 initsolo te contará una pequeña parte de la historia.

Hay una especie de miopía que afecta el mundo de Linux. Las personas piensan que usan una cosa llamada "Sistema 5 init", y eso es lo que es tradicional y el mejor lugar para comenzar. Ninguno de los dos es el caso.

La tradición no es, de hecho, lo que esas personas dicen que es, para empezar. El Sistema 5 inity el Sistema 5 rcdatan del Sistema 5 de AT&T UNIX, que estaba casi tan lejos después del primer UNIX como ahora (digamos) después de la primera versión de Linux-Mandrake.

1ª Edición UNIX solo tenía init. No tuvo rc. El lenguaje ensamblador de la primera edición init( cuyo código ha sido restaurado y puesto a disposición por Warren Toomey et al. ) Generó y reapareció 12 gettyprocesos directamente , montó 3 sistemas de archivos cableados desde una tabla integrada y ejecutó directamente un programa desde el directorio de inicio de un el usuario llamado mel. La gettytabla también estaba directamente en la imagen del programa.

Fue otra década después del Sistema 5 de UNIX que apareció el llamado sistema de inicio Linux "tradicional". En 1992, Miquel van Smoorenburg (re) escribió un Linux init+ rc, y sus herramientas asociadas, que las personas ahora denominan "Sistema 5 init", aunque en realidad no es el software del Sistema 5 de UNIX (y no es solo init)

El sistema 5 init/ rcno es el mejor lugar para comenzar, e incluso si se agrega conocimiento del sistema que no cubre la mitad de lo que hay que saber. Ha habido mucho trabajo en el área del diseño del sistema de inicio (para Linux y los BSD) que ha sucedido solo en las últimas dos décadas. Se han discutido, tomado, diseñado, implementado y practicado todo tipo de decisiones de ingeniería. Los Unices comerciales también hicieron mucho.

Sistemas existentes para estudiar y aprender de

Aquí hay una lista incompleta de algunos de los principales sistemas de inicio distintos de esos dos, y uno o dos de sus (varios) puntos destacados:

  • El finito de Joachim Nilsson fue la ruta del uso de un archivo de configuración más legible para los humanos.
  • El minit de Felix von Leitner eligió un sistema de configuración de sistema de archivos es la base de datos, pequeñas huellas de memoria y dependencias de inicio / detención entre las cosas que initcomienzan.
  • La runa de Gerrit Pape fue por lo que describí anteriormente como el enfoque de solo generar cuatro guiones de shell .
  • InitNG tenía como objetivo tener dependencias, destinos con nombre, múltiples archivos de configuración y una sintaxis de configuración más flexible con una carga completa de más configuraciones para procesos secundarios.
  • la nueva empresa se rediseñó por completo, modelando el sistema no como servicios e interdependencias, sino como eventos y trabajos desencadenados por ellos.
  • El diseño de nosh incluye empujar toda la administración del servicio (incluso el gettydesove y la cosecha de zombis) en un administrador de servicios separado, y solo manejar dispositivos / enlaces simbólicos / directorios y eventos del sistema específicos de la API del sistema operativo.
  • sinit es un init muy simple. Ejecuta el /bin/rc.inittrabajo de quién es iniciar programas, montar el sistema de archivos, etc. Para esto, puede usar algo como minirc .

Además, hace aproximadamente 10 años, hubo discusión entre los usuarios de Daemontools y otros sobre el uso svscancomo proceso n. ° 1, lo que condujo a proyectos como el svscan de Paul Jarc como estudio de proceso 1 , las ideas de Gerrit Pape y el svscan de Laurent Bercot como proceso 1 .

Lo que nos lleva a lo que hacen los programas de proceso # 1.

¿Qué proceso hacen los programas n. ° 1?

Las nociones de qué proceso "1" se supone que debe hacer son, por naturaleza, subjetivas. Un criterio de diseño objetivo significativo es lo que debe hacer el proceso # 1 como mínimo . El núcleo le impone varios requisitos. Y siempre hay algunas cosas específicas del sistema operativo de varios tipos que tiene que hacer. Cuando se trata de lo que el proceso # 1 ha hecho tradicionalmente , entonces no estamos en ese mínimo y nunca lo hemos estado realmente.

Hay varias cosas que varios núcleos del sistema operativo y otros programas exigen del proceso # 1 que uno simplemente no puede escapar.

La gente te dirá que fork()la función principal del proceso n. ° 1 es actuar como padre de los procesos huérfanos. Irónicamente, esto no es cierto. Lidiar con los procesos huérfanos es (con los núcleos Linux recientes, como se explica en https://unix.stackexchange.com/a/177361/5132 ) una parte del sistema que se puede descartar en gran medida del proceso n. ° 1 en otros procesos, como Un gerente de servicio dedicado . Todos estos son gerentes de servicio, que se quedan sin el proceso # 1:

Del mismo modo, como se explica en https://superuser.com/a/888936/38062 , la /dev/initctlidea no necesita estar cerca del proceso n. ° 1. Irónicamente, es el systemd altamente centralizado que demuestra que se puede sacar del proceso # 1.

Por el contrario, las cosas obligatorias para initque la gente suele olvidar en sus diseños fuera de la parte superior-de-la-cabeza, son cosas tales como la manipulación SIGINT, SIGPWR, SIGWINCH, y así enviados desde el núcleo y la promulgación de las diversas peticiones de cambio de estado del sistema enviados de programas que "saben" que ciertas señales para procesar # 1 significan ciertas cosas. (Por ejemplo: como se explica en https://unix.stackexchange.com/a/196471/5132 , los conjuntos de herramientas BSD "saben" que SIGUSR1tiene un significado específico).

También hay tareas de inicialización y finalización que no se pueden escapar, o sufrirán mucho al no hacerlo, como montar sistemas de archivos "API" o vaciar el caché del sistema de archivos.

Los conceptos básicos para tratar con los sistemas de archivos "API" son un poco diferentes al funcionamiento de initrom 1st Edition UNIX: uno tiene una lista de información incluida en el programa y uno simplemente mount()contiene todas las entradas de la lista. Encontrará este mecanismo en sistemas tan diversos como BSD (sic!) init, A través de la nariz system-manager, hasta systemd.

"configurar el sistema para un shell simple"

Como ha observado, init=/bin/shno se montan los sistemas de archivos "API", se bloquea de forma desgarbada sin vaciado de caché cuando uno escribe exit( https://unix.stackexchange.com/a/195978/5132 ), y en general lo deja al (súper) usuario para que realice manualmente las acciones que hacen que el sistema sea mínimamente utilizable.

Para ver lo que uno realmente no tiene más remedio que hacer en los programas del proceso n. ° 1, y así establecer un buen rumbo para su objetivo de diseño establecido, su mejor opción es mirar las superposiciones en la operación de la runa de Gerrit Pape, Felix von Minit de Leitner y el system-managerprograma del paquete nosh. Los dos primeros muestran dos intentos de ser minimalistas, pero aún manejan las cosas que es imposible evitar.

Esto último es útil, sugiero, por su extensa entrada manual para el system-managerprograma, que detalla exactamente qué sistemas de archivos "API" están montados, qué tareas de inicialización se ejecutan y qué señales se manejan; en un sistema que, por diseño, el administrador del sistema solo generó otras tres cosas (el administrador del servicio, un registrador que lo acompaña y el programa para ejecutar los cambios de estado) y solo hace lo inevitable en el proceso # 1.


3
Impresionante respuesta y muy informativo. Pero me pregunto dónde está OSX en este panorama general launchd. A veces la gente olvida por completo que OSX es un (excelente) miembro de la gran familia * nix.
DavAlPi

4

System V init en Debian (hay otras variantes y variaciones) hace lo siguiente:

  • Al ingresar un nivel de ejecución, llama a los scripts en /etc/rcX.d/S*orden alfanumérico, donde Xestá el nivel de ejecución. Estos scripts deberían configurar el nivel de ejecución. La configuración típica es iniciar demonios y realizar tareas de configuración para ese nivel de ejecución. Esto se realiza una sola vez al ingresar al nivel de ejecución.
  • Mientras está en un nivel de ejecución, inicia los demonios que se enumeran en el /etc/inittabque necesitan estar activos durante ese nivel de ejecución. Si esos demonios dejan de ejecutarse, los reinicia. Si bien puede tener cualquier daemon que desee administrar init, como mínimo desea unos pocos gettypara poder iniciar sesión. gettySale una vez que se completa un inicio de sesión, luego lo initreinicia, proporcionando un nuevo inicio de sesión.
    • Si el demonio se reinicia demasiadas veces en muy poco tiempo, deja de intentar reiniciarlo por un tiempo.
    • El hecho de que algo haya sido iniciado por los scripts de inicio al ingresar al nivel de ejecución no hace que initautomáticamente intente mantenerlo en ejecución. Debe especificar eso por separado en el /etc/inittab.
  • Al salir de un nivel de ejecución, llama a los scripts en /etc/rcX.d/K*orden alfanumérico, donde Xestá el nivel de ejecución. Una forma de implementar el apagado o el reinicio es definir un nivel de ejecución para esos eventos y hacer que la última tarea ejecute el comando halto reboot.
  • Llamará a ejecutables en respuesta a ciertos eventos, como eventos de energía o Ctrl-Alt-Del.
  • Escucha en un socket, si recibe ciertos mensajes, cambiará el nivel de ejecución.

Por lo tanto, puede usarlo initcomo administrador de servicio rudimentario si lo desea, pero su tarea principal en estos días es mantenerlo gettydisponible para que un usuario pueda iniciar sesión y comenzar las transiciones de nivel de ejecución.

Me preguntaba, ¿qué tareas hace init para configurar el sistema para un shell simple?

Lo que quieras. En Debian, en cada /etc/rcX.ddirectorio hay un enlace simbólico a un script /etc/init.dy puede personalizarlo o eliminarlo por completo. El orden se establece mediante anterior a cada secuencia de comandos con una 00, 01, etc.

También puede especificar una -bopción para init(es decir, a través de la línea de comando del núcleo) si solo desea initgenerar un shell. Cuando sale de la cáscara, initmuere y cuando initmuere, el núcleo entrará en pánico.


2

El mínimo absoluto que debe hacer init es ejecutar al menos otro programa y nunca salir. Si init sale, el sistema se bloquea. Supongo que incluso ejecutar el otro programa no es estrictamente necesario, pero si no lo hace, init tendría que ser responsable de hacer todo lo que se espera que haga el sistema, o no sería muy útil.


1
He tenido sistemas Linux defectuosos donde PID 1 se bloqueó pero el sistema básicamente siguió funcionando. La falla del PID 1 puede depender de la versión del kernel.
Gilles 'SO- deja de ser malvado'

1

init puedes hacer lo que quieras

init es un ejecutable arbitrario llamado por el kernel de Linux al final del proceso de arranque (y el único ejecutable de este tipo).

Normalmente se implementa como un ejecutable ELF, pero incluso puede ser un script de shell con chmod +x: Init como un script de shell

Las implementaciones típicas como sysemd leerán los archivos de configuración, a menudo /etc/initrc, y luego bifurcarán un montón de procesos de usuario basados ​​en esas configuraciones, para implementar varios aspectos del sistema.

Sin embargo, esto es completamente específico de la implementación y, por lo tanto, su pregunta no puede ser respondida sin especificar una implementación específica. Por ejemplo, he estado jugando con un initproceso que simplemente hace una rebootllamada al sistema con fines educativos.

El kernel de Linux simplemente busca el ejecutable en la ruta /initde forma predeterminada, pero esto puede ser anulado por el init=parámetro de línea de comando del kernel de Linux.

Una excelente manera de jugar inites usar QEMU, ya que puede pasar los parámetros de la línea de comando del kernel a QEMU desde la línea de comando de QEMU con la -appendopción, y sin temor a bloquear su escritorio.

Aquí está mi configuración mínima totalmente automatizada de Buildroot + QEMU que hace que sea muy fácil jugar con sus propios inits para desmitificar el asunto.


0

Si está comprometido con el principio modular de "hacer una cosa y hacerlo bien", entonces un initprograma debe iniciar procesos.

Iniciar procesos

Debe ejecutarse una vez que el núcleo se haya descomprimido con éxito, cuidando todas las tareas rudimentarias involucradas en la inicialización de todos los procesos iniciales que un sistema requiere para operar (como montar unidades encontradas en / etc / fstab, abrir interfaces de red, y pronto).

Dado que el proceso de arranque y apagado son esencialmente inversos entre sí, es común que un programa init también garantice que los procesos se detengan con un comando de apagado.

Detener procesos

Esto significa que debe detener los procesos de acuerdo con la página de manual de ese proceso (en otras palabras, no solo una flagrante kill -9, sino que debe detener el proceso de la forma en que se quiere finalizar), desmontar unidades y finalmente emitir el comando de apagado final .

Referencias

Una buena referencia de cómo lo hacen otros es mirar los scripts /etc/rc.d de Slackware , y también un sistema de inicio simple que ya existe, como ninit (un sucesor para minit). Tiene supervisión de proceso (lo que significa que si un proceso muere, se relanza), lo que posiblemente no sea el trabajo de init, pero sigue siendo bastante básico y simple de entender, especialmente a través de los scripts de muestra del autor.

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.