systemd -como muyahidín- expande su propio orden, su estado, su gran complejidad monumental, haciendo la guerra contra la filosofía Unix. Su inherente naturaleza dominante y viral le convierte en un segundo kernel, que se extiende tentacularmente por todo el ecosistema GNU/Linux, como golpe de estado e intruso que toma el control del sistema, y fuerza al usuario a claudicar ante él.
Tiempo he pasado utilizando distribuciones en base a este malware de Poettering, y cuanto más profundizo y adquiero conocimiento técnico, más detesto la forma en la funciona y está diseñado. Las siguientes palabras, a modo de Syllabus recopilan los que yo considero los errores de systemd, que cada vez se expande más -lo que considero altamente preocupante- en el mundo de GNU/Linux.
-
systemd se enfrenta a la filosofía del «haz una cosa y hazla bien"», representando una colección compleja de docenas de binarios fuertemente acoplados. Sus responsabilidades exceden groseramente las de un sistema de inicio, absorbiendo de forma absolutista el control de energía, manejo de dispositivos, puntos de montaje, cron, cifrado de discos, inetd y api para sockets, syslog, configuración de red, manejo de login y sesiones, readahead, particiones GPT, registro de contenedores, manejo de hostname, locale y tiempo, etcétera.
systemd ni siquiera sabe qué mierda quiere ser. Es referido diversamente como demonio de sistema o un bloque de construcción básico para construir un sistema operativo en espacio usuario, las cuales son definiciones bastante ambiguas. Se deglute funcionalidad que pertenecía anteriormente a util-linux, wireless tools, syslog, y otros proyectos. No tiene una dirección clara más que los caprichos de los desarrolladores. Irónicamente, más allá de que apunta a estandarizar las distribuciones Linux, no tiene un estándar claro en sí mismo, y está perpetuamente liberando versiones.
-
Los archivos de journal de systemd son manipulados por journald son almacenados en un complicado formato binario que debe ser consultado utilizando journalctl. Lo que vuelve los logs de journal potencialmente corruptibles, sin transacciones ACID. El consejo de los desarrolladores de systemd es irracional: ignorar el problema. Además posee integración con un servidor HTTP embebido libmicrohttpd. Y se sirven códigos QR a través de libqrencode. Un caos.
Además, por defecto, systemd guarda los core dumps en el journal, en lugar del filesystem. Los core dumps deben ser explícitamente consultados utilizando coredumpctl. Esto es irracional y crea complicaciones en entornos multiusuario, dado que systemd requiere acceso root para controlarlo.
-
systemd muestra un abierto desprecio hacia el software no-Linux en subsecuente incompatibilidad con todos los sistemas de la familia Unix no-Linux. Esto es debido a que systemd está fuertemente acoplado a la api del kernel Linux, lo que provoca que las diferentes versiones de systemd sean incompatibles entre diferentes versiones del kernel Linux. Se trata de una política aislacionista que esencialmente suelda al ecosistema Linux en su propia jaula, y sirve como obstáculo a la portabilidad del software.
-
udev y dbus son dependencias forzosas. De hecho, udev se fusionó con systemd hace tiempo. La integración del administrador de dispositivos que fue alguna vez parte del kernel Linux no es una decisión que deba tomarse a la ligera. Las implicaciones políticas de ello son altas, y hace que muchos paquetes que dependen de udev, a su vez dependan de systemd (una estrategia maestra para llevar a cabo la yihad), mas allá de la existencia de forks, como eudev. A partir de systemd-209 los desarrolladores ahora tienen su propia, no estándar y escasamente documentada api sd-bus que reemplaza mucho del trabajo de libdbus, y disminuye aún más la transparencia.
-
El tamaño de systemd lo vuelve un punto simple de fallo, un riesgo. Su esencial y prepotente naturaleza lo convertirá en un blanco jugoso, ya que es mucho más pequeño que el kernel Linux en sí mismo, pero prácticamente igual de crítico.
-
system es viral por naturaleza: su alcance en funcionalidad y arrastre como dependencia a cientos de paquetes significa que los mantenedores de distribuciones necesitarán una convertirse a la fe de Lennart Poettering, o quedarán a la deriva. La rápida adopción y conversión por parte de distribuciones como Debian, Archlinux, Ubuntu, Fedora, openSUSE denota una clara lealtad por parte del pueblo.
-
systemd se encierra a sí mismo en el PID 1, por lo que hay toneladas de escenarios en los cuales puede crashear y tumbar al sistema por completo (kernel panic). No sólo eso, a consecuencia, muchas actualizaciones del sistema (obviando el kernel) van a requerir un reinicio. Para ser justo, systemd provee un mecanismo para reserializarse y reejecutarse a sí mismo en tiempo real; pero claro, si esto falla, el sistema cae por completo. Hay muchas formas por las que esto puede ocurrir. Esto es otro ejemplo de SPOF (punto simple de fallo).
Entre las razones por las cuales systemd quiere o necesita correr como PID 1, está el hacerse cargo de los demonios cuyo mal comportamiento hace que se vuelvan huérfanos a sí mismos, impidiendo que su inmediato padre conozca su PID para esperarlo (wait) o enviarle una señal.
-
systemd fue diseñado con glibc en mente, y no se preocupa mucho por soportar otras libcs. En general, la idea de librería C estándar de los desarrolladores de systemd es una que sea compatible bug-por-bug con glibc.
-
La naturaleza complicada de systemd lo vuelve difícil de extender y salir fuera de sus límites. Mientras que es posible más o menos iniciar scripts de forma trivial con archivos, es más difícil implementar un comportamiento que salga de la caja. Muchos usuarios necesitarán posiblemente escribir programas más complicados que directamente interactúen con la api de systemd, o directamente necesitarán parchear systemd. Uno debe preocuparse por una mayor cantidad de caminos de ejecución y comportamiento en un programa crítico del sistema, incluyendo la posibilidad de que systemd no sincronice bien con la cola de mensajes de dbus en tiempo de boot, congelando el sistema. Esto es opuesto al tradicional init, que es determinístico y predecible por naturaleza, dado que mayormente sólo ejecuta scripts.
-
El parasitismo de systemd es el símbolo de algo más sí mismo: muestra un cambio radical de pensamiento en la comunidad Linux, una apostasía y una lealtad a lo vehementemente postmoderno, monolítico, fuertemente orientado a sistemas de escritorio, limitante, aislacionista, reinventor de la rueda, y un gran anti-patrón en general.
Tras este Syllabus errorum complectens praecipuos nostrae aetatis errores, es evidente que desde hace tiempo anhelo liberar mi sistema de systemd, que como bien sabe el lector -o eso espero- ha extendido su oscura influencia en gran parte del mundo GNU/Linux, haciendo difícil experimentar y probar con otros demonios. Aunque tengo un profundo apego y experiencia con Archlinux, debido a su dependencia de systemd, me he visto prácticamente obligado a buscar alternativas libres de éste.
Tras investigar posibles opciones, como Devuan, Alpine, Slackware o void, ha aparecido ante mí Artix, una versión de Archlinux libre de systemd. Esto trae una serie de ventajas para mí, como la fácil adaptación entre Archlinux y Artix, mantenimiento de la comunidad de Archlinux, mantendría el sistema de paquetes pacman, etc.
Sin embargo, esta elección no vendría exenta sufrimiento. Artix me obliga a enfrentar una de las decisiones más complicadas de mi vida técnica en el mundo de GNU/Linux y Unix: elegir el proceso init para mi sistema operativo. Sabía que esto requeriría un arduo trabajo de investigación, reconocimiento y pruebas, pero estaba dispuesto a asumir cualquier reto para alcanzar la libertad. Así, como caballero medieval enfrentando a un dragón, me adentré en la búsqueda del init perfecto. Los nombres de Runit, Dinit, OpenRC y S6 1 resonaban en mi mente como las leyendas de antaño, y estaba dispuesto a poner a prueba cada uno de ellos para encontrar el que más se adaptara a mi uso.
OpenRC es conocido por su simplicidad y estabilidad. Para usuarios venidos de distribuciones como Gentoo parece la opción más obvia. De todos los init fuera de systemd, parece ser el que tiene mejor soporte, es fácil de entender y tiene un comportamiento predecible. Además, permite la ejecución de scripts personalizados durante la fase de inicio.
S6 es muy rápido, simple y eficiente, pero no es particularmente fácil de usar. El uso de recursos es mínimo, cuenta con una arquitectura modular y es muy estable y confiable, lo que le hace un sistema idóneo para sistemas críticos. Sin embargo, su simplicidad proviene del hecho de que es relativamente pequeño y divide la funcionalidad entre diferentes procesos, lo que hace que cualquier cambio en el sistema requiere compilar una base de datos (aunque su enfoque de compilación teórica lo hace más ligero y menos propenso a errores). Está íntimamente ligado al mundo Unix, pareciendo estar diseñado para ser una capa lo más delgada posible sobre el sistema operativo, algo deseable.
Runit es extremadamente simple, especialmente si lo comparamos con el resto. Su estructura sencilla lo hace poco propenso a errores, sin embargo no ofrece muchas características, lo que hace que la complejidad se delega en los scripts de shell que inicia. Runit inicia rápido y tiene un uso de recursos mínimo, es muy estable, configurable y confiable.
Dinit es muy liviano y ligero, lo que le permite mantener una altísima velocidad de arranque y apagado. Es fácil de usar, teniendo una sintaxis sencilla de adaptar desde systemd, y además, constituye una mejora significativa de características y herramientas con respecto a Runit. Su curva de aprendizaje puede ser elevada.
Teniendo en cuenta que mi uso de init y gestión de procesos puede definirse en la simplicidad, aun entendiendo la ambigüedad de la palabra, lo considero elemental y convergente con ligereza y legibilidad. El uso que a mi máquina me exige iniciar y parar regularmente distintos procesos, que de hecho no quiero tener iniciados de forma defectuosa si no es por una razón concreta. Por ello, la gestión y administración de procesos y demonios debe ser sencilla y elegante. Y aunque no lo considero determinante ni fundamental, mantener una buena velocidad de arranque es algo deseable e interesante.
Evidentemente, no hay respuesta correcta y no se basa ni siquiera en mi experiencia, sino en la de otros en la comunidad. Mis conclusiones a raíz de estas lecturas, podrían ser que S6 sería la opción más apropiada para un servidor, por su estabilidad, seguridad y estructura Unix, así como robustez.
Por otro lado, para un uso de escritorio, me habría decatado por Runit. La decisión ha sido complicada con respecto a Dinit, debido a que el segundo mantiene una funcionalidad similar a Runit, pero ofreciendo características adicionales, como soporte para programación de tareas, capacidad de gestionar dependencias complejas entre servicios, API de control, etc.Pero en búsqueda de simplicidad y eficiencia, considero la filosofía de diseño de Runit más cercana a mí, y a mi fórmula de uso.
1 Desgraciadamente he dejado fuera de artículo a SysVInit, puesto que no constituye una opción por defecto en Artix.
Bibliografía y enlaces de interés