El verdadero peligro de Mono

Hace unos meses, en plena discusión mundial sobre si el uso de Mono en Linux suponía un riesgo para el software libre o no, publiqué una entrada ofreciendo mi punto de vista. Sin embargo, lo que conté era sólo la mitad, porque en ese momento me pareció que no era adecuado echar más leña al fuego, así que decidí limitarme a la parte puramente técnica. Ahora que ya ha pasado un tiempo y las cosas están más calmadas he decidido escribir la segunda parte. Preparaos para un articulo de opinión, y encima largo.

Lo primero, decir que Mono, estrictamente hablando (esto es, la implementación libre de los estándares ECMA-334 y ECMA-335), no tiene por qué ser un problema para el software libre, gracias, principalmente, a la promesa de Microsoft de no ejercer esas patentes (vamos a pecar de confiados y, a pesar de no ser abogados, supondremos que realmente es universal, definitiva e irrevocable).

Sin embargo, el primer gran problema que encontramos es que esos dos estándares sólo cubren una parte de .NET, en concreto la máquina virtual, el lenguaje C# y la biblioteca estándar de dicho lenguaje. Pero .NET es mucho más que eso, porque está ASP.NET, ADO.NET y las WinForms, entre otros muchos componentes. Un argumento que esgrimen los defensores de Mono es que éste no pretende ser compatible con .NET hasta el punto de poder ejecutar todas sus aplicaciones (eso es sólo un efecto colateral), sino simplemente ser un entorno de desarrollo moderno para GNU/Linux, que aumente la productividad. Esto se puede ver perfectamente cuando leemos el Mono Rationale y algunas entrevistas a Miguel de Icaza: todo el énfasis lo ponen en el soporte de múltiples lenguajes y en la mejora del rendimiento en el desarrollo, pero no lamenta que no vaya a haber compatibilidad completa porque no hay nadie que se anime a escribir determinadas bibliotecas, sino que incluso recalca que hay muchos módulos específicos de Mono que permiten escribir programas que no funcionarían en .NET.

¿Y qué problema hay, entonces, en utilizar un entorno de desarrollo basado en dichos estándares, y completándolos con herramientas y bibliotecas libres (como GTK#, por ejemplo) para rellenar los huecos que faltan, y sin buscar compatibilidad con el .NET de Windows? Personalmente tiendo a alinearme con la gente que defiende que no hay ninguno (aunque me remito a las razones técnicas que esgrimo en mi anterior entrada): por una parte el riesgo de patentes es prácticamente nulo, porque Microsoft se ha comprometido a no atacar con ninguna de ellas (aunque pienso que la razón es que, estratégicamente, sería peor para ella); y por otro lado, aunque .NET avance demasiado rápido para mantenerse a la par (cosa que ni siquiera hoy en día se está consiguiendo con Mono) o si Microsoft cambiase las APIs creando problemas de compatibilidad, tampoco sería un problema porque el objetivo no es ser compatibles con ellos.

Pero…

Obviamente hay un pero, porque si no, el título de este post no tendría ningún sentido. Ese pero surge del hecho de que la misma existencia de .NET, tan abierto, tan estandarizado, tan portable, no parece tener sentido viniendo de una empresa que ha monopolizado la web durante años, que ha intentado poner trabas al software libre mediante tácticas cuanto menos discutibles, y que ha sido acusada de mantener una posición de monopolio en el mercado de los sistemas operativos y navegadores. ¿Por qué sacar un producto que puede beneficiar tanto a tu rival, y además darle tantas facilidades, cuando tu historial habla siempre de acciones totalmente opuestas? ¿Se está regenerando Microsoft?

La respuesta, en mi opinión, está en Silverlight: Microsoft perdió el control que tenía sobre la web y ahora quiere recuperarlo, pero la gran cantidad de navegadores disponibles hoy en día, así como la sensibilización que hay hacia el uso de estándares, le impide repetir la táctica de añadir sus propias extensiones a HTML. Por otro lado están Java y Adobe Flash. El primero, a nivel web, está hoy de capa caída, aunque intenta recuperar el terreno mediante JavaFX. El segundo es un peso pesado, pero está perdiendo terreno gracias a HTML5 y al peso de la comunidad, que intenta incentivar el uso de estándares. Y es justo aquí donde Microsoft intenta atacar con Silverlight: crea un nuevo plugin para que los desarrolladores hagan lo que hacían con Flash, pero con la ventaja de que es tecnología basada en .NET, lo que significa que se puede reutilizar código de otras aplicaciones aunque no sean aplicaciones web (cosa imposible con HTML5); es una plataforma agnóstica respecto al sistema operativo y a la arquitectura gracias al uso de una máquina virtual (igual que Java y Flash), y encima se basa en estándares abiertos (ECMA-334 y ECMA-335), lo que permite a terceros hacer implementaciones propias, como por ejemplo Moonlight, que se basa, como no, en Mono.

¿Y donde está el problema? Pues en que Silverlight no está dentro de ningún estándar. Como dije al principio, los dos estándares ECMA cubren únicamente el lenguaje C# y su biblioteca estándar, así como la máquina virtual, pero todas las bibliotecas específicas de Silverlight están fuera, por lo que Microsoft tiene libertad absoluta para cambiarlas y ampliarlas a su antojo.

Con esto echamos por tierra el principio de que no importa que cambie la especificación porque la compatibilidad no es un objetivo: si Mono no es 100% compatible con .NET, Moonlight no lo será con Silverlight y no servirá para nada. Y si hay que garantizar la compatibilidad, el software libre siempre irá a remolque, y a buena distancia, de Microsoft, por lo que la gente se verá obligada a utilizar la máquina de .NET, pues Mono y Moonlight no implementarán todo lo necesario (y la especificación se mantendrá en continuo aumento). Para aquellos que piensen que exagero, me remito a los diversos clones de Flash que se han intentado hacer en el mundo del software libre: ninguno funciona lo suficientemente bien como para reemplazar sin problemas al plugin oficial de Adobe. Y que no se me interprete mal: hay un gran trabajo detrás de todos ellos; simplemente es una tarea muy grande sobre un blanco muy móvil.

Hace tiempo ya nos topamos con el primer aviso cuando el SIGPAC se pasó a Silverlight: la respuesta de los creadores comenzaba diciendo que los datos ya están disponibles en formato WMS, que es un estándar para acceso a información cartográfica, aunque sí se puede alegar que no son los datos, sino el servicio, el que también debería ser accesible desde cualquier sistema operativo. A continuación, añadía que la versión en Silverlight es accesible desde multitud de sistemas operativos, incluido Linux, gracias a Moonlight, aunque luego aclaraba que, en este último caso, se conocían algunos problemas porque el SIGPAC necesita la versión 3 de Silverlight, y Moonlight implementa sólo la versión 2. Cinco meses después sólo hay una versión preliminar de la 3, todavía en fase alfa, mientras que Silverlight ya va por la versión 4: el software libre siempre irá a remolque si la especificación depende de una única empresa en lugar de ser un estándar oficial.

Lo mismo ocurre con los mundiales de fútbol en Telecinco: para verlos necesitas Silverlight, y Moonlight todavía no sirve (aunque la versión alfa de la 3.0 parece que sí lo soporta, pues en la página oficial dice textualmente: “With Moonlight you can watch the Olympics on Linux with our 3.0 preview”). Por otro lado, vemos que también quiere integrarlo en televisores y otros dispositivos, lo que parece indicar ya la estrategia de Microsoft: meter Silverlight en todos los ámbitos que pueda.

Y si alguien aún se pregunta qué gana Microsoft consiguiendo que todo el mundo utilice una plataforma que se consigue gratis o de la que cualquiera puede crear una versión alternativa (aunque siempre vaya a remolque de la oficial), la respuesta (aparte de vender más herramientas de desarrollo y de que, como su versión será siempre la más avanzada y sólo la hay para windows, se asegura de que windows se utilice más, que ya es bastante) es que tiene el poder de forzar el uso de otras tecnologías en las que colabora, muchas de ellas de pago. Por poner un ejemplo, Microsoft forma parte del MPEG-LA, que cobra los royalties por el uso de H.264, codec de vídeo que se utiliza en Silverlight para realizar streaming. Al ser Silverlight su tecnología, ellos deciden qué entra y qué no, pudiendo eliminar a la competencia (por ejemplo, a Theora o a WebM) y ganando ellos dinero con las licencias de esas tecnologías. De hecho, la licencia de Microsoft por la que promete no perseguir implementaciones libres de Silverlight excluye expresamente el pago de royalties por codecs patentados. Por otro lado, que actualmente sea gratis no significa que, en el futuro (cuando esté extendido y sea casi obligatorio integrarlo si quieres vender), no haya que pagar por poner Silverlight en el último modelo de televisor.

Y esto es lo realmente peligroso para el software libre, pues no solo iremos siempre a remolque de la implementación privativa, sino que, en muchos casos, podremos vernos completamente atados (baste ver los problemas que tiene Debian o la Mozilla Foundation para incluir algunos codecs de serie en países con patentes de software).

Por todo esto, aunque no rechacemos a Mono en sí, creo que sí deberíamos rechazar con todas nuestras fuerzas a Silverlight y a Moonlight, y exigir que se utilicen únicamente estándares abiertos como HTML5 para realizar las páginas web, en lugar de sistemas privativos controlados por empresas. Precisamente ahora que tenemos las herramientas necesarias para ganar la batalla a Flash no debemos cometer el error de caer en un nuevo plugin privativo.

O esa es, al menos, mi opinión.

Recuperar el applet de sonido en Ubuntu 10.04

Cuando actualicé mi sistema a la nueva Ubuntu 10.04, ocurrió un detalle bastante molesto: el applet de sonido desapareció. Ni rastro. Probé a añadirlo desde la lista de applets y nada, no existía. Busqué con APT, instalé paquetes, y tampoco. Hasta que, finalmente, descubrí como recuperarlo.

Lo primero que necesitamos para que funcione el applet de sonido es tener en nuestra barra de tareas un área de notificación. Esta tiene esta forma:

area de notificacion de gnome

Aquí vemos el área de notificación (que, en realidad está delimitada por esas tres rayitas de la izquierda), mostrando además el icono de conexión de red. Si no tenemos un área de notificación, basta con pulsar con el botón derecho en la barra, seleccionar Añadir al panel, hacer doble click en Area de notificación, y listo.

Si ya os aparece el icono de un altavoz, ya está todo hecho; pero si, como en la imagen de arriba, no aparece, eso es que os falta el applet en sí, en concreto el gnome-volume-control-applet. Dicho programa viene en el paquete gnome-media. Sin embargo, no es un applet a la antigua usanza, sino que es un demonio que utiliza el área de notificación para mostrarse. Si ya instalasteis el paquete y, desde una linea de comandos lanzáis dicho applet (con gnome-volume-control-applet & para que, al hacer un exit del terminal, siga en marcha), veréis que por fin aparece en control de volumen. Pero esa solución sólo sirve para esta sesión, y tan pronto se reinicie el equipo habrá que volver a lanzarlo. Para resolverlo vamos a hacer que se lance automáticamente cada vez que entremos en gnome. Vamos a Sistema -> Preferencias -> Aplicaciones al inicio, pulsamos Añadir, y rellenamos los campos con estos valores:

añadir un programa de inicio a Gnome

(obviamente, en el campo Orden hay que poner gnome-volume-control-applet; ahí está recortado). Una vez hecho esto, siempre que iniciemos tendremos, por fin, el applet del control de volumen, así de hermosote él.

Area de notificacion de gnome con control de volumen

Devede y BT_FTP4Lxmedia

Acabo de lanzar una nueva versión de BT_FTP4lxmedia, el paquete con servidor FTP y cliente BitTorrent para los discos duros multimedia de MemUp. Como novedad, trae la versión 2.9 de BFTP y la 2.01 de Transmission.

También acabo de lanzar una miniactualización de Devede. Las novedades son, simplemente, mostrar el tipo de licencia en el diálogo Acerca de…, por petición de un certificador de instalaciones GNU/Linux (parece ser que es necesario que aparezca claramente la licencia), y añadir la traducción a húngaro. Nada excesivo, por lo que no hay necesidad de actualizarse a menos que se necesite alguna de las dos cosas.

Querida hacienda, dos puntos

Siempre ha sido la protagonista de las pesadillas de muchos contribuyentes, y fue, hasta hace poco, el atractor de toda la ira y odio del español medio (¡pero ya no! ¡ya hay entidades más odiadas que hacienda!). Sin embargo, hoy lanzaré una nota positiva sobre ella, porque cuando las cosas se hacen bien, es justo reconocerlo: este año, hacienda ha lanzado una versión del programa PADRE para Linux, poniendo fin a años de discriminación hacia los que tenemos tendencias informáticas minoritarias. ¡Y fijaos si está bien hecho que me ha salido a devolver!

Trabajando con señales

Estos días he seguido trasteando con Bftpd, y me puse a trabajar en resolver un problema bastante molesto: la cantidad de procesos zombie que deja tras de sí.

Para entender lo que pasa, primero hay que explicar que Bftpd lanza un nuevo proceso por cada nuevo usuario que se conecta, en lugar de utilizar un solo proceso para gestionar todas las conexiones. Así, tenemos un proceso padre que se limita a escuchar, y cada vez que llega una petición de conexión crea un proceso hijo para que la gestione; también comprueba cuando un hijo se muere (porque se haya cerrado la conexión).

Y aquí es de donde surge el problema: cada vez que un hijo termina, emite una señal (en concreto SIGCHLD) hacia el padre, el cual, al recibirla, ejecutará una pequeña función o callback y luego seguirá su ejecución normal. En el caso de Bftpd, dicho callback comprueba qué hijo es el que se ha muerto, pide su valor de retorno (para evitar que se quede zombie) y libera una serie de recursos que le reservó. En concreto, el código de dicha función comienza con un:

pid = wait(NULL);
[codigo para liberar los recursos del proceso PID]

Hasta aquí todo parece correcto; por desgracia, después de cada sesión con Bftpd quedaban varios procesos zombie. La razón era, obviamente, que el proceso padre no había leído su valor de retorno, por lo que el sistema operativo no los podía hacer desaparecer; sin embargo, en el callback se lee siempre dicho valor, así que es obvio que algo raro estaba pasando.

Para depurar el código empecé por añadir unos printfs: uno en el punto en que se crean los procesos hijo, mostrando su PID; otro en el punto de finalización de dichos hijos, y otro en la función de callback de SIGCHLD. Ejecuté el servidor, hice unas cuantas operaciones, vi la salida por pantalla, y… ¡Sorpresa! ¡Había menos llamadas a la función de callback que muertes! Si todo funcionase como se esperaba, el número debería ser exactamente el mismo (cada muerte debería emitir una señal SIGCHLD, la cual haría que se ejecutase el callback). Sin embargo, por alguna misteriosa razón, algunos procesos morían sin emitir la señal.

Para aquellos a los que les de igual el por qué, y simplemente necesiten saber el como, daré primero la solución: se trata de leer los PIDs de todos los hijos muertos en cada llamada al callback, en lugar de leer el de uno sólo. En otras palabras, el código del callback para SIGCHLD debe ser:

do {
        pid = waitpid(-1,NULL,WNOHANG);
        if (pid>0) {
            [codigo para liberar los recursos del proceso PID]
        }
} while (pid>0);

Vale, pero ¿por qué ocurre esto?

Para entender lo que ocurre hay que irse un poco a las profundidades del núcleo, porque se debe a un problema de cómo están implementadas las señales.

En Linux, cada proceso tiene un conjunto de bits, y cada uno representa una señal. Cuando un proceso quiere enviar una señal a otro, lo que hace realmente es poner a uno el bit de dicha señal en el proceso receptor.

¿Y cuando comprueba el receptor la llegada de una señal? En cada cambio de contexto: en un sistema operativo multitarea, los procesos se van turnando en el uso de la CPU, de manera que primero la usa unos milisegundos el proceso A, luego otros milisegundos el proceso B, y así sucesivamente hasta que se acaba la lista y se vuelve al proceso A. Cada vez que se cambia de un proceso al siguiente se realiza un cambio de contexto, en el que primero se guarda el estado del proceso actual, se busca quien será el siguiente proceso, se carga su estado y se le cede el control. Pero, y aquí está la cuestión, antes de este último paso se comprueba la máscara de bits de las señales, y si alguna está activa se ejecutará primero el callback correspondiente.

¿Y por qué se pierden entonces señales SIGCHLD? Pues porque dos o más procesos se mueren «a la vez»; esto es, se mueren dentro del mismo intervalo entre dos ejecuciones del proceso padre. Así, lo que ocurre es que cuando se muere el primero, pone a 1 el bit de la señal SIGCHLD del proceso padre; el repartidor de tareas, al ver que ha muerto, libera todo lo que puede y pasa al siguiente proceso; éste muere también, y también pone a 1 el bit de la señal SIGCHLD del proceso padre… pero ese bit ya estaba a uno, por lo que se queda como está. Finalmente, el repartidor decidirá que es el momento de ejecutar de nuevo el proceso padre, pero antes verá que el bit de la señal SIGCHLD está activo, por lo que lo pondrá a cero y  llamará al callback. El resultado: se murieron dos procesos pero sólo se ejecutó una vez la función asociada a la señal, por culpa de que las señales se almacenan con un único bit.

Es por esto que la solución indicada arriba funciona: la señal nos indica que se ha muerto AL MENOS un proceso hijo, así que debemos comprobar todos, y no asumir que cada uno enviará una señal.

Este caso nos demuestra que las señales son un sistema de comunicación bastante frágil, por lo que no se debe abusar de él. Cosas como «contar el número de veces que llega una señal» o similares pueden dar problemas incluso si hay un único emisor, porque si emite varias veces la misma señal antes de que el padre recupere el control de la CPU, contarán como una única señal. Y como muestra para los incrédulos, un pequeño programita que ejemplifica todo esto:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <signal.h>

int v;

void senal(int valor) {

 printf("Recibidan");
 v++;
}

int main(int argc, char **argv) {

 int pid1,pid2,pid3,pid4,loop;

 v=0;
 signal(SIGUSR1,senal);
 pid1=getpid();
 pid2=fork();
 if(pid2==0) {
 fork();
 fork();
 printf("hijon");
 kill(pid1,SIGUSR1);
 kill(pid1,SIGUSR1);
 kill(pid1,SIGUSR1);
 kill(pid1,SIGUSR1);
 kill(pid1,SIGUSR1);
 sleep(2);
 } else {
 printf("padren");
 for(loop=0;loop<21;loop++) {
 sleep(1);
 }
 printf("Total: %dn",v);
 }
}

Este código crea un primer hijo, el cual se divide en cuatro hijos en total, y cada uno emite, de golpe, cinco señales SIGUSR1 al padre. Sin embargo, al ejecutarlo veremos que nunca se detectan todas ellas, sino, como mucho, una por proceso hijo (y a veces ni eso).

España es asín, o la chapuza de la TDT

Que en ¡Ejpaña! hacemos las cosas como las hacemos es bien sabido desde hace décadas. Pero ni con esas consigo acostumbrarme, oye.

Porque dejando de lado todo el tema de que sea ahora cuando, después de dos años de despliegue, se saquen de la manga la TDT de pago, con lo que la gente que quiera verla tendrá que tirar su deco y comprar uno nuevo con ranura para la tarjeta…

Porque dejando de lado que en unos meses saldrá la TDT de alta definición utilizando H.264, por lo que los decos y teles que se han comprado hasta ahora tampoco valdrán, porque sólo soportan MPEG-2…

Porque dejando de lado todas esas chapuzas que, dentro de lo que cabe, aún tienen una explicación lógica (que la gente gaste una y otra vez, dando más beneficios a los fabricantes de decos), lo que no consigo entender es quien fue el iluminado al que se le ocurrió programar el apagón analógico justo para mitad de la semana santa, cuando todos los comercios estarán cerrados, cuando no podrás llamar al antenista para que te corrija el problema de última hora, etc, etc, etc.

Señores políticos, que a estas alturas deberían saber perfectamente que aquí lo dejamos todo para el último momento.

¿Pero de qué me sorprendo? ¡Si a estas alturas soy YO quien debería saber perfectamente como son nuestros políticos!

Bftpd 2.7 para el LX Multimedia

Nueva versión del paquete ftp_bt4lxmedia, esta vez la 4.2, con la versión 2.7 de BFTPd. Las versiones anteriores enviaban un mensaje de error incorrecto al intentar borrar una carpeta con el comando de borrar archivos, lo que confundía al cliente FTP de Nautilus (el escritorio de Gnome) e impedía, por tanto, borrar carpetas desde él. La nueva versión ya permite borrarlas casi sin problemas.

Y digo casi porque, haciendo pruebas, surgió otro problema, y es que el comando ls -la no devuelve los ficheros ocultos, lo que hace que, si en una carpeta hay alguno, de un error al intentar borrarla. Voy a echar un vistazo al código a ver si puedo enviar al autor otro parche que corrija este detalle.

El paquete se puede encontrar en mi web, en un nuevo apartado que hice en la sección Programas.

Transmission 1.92

Acabo de lanzar una revisión del paquete de mejoras para el disco duro multimedia MemUp LX media. El cambio es la actualización del cliente BitTorrent Transmission a la versión 1.92.

AVISO: a partir de aquí empiezo a tocar en el sistema operativo del disco duro multimedia, lo que significa que estas acciones sólo las deben realizar aquellos que sepan muy bien lo que hacen. Si alguien se carga su disco, será el único responsable.

Avisados estáis.

La instalación es igual que en versiones anteriores: basta con bajarse el fichero ftp_bt4lxmedia_4.1.tar.bz2 y actualizar los ficheros indicados.

Al igual que en versiones anteriores, los binarios contenidos en este paquete están enlazados estáticamente, por lo que funcionarán en cualquier sistema con procesador MIPSel.

Si ya habías instalado una versión igual o anterior a la 3.0 de ftp_bt4lxmedia, debes borrar el fichero /tmp/hdd/volumes/HDD1/BT/transmission_tmp/settings.json o editarlo para modificar el parámetro rpc-whitelist.

Como ya avisé en un mensaje anterior, aquellos que se decidan a probarlo deben limitar el cliente BitTorrent (sea el que sea) a no más de 300 o 400 KBytes/seg de bajada, porque si se recibe a más velocidad, el disco multimedia se satura y acaba colgándose.

Entradas anteriores: