Cómo controlar el runlevel en Linux con systemd

Publicado el 02 enero 2018 por Drassill
La tecnología va evolucionando de forma inexorable con el paso de los años, haciendo que algunos conceptos que se han mantenido intocables con el paso de los años, cambien; cosa inevitable. Esto hace que, nos guste o no, tengamos que adaptarnos a dichos cambios. Uno de los cambios más polémicos que han tenido los entornos de GNU/Linux, es sin lugar a dudas la implantación de systemd, que se ha aplicado a la mayoría de sistemas operativos actuales, con algunas excepciones tales como Devuan. Dicho cambio supone la obligación del aprendizaje de nuevos conceptos, pues aunque en algunos sistemas como Debian o Ubuntu, existen varios enlaces simbólicos para algunas funciones con el fin de que la curva de aprendizaje sea mucho más suave, existen algunas funcionalidades que estamos obligados a aprendernos sí o sí. Uno de dichos conceptos sería el manejo del runlevel del sistema.

Ya se ha hablado de dicho concepto con anterioridad en este blog; pero en dicho caso se trató el concepto con un init de System V; init que ,para bien o para mal, va a tender a desaparecer o perder relevancia progresivamente. En este caso trataremos el el manejo del runlevel, o nivel de ejecución, en un entorno con un init systemd.
Para ello lo primero que tenemos que tener en cuenta es que para hacer referencia a dichos niveles de ejecución, no se hace numéricamente como antes (0, apagado, 1 modo monousuario, etc...), sino que se hace mediante descripciones más técnicas; descripciones a las que luego se hacen referencia mediante enlaces simbólicos, cuyos nombres son parecidos a los usados en System V (runlevel0.target, runlevel1.target...) pero que no dejan de ser enlaces simbólicos, con lo que es mejor tener claros los nombres reales de los niveles de ejecución en systemd. He aquí una pequeña tabla con los runlevels de System V, los nombre "intuitivos" usados en systemd, y los nombres reales utilizados en systemd:
Tabla nombre runlevels
Teniendo claros dichos conceptos, nosotros nos vamos a centrar en los nombres "reales" usados en systemd, sin uso de alias, pues dichos alias puede que en un futuro desaparezcan y es mejor intentar no crear posibles malos hábitos.
Para adivinar el runlevel usado por defecto por el sistema podemos recurrir a la herramienta principal de systemd: systemctl. En concreto habría que recurrir al siguiente comando:
root@debian:~# systemctl get-default
graphicaltarget

Por defecto, lo más común sería que viésemos el resultado mostrado arriba; es decir el runlevel graphical.target; o lo que sería lo mismo, el runlevel5 en System V. Además, si bien lo más común es que coincidan, podemos ver el runlevel actual de diferentes formas:
La primera, y menos recomendada debido a que con el tiempo la obsoletarán, será mediante el comando usado siempre en sistemas system V; es decir mediante el comando runlevel:
root@debian:~# runlevel
5

Otra forma de conocer el runlevel, es mediante systemctl, el cual ofrece un resultado más preciso pero que desgraciadamente no muestra un valor único; veréis, si os fijas bien todos los nombres acaban en "target", y es debido a que ahora muchos conceptos son denominados así, con lo que si listamos todos los targets cargados por el sistema, tendremos que ver entre dicho listado nuestro runlevel actual; el problema es que si bien la información es fidedigna, requiere o bien poner muchos greps para mostrar únicamente una línea, o fijarse entre las líneas mostradas en aquella que hace referencia al runlevel; he aquí el comando y el resultado mostrado por este:
systemctl list-units --type target |grep loaded


Teniendo en mano la información deseada, ahora podemos proceder a cambiar el runlevel, cambio que se puede hacer de dos formas diferentes.
El primero y el más "sólido" sería cambiando el runlevel por defecto usado por el sistema. Esto haría que a partir del siguiente reinicio siempre se usase dicho runlevel; lo cual en algunos casos puede ser útil aunque habría que ser muy cuidadoso, ya que en dicho caso nunca podríamos usar los "targets" poweroff.target ni reboot.target, pues en caso contrario no podríamos arrancar con normalidad a menos que editasemos el runlevel en el propio GRUB para dicho arranque en cuestión. Dicho cambio se haría mediante el comando systemctl tal que así:
systemctl set-default nombre_target
Por ejemplo:
systemctl set-default rescuetarget

Esta acción cambiará el runlevel que cargaremos por defecto y si nos fijamos bien veremos que en realidad lo que realiza es un enlace simbólico desde /lib/systemd/system/nombre_target/etc/systemd/system/default.target, con lo que en caso de no sentirnos cómodos usando la herramienta systemctl, podemos optar por cambiar el runlevel por defecto de la siguiente forma:
rm /etc/systemd/system/default.target
ln -s /lib/systemd/system/rescue.target \
/etc/systemd/system/default.target

Si en cambio quisiésemos cambiar el runlevel del sistema únicamente para la sesión actual, habría que optar por otro comando de systemctl; en concreto sería:

systemctl isolate nombre_target
Por ejemplo:
systemctl isolate rescuetarget

Como veis, la manipulación del runlevel mantiene las mismas bases que en system V, con la diferencia de que se usan herramientas y nomenclaturas distintas; lo más importante dentro de los runlevels de systemd no sería el conocimiento de la herramienta de systemctl, sino la comprensión de las nuevas nomenclaturas de éstos, nomenclaturas que ahora sería "targets" y que estarían estrechamente ligadas a la definición de cada nivel de ejecución.
Espero que os haya resultado útil.
Saludos.