9 de mayo de 2006

Microkernels again

Pavel Machek ha dicho un par de cosas sobre lo que piensa del último artículo de Tanembaum sobre construcción de sistemas operativos.

El tema este empieza a ser cansino. No en vano un servidor escribió un artículo sobre por qué los kernels monolíticos no son el fin del mundo, que fue aceptado y publicado en osnews: algunos estamos cansados de los weenies de los microkernels. Desde los que demuestran su más absoluta ignorancia del tema afirmando que Mac OS X es un microkernel a los que no son ignorantes, pero insisten en dar la lata y en no atenerse a hechos.

Tanenbaum no es tan diferente a veces. Es bueno que sea escéptico y que trate de mejorar las cosas, porque solo los que intentan mejorar las cosas y lo consiguen son los que hacen progresar. El problema es cuando la investigación deja de ser investigación para convertirse en una obstinación. Para que lo voy a negar, el artículo deja ver ciertas cosas que dan risa. Ya las comenta Pavel en su blog. Por ejemplo, el típico mito de que Minix solo ocupa 4500 lineas y el kernel 2.5 millones y que por lo tanto no se puede verificar la correción de Linux. Lo que Tanembaum olvida mencionar en su microuniverso es que un microkernel es un microkernel y que por definición necesitas servidores en espacio de usuario para implementar los drivers, y que implementar toda la funcionalidad, los miles de drivers y varias decenas de arquitecturas de linux sobre un microkernel tomaría aproximadamente.....2.5 millones de líneas de código.

Otra cosa que olvida mencionar y que Pavel si que menciona, es que los dispositivos pueden hacer cascar al sistema. Y no solo eso, Pavel asegura que dado que la mayor parte de los dispositivos utilizan DMA de una manera u otra, pueden utilizar el DMA para sobreescribir zonas aleatorias de memoria. Por no mencionar que tocando los registros adecuados pueden bloquear el bus pci y colgar la máquina de mil maneras diferentes, y todo eso al margen de que los drivers estén implementados en espacio de usuario o no. Eso significa, que uno no puede decir que un driver es simplemente "otro proceso más". Un proceso que puede tirar la máquina no es "un proceso más". Me carcajeo literalmente, partiendome el culo con los que responden a las noticias de que el kernel linux tiene demasiados bugs diciendo que los microkernels son la solución. ¿Qué metodología utilizarian para mantener los 2.5 millones de líneas de código que se necesitan para implementar los drivers equivalentes a los que tiene Linux hoy? ¿Qué metodología utilizarian para asegurar que ninguna de esos 2.5 millones de líneas toca el registro adecuado y cuelga la máquina? ¿La palabra mágica "microkernel" soluciona los problemas magicamente? En fin....

Tampoco ha comentado las dificultades de depuración. El propio Stallman ha contado lo mal que lo pasan los de Hurd, porque mientras que en un kernel monolítico puedes obtener un backtrace mirando a la pila del proceso del lado kernel (los procesos tienen una pila en espacio de usuario y otra en el kernel), en un microkernel casca un servidor pero no sabes nada de lo que ha pasado con los demás

Para hacerse una idea: un kernel monolítico es como un programa compartido a partir de librerias compartidas. Gaim, por ejemplo, utiliza las librerias de las GTK, libc, fontconfig (ldd /usr/bin/gaim). Pero todo eso en tiempo de ejecución se ensambla en un solo programa en memoria que tiene un solo espacio de direcciónes. Es decir, un fallo en libc puede sobreescribir una sección de datos destinada a la GUI, y mandar el programa entero a paseo

Los microkernelistas aquí tambien se ensañarían. Se ensañan ahora con el kernel, pero esto en realidad es aplicable - como no podía ser de otra forma - a todo software. La propuesta de los microkernelistas aplicada a gaim, y a todo software de escritorio consitiría en crear un servidor para libc, otro para gtk, otro para fontconfig. ¿Por qué no? Se trata de la misma idea aplicada de exactamente la misma manera. Y aplicable, por si algún bravo se atreve a decirme que no son ejemplos comparables. Son ejemplos perfectamente comparables. Y cuando el software en espacio de usuario se complique más y las librerias a las que enlaza un ejecutable sean cientos, surgirán - la historia siempre se repite - movimientos sugiriendo la aplicación de este modelo a la producción de software en general. Lo digo aquí y dentro de diez, veinte años lo veré, porque el ser humano es gilipollas. ¿Por qué debería perder la voz y video de mi videoconferencia solo porque la interfaz de usuario (la interfaz de un programa 10x o 100x más complejo de lo que solemos ver hoy) ha tenido un fallo y no se reinicia el programa y sigo en el punto en el que estaba?

La postura de los kernels se trata de un extremo, un extremo sin duda influenciado ideológicamente por las mismas fuentes que influenciaron a la programación orientada a objetos, concretamente la encapsulación (nada sorprendente, porque los microkernels nacieron como una proyección de las inquietudes de los que crearon la orientacion a objetos sobre el núcleo del sistema). Como suele pasar con los extremos, en la práctica no es todo lo bueno que debiera ser. Supongo que su sueño sería isolar totalmente a cada uno de los objetos y que cada uno fuera realmente un proceso, o algo asi. Tampoco es bueno el extremo contrario: En el dibujo del Gaim falta el servidor X, por ejemplo. En Linux falta hablar de los drivers en espacio de usuario que tenemos con libusb o con X.org o con CUPS. Ni tan siquiera es problema de rendimiento: el propio Linus Torvalds escribió algunos buenos emails tratando de analizar lo ideologicamente sospechoso que es querer separar a un sistema de archivos de ciertas partes de la gestión de memoria

La clave de todo el asunto es el concepto de espacio de direcciones. Es algo asi como lo de la latencia y el ancho de banda, muy filosófico: Puedes implementar algo utilizando un espacio de direcciones, o puedes dividirlo en tareas e isolarlo del mundo (vease: el servidor X en Unix). ¿Cuando se debe tender a un extremo y cuando al otro? Sospecho que como en lo de la latencia y el ancho de banda no hay respuesta única, sino que hay que adecuarse a las necesidades, y al igual que un juego en red se optimiza para latencia y un servidor FTP para el ancho de banda habrá que analizar cada situación y decidir en consecuencia

UPDATE: El mismo día que escribi esto, Linus escribió una respuesta con respecto al tema de los microkernels. Me agrada saber que coincido con él en el tema de los espacios de direcciones:

"The real issue, and it's really fundamental, is the issue of sharing address spaces. Nothing else really matters. Everything else ends up flowing from that fundamental question: do you share the address space with the caller, or put in slightly different terms: can the callee look at and change the callers state as if it were its own (and the other way around)?

y otras partes igual de buenas pensando en profundidad sobre el problema:

The fundamental result of access space separation is that you can't share data structures. That means that you can't share locking, it means that you must copy any shared data, and that in turn means that you have a much harder time handling coherency. All your algorithms basically end up being distributed algorithms.

1 comentario:

  1. Anónimo9:47 p. m.

    Parece que el enlace de la acutalización no funciona bien.

    er tuko.

    ResponderEliminar