Servicios del sistema
Entendiendo los niveles de arranque e init
A la hora de iniciar el sistema existen unas configuraciones de arranque para los sistemas Linux. Son configuraciones predefinidas por la distribución pero que pueden ser modificadas por el administrador. Estás configuraciones son conocidas como runlevels o niveles de arranque
Un nivel de arranque, por tanto, es la definición de un estado del sistema. Los niveles de arranque se diferencian por un número número (por defecto). Cada nivel de arranque incluye un conjunto de servicios y algunas aplicaciones que se inician o detienen.
En Ubuntu los niveles de arranque siguen el siguiente esquema:
➤ 0 — Apagado del sistema. No se apaga, pero ningún proceso queda en ejecución. ➤ 1 — Modo monousuario o de mantenimiento. No se puede cambiar de usuario, el sistema arranca con lo básico; un interprete de comandos y algunas utilidades de rescate. ➤ 2 — Nivel de arranque por defecto. Arranca un sistema completo multiusuario. ➤ 3,4,5 — Igual que en el nivel anterior arrancan un sistema completo multiusuario. ➤ 6 — Reinicio; el sistema se apaga y vuelve a iniciarse.
En un sistema en ejecución podemos determinar el nivel de arranque en ejecución con el comando:
$ runlevel
N 2
El primer caracter, N representa el nivel de arranque anterior. Una N en esta posición indica que el sistema fué iniciado directamente desde el nivel de arranque por defecto, representado por el segundo caracter, en este caso un 2. Si el sistema hubiese estado en un nivel de arranque previo, el primer caracter reflejaría dicho nivel de arranque.
Modificar el nivel de arranque desde la consola implica la ejecución del comando init, o del comando telinit que es un enlace simbólico a init y que se mantiene por compatibilidad.
Para cambiar al nivel de arranque 3 ejecutaríamos:
# init 3
El sistema mostraría mensajes indicando el nivel de arranque que se está dejando y en el que se está entrando.
Para hacer un reinicio mediante cambios de nivel de arranque ejecutaríamos:
# init 6
Los directorios de niveles de arranque
Ubuntu utiliza los siguientes directorios para gestionar los niveles de arranque:
Ubuntu /etc/ |-- init.d |-- rc0.d |-- rc1.d |-- rc2.d |-- rc3.d |-- rc4.d |-- rc5.d |-- rc6.d `-- rcS.d
El directorio init.d contiene todos los ejecutables de los servicios y demonios. Estos son enlazados desde los directorios de los niveles de arranque de dos maneras; de inicio o de parada.
- Los enlaces de inicio (Start) tienen el aspecto S24pcmcia, donde la S mayúscula hace que el servicio reciba señal de inicio (start), los números fijan un orden de ejecución, y el nombre del servicio es la última parte del enlace.
- Los enlaces que indican parada usan la misma convención de nombres con una K mayúscula en lugar de la S. La presencia de dicha K hace que los servicios se ejecuten con señal stop para que de forma ordenada se detengan.
Ejemplo de contenido de /etc/rc2.d. Nivel de arranque 2:
ls -l /etc/rc2.d/ total 4 -rw-r--r-- 1 root root 556 2009-03-31 10:02 README lrwxrwxrwx 1 root root 19 2009-08-06 21:50 S01policykit -> ../init.d/policykit lrwxrwxrwx 1 root root 15 2009-08-06 21:50 S10acpid -> ../init.d/acpid lrwxrwxrwx 1 root root 14 2009-08-06 21:50 S10apmd -> ../init.d/apmd lrwxrwxrwx 1 root root 18 2009-08-06 21:50 S10sysklogd -> ../init.d/sysklogd lrwxrwxrwx 1 root root 15 2009-08-06 21:50 S11klogd -> ../init.d/klogd lrwxrwxrwx 1 root root 14 2009-08-06 21:50 S12dbus -> ../init.d/dbus lrwxrwxrwx 1 root root 13 2009-08-05 21:47 S16ssh -> ../init.d/ssh ...
Ejemplo de contenido de /etc/rc6.d. Nivel de arranque 6 de reinicio:
$ ls -l /etc/rc6.d/ total 4 lrwxrwxrwx 1 root root 13 2009-08-06 21:50 K01gdm -> ../init.d/gdm lrwxrwxrwx 1 root root 17 2009-08-06 21:50 K02usplash -> ../init.d/usplash lrwxrwxrwx 1 root root 17 2009-09-20 17:09 K09apache2 -> ../init.d/apache2 lrwxrwxrwx 1 root root 16 2009-08-06 21:50 K20apport -> ../init.d/apport lrwxrwxrwx 1 root root 23 2009-09-27 13:01 K20apt-cacher-ng -> ../init.d/apt-cacher-ng lrwxrwxrwx 1 root root 17 2009-09-18 16:03 K20vboxdrv -> ../init.d/vboxdrv lrwxrwxrwx 1 root root 24 2009-09-18 10:29 K20virtualbox-ose -> ../init.d/virtualbox-ose lrwxrwxrwx 1 root root 36 2009-09-18 10:30 K20virtualbox-ose-guest-utils -> ../init.d/virtualbox-ose-guest-utils lrwxrwxrwx 1 root root 17 2009-09-23 12:31 K20winbind -> ../init.d/winbind lrwxrwxrwx 1 root root 24 2009-09-23 15:12 K21postgresql-8.3 -> ../init.d/postgresql-8.3 lrwxrwxrwx 1 root root 20 2009-08-06 21:50 K25hwclock.sh -> ../init.d/hwclock.sh lrwxrwxrwx 1 root root 20 2009-08-06 21:50 K50alsa-utils -> ../init.d/alsa-utils lrwxrwxrwx 1 root root 26 2009-08-06 21:50 K63mountoverflowtmp -> ../init.d/mountoverflowtmp lrwxrwxrwx 1 root root 19 2009-08-06 21:50 K74bluetooth -> ../init.d/bluetooth lrwxrwxrwx 1 root root 21 2009-08-06 21:50 K99laptop-mode -> ../init.d/laptop-mode -rw-r--r-- 1 root root 351 2009-03-31 10:01 README lrwxrwxrwx 1 root root 41 2009-08-06 21:50 S01linux-restricted-modules-common -> ../init.d/linux-restricted-modules-common lrwxrwxrwx 1 root root 22 2009-08-06 21:50 S15wpa-ifupdown -> ../init.d/wpa-ifupdown lrwxrwxrwx 1 root root 18 2009-08-06 21:50 S20sendsigs -> ../init.d/sendsigs lrwxrwxrwx 1 root root 17 2009-08-06 21:50 S30urandom -> ../init.d/urandom lrwxrwxrwx 1 root root 22 2009-08-06 21:50 S31umountnfs.sh -> ../init.d/umountnfs.sh lrwxrwxrwx 1 root root 20 2009-08-06 21:50 S35networking -> ../init.d/networking lrwxrwxrwx 1 root root 18 2009-08-06 21:50 S40umountfs -> ../init.d/umountfs lrwxrwxrwx 1 root root 20 2009-08-06 21:50 S60umountroot -> ../init.d/umountroot lrwxrwxrwx 1 root root 16 2009-08-06 21:50 S90reboot -> ../init.d/reboot
Configurando los niveles de arranque
Para alterar la configuración de los scripts de inicio y parada de los diferentes niveles de arranque en Ubuntu desde la línea de comandos utilizamos update-rc.d.
La ventaja de usar este script es que se encargará de añadir y eliminar los enlaces requeridos a /etc/init.d de forma automática.
Si queremos ver en que niveles se inicia y detiene el servidor web apache2 lo podemos hacer ejecutando:
# ls -l /etc/rc?.d/*apache2 lrwxrwxrwx 1 root root 17 2007-07-05 22:51 /etc/rc0.d/K91apache2 -> ../init.d/apache2 lrwxrwxrwx 1 root root 17 2007-07-05 22:51 /etc/rc1.d/K91apache2 -> ../init.d/apache2 lrwxrwxrwx 1 root root 17 2007-07-05 22:51 /etc/rc2.d/S91apache2 -> ../init.d/apache2 lrwxrwxrwx 1 root root 17 2007-07-05 22:51 /etc/rc3.d/S91apache2 -> ../init.d/apache2 lrwxrwxrwx 1 root root 17 2007-07-05 22:51 /etc/rc4.d/S91apache2 -> ../init.d/apache2 lrwxrwxrwx 1 root root 17 2007-07-05 22:51 /etc/rc5.d/S91apache2 -> ../init.d/apache2 lrwxrwxrwx 1 root root 17 2007-07-05 22:51 /etc/rc6.d/K91apache2 -> ../init.d/apache2
Como podemos ver tenemos una K al comienzo del enlace para los niveles de arranque 0, 1, 6 (apagado, monousuario y reinicio) y para los niveles 2, 3, 4 y 5 (niveles multiusuario en Debian Ubuntu) los enlaces empiezan por S que como hemos visto provocan que init les envíe una señal de inicio (start).
Eliminando un servicio
Si quisieramos deshabilitar apache2 completamente a mano tendríamos que borrar cada enlace contenido en /etc/rcX.d/. Utilizando update-rc.d es tan simple como:
# update-rc.d -f apache2 remove
La opción -f fuerza la eliminación de los enlaces simbólicos aunque exista /etc/init.d/apache2.
Añadiendo un servicio
Si queremos que un servicio se inicie al arrancar podemos ejecutar:
# update-rc.d apache2 defaults Adding system startup for /etc/init.d/apache2 ... /etc/rc0.d/K20apache2 -> ../init.d/apache2 /etc/rc1.d/K20apache2 -> ../init.d/apache2 /etc/rc6.d/K20apache2 -> ../init.d/apache2 /etc/rc2.d/S20apache2 -> ../init.d/apache2 /etc/rc3.d/S20apache2 -> ../init.d/apache2 /etc/rc4.d/S20apache2 -> ../init.d/apache2 /etc/rc5.d/S20apache2 -> ../init.d/apache2
defaults aplica las opciones por defecto del servicio. Se inicia en los niveles de arranque 2, 3, 4 y 5 y se detiene en 0, 1 y 6 con orden 20.
Estableciendo prioridades
Como podemos ver en el caso anterior, la prioridad por defecto vale 20 que puede no servirnos si el servicio depende de otros que se lanzan con prioridad menor. Si queremos ponerle de orden de prioridad 91:
# update-rc.d apache2 defaults 91 Adding system startup for /etc/init.d/apache2 ... /etc/rc0.d/K91apache2 -> ../init.d/apache2 /etc/rc1.d/K91apache2 -> ../init.d/apache2 /etc/rc6.d/K91apache2 -> ../init.d/apache2 /etc/rc2.d/S91apache2 -> ../init.d/apache2 /etc/rc3.d/S91apache2 -> ../init.d/apache2 /etc/rc4.d/S91apache2 -> ../init.d/apache2 /etc/rc5.d/S91apache2 -> ../init.d/apache2
Diferentes prioridades de inicio y parada
Si queremos establecer diferentes prioridades de inicio y de parada, por ejemplo 20 de inicio y 80 de parada, ejecutaríamos:
# update-rc.d apache2 defaults 20 80 Adding system startup for /etc/init.d/apache2 ... /etc/rc0.d/K80apache2 -> ../init.d/apache2 /etc/rc1.d/K80apache2 -> ../init.d/apache2 /etc/rc6.d/K80apache2 -> ../init.d/apache2 /etc/rc2.d/S20apache2 -> ../init.d/apache2 /etc/rc3.d/S20apache2 -> ../init.d/apache2 /etc/rc4.d/S20apache2 -> ../init.d/apache2 /etc/rc5.d/S20apache2 -> ../init.d/apache2
El sistema de arranque Upstart
Como hemos visto, El demonio init actual (primer proceso del sistema y padre de todos los procesos)se basa en el del UNIX System V, por lo que se le conoce como sysvinit. Los sistemas operativos que siguen este esquema clasifican las tareas en diferentes “run levels” o niveles de ejecución, y se lanzaran una serie de servicios y demonios dependiendo del nivel de ejecución (o arranque) que hayamos seleccionado.
Ejecutar una serie fijada de scripts, uno tras otro, en un determinado orden ha funcionado razonablemente bien hasta ahora. No obstante, conforme Linux ha ido mejorando y adáptandose a los sistemas modernos (posiblemente el manejo de dispositivos desmontables es mejor en Linux que en Windows) este enfoque ha empezado a plantear problemas.
La antigua solución sólo funciona si garantizamos que en determinados instantes de la secuencia de arranque están disponibles ciertos recursos, por ello para que los scripts de init funcionen se deben ejecutar en puntos concretos de dicha secuencia. Normalmente se ordenan teniendo en cuenta que:
- Los discos duros deben haberse encontrado, iniciado y haber detectado sus particiones antes de que intentemos montarlas desde /etc/fstab.
- Los dispositivos de red deben haberse detectado e iniciado antes de que activemos los servicios de red.
Esto funcionaba hace diez años, ¿por qué ahora no? La respuesta breve es que nuestras computadoras se han vuelto mucho más flexibles:
- Los dispositivos pueden enchufarse y desenchufarse en cualquier momento, e.g. dispositivos USB.
- Los buses de almacenamiento aceptan un número variable de dispositivos, por lo que hay que explorar el bus. Esta operación no debe ser bloqueante.
- Para reducir el consumo eléctrico, las unidades de disco duro pueden dejar de girar hasta que se explore el bus, por lo que tardarán un tiempo mayor en aparecer.
- Los dispositivos de red pueden enchufarse y desenchufarse en cualquier instante.
Hasta ahora se ha podido hackear el sistema para que gran parte de esto sea posible, pero ya era hora de diseñar un sistema nuevo que pudiera enfrentarse a todas estas situaciones sin problemas.
Necesitábamos un sistema init que pudiera reordenar dinámicamente la secuencia de inicio basándose en la configuración y el hardware disponible en cada situación.
Diseño de upstart
Upstart es un demonio controlado por eventos. Los eventos generados por el sistema pueden iniciar una tarea y parar las que ya se están ejecutando. Los eventos pueden ser diversos, pueden ser cosas como:
- Se ha iniciado el sistema
- Se ha montado el sistema de ficheros raíz
- Se ha montado un sistema de archivos
- En un cierto momento o cada cierto tiempo
- Se ha detectado un dispositivo de red.
- etc.
De hecho, cualquier proceso del sistema puede enviar eventos a init, por lo que no hay límite en los eventos posibles.
Tal y como se ha dicho, los eventos generados por el demonio init o enviados por otros procesos a init, pueden provocar que las tareas se inicien o detengan. También pueden recibirse peticiones manuales para iniciar o parar una tarea.
¿Qué pasa con la compatibilidad?
Hay muchos administradores de sistemas que ya están acostumbrados al funcionamiento de Linux y no querrán aprender otra vez de nuevo. También hay una ingente cantidad de libros sobre el software actual y no se ocuparán de upstart hasta dentro de unos años.
Por este motivo, la compatibilidad es muy importante. Upstart continuará ejecutando los scripts del anterior sistema de arranque SysVinit, y seguira leyendo anteriores archivos de configuración como /etc/inittab
en el futuro cercano, de manera que los paquetes no tendrán que actualizarse hasta que sus autores lo estimen oportuno.
Configuración de Upstart
Upstart ya se ha empezado a implementar en Ubuntu y Redhat y Debian tiene planes de incorporarlo en la próxima versión estable.
Si en el arranque SysV init se configura en /etc/inittab, upstart se configura en una serie de ficheros incluidos en la carpeta /etc/init:
$ ls /etc/init acpid.conf hwclock.conf network-manager.conf tty3.conf alsa-mixer-save.conf hwclock-save.conf nmbd.conf tty4.conf anacron.conf irqbalance.conf plymouth.conf tty5.conf apport.conf module-init-tools.conf plymouth-log.conf tty6.conf atd.conf mountall.conf plymouth-splash.conf udev.conf avahi-daemon.conf mountall-net.conf plymouth-stop.conf udev-finish.conf console-setup.conf mountall-reboot.conf procps.conf udevmonitor.conf control-alt-delete.conf mountall-shell.conf rc.conf udevtrigger.conf cron.conf mounted-dev.conf rcS.conf ufw.conf cups.conf mounted-tmp.conf rc-sysinit.conf upstart-udev-bridge.conf dbus.conf mounted-varrun.conf rsyslog.conf ureadahead.conf dmesg.conf mysql.conf screen-cleanup.conf ureadahead-other.conf failsafe-x.conf networking.conf smbd.conf gdm.conf network-interface.conf tty1.conf hostname.conf network-interface-security.conf tty2.conf
Por compatibilidad los servicios de Upstart se siguen enlazando en /etc/init.d para poder invocarlos de la manera tradicional. Para averiguar que servicios de los que aparecen en /etc/init.d ya han sido adaptados a Upstart podemos hacer listando el contenido de dicha carpeta y buscando aquellos que son enlaces simbólicos al archivo /lib/init/upstart-job
$ ls -l /etc/init.d | grep upstart-job lrwxrwxrwx 1 root root 21 2011-12-08 18:27 acpid -> /lib/init/upstart-job lrwxrwxrwx 1 root root 21 2011-10-11 08:28 alsa-restore -> /lib/init/upstart-job lrwxrwxrwx 1 root root 21 2011-10-11 08:28 alsa-store -> /lib/init/upstart-job lrwxrwxrwx 1 root root 21 2011-10-29 18:13 anacron -> /lib/init/upstart-job lrwxrwxrwx 1 root root 21 2011-10-25 06:28 apport -> /lib/init/upstart-job lrwxrwxrwx 1 root root 21 2011-10-29 18:13 atd -> /lib/init/upstart-job lrwxrwxrwx 1 root root 21 2011-10-29 18:13 avahi-daemon -> /lib/init/upstart-job lrwxrwxrwx 1 root root 21 2011-10-29 18:13 binfmt-support -> /lib/init/upstart-job lrwxrwxrwx 1 root root 21 2011-10-29 18:13 console-setup -> /lib/init/upstart-job lrwxrwxrwx 1 root root 21 2011-10-29 18:13 cron -> /lib/init/upstart-job lrwxrwxrwx 1 root root 21 2011-12-05 06:25 cups -> /lib/init/upstart-job lrwxrwxrwx 1 root root 21 2011-10-29 18:13 dbus -> /lib/init/upstart-job lrwxrwxrwx 1 root root 21 2011-10-29 18:13 dmesg -> /lib/init/upstart-job lrwxrwxrwx 1 root root 21 2011-10-29 18:13 friendly-recovery -> /lib/init/upstart-job lrwxrwxrwx 1 root root 21 2011-09-23 23:33 gdm -> /lib/init/upstart-job lrwxrwxrwx 1 root root 21 2011-10-29 18:13 hostname -> /lib/init/upstart-job lrwxrwxrwx 1 root root 21 2011-10-29 18:13 hwclock -> /lib/init/upstart-job lrwxrwxrwx 1 root root 21 2011-10-29 18:13 hwclock-save -> /lib/init/upstart-job lrwxrwxrwx 1 root root 21 2011-10-29 18:13 irqbalance -> /lib/init/upstart-job lrwxrwxrwx 1 root root 21 2012-03-05 01:33 lightdm -> /lib/init/upstart-job lrwxrwxrwx 1 root root 21 2011-10-07 00:57 lxdm -> /lib/init/upstart-job ... lrwxrwxrwx 1 root root 21 2012-01-09 17:15 udev -> /lib/init/upstart-job lrwxrwxrwx 1 root root 21 2012-01-09 17:15 udev-fallback-graphics -> /lib/init/upstart-job lrwxrwxrwx 1 root root 21 2012-01-09 17:15 udev-finish -> /lib/init/upstart-job lrwxrwxrwx 1 root root 21 2012-01-09 17:15 udevmonitor -> /lib/init/upstart-job lrwxrwxrwx 1 root root 21 2012-01-09 17:15 udevtrigger -> /lib/init/upstart-job lrwxrwxrwx 1 root root 21 2011-10-29 18:13 ufw -> /lib/init/upstart-job
Arranque y parada manual de servicios
Servicios Upstart
Los servicios que ya funcionan con el sistema Upstart se gestionan manualmente con los comandos:
- start: para iniciar un servicio.
- stop: para detener un servicio.
- status: para comprobar su estado actual.
- restart para reiniciar el servicio
Los servicios que han sido adaptados al nuevo sistema de arranque, como vimos, tienen su configuración en /etc/init
$ ls /etc/init acpid.conf networking.conf alsa-restore.conf network-interface.conf alsa-store.conf network-interface-security.conf anacron.conf network-manager.conf apport.conf nmbd.conf atd.conf plymouth.conf avahi-daemon.conf plymouth-log.conf binfmt-support.conf plymouth-splash.conf console-setup.conf plymouth-stop.conf control-alt-delete.conf plymouth-upstart-bridge.conf cron.conf procps.conf cups.conf rc.conf dbus.conf rcS.conf dmesg.conf rc-sysinit.conf failsafe.conf rsyslog.conf friendly-recovery.conf setvtrgb.conf gdm.conf smbd.conf hostname.conf ssh.conf ...
Ejemplos
Para ver el estado actual de un servicio (en este caso ssh):
$ sudo status ssh ssh start/running, process 1016
Nos indica que el servicio ssh está arrancado y en ejecución. Nos informa además de su PID
Para detener un servicio:
$ sudo stop ssh ssh stop/waiting
El servicio es detenido y queda a la espera de recibir otros eventos,
Para iniciar un servicio:
$ sudo start ssh ssh start/running, process 3258
Para reiniciar un servicio lo podemos hacer mediante:
$ sudo restart ssh ssh start/running, process 3264
Servicios SysV
Hay servicios que todavía no han sido adaptados al nuevo sistema de arranque upstart y que se gestionan mediante el anterior sistema de arranque SysV. Para gestionar manualmente dichos servicios lo hacemos de la forma:
$ sudo /etc/init.d/[servicio] start|stop|restart|status
- servicio es el nombre del servicio a gestionar.
- start|stop|restart|status son las señales que podemos enviar a los servicios.
Si ejecutamos el script del servicio sin especificarle ninguna señal nos suele informar de todas las señales que le podemos enviar. Estas pueden variar de un servicio a otro.
Ejemplos
Si queremos enviar diferentes tipos de señales al servicio web apache2 lo podemos hacer de la forma:
$ sudo /etc/init.d/apache2 status Apache2 is running (pid 3306).
Permite ver el estado actual del servicio.
$ sudo /etc/init.d/apache2 stop * Stopping web server apache2 ... waiting [ OK ]
Para detener el servicio.
$ sudo /etc/init.d/apache2 start * Starting web server apache2 [ OK ]
Para iniciarlo
$ sudo /etc/init.d/apache2 restart * Restarting web server apache2 [ OK ]
Para reiniciarlo.
Si queremos ver que señales se le pueden enviar a apache2 invocamos el script de inicio sin ninguna señal:
$ sudo /etc/init.d/apache2 * Usage: /etc/init.d/apache2 {start|stop|graceful-stop|restart|reload|force-reload|start-htcacheclean|stop-htcacheclean|status}
Compatibilidad hacia atrás
Por compatibilidad, los servicios que han sido adaptados al nuevo sistema de arranque upstart pueden ser gestionados usando el sistema SysV, pero aperece entonces un mensaje de advertencia.
Por ejemplo, si queremos reiniciar el servicio cron, podemos usar el mecanismo de SysV Init:
$ sudo /etc/init.d/cron restart Rather than invoking init scripts through /etc/init.d, use the service(8) utility, e.g. service cron restart Since the script you are attempting to invoke has been converted to an Upstart job, you may also use the stop(8) and then start(8) utilities, e.g. stop cron ; start cron. The restart(8) utility is also available. cron stop/waiting cron start/running, process 3468
Como vemos, reinicia el servicio, pero nos informa que podemos usar directamente el mecanismo provisto por Upstart:
$ sudo restart cron