LPIC-1 101.2: SysV vs systemd
Continuo con la segunda parte de LPIC-1 Tema 101.2. Una vez visto el proceso de arranque bajo GNU/Linux en sistemas con BIOS y UEFI, ahora pasamos a describir los sistemas de gestión de servicios. De todas formas, volveré a estos sistemas más adelante con el tema 101.3, donde se estudia los runleves (o targets para systemd), ejemplos sobre los scripts de inicio, el uso del comando systemctl, etc.
Por el momento, solo conocer qué es SysV y systemd, las diferencias que existen entre ambos, y algunos comandos de consulta para los logs (registros) del sistema como dmesg, journalctl, etc., para conocer información o eventos que hayan ocurrido durante el arranque.
Si recuerdas la primera parte de LPIC-1 Tema 101.2, el primer proceso PID=1 que se generaba durante el arranque podría corresponderse con init o sysvinit en los UNIX clásicos u originales. En GNU/Linux se adoptó System V o SysV como sistema por defecto, aunque algunas distros como Gentoo tenían su propio sistema o Slackware adoptaba un esquema estilo BSD. Otras como Ubuntu de Canonical también adoptaron por upstart, etc.
Pero los dos principales y que son necesarios conocer para LPIC son SysV y systemd… Las principales distribuciones actuales usan systemd, como Ubuntu, Arch Linux, CentOS, Red Hat, Debian, openSUSE, Mandriva, SUSE, Fedora, etc. En cambio, otras se han opuesto como Devuan (Debian con SysV), Gentoo, Puppy Linux, etc. No obstante, podrías usar cualquier sistema en la distribución que elijas aunque carezcan de soporte oficial…
Los sistemas de gestión de servicios alternativos a SysV y systemd son:
- Upstart: reemplazo a init escrito en C y creado por Scott James Remmat (trabajador de Canonical en aquella época). Sigue manteniendo un esquema muy similar al clásico, de hecho tiene retrocompatibilidad con sysvinit, solo que con algunos cambios para adaptarlo a los nuevos SSOO.
- OpenRC: creado para FreeBSD y NetBSD, también lo usa Gentoo. Básicamente es un init con mayor portabilidad y no dependiente de D-bus. En muchos aspectos es compatible con SysV, en otros se parece al BSD-style.
- GNU dmd (Sheperd): surgió como un reemplazo para SysV init, pero no es demasiado popular.
- BootScrips: un proyecto usado en GoboLinux. Simplifica mucho la configuración.
- Busybox-init: esquema creado bajo BusyBox iniciado por Bruce Perens. También resulta muy minimalista como el anterior. Se usa en OpenWrt y otros embebdios.
- initg: otro proyecto como reemplazo a init clásico para iniciar proceso de forma asíncrona, aunque no muy popular.
- Runit: capaz de iniciar servicios de forma paralela y escrito por Gerrit Pape. Compatible con Linux, BSD, MacOS y Solaris. Usado por defecto en Void Linux.
¿Cuál es tu sistema? ¿Cuál es tu PID=1? Te invito a que ejecutes la siguiente orden para ver de qué proceso cuelga el resto de procesos en ejecución:
pstree
SysV init
El clásico SysV dispone de un init que encontrarás en /etc, aunque también en /bin y /sbin. Todo lo que hace init se controla a través de /etc/inittab. Si dispones de una distro con SysV, te recomiendo que veas el contenido:
cat /etc/inittab
También puedes comprobar que los scripts o procesos a ejecutar durante el arranque se guardan en ficheros rc. En algunas distros varían su localización, usando enlaces simbólicos para /etc/init.d. Por ejemplo, en openSUSE están en /etc/init.d/rc y en Debian en /etc/rc-.d.
Dentro hay ficheros tipo /etc/rc.d/rcN.d, siendo N el nivel de ejecución correspondiente. Por ejemplo rc1.d contendrá la secuencia de comandos o script a ejecutar cuando se arranca en el nivel de ejecución 1. También encontrarás ficheros tipo Snnservicio y Knnservicio. En este caso, nn será un número del 00 al 99 y servicio el nombre del servicio correspondiente.
Los primero en ejecutarse son los que comienzan por K (Kill), que cierran o matan servicios para luego dar paso al inicio de servicios mediante los que comienzan por S (Start). Por ejemplo, K85syslog cierra el demonio de inicio de sesión del sistema y S11network inicia el servicio de red. En cuanto al número, te recomiendo que mires el manual, ya que hay distros donde el número de inicio y parada de un servicio siempre debe sumar 99 o no funcionará. Por ejemplo, K85apache y S14apache (85+14=99).
Como puede variar en cada distro, te recomiendo ir buscando los ficheros y directorios que cito mientras lees el artículo…
Otros ficheros interesantes son /etc/init.d/boot.local y /etc/init.d/halt.local. En ellos podrás agregar comandos para ejecutar al inicio y al apagar el sistema respectivamente. Incluso puedes usar herramientas como update-rc.d (para Debian y derivados) y chkconfig (SUSE, Red Hat y derivados).
man chkconfig man update-rc.d
Por ejemplo, para habilitar el servicio nscd para los runlevels 1 y 4 puedes usar, así como descactivarlo para 3, 5 y 6, y finalmente comprobar el estado del servicio:
chkconfig --level 14 nscd on chkconfig --level 357 nscd off chkconfig --list nscd
Ejemplos con update-rc.d para eliminar Squid del arranque, iniciar el servicio SSH para los niveles 2345 y pararlo para los 016, y especificar los niveles para los que XDM tiene que iniciarse (2,5) o pararse (0,1,4,6) respectivamente:
update-rc.d -f squid remove update-rc.d ssh defaults update-rc.d xdm start 20 2 5 . stop 20 0 1 4 6
En mi curso he reordenado todos los temas de LPIC porque, para mi gusto, no siguen un orden demasiado bueno. Por ejemplo, los runlevels y targets se ven en LPIC-1 Tema 101.3, mientras que estaría bien haberlos visto antes para entender mejor estos ejemplos… No obstante, en el blog voy a respetar el orden de LPI.
Otras distros también usan la herramienta service, que es bastante practica. Por ejemplo, puedes parar el servicio SSH, volverlo a poner en marcha y obtener información con:
service sshd stop service sshd start service sshd status
Estas herramientas serían equivalentes usar la ruta completa del servicio al que quieres manipular, por ejemplo:
/etc/init.d/apache stop /etc/init.d/apache start /etc/init.d/apache status
Con Upstart, la mayor parte de lo que hemos comentado serviría, pero deberías saber qu eno usa /etc/inittab. En cambio, usa /etc/init donde encontrarás los scripts de configuración con nombres tipo /etc/init/<servicio>.conf. Aquí también podrás usar los comandos anteriores, e incluso initctl de forma muy similar:
man initctl
systemd
Este sustituto del tradicional init no ha gustado a muchos, pero se ha impuesto en la mayoría de distros. Algunas de las cosas que no gustan son su mayor complejidad al no respetar la filosofía KISS, que los logs se almacenan en formato binario y eso puede dejarlos corruptos en caso de algún fallo, por lo que no se podrían leer, se entromete en la gestión de energía, cifrado, etc.
En cambio, no todo son desventajas. Y no voy a ser yo el que eche más leña al fuego de esta guerra (elige el que más te guste a ti). A su favor tengo que decir que systemd es eficiente y hace uso de cgroups para evitar procesos zombies. Aunque bien es cierto, que al hacer uso de la API de Linux, ya no es compatible con POSIX y no puede usarse en otros UNIX.
Otra cosa a tener en cuenta con systemd es que se compone de unidades (*.servicies, *.sockets, *.targets…). Son elementos básicos que podrás encontrar en /lib/systemd/system o /usr/lib/systemd/system/. También te recomiendo que eches un vistazo a /etc/systemd/system. Estas variaciones entre una distro y otra pueden ser un incordio, pero no nos queda más que acostumbrarnos. Puedes consultar:
man 7 file-hierarchy man systemd.unit
Más adelante estudiaremos ejemplos de los ficheros, la equivalencia entre runlevels y targets, etc.
Aunque se siguen admitiendo algunos comandos del sistema clásico para conseguir información, o gestionar los servicios, con systemd lo adecuado es usar systemctl:
systemctl start ssh systemctl status ssh systemctl stop ssh systemctl restart ssh systemctl reload ssh systemctl enable ssh systemctl disable ssh systemctl list-unit-files --all systemctl list-units
En estos ejemplos son muy similares a los conseguidos con los mismos parámetros para los comandos clásicos. Es decir, para poner en marcha un servicio, obtener el estado, pararlo, resetear, recargar, habilitar, deshabilitar, y listar las unidades respectivamente.
Consultar eventos sobre el arranque en los registros
La forma en que se consultan los logs o registros del sistema pueden ser diferentes en el caso de tener un sistema basado en SysV y otro con systemd. No obstante, algunos comandos o herramientas pueden valer para ambos y en el caso de systemd, se puede habilitar una opción para que se sigan almacenando como en el sistema clásico. Esto también lo trataré más adelante, ahora simplemente ver algunas opciones para obtener información referente al arranque del sistema.
El comando dmesg muestra mensajes pasados por el kernel, entre ellos los que suceden durante el arranque y que nos pueden servir para detectar algunos errores o problemas que están sucediendo:
dmesg
Puedes filtrar por el nombre de lo que estás intentando buscar con grep o por el nivel del mensaje (error, warning, info, critical, alert,…):
dmesg | grep usb dmesg -l err,warm
Si lo prefieres, puedes consultar los ficheros /var/log/boot.log y /var/log/kern.log. La diferencia de consultar este último fichero y usar dmesg, es que el comando examina el llamado kernel ring buffer, por tanto, solo mostrará los 16392 octetos finales de este fichero desde el último boot.
Ahora bien, aunque esto puede funcionar para systemd, si quieres saber la herramienta específica para analizar los logs de arranque sería:
journalctl -b 0 journalctl -b 1 journalctl --list-boots journalctl -b 05d53c9961a649b78de882d530d5a1dc
Con ellos podrás ver la información almacenada del boot con ID 0 y 1, listar todos los registros de arranque almacenados y finalmente elegir uno de la lista para que muestre información sobre él.
En próximos posts volveremos a estos temas para tratar los runlevels, targets de systemd, journalctl y systemctl…
Pingback: LPIC-1 101.3: runlevels & boot targets | ArchiTecnologia