Justo cuando parecía seguro que upstart era el futuro, cuando
todas las distribuciones lo habían integrado o planeaban hacerlo,
ocurre lo que tantas veces en el mundo linuxero: Sale alguien
implementado algo totalmente diferente porque no termina de gustarle la
nueva propuesta. Estas cosas sin duda son una enorme pérdida tiempo en
muchos casos, pero también una gran fuente de creatividad. Ese es el caso de systemd, el nuevo juguete de Lennart Poettering (tambien creador del magnífico Pulseaudio).
Pero antes, algo sobre upstart. En lugar de usar
dependencias de unos archivos a otros, como hicieron
varias intentonas de paralelización del sistema tradicional sysvinit,
las dependencias son en base a eventos. Por ejemplo, al iniciarse el
sistema upstart genera el evento "startup". A continuación, upstart interpreta todos los archivos de eventos (trabajos, en jerga upstart)
de /etc/event.d que tengan la dependencia "start on startup". El
trabajo puede ejecutar un script, un comando, o emitir un evento ("emit
mi-propio-evento"). En este último caso, upstart ejecutaría
todos los trabajos que tengan un "start on mi-propio-evento". Tambien
hay eventos específicos para interfaces de red, etc.
Poettering ha aplicado otro punto de vista al problema. Prescinde de
las dependencias y la sincronización la relega a mecanismos sistémicos
de bajo nivel. Bajo systemd
todos los servicios del sistema podrían arrancarse a la vez, sin
preocuparse de que tal servicio depende de otro. Por ejemplo, podría
arrancarse X.org antes que D-Bus (que X.org necesita para pedir a udev
la lista de dispositivos de entrada). Esto, claro está, causaría un
fallo en el inicio de X.org, las dependencias de upstart existen, precisamente, para prevenir este problema. ¿Y qué hace systemd para evitar el fallo de X.org?
El truco utilizado es el mismo que utiliza inetd o el launchd de Mac OS X. Buena parte de las dependencias de sysvinit o de upstart
están para que un servicio (ej, X.org) espere a que otro servicio
arranque y cree un socket Unix (ej, el socket de D-Bus) para poder
comunicarse con él. Bien, pues resulta que esos sockets pueden crearse
antes de que los servicios (D-Bus en este caso) arranquen. systemd,
mismamente, puede crearlos -pero sin "escuchar" lo que se envía a
ellos-, y las aplicaciones (X.org) pueden conectarse e incluso escribir
a ese socket, porque el kernel va guardando en un buffer todo, a espera
de que alguien se decida a leerlo. Solo cuando esto sucede, systemd
decide iniciar el servicio (D-Bus), que una vez finalizado su arranque
se pone al día leyendo los buffers acumulados. Esto implica que las
dependencias no son necesarias, systemd crearía todos los
sockets de todos los servicios pero sin iniciar ninguno inicialmente,
solo los arrancaría a medida que los clientes los intentan utilizar.
Hay una gran ventaja de este sistema sobre upstart, derivado de la ausencia de dependencias. Si en upstart hay,
por ejemplo, varios servicios que tienen la línea "start on dbus", al
iniciar D-Bus se iniciarán esos servicios (X.org, avahi,
networkmanager, vaya usted a saber). Esto ocurre incluso si no era esa
la intención del administrador. Con systemd esta situación no
es posible. Simplemente se iniciaría X.org, o Networkmanager, o avahi,
y D-Bus sería iniciado automáticamente sólo cuando alguien intente leer
su socket.
Aun con todo lo hasta aquí descrito, systemd no sería más que una reimplementación del launchd
de Mac OS X. Sin embargo, no se queda ahí. Poettering identifica otro
"punto de contención" en el inicio: los montajes en el sistema de
archivos. Ciertos servicios tienen que esperar a que ciertos puntos de
montaje estén disponibles antes de iniciarse. Además, al iniciar el
sistema hay que montar -y quizás fsck'ear- los sistemas de archivo que
indique /etc/fstab (y mientras se hace esta tarea quizás se pierde la
oportunidad de iniciar algunos scripts que tienen sus puntos de montaje
ya montados). systemd se basa en el viejo y fiable autofs (un
"montador automático") para aplicar la misma idea que en los sockets:
todos los montajes posibles se pre-crean sin que esté montados
realmente, y autofs los irá montando de verdad -y quizás fsckeando- a
medida que los servicios intenten acceder a ellos, pero no antes. Con
este sistema, systemd hace que /etc/fstab sea algo obsoleto o al menos prescindible.
Todo esto ya de por si hace de systemd una seria alternativa a upstart y una mejora respecto a otros sistemas de inicio.
Sin embargo, un sistema de inicio debe hacer más cosas que gestionar lo
descrito anteriormente. Debe intentar reiniciar un servicio si se cae,
o apagarle y enviar una alerta al administrador si se cae demasiado.
Para hacer bien esta tarea de niñera, el sistema de inicio debe tener
conocimiento de lo que hacen todos los procesos hijos que los servicios
crean, algo que no es sencillo en Unix (upstart lo logra
analizando datos de /proc), ya que los procesos "nietos" del sistema de
inicio pueden perderse y existir a su aire sin que su "abuelo" se
entere de qué ocurre.
Para solucionarlo Poettering usa, en vez de los trucos que utilizan
otros sistemas, una de las novedades más potentes y menos conocidas de
los últimos kernels: "Control Groups" (cgroups). cgroups son "grupos de
procesos" elegidos al azar, y que comparten, como grupo, una serie de
características. Los hijos de un proceso de un cgroup heredan la
pertenencia a ese cgroup. Esto permite a systemd
gestionar a nietos y biznietos con seguridad. Pero tengamos en cuenta
que las propiedades configurables de los cgroups pueden ser cosas como
límites de CPU, de memoria, de prioridad de disco...pues systemd
tambien permite, ya de paso, que los servicios puedan configurar todas
esas características. Por ejemplo, updatedb puede configurarse para
usar una prioridad de disco baja.
Hay mucho más que decir de este sistema: los tipos de archivos de configuración, o units, una UI para visualizar los servicios -escrita en Vala-, planes de una unit timer que sustituiría a cron, una unit swap,
potencial reemplazo al menos de parte de la funcionalidad de los
gestores de sesion de los escritorios (gnome-session/kdeinit), etc. Y
varias funcionalidades avanzadas (por ejemplo, guardar el estado de los
servicios en un momento dado, apagarlos todos, ir a un shell de
emergencia, y regresar al estado anterior). El documento del proyecto es una lectura muy recomendable. Aun así, podemos decir que es, en principio, conceptualmente superior a upstart, y es muy fácil de migrar a él por no ser necesario reescribir scripts y crear nuevas dependencias.
Dado que Poettering trabaja para Red Hat, no será sorprendente que Fedora lo adopte en futuras versiones.