6 de abril de 2014

Las novedades de Linux 3.14

Ya se ha anunciado la versión 3.14 de Linux. Entre las novedades de esta versión destacan un planificador de procesos para tareas que tengan requisitos de tiempo real, la estabilización de un sistema de compresión de memoria, un port del validador de bloqueos a espacio de usuario, la habilidad para almacenar propiedades en inodos en Btrfs, soporte para ejecutar comandos tras un evento en la infraestructura de trazado, aleatorización del espacio de direcciones del kernel, fusión automática de paquetes en cierta clase de conexiones TCP, y un nuevo planificador de paquetes de red para luchar contra el bufferbloat. También se han incluido drivers nuevos y muchas otras mejoras y pequeños cambios. La lista completa de cambios, en inglés, puede encontrarse aquí, como siempre.

· Planificador de procesos "deadline" para planificación de tiempo real
Normalmente los sistemas operativos proporcionan prioridades en el planificador de procesos, cuanta más prioridad tiene un proceso, más tiempo de ejecución puede conseguir ese proceso respecto a otros con prioridades menores. En Linux, los usuarios configuran las prioridades con valores de -20 a 19 utilizando la herramienta nice(2). Adicionalmente, Linux soporta la noción de "clases de planificación", en cada clase hay una política de planificación diferente, por ejemplo, hay una clase SCHED_FIFO con una política FIFO "el primero que entra, el primero que sale", y una política round-robin en  SCHED_RR.

Este sistema de prioridades no es, sin embargo, el más apropiado para tareas que requieren tiempo real. En esta versión Linux implementa una alternativa que está diseñada sobre ideas que parten de la investigación en sistemas de tiempo real: planificación "deadline" ("plazos" de tiempo), que ha sido implementada como una nueva política de planificación, SCHED_DEADLINE.

La planificación "deadline" deja atrás la noción de prioridades. En su lugar, los procesos proporcionan tres parámetros: tiempo de ejecución, periodo y plazo. A una tarea que esté planificada bajo la política SCHED_DEADLINE, se la garantiza que obtendrá "tiempo de ejecución" microsegundos de ejecución cada "periodo" microsegundos, y ese "tiempo de ejecución" estará disponible dentro de "plazo" microsegundos desde el inicio del periodo. El planificador de tareas utiliza esa información para ejecutar el proceso con el plazo más cercano al momento actual, un comportamiento más cercano a los requerimientos de los sistemas de tiempo real. Para más detalles sobre los algoritmos de planificación, ver la documentación.

· zram: compresión de memoria considerada estable
zram crea dispositivos de bloques en la memoria RAM. Todo lo que escrito a esos dispositivos de bloques es comprimido. Si los dispositivos de bloque zram son utilizados como espacio de intercambio, cuando el sistema intente mover liberar memoria enviando porciones al espacio de intercambio, en realidad lo estará moviendo de una zona de la memoria a otra, excepto que los datos movidos habrán sido comprimidos antes de ser copiados a su destino. Esto funciona en la práctica como un sistema de compresión de memoria capaz de mejorar la respuesta en sistemas con cantidades de memoria limitadas. Zram está siendo utilizado por compañías de TV, Android 4.4, Cyanogenmod, Chrome OS, Lubuntu...

Zram ha estado en "staging" desde Linux 2.6.33. En esta versión, zram ha sido movido fuera de staging, a drivers/block/zram.

· Btrfs: Propiedades de inodo
Esta versión añade infraestructura para añadir parejas nombre/valor como xattrs a los inodos en Btrfs. El propósito de estas parejas es almacenar propiedades para los inodos, tales como la compresión. Estas propiedades pueden heredarse; esto significa que cuando el inodo de un directorio tiene la propiedad compresión activada, todos los inodos que sean creados en ese directorio serán también comprimidos. Los subvolúmenes pueden tener también propiedades asociadas, y pueden hederarse del subvolumen padre. Esta versión añade una implementación de propiedades, llamada "compresión", cuyos valores pueden ser "lzo" o "zlib".

· Soporte para ejecutar comandos en los eventos de trazado
La infraestructura de trazado en Linux permite registrar sondas en las funciones del código como eventos (para más detalles, ver Documentation/trace/events.txt). Esta versión permite que estos eventos desencadenen la ejecución de comandos. Estos comandos pueden tener varias formas, por ejemplo podrían activar o desactivar otros eventos o invocar el volcado de pila. Cualquier comando puede tener incorporado además un filtro de eventos, de ese modo el comando será invocado solamente si el evento pasa por el filtro asociado

Por ejemplo, este comando causa el volcado de pila las primeras cinco veces que hay una petición de kmalloc que pide >= 64KB de memorua: # echo 'stacktrace:5 if bytes_req >= 65536' > \ /sys/kernel/debug/tracing/events/kmem/kmalloc/trigger

Para más detalles, ver Sección 6 de Documentation/trace/events.txt

· Las sondas de espacio de usuario tienen acceso a todos los argumentos
Las sondas de espacio de usuario son una característica de Linux 3.5 que permite activar sondas en programas de espacio de usuario. Esta versión permite que las sondas de espacio de usuario (uprobes) tengan acceso a todo tipo de argumentos en las funciones de los programas: pila de memoria, deference, bitfield, retval y offset de archivo. Para más detalles, aquí.

· Validador de bloqueos en espacio de usuario
El kernel Linux ha tenido (desde 2.6.18) un validador de bloqueos que permite encontrar fallos en la programación de los bloqueos en tiempo de ejecución. Esta versión permite ejecutar el validador de bloqueos de Linux en espacio de usuario, haciendo posible depurar problemas de bloqueo en espacio de usuario.

· Espacio de direcciones del kernel aleatoria
Esta versión permite aleatorizar la dirección física y virtual en la que se descomprime la imagen del kernel, lo cual ayuda a bloquear ciertos tipos de exploits que confían en conocer la localización de las direcciones del kernel.

· TCP automatic corking
Cuando las aplicaciones hacen llamadas pequeñas y consecutivas a write()/sendmsg(), el kernel intenta fusionarlas, para disminuir el número de paquetes enviados en total, esta característica se llama "automatic corking". Las aplicaciones aun pueden usar TCP_CORK para conseguir un comportamiento óptimo cuando sepan cómo o cuando tengan que "uncork" sus sockets. Se añade una nueva sysctl (/proc/sys/net/ipv4/tcp_autocorking), que por defecto está activada. Para benchmarks y más detalles, ver commit

· Antibufferbloat: planificador de paquetes "Proportional Integrarl controller Enhanced"
Bufferbloat es un fenómeno consistente en la creación de demasiados búffers en la red, lo cual causa excesiva latencia y fluctuaciones. A medida que más aplicaciones interactivas (VoIP, streaming de vídeo, transacciones financieras) funcionan sobre Internet, esos defectos empeoran el rendimiento de la aplicación. Ha habido varias mejoras y características en las últimas versiones de Linux que tratan de frenar ese problema.

Esta versión añade un nuevo planificador de paquetes: PIE(Proportional Integral controller Enhanced), que puede controlar la latencia media de la cola a un valor determinado. Los resultados han demostrado que PIE puede asegurar latencia baja  y conseguir una utilización alta de los enlaces en situaciones de congestión. El diseño añade una sobrecarga mínima. Para más información, ver este papel técnico sobre PIEo este borrador del IETF. Todo el código, documentación y scripts y resultados puede encontrarse en ftp://ftpeng.cisco.com/pie/


Y eso es todo. La lista completa de cambios en inglés, aquí.

8 de marzo de 2014

¿Qué pasó en Windows 8?

Pocas veces en mi vida me he sentido tan desorientado e inútil frente a un ordenador como cuando probé por primera vez una versión previa de Windows 8. No fui el único, durante todo el tiempo que se tardó en desarrollar la versión final las quejas sobre la nueva interfaz metro fueron continuas, con especial énfasis en la imposibilidad de configurar el escritorio tradicional como escritorio por defecto y poder volver a usar el menú de inicio.

A pesar de ello, la reacción de Microsoft fue la de justificar con datos y estadísticas -todos ellos muy razonables sobre el papel- por qué las decisiones que habían tomado eran las mejores. En lugar de intentar comprender que había muchas quejas, y que si las había debía ser por algo, parecían esforzarse en intentar demostrar que las críticas eran irrelevantes. Ni tan siquiera añadieron algún tipo de guía o ayuda que explicase Metro a los nuevos usuarios, a pesar de que es algo que se reclamó constantemente. Naturalmente, pensaron que una interfaz bien diseñada era intuitiva por si misma y no necesitaba de esas cosas, y Metro sin duda era buena: afirmaron que la gente se adaptaría a Windows 8 en dos semanas. Y llegó el día, y Windows 8 vio la luz, y ya sabe todo el mundo como fue el recibimiento. Ni dos semanas, ni dos meses.

Como consecuencia, en la actualización 8.1 tuvieron que enmendarse y permitir la configuración de varios aspectos: el escritorio tradicional puede ser el escritorio por defecto, los charms son opcionales, se reincorpora el icono del menú de inicio (aunque no el menú), ciertas ayudas para guiar a los nuevos usuarios. En la próxima "Spring update", se arrancará por defecto en el escritorio tradicional en equipos no táctiles, además de otros cambios sustanciales en la interfaz, como permitir usar la barra de tareas dentro de Metro, o añadir iconos en la pantalla de inicio de metro para apagar o buscar. Ya no se espera que la gente se adapte, y no sólo se asume que hay gente que no se adaptará, sino que se construyen alternativas mixtas que rompen con la visión original. Sorprende como se justifica estas marchas atrás (negrita mía):
"Some of those touch affordances weren’t really tuned as well as we could do for those mouse and keyboard users. We found people weren’t aware of where they should look in the UI. Those are the things we’ve really started to improve for this update coming this spring"
El equipo de usabilidad de Microsoft debe ser, por necesidad, de los mejores del mundo, y es una locura sugerir que no son profesionales. Cabría preguntarse, por tanto, cómo es posible que ese equipo no viese con antelación en las pruebas lo que para casi todo el mundo era una obviedad, y que sólo ahora se hayan percatado de que "people aren’t aware of where they should look in the UI". Parte de ello se debe, sin duda, a cierto talibanismo en el que los mejores expertos pueden caer: "mi solución es la mejor y sin duda a la gente le encantará".

Una respuesta incompleta podemos encontrarla en este famoso post de un diseñador de Microsoft en reddit, donde nos revela la concepción que hay detrás de la nueva interfaz: Metro es una interfaz diseñada para los usuarios menos expertos en mente, mientras que el escritorio tradicional se reserva para los "power users". Metro es para consumidores de contenido, el escritorio para los creadores de contenido. Hay varios hechos que ponen contra las cuerdas esta concepción: la evidencia de que Metro ha sido diseñada no directamente para una clase de usuarios sino para una clase de hardware (táctil), la realidad de que muchos "consumidores de contenido" no se sienten a gusto en Metro (esta contestación al post anterior, citando casos de usuarios que tienen más problemas con Windows 8 que con 7, es un ejemplo claro), el hecho de que se mantengan dos interfaces para una misma clase de usuario en un mismo equipo...

Aun a riesgo de ser atrevido, sospecho que tras esas explicaciones se esconde el deseo de Microsoft de racionalizar y crear teorías para justificarse ante si mismos su falta de adaptación a las nuevas tecnologías. La realidad es que Metro no es una interfaz creada por expertos de usabilidad dedicados tranquilamente a ello aislados del mundo: es una creación apresurada de una compañía que se enfrentaba al terror de estarse volviendo irrelevante. La explicación más probable de los problemas de Windows 8 es que las prisas por tener algo tangible les ha llevado a pasar por alto demasiadas cosas. Como consecuencia se ven ahora obligados a centrar las siguientes actualizaciones en corregir lo que no hicieron bien en un principio, con la esperanza de paliar el rechazo existente, que les ha llevado en la misma dirección que pretendían evitar.

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.