« Pour ne pas perdre la face | Le prix à payer » |
J'ai une crise de foi, je l'avoue humblement. Depuis quelques jours, rien ne va plus. Contributeur aux logiciels libres et soucieux de la qualité du produit, je déprime. En fait, je déprime depuis que j'ai vu les sources d'un micro-noyau pour essayer de relancer FreeVMS. L'idée est de relancer le projet en utilisant un micro-noyau et en codant les serveurs dans un langage solide comme ADA. La procédure de compilation de ce micro-noyau est une aberration comme je n'en ai que rarement vu et je n'en suis pas encore arrivé au bout. Pourtant, je m'obstine.
J'ai fait mes armes en Fortran 77, voire 66, entre un VAX et un Convex. Arrivé à l'armée — oui, je suis un vieux con modèle réserviste qui a eu l'immense chance de passer plus d'un an dans les rangs de l'armée et qui regrette que ce ne soit plus une obligation tant cela apprendrait à certains bipèdes à vivre —, j'étais enfermé dans une cage de Faraday à produire du code C89 aux normes des laboratoires de la défense, le genre de code C qui ne plante pas, où l'on vérifie toutes les valeurs de retour des fonctions, où l'on regarde à deux fois les types des objets. J'avais même derrière moi un spécialiste de la revue de code. Depuis, mes productions sont carrées, rien ne dépasse et voir les sources d'un simple noyau Linux me fiche un coup de bourdon indescriptible.
Pour pouvoir écrire des choses simplement, c'est-à-dire avec un environnement de développement correct et un compilateur décent et 32 bits, j'ai été amené à utiliser un système s'appelant Linux. C'était au siècle dernier sur un i386DX16/i387DX16 avec 8 Mo de mémoire, le noyau était un 1.0.9 parfaitement utilisable. Depuis, il y a eu quelques évolutions comme le 2.0 et le 2.2, dernier noyau réellement utilisable. Quoique s'il on regarde de plus près, on peut raisonnablement se demander ce que faisait un serveur web dans le noyau 2.2. J'avais alors la foi et étais prêt à lancer une sainte croisade. Et tout s'est dégradé. D'abord, on a eu le 2.4 et aujourd'hui, il faut faire avec un noyau 2.6 qui ne ressemble plus à rien. Il n'y a plus de branche de développement séparée. En dehors de l'architecture principale amd64, le reste fonctionne au petit bonheur la chance et il n'y a plus aucune garantie d'avoir un noyau bootable lorsqu'on le pêche directement dans la branche 2.6 de kernel.org. On ne sait pas pourquoi des pilotes stables depuis des années ne sont pas intégrés au noyau alors que de sombres saletés le sont. Les API changent subtilement d'un patch à l'autre.
Et c'est sans compter avec la glibc. Le type qui développe cette bibliothèque est un sombre idiot qui n'est pas capable de comprendre des spécifications qu'il prétend pourtant avoir lui-même écrites. Pour avoir poussé la programmation POSIX jusque dans des coins obscurs des spécifications, je suis tombé sur un certain nombre de problèmes inhérents à la glibc. À chaque fois que je remontais des rapports de dysfonctionnement, la réponse était toujours la même : l'erreur était dans mon code et non dans la glibc. Jamais, ce Ulrich Drepper n'a pu accepter qu'il était incapable de faire la différence entre un « shall » et un « should ».
Exemple :
PTHREAD_KILL(3) Manuel du programmeur Linux PTHREAD_KILL(3)
NOM
pthread_kill - Envoyer un signal à un thread
SYNOPSIS
#include <signal.h>
int pthread_kill(pthread_t thread, int sig);
Compilez et effectuez l'édition des liens avec l'option -pthread.
DESCRIPTION
La fonction pthread_kill() envoie le signal sig à thread, un autre
thread du même processus que l'appelant. Le signal est dirigé de
manière asynchrone vers thread.
Si sig est 0, aucun signal n'est envoyé, mais la détection d'erreur est
quand même effectuée. Cela peut être utilisé pour vérifier l'existence
d'un identiant de thread.
VALEUR RENVOYÉE
En cas de réussite, pthread_kill() renvoie 0 ; en cas d'erreur, elle
renvoie un numéro d'erreur, et aucun signal n'est envoyé.
ERREURS
ESRCH Aucun thread avec pour identifiant thread n'a pu être trouvé.
EINVAL Un signal invalide a été spécifié.
CONFORMITÉ
POSIX.1-2001.
Oui, je vous ai mis directement la traduction de la page du manuel en français. J'ai tout de même vérifié les spécifications POSIX et les pages de manuel de tous les autres systèmes POSIX à ma disposition : OpenVMS, NetBSD, FreeBSD et Solaris. Toutes sont d'accord entre elles et confirment bien cette page.
Notez qu'il est indiqué qu'on peut utiliser un sig
nul pour tester l'existence du thread. Si le thread n'existe pas, la fonction doit renvoyer la valeur ESRCH
. Le type pthread_t
est un type opaque. Dans tous les systèmes corrects, cette valeur n'est pas directement un pointeur, il y a toujours une indirection. Cela signifie qu'on peut utiliser cette fonction pour tester la présence d'un thread. Sous Linux, pour des raisons de performances — tu parles, ça évite juste une indirection et un tableau de pointeurs dans la mémoire statique du processus —, il s'agit d'un pointeur. Lorsque le thread n'existe plus, la mémoire pointée est libérée et pthread_kill()
renvoit bien une erreur, mais une erreur sale de segmentation. Pour des raisons de performances, on doit alors ou placer un gestionnaire de signal sur SIGSEGV
, ce qui n'est pas toujours ni aisé ni faisable, soit rajouter des mutexes un peu partout pour être sûr, lorsqu'on envoie un signal à un thread, que ce thread existe toujours. C'est donc optimal du point de vue de la glibc mais pas du tout du point de vue du programme. Ce qui est amusant, c'est que tous les programmes qui utilisent cette fonction avec un signal nul et qui n'ont pas été développés sous Linux risquent d'avoir de sérieux problèmes.
Des exemples comme celui-là, j'en ai des tas, et pas que dans la glibc. Il y en a dans un paquet de bibliothèques livrées en standard avec toute distribution Linux qui se respecte. Mais il y en a aussi dans le noyau. Les développeurs du noyau touchent à tout et dans tous les sens. Ils développement essentiellement sur x86 et se contrefichent des problèmes d'alignement de la mémoire ou d'ordre des octets. Cela peut donner des choses amusantes. Entre la libpcap qui ne fonctionnait plus du 2.6.27 au 2.6.30 sans la patcher dans tous les sens, les règles iptables qui ne fonctionnent plus sous 2.6.35, le pilote i2c_bbc qui est cassé depuis le 2.6.27, l'instabilité chronique du 2.6.36, les utilisateurs de sparc64 sont des petits gâtés.
Utilisant Linux sur des architectures différentes du PC x86, j'ai de plus en plus l'impression d'essuyer les plâtres avec une brique.
Développeurs, il est grand temps de rechercher la qualité. Linux s'est imposé par sa qualité. Ne cassez pas ce que vous avez créé. Ne perdez pas de vue que si Linux est la partie émergée de l'iceberg, il a entraîné un certain nombre d'autres projets dont certains pourraient lui damer le pion. OpenBSD est prétendûment sécurisé, mais il est inutilisable pour autre chose qu'une machine frontale. FreeBSD suit malheureusement la philosophie linuxienne. Mais il reste NetBSD, activement développé et bien plus propre que Linux.
Et pour ne pas aggraver ton coup de bourdon, je te déconseille de te jeter sans parach^aspirine dans l’utilisation des APIs “userland” d’ALSA-MIDI et de Video4Linux,
Le problème, c’est que les documentations ne sont utilisables que par ceux qui n’ont plus besoin de les lire, et qu’il faut souvent plonger dans le code source de la machinerie sous-jacente pour comprendre ce que l’on essaye de faire.
Bon, oké, pour v4l, l’extrême variété des périphériques gérés explique (ou excuse) un peu le fouillis, mais quand même…
Je tiens à ma santé mentale. J’ai déjà du mal avec L4ka qui a des API stables, je ne vais pas essayer de comprendre comment fonctionne V4L. Enfin, pas ce soir…
Dans mon souvenir et wikipedia semble aller dans mon sens, tux n’a jamais été accepté directement dans le kernel 2.2 ( même si des distros ont proposés le patch, vu que les developpeurs de RH parle de rebaser le patch : http://kernelslacker.livejournal.com/tag/tux). Par contre, il y a eu un serveur du nom de khttpd cf la page wikipedia (http://en.wikipedia.org/wiki/TUX_web_server ), et il a lui aussi disparu.
Quand à l’API stable du kernel, il suffit de chercher un peu pour trouver que des codeurs kernels expliquent leur point de vue : http://www.kroah.com/log/linux/stable_api_nonsense.html
Ceci dit, comme je le dit si souvent, personne ne force les gens à utiliser Linux, et je pense qu’un projet comme NetBSD ferait plus ton bonheur au niveau de la portabilité ou de la stabilité. On parle pas assez souvent des alternatives, et c’est dommage.
Je parlais de khttpd qui n’avait strictement rien à faire dans un noyau. Ou alors, il faudrait que je retourne en cours pour qu’on essaie de me réapprendre ce qu’est le noyau d’un système d’exploitation.
Pour rester sur la stabilité des API, il est évident qu’elles ne peuvent être stables sur le long terme. Ma remarque ne porte pas sur le long terme, mais sur une échelle de temps beaucoup plus courte. Aujourd’hui, en dehors de l’architecture principale, les développeurs (dont je faisais modestement partie pour une architecture qui n’est pas dite prioritaire) n’arrivent plus à convertir les pilotes spécifiques assez rapidement au vu du changement des API. On se retrouve donc avec des pilotes complètement cassés depuis trop longtemps, voire avec des instabilités des noyaux comme trop régulièrement sur Sparc64. Comme l’architecture de Linux est mauvaise (monolithique avec seulement deux anneaux), l’instabilité d’un pilote provoquée par un subtil changement d’API plante tout le système.
J’ai un exemple particulièrement amusant. La température des processeurs UltraSPARC-III+ est notoirement mal lue depuis quelques révisions du noyau (avant que le pilote du bbc soit complètement cassé). Lorsque la valeur renvoyée est supérieure à 85 °C, le noyau envoie un signal d’arrêt. J’ai donc des serveurs qui s’arrêtaient aléatoirement, jusqu’à ce que je décide de virer ce support du noyau. Et qu’on ne me dise surtout pas que les processeurs surchauffaient parce que ces machines possèdent une protection matérielle qui les arrête violemment en cas de surchauffe ! Il a été impossible de trouver quel était la modification du noyau dans la série 2.6 qui provoquait une mauvaise lecture de cette température et on y a passé du temps !
Il faut donc pour un système comme Linux (ou les BSD) que les API du noyau soient assez stables pour que le système entier le soit. Un système comme NetBSD y arrive. Linux ne peut aujourd’hui y arriver parce que j’ai de plus en plus l’impression que son seul but est de concurrencer Windows et de supporter toujours plus vite les nouveaux périphériques au détriment des anciens. La conséquence est un effort de développement sur l’architecture principale en laissant mourir les autres.
Et là, je ne parle que du noyau, pas de toutes les bibliothèques dont certaines comme la glibc sont développées à la va comme je te pousse. C’est ailleurs certainement voulu pour que de plus en plus de programmes soient développés sous Linux et qu’il faille tellement de ‘workarounds’ qu’ils ne tournent plus directement sur d’autres systèmes Unix.
http://linuxfr.org/2010/10/21/27463.html
et cela ne va pas vous mettre de bonne humeur: je n’ai rien lu sur la lecture de la température des processeurs UltraSparc-III-+ :-)
Mais les diodes des claviers des portables Toshiba clignotent enfin correctement. Ma femme possède un portable Toshiba. Je n’avais pas remarqué d’anomalies, mais voyez vous, avec cette nouvelle version du noyau: je suis un homme heureux :-D
Comme nous sommes sous Linux Mandriva, alors vivement l’arrivée de la première version du fork qui vient de naître avec la dernière version du noyau : Mageia :-)
Je n’ai jamais eu de problème avec les diodes des claviers Toshiba… Pourtant, je n’ai que ça sous la main ! Concernant Mageia, je ne sais pas si c’est une bonne ou une mauvaise nouvelle. Je crois franchement que la meilleure chose qui puisse arriver à Linux, c’est un fork du noyau pour le stabiliser une fois pour toute et non le fork d’une distribution…
oui mais quand même: Linus Torvalds ferait beaucoup mieux de traiter les vrais problèmes du noyau plutôt que de faire en sorte que les diodes des portables Toshiba fonctionnent (alors qu’amha, leur fonctionnement est déjà correct).
D’ailleurs, sauf erreur de ma part, il s’est déjà plaint lui même de la “grosseur” du noyau.
Le problème du noyau Linux et par conséquence de Linus Torvalds est l’architecture Unix. Loin de moi l’idée de cracher dans la soupe, mais cette architecture n’est pas bonne. C’est juste la moins pire qui existe dans le monde du système d’exploitation libre. Globalement, il n’y a que deux niveaux de protection, celui du noyau et celui de l’utilisateur, et tous les pilotes doivent tourner en mode noyau. Un noyau comme Linux est donc obligé d’intégrer de plus en plus de pilotes dont certains ont été écrits par des pieds et d’autres sont fournis sous forme de binaires buggués jusqu’à la moëlle. Ces pilotes ont accès à toute la mémoire et ceux-ci peuvent planter le système. Il n’est pas rare de trouver des accès à des (void*) NULL pour signaler des erreurs ! Le résultat est au mieux un Oops, au pire un Panic et tout le système est en vrac.
Les autres Unix sont confrontés au même problème, mais la solution est différente. Un système comme NetBSD affiche moins de pilotes, mais ceux-ci sont mieux testés et globalement NetBSD est largement plus stable que Linux, au moins depuis les noyaux Linux 2.6. J’ajoute que lorsqu’on remonte un bug critique chez NetBSD ou FreeBSD, il est traité dans la semaine. Sous Linux, il est traité si le bug concerne l’architecture mainstream.
À l’opposé, un système façon VMS segmente la mémoire en plusieurs morceaux indépendants. D’un côté, il y a une couche d’abstraction compacte (mode kernel) qui appelle un noyau (mode executive) s’occupant de la mémoire et du scheduler (avec naturellement, toute la gestion des processus). Les pilotes fonctionnent dans des espaces mémoire distincts (mode supervisor). Si jamais un pilote se tire une balle dans le pied, il est seul à exploser et le noyau ne s’en porte pas plus mal. Quant à l’utilisateur, il est dans l’espace dit utilisateur et peut faire ce que bon lui semble. Au pire, ça terminera par un “access violation". La contrepartie est qu’un développeur peut écrire des pilotes n’importe comment, ça ne touchera jamais la stabilité du système.
Pour revenir au problème de Linus, son noyau lui échappe parce qu’il est monolithique. Il ne peut donc qu’enfler s’il doit supporter de plus ne plus de matériel dernier cri et devenir instable si ces pilotes (ou ces matériels) sont mal ficelés. C’est donc plus un problème de design lié à l’architecture Unix qu’un problème de volonté du concepteur.