16 de febrero de 2014

La sombras de sysvinit

La burocracia debianera ha elegido finalmente systemd, y como consecuencia de ello Ubuntu abandona upstart. Como dice el refranero, para este viaje no hacían falta alforjas. Quizás lo más destacable de todo es una de las ventajas menos comentadas, que es la unificación del sistema de inicio a lo largo y ancho de la mayor parte de distribuciones.

Es buen momento para recordar que la defensa del actual sysvinit como supuesta encarnación de un ideal Unix no tiene fundamentos sólidos. Cada vez es más rechinante la obsesión con considerar "esencia Unix" una especie de nihilismo informático en el que la regla principal es diseñar todo a base de comandos comunicados por tuberías, incluso cuando los programas resultantes son horribles. Como ya conté aquí, esa manera de pensar es un lastre cultural que ignora que la concatenación de comandos comunicados por tuberías era literalmente la única manera de hacer cosas complejas en Unix, en aquel entonces no había otros sistemas de IPC.

Hace tiempo que los sistemas Unix se dieron cuenta de esas limitaciones y adoptaron el concepto de librerías compartidas, ausente en sus inicios. Llevamos décadas apuñalando por la espalda la idea de comandos simples + tuberías. Ningún sistema Unix moderno se construye únicamente así, ni lo hará en el futuro. Hoy en día las librerías compartidas predominan como manera de crear programas locales complejos a partir de elementos más simples.

Eso no quiere decir que el shell esté obsoleto, o que no sea útil. Pero proponerlo como fundamento para crear un sistema complejo como systemd o upstart no tiene por qué ser la mejor idea.  SysVinit es más bien un manojo de herramientas pegadas con celo que suelen funcionar la mayor parte de las veces, otras simplemente explotan por los aires, como podemos ver en este PDF de los programadores de upstart, en el que citan una serie de bugs típicos de sysvinit.

Sin embargo, la principal característica de systemd no está resultando tener que ver tanto con su implementación, sino con el modo de integrar diferentes partes del sistema. systemd requiere kernels compilados con una serie de opciones del kernel (cgroups, inotify, seccomp...), va a requerir en breve kdbus, proporciona un sistema de logging propio, proporcional logind, una alternativa a xinetd, deja obsoletos varios comandos de gestión del sistema, proporciona un sistema de gestion de sesiones de usuario que reemplaza a cosas como gnome-session...todo ello con el objetivo de que todo sistema que adopte systemd tenga una serie de funcionalidades y de manera de integrar servicios básicos del sistema estandarizados. Aunque muchas de esas funcionalidades son configurables y se pueden desactivar o dejar de lado, es obvio que quien adopta systemd lo hace generalmente para activarlas.

Esto es, en realidad, lo que más rechazo genera contra systemd. Pero en este blog se ha destacado en el pasado la importantísima y frecuentemente denostada función de la integración de diferentes partes de software: aunque haya quien se queje de que systemd impone, fuerza o anima a hacer cosas que no a todos podrían gustarle, también hay que tratar de ver el valor que proporciona toda esa integración y uniformidad. Como cuentan en este blog, systemd ha ganado porque se ha preocupado por los usuarios más que nadie.

Ese es un aspecto en el que los sistemas basados en shell no pueden alcanzar a systemd: obsesionados con supuestos espíritus que han distorsionado o que en realidad no existen, se han olvidado que la prioridad es crear sistemas útiles. No se trata sólo de cómo crear las cosas, sino en qué cosas deben crearse. Paradójicamente, el dejar de lado una visión "top-down" de las cosas les ha llevado posteriormente a hacer mal las cosas. El mejor ejemplo de esto último lo he visto en una historia que Lennart Poettering contaba sobre como algo en apariencia tan simple como el proceso de matar todos los procesos y apagar el sistema es mucho más complejo de lo que parece, y como, de hecho, systemd es el único sistema de inicio que apaga el sistema de manera total y absolutamente segura. El OpenRC en Gentoo, que se ha erigido en bastión de resistencia contraria a la adopción de systemd, no hace las cosas ni la mitad de bien, ni en ese aspecto ni en otros: eso si, lo hace en shell, que para sus desarrolladores es la principal medida de éxito.

6 de febrero de 2014

¿Por qué kdbus?

De entre todas las polémicas sobre Systemd sigue sobresaliendo la relacionada con Debian, pero últimamente se ha hablado de la integración de dbus en el kernel bajo el nombre de kdbus. Y junto con kdbus, ha surgido la inevitable discusión sobre la barbaridad que es meter dbus en el kernel, que dbus es una cosa maloliente de escritorio, Linux se está alejando de Los Sagrados Principios Unix, etc etc.

Pero son discusiones sin sentido: kdbus no es una mala idea.

Empezaré reconociendo que, en sus inicios, yo también fui de los que odió la proliferación de dbus, por tener ese olor a software redundante del que podríamos librarnos si se hicieran las cosas como es debido. Sin embargo basta informarse un poco (este vídeo/diapositivas de una charla de Lennart Poettering es muy recomendable) para comprender que su propósito es necesario, se trata de un tipo de IPC de alto nivel disponible en muchos otros sistemas operativos -algunos de ellos microkernels- que no puede ser sustituido por los mecanismos de IPC tradicionales.

Para suplir esa carencia nació dbus, que surgió como un intento de Gnome de librarse de Bonobo e imitar el DCOP de KDE, y que finalmente incluso KDE acabó usando en KDE 4. ¿Pero por qué incluir kdbus en el kernel, en lugar de seguir usando dbus el demonio dbus en espacio de usuario?

En parte, la respuesta es que dbus es bastante ineficiente: Un mensaje dbus de una aplicación a otra requiere copiar los datos y cambiar de contexto de la aplicación al demonio dbus, y este a su vez ha de hacer lo mismo con la otra aplicación. Tampoco es posible tener comunicación dbus desde el arranque del sistema, hay que esperar a que se arranque el servicio, y no está bien integrado con los mecanismos de seguridad del kernel.

En realidad, el kernel es el sitio donde se deben implementar esta clase de cosas: tuberías, FIFOs, sockets Unix, pila TCP/IP, IPC de System V, etc; todos están implementados en el kernel, y en muchos casos lo están por la simple razón de que son muy utilizados y es conveniente hacerlo así. Podría mantenerse dbus en espacio de usuario, pero también se puede implementar la pila TCP/IP en espacio de usuario, y hay razones para no hacerlo. Hay que hacer notar que incluso algunos microkernels implementan sistemas IPC similares dentro del kernel, precisamente porque el IPC entre procesos es su fundamento. Así que creo que las alarmas por kdbus están injustificadas.