Sistemas Informáticos Monousuario y Multiusuario TEMA 15 Página 1 TEMA 15: INICIO DE LINUX 1.- Sistemas de arranque init de SysV. .......................................................................... 2 1.1.- Inicio del sistema. El proceso Init. ....................................................................... 2 1.2.- Fichero /ETC/INITTAB ........................................................................................ 5 1.3.- Directorios diréctamente implicados. .................................................................. 5 1.4.- El comando Init ................................................................................................... 7 2.- Sistemas de arranque Upstart (Ubuntu/Kubuntu) ..................................................... 8 Administración de Sistemas Informáticos I.E.S. Bezmiliana Sistemas Informáticos Monousuario y Multiusuario TEMA 15 Página 2 TEMA 15: INICIO DE LINUX Adevertencia: Las explicaciones que vienen a continuación toman como distribución base Fedora-Core. El inicio del sistema difiere sensiblemente para las distribuciones de Ubuntu/Kubuntu 6.10 y posteriores. Se encuentra documentado dicho inicio al final de este tema. El administrador se debe hacer cargo de arrancar y detener el sistema, controlando los servicios que se inician y aquellos que deben finalizar. 1.- Sistemas de arranque init de SysV. Gnu/Linux utiliza el proceso de arranque init de Sys V; init es el primer proceso que se ejecuta en el sistema, es el más importante, el padre de todos los procesos. El PID (identificador de proceso) de init es siempre 1. 1.1.- Inicio del sistema. El proceso Init. El núcleo ejecuta init al arrancar. Este programa, ahora como proceso, cargará los subprocesos necesarios para la puesta en marcha del sistema. Cuando init ha terminado de cargarse vacía el subdirectorio /tmp y lanza getty que se encarga de ejecutar login en el sistema para permitir la autenticación a los usuarios. Los niveles de ejecución (runlevel) determinan los servicios que tendremos disponibles en cada uno de ellos. Es una forma de tener diferentes modos de trabajo, cada uno de ellos con características bien definidas, en función del tipo de tarea a que estén orientados. Existen ocho niveles de ejecución, que están numerados del cero al seis, más otro denominado con la letra «S» (tiene un alias con la letra «s», que realmente es igual al 1). Los niveles de ejecución que manejaremos y una descripción de para qué están definidos se puede ver en la siguiente tabla: Administración de Sistemas Informáticos I.E.S. Bezmiliana Sistemas Informáticos Monousuario y Multiusuario Nivel de ejecución TEMA 15 Página 3 Modo 0 Detener el sistema 1 Mono usuario, sin soporte de red 2 Multiusuario, sin soporte de red 3 Modo multiusuario completo 4 Sin uso. Recomendado para pruebas 5 Multiusuario completo en entorno gráfico 6 Reiniciar el sistema Init necesita un fichero de configuración para saber exactamente lo que tiene que hacer. Este fichero es /etc/inittab y contiene información sobre el nivel a ejecutar por defecto, previsión sobre lo que hacer ante determinadas situaciones, describe qué procesos se inician en la carga y durante la operación normal. Las entradas del fichero /etc/inittab tienen el siguiente formato: id:niveles_ejecución:acción:proceso id: Una secuencia única de 1 a 4 caracteres que identifican la entrada de inittab. niveles_ejecución: Lista de niveles de ejecución para los que se llevarán a cabo las acciones definidas a continuación en la línea. acción: La acción se llevará a cabo. proceso: El proceso a ejecutar. Para que una línea sirva para varios niveles de ejecución, el campo niveles_ejecución tiene que incluirlos. Por ejemplo, 135 indica que el proceso se iniciará en los niveles 1, 3 y 5. Cuando se cambia de un nivel de ejecución a otro, los procesos en ejecución que no estén definidos en el nuevo nivel se matan. Las acciones que podemos definir, más habitualmente, en el campo acción son: initdefault: Especifica el nivel de ejecución por defecto al arrancar el sistema. El campo proceso se ignora. Respawn: El proceso se reiniciará cuando termine. once: El proceso se ejecutará una sola vez cuando se entre en el nivel de ejecución especificado. wait: El proceso se iniciará una vez cuando se entre en el nivel de ejecución e Administración de Sistemas Informáticos I.E.S. Bezmiliana Sistemas Informáticos Monousuario y Multiusuario TEMA 15 Página 4 init esperará a su terminación. boot: El proceso se ejecutará durante el arranque del sistema. El campo niveles_ejecución se ignora. bootwait: El proceso se ejecutará durante el arranque del sistema, mientras init espera su terminación. El campo niveles_ejección se ignora. sysinit: El proceso se ejecutará durante el arranque del sistema, antes que cualquier entrada boot o bootwait. El campo niveles_ejecución se ignora. powerwait: El proceso se ejecutará si init recibe una señal SIGPWR, que indica algún problema con la alimentación eléctrica. Init esperará que el proceso termine. powerfail: Como powerwait, excepto que init no espera a que termine el proceso. powerokwait: El proceso se ejecutará si init recibe la señal SIGPWR, con la condición de que haya un fichero llamado /etc/powerstatus que contenga la palabra OK. Esto significa que se ha restablecido la alimentación eléctrica. ctrlaltdel: Especifica qué proceso se ejecutará al pulsar la combinación de teclas [Ctrl+Alt+Supr]. Normalmente, reiniciar la máquina. El fichero /etc/inittab de una máquina linux podría ser el siguiente: (traducido al español) # inittab Este fichero describe como arrancará el sistema el proceso INIT # en cada nivel de ejecución. # # Autor: Miquel van Smoorenburg, <miquels@drinkel.nl.mugnet.org> # # Nivel de ejecución por defecto son: # 0 -Apagar. (NO ponga initdefault a 0 !) # 1 -Mono Usuario # 2 -Multiusuario, sin NFS (Es igual que 3, si no dispone de red.) # 3 -Multiusuario, con soporte de red. # 4 -Sin uso. # 5 -X11, entorno gráfico. # 6 -Reiniciar. (NO ponga initdefault a 6 !) # # id:5:initdefault: # Inicialización del Sistema si::sysinit:/etc/rc.d/rc.sysinit l0:0:wait:/etc/rc.d/rc 0 l1:1:wait:/etc/rc.d/rc 1 l2:2:wait:/etc/rc.d/rc 2 l3:3:wait:/etc/rc.d/rc 3 l4:4:wait:/etc/rc.d/rc 4 l5:5:wait:/etc/rc.d/rc 5 l6:6:wait:/etc/rc.d/rc 6 # Cosas a hacer en cada Run-Level ud::once:/sbin/update # Al pulsar [Ctrl+Alt+Supr] Administración de Sistemas Informáticos I.E.S. Bezmiliana Sistemas Informáticos Monousuario y Multiusuario TEMA 15 Página 5 ca::ctrlaltdel:/sbin/shutdown -t3 -r now # Cuando la SAI informe de una caída de tensión, dispone de varios minutos antes # de que el sistema se apague. Se han programado 2 minutos. # Esto solo funcionará, si tiene una SAI conectada y funcionando correctamente. pf::powerfail:/sbin/shutdown -f -h +2 «Fallo Eléctrico; El sistema se apagará en 2 minutos» # Si vuelve la alimentación eléctrica antes de que el sistema se apague, se cancelará. pr:12345:powerokwait:/sbin/shutdown -c «Alimentación correcta; Sigan trabajando» # Ejecuta « getty» en run-levels 1:2345:respawn:/sbin/mingetty tty1 2:2345:respawn:/sbin/mingetty tty2 3:2345:respawn:/sbin/mingetty tty3 4:2345:respawn:/sbin/mingetty tty4 5:2345:respawn:/sbin/mingetty tty5 6:2345:respawn:/sbin/mingetty tty6 # Ejecuta» xdm» en run-level 5 x:5:respawn:/etc/X11/prefdm -nodaemon 1.2.- Fichero /ETC/INITTAB Uno de los scripts más importantes en el arranque del sistema es /etc/rc.d/rc.sysinit. Es el primer script que init encuentra y ejecuta. En él están definidas funciones como: Inicio y activación del espacio de intercambio. (swap) Configuración de la red. Especificación de variables del sistema. Comprobación y montaje de los sistemas de archivos. Inicialización de puertos serie. Carga los módulos del kernel. Establecimiento de cuotas de usuarios. Ajuste del reloj del sistema. El último script en ejecutarse es /etc/rc.d/rc.local. En este fichero podremos poner inicializaciones especificas del sistema, aunque su propósito inicial es controlar los servicios de red. 1.3.- Directorios diréctamente implicados. El directorio rc.d es de vital importancia para el arranque del sistema. Tiene una estructura bien definida ya que existe un directorio para cada nivel de ejecución, identificado con el mismo número que el nivel, y en cada uno de estos directorios se indican qué servicios se iniciarán o detendrán al entrar en ese nivel de ejecución. El directorio init.d contiene los scripts que lanzarán o detendrán los servicios que Administración de Sistemas Informáticos I.E.S. Bezmiliana Sistemas Informáticos Monousuario y Multiusuario TEMA 15 Página 6 tengamos disponibles en nuestro equipo. Normalmente es suficiente invocar al servicio por su nombre y pasarle uno de los siguientes argumentos: start, stop, status, restart o reload. Los directorios numerados para cada runlevel contienen enlaces simbólicos que apuntan a los scripts del directorio init.d. Veamos un muestra, esto es parte del directorio rc5.d: lrwxrwxrwx lrwxrwxrwx lrwxrwxrwx lrwxrwxrwx lrwxrwxrwx lrwxrwxrwx lrwxrwxrwx lrwxrwxrwx lrwxrwxrwx lrwxrwxrwx lrwxrwxrwx lrwxrwxrwx lrwxrwxrwx lrwxrwxrwx lrwxrwxrwx lrwxrwxrwx lrwxrwxrwx lrwxrwxrwx lrwxrwxrwx lrwxrwxrwx lrwxrwxrwx lrwxrwxrwx lrwxrwxrwx lrwxrwxrwx lrwxrwxrwx lrwxrwxrwx 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 root root root root root root root root root root root root root root root root root root root root root root root root root root root root root root root root root root root root root root root root root root root root root root root root root root root root 14 16 15 15 20 15 18 15 16 17 18 23 17 25 15 18 22 19 18 14 16 17 16 20 17 17 ene ene ene ene ene ene ene ene ene ene ene ene ene ene ene ene ene ene ene ene ene ene ene ene ene ene 17 17 16 17 17 16 16 16 17 17 16 17 17 17 16 16 17 17 16 16 16 16 16 17 16 16 2006 2006 2006 2006 2006 2006 2006 2006 2006 2006 2006 2006 2006 2006 2006 2006 2006 2006 2006 2006 2006 2006 2006 2006 2006 2006 K84ripd -> ../init.d/ripd K84ripngd -> ../init.d/ripngd K85mdmpd -> ../init.d/mdmpd K85zebra -> ../init.d/zebra K87multipathd -> ../init.d/multipathd K89named -> ../init.d/named K89netplugd -> ../init.d/netplugd K89rdisc -> ../init.d/rdisc K90isicom -> ../init.d/isicom K92ipvsadm -> ../init.d/ipvsadm K94diskdump -> ../init.d/diskdump K99microcode_ctl -> ../init.d/microcode_ctl S01sysstat -> ../init.d/sysstat S04readahead_early -> ../init.d/readahead_early S05kudzu -> ../init.d/kudzu S06cpuspeed -> ../init.d/cpuspeed S08arptables_jf -> ../init.d/arptables_jf S08ip6tables -> ../init.d/ip6tables S08iptables -> ../init.d/iptables S09isdn -> ../init.d/isdn S09pcmcia -> ../init.d/pcmcia S10network -> ../init.d/network S12syslog -> ../init.d/syslog S13irqbalance -> ../init.d/irqbalance S13portmap -> ../init.d/portmap S14nfslock -> ../init.d/nfslock Observemos con atención cómo se llaman los enlaces, cada uno de ellos tiene el nombre del script al que están asociados. Los que empiezan con una «S» («S» de start) define si el servicio se inicia, y otros con una «K»define si el servicio se detiene («K» de kill). El número que lucen es simplemente una facilidad para ordenar y que no tiene mayor relevancia. Lo realmente ventajoso de este sistema es que, en primer lugar, no se repiten los scripts en cada directorio de runlevel, si no que permanecen en un único lugar bien definido, el directorio init.d, y en segundo lugar, la modificación a realizar si lanzamos un servicio o no, en un runlevel determinado, es tan sencilla como cambiar el nombre del enlace al servicio en cuestión. Si queremos que se inicie bastará con asegurarse de que su nombre empieza por una «S» y en caso contrario, o sea que en ese nivel de ejecución no se ofrezca el servicio, pondremos el nombre empezando por una «K». Así de sencillo. Vuelve a mirar el fichero /etc/inittab de más arriba. Hay una línea para cada nivel de ejecución que tiene como proceso «rc» con los números de los runlevels como parámetro. El script rc se encarga de reinicializar el sistema en un nivel de ejecución distinto. Otra ventaja es el control que tenemos sobre los servicios del sistema. Independiente del estado en el que estén, los podemos lanzar, detener, reiniciar, etc. sobre la marcha, sin necesidad de reiniciar la máquina, ni nada parecido. Administración de Sistemas Informáticos I.E.S. Bezmiliana Sistemas Informáticos Monousuario y Multiusuario TEMA 15 Página 7 1.4.- El comando Init Podemos ejecutar init desde línea de comandos con alguno de los siguientes argumentos: 0, 1, 2, 3, 4, 5, 6: Para cambiar al nivel de ejecución especificado. Q, q: Si queremos que init relea el fichero /etc/inittab. S, s: Entra en modo monousuario. U, u: Reejecuta init respetando el estado actual. No se relee el fichero /etc/inittab. Administración de Sistemas Informáticos I.E.S. Bezmiliana Sistemas Informáticos Monousuario y Multiusuario TEMA 15 Página 8 2.- Sistemas de arranque Upstart (Ubuntu/Kubuntu) Upstart es un init daemon creado por el Ubuntu-team que pretende ser sustituto del init de System V. Es el único proceso que arranca el núcleo y encargado de llamar al resto de programas/servicios del sistema. En Linux, todo proceso es hijo de init. Ciertamente Upstart presenta interesantes mejoras respecto del init de System V: Arranque de servicios en paralelo, guiado por eventos, servicios que se rearrancan automáticamente si mueren, etc ... Por el momento las únicas distribuciones que lo implementan son Ubuntu/Kubuntu (Edgy/Feisty) y Debian Experimental. Es mas, toda la potencia de Upstart no es aprovechada pues, por retrocompatibilidad con los scripts de sysvinit, upstart sólo se acaba comportando como un envoltorio (wrapper) de éste. En /etc/event.d/ tenemos los ficheros de configuración de upstart que, podríamos decir, funcionan como si del fichero /etc/inittab se tratase: Ficheros ttyX: que llaman a la creación de las terminales con getty. Ficheros rcX: que acaban ajustando el runlevel y llamando a /etc/init.d/rc para ejecutar los scripts del nivel de arranque correspondiente. Otros ficheros como ctrl-alt-del que mapea dicha combinación al reincio ordenado del equipo, o rc-default que define el nivel de inicio por defecto. Es este último fichero, rc-default, es el objeto de nuestro estudio. Fichero /etc/event.d/rc-default Originalmente, Ubuntu Edgy y Feisty, define este fichero como sigue: # rc - runlevel compatibility # # This task guesses what the "default runlevel" should be and starts the # appropriate script. start on rcS/stop script runlevel --reboot || true if grep -q -w -- "-s\|single\|S" /proc/cmdline; then telinit S elif [ -r /etc/inittab ]; then RL="$(sed -n -e "/^id:[0-9]*:initdefault:/{s/^id://;s/:.*//;p}" /etc/inittab || true)" if [ -n "$RL" ]; then telinit $RL else telinit 2 fi else telinit 2 fi end script Administración de Sistemas Informáticos I.E.S. Bezmiliana Sistemas Informáticos Monousuario y Multiusuario TEMA 15 Página 9 Aquel que conozca bash-scripting puede darse cuenta rápidamente que el script busca en la línea de comandos del núcleo la directiva single para arrancar en single-mode user, caso contrario busca en /etc/inittab el runlevel por defecto (retrocompatibilidad con sysvinit) y si no hay ninguno definido se toma el runlevel 2 como nivel de inicio. Vemos pues que incluso este script parsea la línea de comandos del kernel, en busca de parámetros para iniciar el single-user mode, si procede. No es, por tanto, mucho más difícil imaginar cómo modificar dicho script para que se parsee la línea de comandos del núcleo en busca de nuestro parámetro runlevel. La aproximación seguida, aunque no la mejor, es la siguiente: # rc - runlevel compatibility # # This task guesses what the "default runlevel" should be and starts the # appropriate script. # # (c) J. Félix Ontañón 2007. Distribuido con licencia GPLv2 # # Modificado para correr uno u otro nivel de inicio según lo que indique el # parámetro "runlevel" pasado al kernel por la cmd-line en tiempo de arranque. # start on rcS/stop script runlevel --reboot || true RUNLEVEL=2 for x in $(cat /proc/cmdline); do case $x in runlevel=*) RUNLEVEL=${x#runlevel=} ;; esac done telinit $RUNLEVEL end script Sencillo y funcional: extrae el nivel de arranque de la línea de comandos del núcleo y ajusta el runlevel 2 por defecto. Podríamos complicarlo un poco mas determinando el nivel de arranque por defecto extrayéndolo del /etc/inittab si hubiere. Además, por haberse construido con un bloque case este script es fácilmente extensible para añadir nuevos parámetros. Si has llegado hasta aquí sin entender aún nada de lo que significa, no te preocupes, pronto empezaremos con los scripts. De momento quédate con que usando Upstart podremos pasar el nivel de ejecución de inicio desde el mismo GRUB, sustituyendo el script original del equipo de Ubuntu por el último que has visto. Venga pruebalo ya. Administración de Sistemas Informáticos I.E.S. Bezmiliana