El sistema de inicio System V, también llamado SysV, controla el arranque de los programas en el instante de inicio del sistema operativo Linux. El otro sistema de inicio tradicional se llama BSD.
Tras la carga del kernel, se ejecuta un proceso que es el primero siempre y se llama init.
El init es un proceso que se ejecuta como demonio mediante un binario situado en /sbin y siempre se le asocia el PID1.
# ps -ef |grep ini root 1 0 0 06:18 ? 00:00:00 /sbin/init #
Todos los demás procesos se generan a partir del init. (Con pstree 1 podemos visualizar el árbol completo de procesos del sistema.)
Cómo se ejecutan las cosas a partir del init es lo que dio lugar a los distintos sistemas de arranque, distinguiéndose el System V y BSD como los dos grandes sistemas. En el Unix original, el proceso init arrancaba los servicios de mediante un único script denominado /etc/rc.
En System V introdujo un nuevo esquema de directorios en /etc/rc.d/ que contenía scripts de arranque/parada de servicios. Aunque la mayoría de distros Linux han usado SystemV, otras como Slackware, usan el estilo BSD y algunos como Gentoo, tienen su propia versión personalizada. Ubuntu y algunas otras distribuciones de Linux utilizan un esquema de arranque llamado upstart como reemplazo para el proceso de inicialización tradicionales.
El flujo de control habitual en el arranque de un ordenador es:
BIOS → Gestor de arranque → Kernel → init
A partir de init se ejecutan los scripts de configuración de todos los servicios y aplicaciones que no sean del sistema operativo y que permitan crear el entorno de usuario para que se pueda presentar una pantalla de inicio de sesión.
Init se ejecuta con un parámetro, conocido como nivel de ejecución, que tiene un valor entre 1 y 6, y que determina qué subsistemas pueden ser operacionales. Cada nivel de ejecución tiene sus propios scripts que codifican los diferentes procesos involucrados en la creación o salida del nivel de ejecución determinado, y son estas secuencias de comandos los necesarios en el proceso de arranque.
Los scripts de Init se localizan normalmente en directorios con nombres como /etc/rc….
init utiliza un archivo de configuración llamado /etc/inittab. En este archivo se le indica a init, entre otras cosas, el nivel de ejecución (runlevel) que se va utilizar y por tanto los scripts que se arrancarán en el sistema (opción inidefault).
Durante el arranque del sistema, se verifica si existe un nivel de ejecución predeterminado en el archivo /etc/inittab
, si no, se debe introducir por medio de la consola del sistema. Después se procede a ejecutar todos los scripts relativos al nivel de ejecución especificado.
Después de que se han dado lugar todos los procesos especificados, Init se aletarga, y espera a que uno de estos tres eventos sucedan: que procesos comenzados finalicen o mueran; un fallo de la señal de potencia (energía); o una petición a través de /sbin/telinit
para cambiar el nivel de ejecución.
Los runlevels son:
0 – Halt (Do NOT set initdefault to this)
1 – Modo monousuario
2 – Moo multiusuario, sin networking
3 – Modo multiusuario
4 – No se usa
5 – Lo mismo que el 3 más entorno gráfico (X11)
6 – Reboot
Los comandos halt, reboot, shutdown o poweroff lo único que hacen en realidad es llamar al nivel de ejecución 0 ó 6 realizando alguna operación antes si acaso.
Cada nivel de ejecución llama a unos scripts situados en un directorio en /etc/rcX.d/ donde la X es el número de nivel. En estos directorios lo que hay son enlaces simbólicos a los scripts de los daemons situados en /etc/init.d/.
El nombre de estos enlaces es importante porque dependiendo de la letra por la que empiezan tienen un significado:
K → Kill (matar servicio)
S → Start (arrancar el servicio)
Si el nombre del enlace no empieza por ninguna letra, el sistema lo ignora y no ejecuta nada.
Después de la letra viene un número de dos cifras del 00 al 99 que indican el orden en que se ejecutan (o se paran dependiendo de si la letra anterior es K o S) los scripts.
Al iniciar el sistema, o cambiar el nivel de ejecución, el sistema inspecciona los daemons del directorio correspondiente y comienza primero parando los daemons indicados (letra K) y después iniciando los demás (letra S) en el orden indicado por sus cifras. En realidad esto lo que se hace es llamar al daemon correspondiente en /etc/init.d/ pasándole como parámetro start o stop.
Un ejemplo de ejecución de runlevel 3 en Red Hat 5:
[root@localhost ~]# ll /etc/rc3.d/ total 304 lrwxrwxrwx 1 root root 24 ago 29 2014 K02avahi-dnsconfd -> ../init.d/avahi-dnsconfd lrwxrwxrwx 1 root root 16 ago 29 2014 K02dhcdbd -> ../init.d/dhcdbd lrwxrwxrwx 1 root root 24 sep 3 15:03 K02NetworkManager -> ../init.d/NetworkManager lrwxrwxrwx 1 root root 34 ago 29 2014 K02NetworkManagerDispatcher -> ../init.d/NetworkManagerDispatcher lrwxrwxrwx 1 root root 16 ago 29 2014 K05conman -> ../init.d/conman lrwxrwxrwx 1 root root 19 ago 29 2014 K05saslauthd -> ../init.d/saslauthd lrwxrwxrwx 1 root root 17 ago 29 2014 K05wdaemon -> ../init.d/wdaemon lrwxrwxrwx 1 root root 19 ago 29 2014 K10dc_server -> ../init.d/dc_server lrwxrwxrwx 1 root root 15 oct 17 2014 K10lircd -> ../init.d/lircd lrwxrwxrwx 1 root root 16 ago 29 2014 K10psacct -> ../init.d/psacct lrwxrwxrwx 1 root root 19 ago 29 2014 K12dc_client -> ../init.d/dc_client lrwxrwxrwx 1 root root 15 ago 29 2014 K15httpd -> ../init.d/httpd lrwxrwxrwx 1 root root 13 mar 10 2015 K20nfs -> ../init.d/nfs lrwxrwxrwx 1 root root 14 ago 29 2014 K24irda -> ../init.d/irda lrwxrwxrwx 1 root root 15 ago 29 2014 K25squid -> ../init.d/squid lrwxrwxrwx 1 root root 15 feb 5 2015 K35dhcpd -> ../init.d/dhcpd lrwxrwxrwx 1 root root 18 feb 5 2015 K35dhcrelay -> ../init.d/dhcrelay lrwxrwxrwx 1 root root 13 ago 29 2014 K35smb -> ../init.d/smb lrwxrwxrwx 1 root root 19 ago 29 2014 K35vncserver -> ../init.d/vncserver lrwxrwxrwx 1 root root 17 ago 29 2014 K35winbind -> ../init.d/winbind lrwxrwxrwx 1 root root 14 ago 29 2014 K36lisa -> ../init.d/lisa lrwxrwxrwx 1 root root 16 ago 29 2014 K36mysqld -> ../init.d/mysqld lrwxrwxrwx 1 root root 20 ago 29 2014 K36postgresql -> ../init.d/postgresql lrwxrwxrwx 1 root root 20 ago 29 2014 K50netconsole -> ../init.d/netconsole lrwxrwxrwx 1 root root 15 feb 25 2015 K50snmpd -> ../init.d/snmpd lrwxrwxrwx 1 root root 19 feb 25 2015 K50snmptrapd -> ../init.d/snmptrapd lrwxrwxrwx 1 root root 13 ago 29 2014 K50tux -> ../init.d/tux lrwxrwxrwx 1 root root 20 ago 29 2014 K69rpcsvcgssd -> ../init.d/rpcsvcgssd lrwxrwxrwx 1 root root 16 ago 29 2014 K73ypbind -> ../init.d/ypbind lrwxrwxrwx 1 root root 14 ago 29 2014 K74nscd -> ../init.d/nscd lrwxrwxrwx 1 root root 14 sep 3 15:03 K74ntpd -> ../init.d/ntpd lrwxrwxrwx 1 root root 15 ago 29 2014 K80kdump -> ../init.d/kdump lrwxrwxrwx 1 root root 15 ago 29 2014 K85mdmpd -> ../init.d/mdmpd lrwxrwxrwx 1 root root 20 ago 29 2014 K87multipathd -> ../init.d/multipathd lrwxrwxrwx 1 root root 24 ago 29 2014 K88wpa_supplicant -> ../init.d/wpa_supplicant lrwxrwxrwx 1 root root 14 ago 29 2014 K89dund -> ../init.d/dund lrwxrwxrwx 1 root root 18 ago 29 2014 K89netplugd -> ../init.d/netplugd lrwxrwxrwx 1 root root 14 ago 29 2014 K89pand -> ../init.d/pand lrwxrwxrwx 1 root root 15 ago 29 2014 K89rdisc -> ../init.d/rdisc lrwxrwxrwx 1 root root 14 ago 29 2014 K91capi -> ../init.d/capi lrwxrwxrwx 1 root root 19 sep 3 15:03 K92ip6tables -> ../init.d/ip6tables lrwxrwxrwx 1 root root 18 sep 3 15:03 K92iptables -> ../init.d/iptables lrwxrwxrwx 1 root root 25 ago 29 2014 K99readahead_later -> ../init.d/readahead_later lrwxrwxrwx 1 root root 23 ago 29 2014 S00microcode_ctl -> ../init.d/microcode_ctl lrwxrwxrwx 1 root root 22 ago 29 2014 S02lvm2-monitor -> ../init.d/lvm2-monitor lrwxrwxrwx 1 root root 25 ago 29 2014 S04readahead_early -> ../init.d/readahead_early lrwxrwxrwx 1 root root 15 ago 29 2014 S05kudzu -> ../init.d/kudzu lrwxrwxrwx 1 root root 18 ago 29 2014 S06cpuspeed -> ../init.d/cpuspeed lrwxrwxrwx 1 root root 14 ago 29 2014 S09isdn -> ../init.d/isdn lrwxrwxrwx 1 root root 17 sep 3 15:03 S10network -> ../init.d/network lrwxrwxrwx 1 root root 16 ago 29 2014 S11auditd -> ../init.d/auditd lrwxrwxrwx 1 root root 21 ago 29 2014 S12restorecond -> ../init.d/restorecond lrwxrwxrwx 1 root root 16 ago 29 2014 S12syslog -> ../init.d/syslog lrwxrwxrwx 1 root root 20 ago 29 2014 S13irqbalance -> ../init.d/irqbalance lrwxrwxrwx 1 root root 18 ago 29 2014 S13mcstrans -> ../init.d/mcstrans lrwxrwxrwx 1 root root 17 ago 29 2014 S13portmap -> ../init.d/portmap lrwxrwxrwx 1 root root 24 ago 29 2014 S13setroubleshoot -> ../init.d/setroubleshoot lrwxrwxrwx 1 root root 17 ago 29 2014 S14nfslock -> ../init.d/nfslock lrwxrwxrwx 1 root root 19 ago 29 2014 S15mdmonitor -> ../init.d/mdmonitor lrwxrwxrwx 1 root root 19 ago 29 2014 S18rpcidmapd -> ../init.d/rpcidmapd lrwxrwxrwx 1 root root 17 ago 29 2014 S19rpcgssd -> ../init.d/rpcgssd lrwxrwxrwx 1 root root 16 nov 11 2014 S19vmware -> ../init.d/vmware lrwxrwxrwx 1 root root 20 ago 29 2014 S22messagebus -> ../init.d/messagebus lrwxrwxrwx 1 root root 19 ago 29 2014 S25bluetooth -> ../init.d/bluetooth lrwxrwxrwx 1 root root 15 ago 29 2014 S25netfs -> ../init.d/netfs lrwxrwxrwx 1 root root 15 ago 29 2014 S25pcscd -> ../init.d/pcscd lrwxrwxrwx 1 root root 14 ago 29 2014 S26apmd -> ../init.d/apmd lrwxrwxrwx 1 root root 14 ago 29 2014 S26hidd -> ../init.d/hidd lrwxrwxrwx 1 root root 14 sep 8 09:46 S26ipmi -> ../init.d/ipmi lrwxrwxrwx 1 root root 20 ago 29 2014 S26lm_sensors -> ../init.d/lm_sensors lrwxrwxrwx 1 root root 16 ago 29 2014 S28autofs -> ../init.d/autofs lrwxrwxrwx 1 root root 15 ago 29 2014 S44acpid -> ../init.d/acpid lrwxrwxrwx 1 root root 15 ago 29 2014 S50hplip -> ../init.d/hplip lrwxrwxrwx 1 root root 14 ago 29 2014 S55sshd -> ../init.d/sshd lrwxrwxrwx 1 root root 14 ago 29 2014 S56cups -> ../init.d/cups lrwxrwxrwx 1 root root 16 ago 29 2014 S56xinetd -> ../init.d/xinetd lrwxrwxrwx 1 root root 18 ago 29 2014 S80sendmail -> ../init.d/sendmail lrwxrwxrwx 1 root root 13 ago 29 2014 S85gpm -> ../init.d/gpm lrwxrwxrwx 1 root root 15 ago 29 2014 S90crond -> ../init.d/crond lrwxrwxrwx 1 root root 13 ago 29 2014 S90xfs -> ../init.d/xfs lrwxrwxrwx 1 root root 17 ago 29 2014 S95anacron -> ../init.d/anacron lrwxrwxrwx 1 root root 13 ago 29 2014 S95atd -> ../init.d/atd lrwxrwxrwx 1 root root 21 oct 20 2014 S96serial_qt -> /etc/pcmcia/serial_qt lrwxrwxrwx 1 root root 15 ago 29 2014 S97rhnsd -> ../init.d/rhnsd lrwxrwxrwx 1 root root 22 ago 29 2014 S97yum-updatesd -> ../init.d/yum-updatesd lrwxrwxrwx 1 root root 22 ago 29 2014 S98avahi-daemon -> ../init.d/avahi-daemon lrwxrwxrwx 1 root root 19 ago 29 2014 S98haldaemon -> ../init.d/haldaemon lrwxrwxrwx 1 root root 19 ago 29 2014 S99firstboot -> ../init.d/firstboot lrwxrwxrwx 1 root root 11 ago 29 2014 S99local -> ../rc.local lrwxrwxrwx 1 root root 20 ago 29 2014 S99nxsensor -> /etc/init.d/nxsensor lrwxrwxrwx 1 root root 20 ago 29 2014 S99nxserver -> /etc/init.d/nxserver lrwxrwxrwx 1 root root 16 ago 29 2014 S99smartd -> ../init.d/smartd [root@localhost ~]#
En el fichero /etc/inittab, además de indicar el runlevel por defecto, se definen toda la configuración de los runlevels, el número de consolas disponibles en cada uno de ellos, qué se hace cunado se pulsa Ctrl+Alt+Del, etc.
Cada línea del fichero inittab es una directiva con la sintaxis:
<id> :<runlevels> : <action> : <process>
donde:
<id> identificador de la directiva
<runlevels> niveles en la que se aplica la directiva
<action> acción que se va a realizar
<process> proceso o demonio que se va a lanzar
Algunas actions importantes son:
sysinit: Se ejecuta durante el arranque del sistema antes que boot o bootwait.
boot: El proceso se ejecuta durante el arranque del sistema, se ignoran los runlevels.
bootwait: Igual que boot pero init se espera hasta que acabe la ejecución.
wait: Inicia el proceso e init espera hasta la terminación.
respawn: Reinicia es servicio automáticamente en caso de se pare.
Ejemplo de archivo inittab:
[root@localhost ~]# cat /etc/inittab # # inittab This file describes how the INIT process should set up # the system in a certain run-level. # # Author: Miquel van Smoorenburg, <miquels@drinkel.nl.mugnet.org> # Modified for RHS Linux by Marc Ewing and Donnie Barnes # # Default runlevel. The runlevels used by RHS are: # 0 - halt (Do NOT set initdefault to this) # 1 - Single user mode # 2 - Multiuser, without NFS (The same as 3, if you do not have networking) # 3 - Full multiuser mode # 4 - unused # 5 - X11 # 6 - reboot (Do NOT set initdefault to this) # id:5:initdefault: # System initialization. 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 # Trap CTRL-ALT-DELETE ca::ctrlaltdel:/sbin/shutdown -t3 -r now # When our UPS tells us power has failed, assume we have a few minutes # of power left. Schedule a shutdown for 2 minutes from now. # This does, of course, assume you have powerd installed and your # UPS connected and working correctly. pf::powerfail:/sbin/shutdown -f -h +2 "Power Failure; System Shutting Down" # If power was restored before the shutdown kicked in, cancel it. pr:12345:powerokwait:/sbin/shutdown -c "Power Restored; Shutdown Cancelled" # Run gettys in standard runlevels 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 # Run xdm in runlevel 5 x:5:respawn:/etc/X11/prefdm -nodaemon [root@localhost ~]#
Hay que indicar también que existe un script específico para el usuario indique sus propios scripts o ejecutables que se lanzaran con cada runlevel. Ese scritp se llama rc.local.
rc.local es aquel destinado a la ejecución de instrucciones en el arrnque o script definidos por el usuario y que se ejecuta normalmente al final de todos los demonios del runlevel correcpondiente:
[root@localhost /]# ll /etc/rc5.d/ |grep rc.local lrwxrwxrwx 1 root root 11 ago 29 2014 S99local -> ../rc.local [root@localhost /]#
Por último indicar que si queremos modificar los demonios a lanzar o parar en cada runlevel, no es necesario crear a mano los scripts en /etc/rc[0-6].d sino que se dispone de la instrucción chkconfig.
chkconfig permite consultar y actualizar los runlevels y servicios asociados. Sin argumentos visualiza información de uso.
Resumen de uso:
chkconfig [–list] [name]
chkconfig –add <name>
chkconfig –del <name>
chkconfig –override <name>
chkconfig [–level levels] <name> <on|off|reset|resetpriorities>
chkconfig [–level levels] name
El equivalente a chkconfig en entorno gráfico es system-config-services.