David Madore's WebLog: Linux

This WebLog is bilingual, some entries are in English and others are in French. A few of them have a version in either language. Other than that, the French entries are not translations of the English ones or vice versa. Of course, if you understand only English, the English entries ought to be quite understandable without reading the French ones.

Ce WebLog est bilingue, certaines entrées sont en anglais et d'autres sont en français. Quelques-unes ont une version dans chaque langue. À part ça, les entrées en français ne sont pas des traductions de celles en anglais ou vice versa. Bien sûr, si vous ne comprenez que le français, les entrées en français devraient être assez compréhensibles sans lire celles en anglais.

Note that the first entry comes last! / Notez que la première entrée vient en dernier !

Index of all entries / Index de toutes les entréesXML (RSS 1.0) • Recent comments / Commentaires récents

Entries with category linux / Entrées de la catégorie linux:

(lundi)

Encore une râlerie sur CUPS

J'ai déjà dit que je détestais CUPS ? Ah oui, et plus d'une fois.

Le contexte : Télécom ParisSaclayPloumTech a mis en place un nouveau système d'impression : maintenant, pour imprimer un document, il ne nous est plus possible de simplement l'envoyer à l'imprimante et aller le chercher un peu plus tard : à la place, il faut l'envoyer à un serveur centralisé, puis marcher jusqu'à l'imprimante, badger avec notre carte RFID, sélectionner le document qui est censé être apparu dans une liste de travaux d'impression, et poireauter le temps que l'imprimante fasse son travail. Le motif officiel du changement est que c'est tellement plus simple, plus commode, plus confidentiel et globalement plus mieux comme ça. Le motif réel est sans doute de contrôler la dépense de consommables : ce qui est parfaitement légitime, parce que vu que j'ai déjà gâché une centaine de pages juste pour réussir à faire fonctionner tout ce foutoir, j'imagine effectivement qu'il y a beaucoup de pertes, et le fait de devoir attendre devant l'imprimante pour que le document sorte limitera sans doute le zèle dont on peut faire preuve en matière de consommation de papier.

Maintenant, pour imprimer avec ce système centralisé, il faut soumettre le document au serveur CUPS central (qui va ensuite l'envoyer à l'imprimante qui le demande, je ne sais pas par quel protocole). Il faut donc convaincre mon serveur CUPS local (celui qui tourne sur mon ordinateur de bureau) d'envoyer les documents que je veux imprimer au serveur CUPS central de l'école. Jusque là, pas de difficulté : il suffit de déclarer une imprimante ipps://le-serveur-centralise.telecom-parissaclayploumtech.tld/printers/Central_Printer et d'y envoyer tout. • La difficulté, en revanche, c'est que mon nom d'utilisateur n'est pas le même sur ma machine locale (où c'est mon prénom) que sur le système d'authentification de l'école dont dépend le serveur centralisé (c'est mon nom de famille). En principe, il devrait suffire de changer l'adresse ci-dessus en ipps://monlogin@le-serveur-centralise.telecom-parissaclayploumtech.tld/printers/Central_Printer pour que ça marche. Sauf que cet imbécile de CUPS ignore purement et simplement la partie monlogin@ de l'adresse sans me dire ni que l'adresse est incompréhensible ni qu'il ne peut pas utiliser de login différent ni quoi que ce soit. Pas de panique : on peut aussi changer les options job-originating-user-name ou requesting-user-name dans les réglages de l'imprimante. Sauf qu'en fait non : soit je n'ai pas réussi à trouver comment les changer, soit ça n'a aucun effet (de nouveau, ces paramètres sont ignorés silencieusement, ils ne provoquent pas d'erreur ou d'avertissement quelconque). • Bon, alors que conseille le service informatique ? Une solution affreuse : au lieu de changer le login auquel le document sera envoyé sur leur serveur à eux, ils proposent de le changer dès le serveur local (i.e., envoyer les documents à mon serveur CUPS local sous mon nom de login distant). Cette solution est affreuse, parce que ça suppose que je ne parlerai jamais à d'autre serveur CUPS (ce qui est sans doute vrai de ma machine de bureau, mais beaucoup plus incertain pour ce qui est de mon portable), ou en tout cas d'autre serveur CUPS sur lequel j'aurais un login différent. Elle est affreuse, aussi, parce que ça veut dire que je dois la répéter pour chacun des comptes sur mon ordinateur local sur lequel je peux avoir envie d'imprimer. Et elle est affreuse parce que ça signifie que tous les mécanismes de configuration de CUPS par l'interface Web ne vont pas en tenir compte (par exemple, ça casse la possibilité d'imprimer une page de test simplement). Mais admettons, je me résous à cette solution affreuse. Je modifie donc mon $HOME/.cups/client.conf pour y ajouter User monlogin (et je redémarre tout ce qui a un rapport avec CUPS). Est-ce que ça marche ? Non, bien sûr : de nouveau, la précision est purement et simplement ignorée. Finalement, ce qui a marché est d'ajouter une variable d'environnement CUPS_USER=monlogin (et ajouter une variable d'environnement dans les environnements graphiques d'Unix, i.e., convaincre tout le labyrinthe de programmes Gnome, KDE ou autres de propager la valeur de cette variable, ce n'est d'ailleurs pas du gâteau).

Bon, à la limite, je ne me plains pas du fait qu'on doive changer une variable d'environnement ou autre chose. Mais ce qui est franchement insupportable, c'est toutes ces tentatives qui ne font tout simplement rien. Si le serveur ne comprend pas une adresse en ipps://login@server, il devrait la refuser, pas ignorer silencieusement la partie qu'il ne comprend pas ! Si les programmes ne comprennent pas la directive User dans le .cups/client.conf, ils devraient le signaler, pas l'ignorer silencieusement.

Et l'autre chose pénible, c'est que même si maintenant j'ai quelque chose qui marche, est évident que cette solution n'est pas robuste du tout : tôt ou tard, je vais me retrouver dans une situation où la variable CUPS_USER aura disparu (par exemple parce qu'Ubuntu aura changé une fois de plus son mécanisme de démarrage des sessions graphiques et donc cassé mon code) ou bien elle va cesser de fonctionner, ou encore je vais oublier qu'elle est là et vouloir me connecter à un autre serveur et ne pas comprendre pourquoi mon login est madore plutôt que david, ou je ne sais quoi encore. Forcément, ce truc va revenir me mordre un jour ou un autre, et je ne vois vraiment pas comment l'éviter.

[Références : ce bug Ubuntu et ce thread sur serverfault.]

Et hop, une entrée de plus pour le Unix-Haters Handbook.

(mardi)

La 3D sous Linux, c'est toujours incompréhensible

Il y a quatre ans, j'avais écrit cette entrée pour me plaindre que je n'arrivais pas à faire fonctionner la 3D et le WebGL sous GNU/Linux parce que que Personne N'Y Comprend Rien® : ce n'est pas la peine de la (re)lire, parce que je vais surtout me plaindre ici que les choses sont encore largement incompréhensibles. Mais pour tâcher d'être un peu constructif, je vais quand même rapporter les rares choses que j'ai quand même réussi à comprendre. (Je souligne : mon grief n'est pas tant que les choses ne marchent pas — globalement, elles ne marchent pas si mal — mais que c'est si difficile de comprendre comment elles marchent.)

Pour fixer la terminologie pour ceux qui ne sont pas au courant des derniers gadgets à la mode, je rappelle que ce que j'appelle la 3D, c'est un ensemble d'interfaces graphiques permettant d'effectuer du dessin principalement (quoique non exclusivement) orienté vers le tracé d'images tridimensionnelles (c'est-à-dire, plus exactement, de projections en deux dimensions d'images tridimensionnelles) — l'opération de base étant typiquement le tracé d'un triangle en projection (on trace des formes plus complexes en les triangulant), l'intérêt étant notamment que le mécanisme 3D va s'occuper de ne tracer que les triangles visibles et pas ceux qui sont masqués par d'autres. Les calculs peuvent être faits par le processeur principal, ou par des circuits dédiés dans la carte graphique, et dans ce dernier cas on parle de 3D accélérée ou de 3D en matériel. Sinon, on parle de 3D non-accélérée ou émulée ou en logiciel. Faire de la 3D accélérée nécessite un chipset graphique correctement supporté ; faire de la 3D émulée (=logicielle), en revanche, devrait être possible sur absolument tous les systèmes — en contrepartie, c'est plus lent. Je dis devrait, parce que ce n'est pas forcément évident de trouver comment il faut s'y prendre en pratique.

L'interface dominante pour faire de la 3D (et en tout cas celle qui servira sous Unix) s'appelle OpenGL, et il y a une variante d'OpenGL connue sous le nom de WebGL, qui rend ces fonctions graphiques 3D disponibles aux pages Web, c'est-à-dire, aux programmes JavaScript. De plus en plus de pages Web dynamiques se servent de ces fonctionnalités WebGL, par exemple le nouveau Google maps (que je trouve épouvantablement mauvais par rapport à l'ancien, mais c'est un autre problème), même s'il y a un mode lite qui n'utilise pas WebGL et qui sera activé si celui-ci n'est pas disponible. J'avais moi-même écrit (cf. cette entrée passée) un petit jeu de labyrinthe en JavaScript utilisant WebGL, et qui peut servir de test extrêmement simpliste pour vérifier que WebGL fonctionne au moins minimalement (sinon, l'exemple le plus simple qui puisse servir de test standardisé est probablement cette page qui doit afficher un bête cube qui tourne).

J'ai cru comprendre les choses suivantes. Je rappelle que sous Unix (et notamment sous GNU/Linux, au moins avant l'arrivée de Wayland), l'affichage graphique passe par un programme appelé le serveur X[11], qui centralise les accès à la carte graphique, les programmes voulant faire de l'affichage étant alors des clients X, qui parlent au serveur X pour lui demander d'afficher tel ou tel truc. J'ai cru comprendre, donc, qu'il existe quatre mécanismes possibles pour faire de la 3D dans le cadre X11 :

  1. on peut faire de la 3D émulée (c'est-à-dire, non accélérée), et pour ça, il y a deux approches :
    1. soit l'émulation est faite au niveau du serveur X, qui prétend donc avoir des capacités 3D, et qui reçoit des commandes OpenGL (≈GLX) de la part du client, et effectue les calculs 3D de son côté (dans ce cas de figure, le client X n'a même pas à savoir si la 3D est accélérée ou non : il fait des appels OpenGL et le serveur X se débrouille comme il peut avec le matériel derrière),
    2. soit l'émulation est faite au niveau du client X, qui fait les calculs avant de les envoyer au serveur X (dans ce cas de figure, le serveur X n'a rien à savoir de la 3D, il ne reçoit que des ordres de tracé 2D) ;
  2. soit le serveur X parle à une carte graphique capable de faire de la 3D accélérée, reçoit des commandes OpenGL (≈GLX) de la part du client et les transmet à la carte graphique (ou plutôt, au pilote pour la cate graphique qui est dans le noyau Linux), en convertissant éventuellement au passage certaines opérations (dans ce cas de figure, le client voit exactement la même chose que dans le cas (1a) ci-dessus, à savoir, il parle OpenGL à un serveur X qui se débrouille comme il peut derrière) ;
  3. soit enfin le client parle directement à la carte graphique capable de faire de la 3D accélérée : le client négocie avec le serveur X le droit de parler à la carte graphique, et il doit aussi recevoir cette possibilité de la part du pilote noyau, et alors le serveur X se contente de laisser le client s'occuper d'un bout de l'écran (une fenêtre, un tampon graphique dans la carte graphique, je ne sais quoi) (on notera que ce mécanisme est probablement plus rapide que tous les précédents, mais il a l'inconvénient d'exiger que le client tourne sur la même machine que le serveur).

J'ai repris la typologie de l'entrée précédente que j'avais écrit sur ce sujet (en gros du plus lent au plus rapide, sachant qu'entre (1a) et (1b) ce n'est pas certain), mais elle n'est sans doute pas idéale, et il sera peut-être plus clair de la disposer sous forme du tableau suivant :

Indirect renderingDirect rendering
3D émulée (=logicielle)(1a)(1b)
3D accélérée (=matérielle)(2)(3)

J'ai déjà expliqué ce que signifie 3D émulée et accélérée. Le direct rendering fait référence au mécanisme (3), et peut-être aussi à (1b), c'est-à-dire au fait que c'est le client qui gère la 3D directement (soit en parlant au matériel qui va faire les calculs, soit en faisant lui-même les calculs). Lorsque c'est le serveur X qui gère la 3D en recevant des commandes OpenGL du client, on parle d'indirect rendering.

Le mode que tout le monde essaye d'utiliser, puisque c'est le plus rapide, c'est celui que j'ai appelé (3) : l'accélération matérielle avec rendering direct. À cause de ça, il est assez difficile de trouver des informations sur les autres mécanismes (comment les détecter, ou comment les utiliser).

Je répète que je ne suis pas sûr d'avoir bien compris (ni si ceci est toujours d'actualité). Même si j'ai bien compris, je n'ai pas de source fiable pour confirmer mon analyse : personne n'a l'air foutu de faire un petit tableau clair montrant les quatre cas de figure que je viens de décrire ; le plus proche que je trouve d'une confirmation est cette page qui affirme bien que all four combinations of direct/indirect software/hardware rendering are possible, ce qui semble coller avec les quatre cases de mon tableau ; elle explique par ailleurs comment distinguer les cas (1a|2), (1b) et (3) (mais pas comment départager (1a) et (2)) : pour savoir si on est en rendering direct ou indirect, il faut chercher la ligne direct rendering dans la sortie de glxinfo, et pour distinguer (1b) du reste, on devrait voir apparaître Software Rasterizer dans la ligne OpenGL renderer string (mais je soupçonne que cette explication est partielle et cache des choses, cf. plus bas).

On en déduit même quelques indications sur comment forcer certains de ces modes, et l'information semble être sur cette page : mettre LIBGL_ALWAYS_INDIRECT à 1 dans l'environnement force le passage à la colonne de gauche, et mettre LIBGL_ALWAYS_SOFTWARE à 1 force le passage à (1b) (je ne sais pas comment les deux interagissent : je crois que c'est la première qui a priorité ; on ne peut logiquement pas choisir entre (1a) et (2) côté client, ça doit être dans la configuration du serveur — mais je ne sais pas où). Ceci étant, chez moi, LIBGL_ALWAYS_INDIRECT ne marche pas :

vega david ~ $ LIBGL_ALWAYS_INDIRECT=1 glxgears
X Error of failed request:  BadValue (integer parameter out of range for operation)
  Major opcode of failed request:  156 (GLX)
  Minor opcode of failed request:  3 (X_GLXCreateContext)
  Value in failed request:  0x0
  Serial number of failed request:  21
  Current serial number in output stream:  23

…je me demande si le mécanisme (2) est encore supporté ou s'il est tombé en désuétude. Je n'ai pas vraiment envie de pousser mon enquête trop loin, de peur de faire planter mon serveur X, sur lequel j'ai des fenêtres ouvertes que je ne veux pas perdre pour le moment.

Ajout () : Si j'en crois cette page, pour que LIBGL_ALWAYS_INDIRECT=1 fonctionne, il faut mettre l'option IndirectGLX et/ou AllowIndirectGLX dans la configuration du serveur. Je n'ai pas testé.

Une chose pas très claire dans l'histoire, c'est le rôle exact joué par la bibliothèque Mesa, qui est responsable de l'interface OpenGL sous les Unix libres. Celle-ci semble servir à la fois à parler au matériel (via, sans doute, une autre bibliothèque) et à faire de l'émulation logicielle. J'ai tendance à imaginer que dans les cas de figure (1a) et (2), le serveur X doit utiliser la bibliothèque Mesa (dans le cas (1a), pour faire l'émulation, et dans le cas (2), pour parler à la carte graphique) alors que le client utilisera la bibliothèque Mesa dans les cas (1b) et (3) et peut-être en fait dans tous les cas, mais ça non plus, ce n'est pas clair du tout.

Par ailleurs, je crois que les choses sont en fait un peu plus compliquées que ce que suggère la typologie ci-dessus, et qu'il existe plusieurs variantes de (1b). Notamment, si j'en crois cette discussion, où un autre utilisateur tout aussi perdu que moi dans le dédale des subtilités de Mesa se fait engueuler par des développeurs qui daignent à peine expliquer les choses, il y a deux mécanismes pour faire (1b), qui consistent (sous Debian, pour fixer les idées) à utiliser (1b₁) le paquet libgl1-mesa-swx11, ou (1b₂) le paquet libgl1-mesa-glx avec le module/pilote(?) swrast_dri.so — tout ceci n'étant bien sûr documenté absolument nulle part. Je pense que LIBGL_ALWAYS_SOFTWARE force le mécanisme (1b₂), mais je ne suis vraiment sûr de rien. Ce qui est sûr, c'est que chez moi, glxinfo renvoie OpenGL renderer string: Gallium 0.4 on llvmpipe (LLVM 3.5, 128 bits) si j'ai mis LIBGL_ALWAYS_SOFTWARE et Gallium 0.4 on AMD CAICOS si je ne l'ai pas mis, mais apparemment jamais Software Rasterizer comme suggéré par la page mentionnée plus haut. C'est peut-être un signe de la différence entre (1b₁) et (1b₂). Je n'en sais pas plus, et je ne comprends pas grand-chose à ces subtilités.

Ajout () : On me signale en commentaire l'existence de la variable d'environnement (évidemment documentée nulle part…) GALLIUM_DRIVER qui, combinée à LIBGL_ALWAYS_SOFTWARE, permet de choisir entre softpipe et llvmpipe, deux rasterizers logiciels différents de Mesa (que je devrais sans doute appeler (1b₂(i)) et (1b₂(ii))) ; je n'ai aucune idée de la différence entre eux, ni de si swrast est au même niveau que ces deux-là ou encore autre chose. D'autre part, j'aurais dû souligner que si on utilise une carte graphique nVidia avec le pilote propriétaire nVidia, celui-ci vient avec sa propre version de Mesa, qui ne fonctionne pas comme le reste, du coup ces diverses variables d'environnement n'auront pas d'effet (c'est une raison parmi d'autres de ne pas aimer ce pilote propriétaire).

À part les variables d'environnement servant à configurer la bibliothèque Mesa, il existe aussi un fichier .drirc (ou globalement /etc/drirc), lu par Apollon sait qui, dont le seul semblant de documentation semble être cette page (qui ne dit essentiellement rien), celle-ci (idem) ainsi que ce que peut afficher la commande xdriinfo (notamment xdriinfo options 0 et xdriinfo options $(xdriinfo driver 0) si votre écran s'appelle 0, ce qui est probable), mais tout ceci est de toute façon assez incompréhensible.

Mais sinon, une autre difficulté est que Firefox (qui est, après tout, le principal programme sur lequel j'ai envie de faire de la 3D, de façon à avoir du WebGL qui marche) n'utilise apparemment pas Mesa. Enfin, ce dont je suis sûr, c'est que Mesa n'apparait pas dans la liste des bibliothèques chargées en mémoire par lui dans le /proc/$PID/maps de mes processus Firefox. Du coup, les variables LIBGL_ALWAYS_INDIRECT et LIBGL_ALWAYS_SOFTWARE, qui sont lues par Mesa, n'ont pas de raison a priori de fonctionner sous Firefox : comment forcer Firefox à faire du rendering indirect ou du rendering logiciel ? J'avais noté autrefois qu'il fallait faire pointer la préférence webgl.osmesalib vers le chemin de Mesa (du genre, /usr/lib/x86_64-linux-gnu/libOSMesa.so sous Debian) et mettre webgl.prefer-native-gl à false — mais ça ne semble plus marcher. Mais en fait, LIBGL_ALWAYS_SOFTWARE a quand même l'air de marcher chez moi (si j'ouvre about:support, il affiche quelque chose de différent). Soit c'est parce que Firefox utilise quand même Mesa de façon cachée (compilé en statique ? ils n'auraient quand même pas osé ?), soit parce qu'ils ont repris la convention. Au final, je n'en sais rien, et je suis perdu.

Ajout () : On me rappelle en commentaire que Firefox a une liste blanche/noire de pilotes avec lesquels il accepte/refuse de fonctionner. Autrefois, on demandait à Firefox d'ignorer cette liste en mettant MOZ_GLX_IGNORE_BLACKLIST à 1 dans l'environnement, mais ce n'est pas clair que ce soit encore d'actualité : maintenant il semble plutôt que ce soit la variable de configuration webgl.force-enabled qui soit pertinente. L'effet des autres variables mentionnées m'est complètement obscur (qu'est-ce que c'est que le layers acceleration et en quoi est-ce différent de l'accélération 3D ?). Et de nouveau, je ne sais pas si les variables webgl.osmesalib et webgl.prefer-native-gl ont encore un sens.

Bref, voilà à peu près ce que j'ai réussi à comprendre, et où je ne comprends plus. Si par hasard un de mes lecteurs comprend mieux que moi et peut m'éclairer un point quelconque (ou simplement confirmer que j'ai bien compris tel ou tel aspect des choses), je lui en serai très reconnaissant !

On va dire que mon but principal est d'avoir au moins les fonctionnalités WebGL basiques dans Firefox et si possible aussi dans Google Chrome, sur toutes les machines que j'utilise physiquement (c'est-à-dire, le PC qui est chez moi, celui qui est dans mon bureau, et celui qui est chez mes parents). Je souligne qu'à défaut de 3D accélérée par la carte graphique, je suis prêt à me contenter au moins de 3D émulée, si elle marche correctement (c'est plus la fiabilité que l'efficacité qui m'intéresse). Mon PC chez moi utilise une carte graphique AMD (ex-ATI) avec le pilote Linux radeon, ça a l'air de marcher à peu près correctement depuis que j'ai mis à jour ma Debian vers la Jessie (8). Mon PC de bureau utilise une carte graphique nVidia avec le pilote propriétaire nvidia, et les choses marchouillent aussi à peu près (même si je voudrais bien me débarrasser de ce pilote, qui est une horreur). Mon PC chez mes parents, en revanche, utilise une carte graphique nVidia avec le pilote libre nouveau, et si le WebGL fonctionnait (fût-ce lentement) avant la mise à jour de Debian, maintenant ma page de labyrinthe qui me sert de test affiche n'importe quoi (pourtant, glxgears semble marcher correctement) ; c'est peut-être lié à un message d'avertissement me signalant que la variable force_s3tc_enable a été modifiée par rapport au défaut (apparemment c'est quelque chose qui se change dans le .drirc, mais je n'y ai pas touché, donc je n'en sais rien). Je n'ai pas eu le temps de comprendre les choses en détail (notamment parce que je ne connaissais pas certaines des choses que j'ai racontées ci-dessus), mais il est sûr que j'ai encore des choses à régler.

(samedi)

Il faudrait faire une analyse statistique des bugs dans Linux

J'assistais cette semaine, dans le cadre du séminaire Codes sources (dont j'ai déjà dit un mot, et où j'interviendrai moi-même plus tard ce mois-ci), à un exposé de Greg Kroah-Hartman, un des principaux développeurs du noyau Linux (et le mainteneur des noyaux stables/longterm). L'exposé portait sur la manière dont le noyau a commencé à introduire des concepts de programmation orientée objet, en partant du struct device, qui s'est mis à « hériter » de struct kobject puis de struct kref (cet héritage étant cependant sans fait aucune sécurité de typage statique ni vérification à l'exécution, et assuré — de façon très efficace — par la magie de l'arithmétique de pointeurs et de la macro container_of, au sujet de laquelle voir par exemple ici). Je peux peut-être juste lui reprocher d'avoir été un peu rapide (par exemple quand il a discuté de la fonction kref_put_mutexsource ici, cherchez le nom de la fonction — et expliqué pourquoi elle marchait et pourquoi une version antérieure contenait une race-condition, je n'ai pas vraiment eu le temps de digérer). Mais une chose est certaine : malgré des efforts pour harmoniser les API et les rendre plus systématiques et pratiques, la programmation de pilotes de périphériques pour Linux est difficile (et la programmation de nouveaux bus est, à ce qu'a dit l'orateur, extrêmement difficile). (La question a évidemment été posée de si le noyau devrait ou pourrait être programmé dans un autre langage que le C. Greg KH a brièvement mentionné Rust — ce qui m'a fait plaisir, parce que c'est un langage qui me semble très prometteur — mais il est évident que pour l'instant c'est de la science-fiction de penser changer quelque chose d'aussi profond.)

Mais ceci m'amène à une question qui me fascine, et sur laquelle je pense qu'il faudrait vraiment lancer une recherche un peu approfondie :

Peut-on approximer le nombre de bugs (et si possible, plus finement : le nombre de trous de sécurité, par exemple) qui existent actuellement dans Linux ? Peut-on évaluer la probabilité qu'un organisme un tant soit peu motivé (au hasard : la NSA) ait connaissance d'un tel bug qu'il ne dévoilerait pas, voire, en ait planté un volontairement, et la difficulté d'une telle entreprise ?

Je parle d'essayer de faire mieux qu'une estimation « au doigt mouillé », mais de mettre en place des modèles probabilistes un peu sérieux, à la fois de l'apparition des bugs dans le code et de leur détection. Puis fitter ces modèles contre toutes les informations qu'on peut extraire de l'arbre des commits Git et les bugfixes dans les noyaux stables.

Le modèle le plus grossier serait déjà de dire que chaque ligne de code ajoutée comporte une certaine probabilité — à déterminer — de contenir un bug, et que chaque unité de temps qu'elle reste dans le noyau apporte une certaine probabilité — à déterminer aussi — que ce bug soit détecté et corrigé. Rien qu'avec ce modèle grossier, en regardant depuis combien de temps existent les bugs qui sont corrigés dans les noyaux stables, on devrait pouvoir se faire une idée d'un ordre de grandeur du nombre de bugs et de trous de sécurité existant, et de combien de temps il faudrait continuer à maintenir un noyau stable/longterm pour qu'il y ait au moins 99% de chances qu'il ne contienne plus un seul trou de sécurité. Ensuite, on peut améliorer ce modèle de toutes sortes de façons : en raffinant selon l'auteur du code ou le sous-système où il s'inscrit (ou son mainteneur), en essayant d'estimer le nombre de fois que le code a été relu ou utilisé, en catégorisant finement les bugs, ou toutes sortes d'autres choses du genre.

C'est le genre d'idée extrêmement évidente dont je n'arrive pas à comprendre qu'elle n'ait pas déjà été poursuivie (et pourtant je ne trouve rien de semblable en ligne). Ça a pourtant tout pour plaire : on peut y glisser les mots-clés de sécurité informatique, de logiciel open source, de Big Data (la dernière connerie à la mode : il faut que tout soit à la sauce du Big Data maintenant), les conclusions d'une telle étude pourraient certainement intéresser la presse et leur fournir des gros titres racoleurs (cf. la NSA plus haut), ce serait d'ailleurs certainement le genre de choses qui aurait sa place dans, disons, une grande école spécialisée en télécommunications et informatique (exemple complètement au hasard). Mais bon, dans le monde actuel de la recherche, qui fonctionne par « projets » (i.e., par bullshit-scientifique-transformé-en-paperasse-administrative), tout est fait pour couper court à toute forme de créativité ou d'originalité : on ne peut faire quelque chose qu'en étant bien établi dans un domaine et en passant à travers un tel nombre d'obstacles dressés par des organismes à la con (ceux qui sont censés donner des sous pour aider la recherche, et qui dans la réalité servent surtout à faire perdre du temps) qu'il est quasiment impossible de se lancer — pour ma part, je serais certainement intéressé par un projet comme celui que je décris ci-dessus, mais pas au point de passer le temps délirant en écriture de rapports en tout genre qu'il faut soumettre pour obtenir quoi que ce soit de qui que ce soit.

(jeudi)

De la difficulté de soumettre du code à Linux

Il y a des problèmes informatiques qui ne seront jamais résolus parce qu'ils sont intrinsèquement difficiles (par exemple, pour une raison algorithmique) : on est bien obligé de le comprendre. Il y en a d'autres qui posent des difficultés non pas pour des raisons intrinsèques mais pour des raisons historiques : on peut aussi comprendre que ce soit difficile de se battre avec des bizarreries historiques qui se sont profondément enracineés (le changement du protocole Internet d'IPv4 à la version IPv6 représent un bon exemple de cette nature). Mais il y en a aussi, et là c'est vraiment désolant, qui ne seront jamais résolus parce que les gens qui pourraient les résoudre ont des opinions dogmatiques sur la façon dont les choses devraient être faites, et que ces opinions empêchent toute résolution possible du problème. Je voudrais donner un exemple très concret.

Je situe d'abord un peu les choses pour ceux qui ne connaissent pas le monde Unix. Le principal protocole qui permet à Internet de fonctionner est appelé TCP/IP : plus exactement, IP est le protocole qui donne un (ou plusieurs) numéro(s) à chaque ordinateur, et leur permet d'échanger des « paquets » d'information, et TCP vient là-dessus fournir une notion de connexion fiable. Dans le monde Unix, les deux bouts de cette connexion s'appellent des sockets (traduire ça comme des prises et pas comme des chaussettes ; mais en pratique, même quand on parle en français, on dit une socket) : une socket TCP/IP (ou, dans le jargon plus unixien, une socket de domaine AF_INET et de type SOCK_STREAM) est l'abstraction par laquelle un processus (=programme) sur une machine peut parler à un autre, a priori situé sur une machine distante, via le réseau. Maintenant, il arrive aussi qu'un processus veuille communiquer avec un processus sur la même machine : Unix offre un véritable labyrinthe de façons différentes de faire ça ; d'aucunes sont très différentes, mais certaines utilisent la même abstraction de socket. Notamment, deux processus Unix peuvent communiquer entre eux par une socket de domaine Unix (AF_UNIX), qui apparaît alors comme un fichier spécial sur la machine (représentant le point de communication), ou encore par une socket de domaine INET (AF_INET), c'est-à-dire en faisant exactement comme une connexion réseau Internet mais qui se trouve simplement relier la machine à elle-même. Il peut y avoir plein de raisons, liées aux idiosyncrasies d'Unix, de préférer, ou de devoir choisir, une socket Unix ou au contraire une socket INET.

Maintenant, quand deux processus Unix communiquent par une socket de domaine Unix, chacun des deux a la capacité d'identifier l'autre, c'est-à-dire de demander au système qui est en train de me parler par cette socket ? (la réponse donne le numéro du processus et l'identitié de l'utilisateur qui en est propriétaire ; cette réponse est fiable, parce qu'apportée par le noyau Unix lui-même ; techniquement, sous Linux, cette information s'obtient avec getsockopt(socket, SOL_SOCKET, SO_PEERCRED,,)). Quand on a affaire à une socket de domaine INET, en général, vu que la communication peut venir de n'importe où sur Internet, on ne peut pas identifier complètement le processus en face, on peut simplement demander l'identité de la machine en face (son numéro IP ; techniquement, ceci s'obtient avec getpeername(socket,,)). Mais si la socket INET est reliée à la machine elle-même, c'est-à-dire, si deux processus sur la même machine, sont en train de parler entre eux par une connexion TCP/IP, le système pourrait très bien fournir la même information (quel est le processus en face ?) qu'il accepte de le faire pour les sockets de domaine Unix : seulement, il ne le fait pas. Ou plus exactement, ni Linux ni Unix BSD ne le font (Solaris, en revanche, accepte de le faire par l'appel système getpeerucred()).

Or ceci est un manque grave, que je voudrais bien voir corrigé. Pourquoi ? Le problème est que pour toutes sortes de raisons, on peut ne pas avoir le choix du protocole qu'on parle : si on est obligé d'utiliser une socket de domaine INET, le fait de ne pas pouvoir obtenir plus d'information que l'autre bout est sur la même machine empêche de mettre des contrôles d'accès offrant une sécurité minimale dans certaines situations. Je donne un exemple.

(mercredi)

Quelques misères informatiques (et une upgrade d'Ubuntu)

Je vais raconter un peu mes petits malheurs informatiques, ça ne servira à rien sauf à me défouler.

D'abord, le rant général que j'ai déjà dû répéter mille fois : les deux distributions Linux que je connais bien sont Debian et Ubuntu. Le choix entre les deux s'apparente à un choix entre Charybde et Scylla :

(jeudi)

Déprimante sécurité informatique

[La réflexion qui suit est sans doute assez décousue et mal écrite, parce que j'écris comme les idées me viennent, sans prendre le temps de les structurer correctement, et je n'ai pas envie de me relire. C'est même tellement en vrac que les paragraphes qui suivent peuvent sans doute se lire dans à peu près n'importe quel ordre.]

Hier a été révélé un trou de sécurité assez grave dans le noyau Linux (détails ici, ici et  ; et pour une explication très détaillée). Et ce n'est pas comme si c'était rare : des vulnérabilités de cette nature sont annoncées environ tous les deux ou trois mois (estimation au doigt mouillé, je n'ai pas fait de stats précises). À chaque fois je perds des heures à recompiler, ou au moins réinstaller, des noyaux pour toute une flopée de machines que j'administre (déjà pour mes DreamPlugs c'est douloureux, et pour mon téléphone j'ai jeté l'éponge).

C'est tout de même ennuyeux : ça veut dire, par exemple, que toute personne ayant un téléphone Android et n'ayant pas reçu une mise à jour depuis hier, est à la merci d'une application malicieuse qu'il installerait ou aurait déjà installée. (Bon, le côté positif, c'est que ceux qui ont un téléphone Android verrouillé peuvent en profiter pour le déverrouiller, i.e., devenir root dessus.)

Pour éclaircir les choses pour le lecteur profane, précisons que la plupart des systèmes informatiques actuels distinguent essentiellement trois niveaux de confiance :

  1. les administrateurs (root en jargon Unix), qui ont un accès complet à la machine,
  2. tout ce qui tourne sur le système mais qui n'est pas administrateur (les utilisateurs non-privilégiés), et qui a donc un accès limité à certaines ressources,
  3. et tout ce qui n'est pas censé avoir accès au système (i.e., le reste du monde).

Il y a donc, en simplifiant, deux barrières à maintenir : la première interdit aux utilisateurs non-privilégiés d'acquérir le privilège d'administrateur, et quand il y a un trou dans cette barrière le jargon Unix parle de local root exploit ; la seconde interdit au monde extérieur d'entrer dans le système ; parfois un trou permet de passer à travers les deux barrières simultanément, et on parle de remote root exploit (heureusement, c'est très rare). C'est évidemment très simplifié, parce qu'il y aussi des barrières entre les différents utilisateurs non-privilégiés. Le trou que je prends comme exemple est un local root exploit, i.e., un trou dans la première barrière : toute personne ayant un accès à un système Linux peut en prendre un contrôle complet. Par exemple, une application sur un téléphone Android opère comme un utilisateur non-privilégié (il y en a un par application, essentiellement), et comme Android utilise le noyau Linux et que cette vulnérabilité concerne toutes les versions depuis fort longtemps, toutes les architectures, et quasiment toutes les circonstances, ces applications peuvent passer administrateur. Bon, heureusement, on espère que l'immense majorité des applications ne sont pas malicieuses (et notamment celles qu'on utilise depuis longtemps n'ont certainement pas été écrites pour déclencher du code malveillant le jour où un trou de sécurité serait découvert), néanmoins il est certain qu'il y en a. Par ailleurs, cela signifie que si une application, sur un système Linux quelconque, à défaut d'être malveillante, est elle-même vulnérable à autre chose (i.e., qu'il y a un trou dans la deuxième barrière, ce qui est possible pour à peu près n'importe quoi qui communique avec l'extérieur, soit beaucoup de choses), toute la sécurité est perdue.

Je prends surtout l'exemple des téléphones Android, parce que pour beaucoup d'autres systèmes Linux, notamment tout système sur lequel il n'y a qu'un seul compte utilisateur, la barrière entre utilisateur et administrateur ne sert pas à grand-chose : dès que le navigateur web est vulnérable, de toute façon le plus grave est déjà acquis.

Certes, le fait qu'il y ait un trou n'est pas la fin du monde : une vulnérabilité, ça se corrige, le correctif est déjà paru, il suffit de l'appliquer (en plus, pour ce trou particulier, il est possible sur certains systèmes d'appliquer un correctif « à chaud », une rustine sur le trou, comme montré par le deuxième lien tout en tête de cette entrée).

Sauf que : les fabricants de téléphone ne sont généralement pas très pressés d'appliquer des correctifs de sécurité. Ils ne le font que lentement, et, bien sûr, que pour leur tout derniers modèles : HTC, Motorola et toute la bande n'ont qu'un intérêt très faible à s'occuper de la sécurité de leurs clients d'il y a deux ou trois ans. Je pense que les pouvoirs publics devraient imposer à toute personne qui vend un téléphone mobile (ou équivalent : tablette ou autre) qui ne soit pas complètement ouvert de fournir des mises à jour de sécurité pour tous les problèmes portés à sa connaissance et pour une durée clairement annoncée lors de l'achat de l'appareil, et qui ne pourrait pas être inférieure à cinq ans. Ou alors ils doivent fournir toutes les informations nécessaires pour que l'homme de l'art (la communauté, donc) puisse corriger lui-même les trous de sécurité. Parce que actuellement, recompiler un noyau Linux pour son téléphone (sans même parler du reste d'Android), c'est extrêmement difficile : les sources de Linux sont peut-être disponibles, mais pas la configuration exacte que le fabricant a utilisée, sans parler des patchs propriétaires et drivers binaires.

Le problème des trous de sécurité, aussi, c'est que ceux qui les exploitent sont malins : le plus souvent, ils ne l'utilisent pas directement contre le système dont ils exploitent un trou. Par exemple, quand j'attire l'attention de ma maman sur l'importance de mettre à jour tous les logiciels sur son Mac (notamment le lecteur Flash, dont on découvre un trou de sécurité, lui, quasiment toutes les semaines), elle me dit qu'elle n'a rien de vraiment important dessus : ce qui est sans doute vrai, mais ce qui intéresse les black hats payés par la mafia russe ou chinoise ce n'est pas d'avoir accès aux photos de chat sur le Mac de ma maman, c'est de se servir de ce Mac comme un relai ou membre d'un botnet pour, dans le meilleur des cas, envoyer du spam pour du Viagra, et dans le pire des cas, monter des attaques denial-of-service (c'est-à-dire qu'on ne cherche pas à pénétrer la cible, on cherche à la submerger de requêtes) contre, par exemple, l'architecture centrale d'Internet.

Tout ceci est fort déprimant parce que la sécurité informatique est un sujet sur lequel l'utilisateur lambda n'est pas renseigné, et on ne peut donc pas s'attendre à ce qu'il ait des réactions sensées — le plus souvent, cela reste au niveau du quasi-rituel, comme faire tourner des antivirus. Et surtout, il faut bien l'avouer : nous (nous humains, collectivement) ne savons pas programmer : en théorie il est parfaitement possible de faire du code qui ne comporte aucun trou de sécurité, mais nous ne savons pas (il y a des gens qui prétendent savoir écrire du code sans aucun trou de sécurité, et qui ont sans doute raison, mais bizarrement ils n'écrivent jamais quelque chose d'aussi complexe qu'un navigateur web). Du coup, on se retrouve devant cette boucle infinie : trouver un trou, se précipiter pour le boucher, attendre le suivant, répéter à l'infini. Et celui qui a trouvé un trou sans prévenir les autres (le black hat), il a un pouvoir potentiellement immense. Or le trou qui me sert de prétexte pour écrire cette entrée, il semble que certains le connaissaient depuis deux ou trois ans et le gardaient pour eux (et il est probable que l'auteur de l'exploit en ait un bon nombre d'autres comme ça sous le coude).

La moindre des choses, je trouve, ce serait d'essayer de faire une estimation du nombre de trous de sécurité de cet ordre qui existent actuellement dans Linux. Je pense qu'on doit pouvoir y arriver avec des statistiques assez élémentaires : en regardant l'âge de chaque bout de code au moment où un trou est découvert dedans, on doit pouvoir estimer le temps moyen qu'un trou survit avant d'être détecté et corrigé — et on pourra alors estimer le nombre typique de trous par ligne de code, et donc le nombre de trous total dans Linux (il faudra sans doute faire des stats un peu plus fines parce que toutes les lignes de code ne sont pas équivalentes, mais toujours est-il que c'est possible, et ce serait un travail intéressant à refiler à un étudiant ou stagiaire, je devrais y réfléchir).

Y a-t-il une lueur d'espoir ? Il me semble en effet que la meilleure — ou plutôt la moins mauvaise — réponse que nous ayons pour l'instant trouvé aux trous de sécurité, ce sont les mécanismes de cloisonnement (sandboxing) en tous genres : c'est-à-dire tout ce qui permet d'ajouter de nouvelles barrières de sécurité, et notamment de donner le moins de permissions possibles aux programmes auxquels on n'a pas la plus grande confiance, ou dont ils n'ont pas besoin (par exemple, le trou dont je parle initialement repose sur l'utilisation de l'appel système exotique sys_perf_event_open() : et il y a beaucoup à dire sur le fait qu'on ne devrait pas donner à quelque programme ou utilisateur que ce soit le droit de faire un appel système sortant des appels Unix traditionnels sans une bonne raison). Malheureusement, les mécanismes de cloisonnement souffrent de beaucoup de problèmes d'utilisabilité : mettre en place une machine virtuelle est encore lourd et pénible (quand le BIOS de votre portable ne vous l'interdit pas tout simplement), et pour ce qui est de cloisonnements moins lourds, même si ce genre d'outil a l'air extrêmement utile et prometteur, ça reste encore très difficile et mal supporté de faire quelque chose d'aussi simple que lancer un processus sous-privilégié sous Linux.

(vendredi)

Le labyrinthe de l'impression sous Unix

Il m'arrive de vouloir lire des documents sous forme de traces de carbone sur des bouts d'arbre mort (plutôt que sous forme d'excitations de photophores derrière un plastique mal fichu). Fort heureusement, notre civilisation a conçu des engins prévus spécifiquement pour déposer du carbone sur des bouts d'arbre mort, ça s'appelle des imprimantes. Malheureusement, si Unix a prévu des moyens pour ce servir de ces engins, il en a prévu trop, si bien qu'on se perd rapidement dans un labyrinthe de petites façons d'imprimer toutes semblables.

Je pense que le problème vient de quelque chose comme ceci : chaque système d'exploitation a inventé une façon différente d'imprimer (et a peut-être même changé plusieurs fois d'avis au cours de son histoire), et chacun a récupéré toutes les méthodes connues par tous les autres ; pire, l'impression est constituée de plusieurs couches logicielles (le document pouvant subir différentes transformations en chemin vers l'imprimante) et chacune peut se faire de cinquante manières. Et les imprimantes elles-mêmes sont trop intelligentes, donc elles prévoient elles aussi plein de façons de parler. Au final on ne s'y retrouve plus du tout.

L'impression sous Unix fonctionne par le mécanisme CUPS, inventé par Apple [correction () : on me souffle dans l'oreillette qu'ils ne l'ont pas inventé, juste repris] pour remplacer un mécanisme plus ancien qui existait sous BSD ; comme Apple a lui-même remplacé CUPS par — euh — autre chose sous les versions plus récentes de Mac OS, et que le mécanisme plus ancien doit toujours fonctionner pour compatibilité, on voit déjà une source de bordel. Beaucoup d'imprimantes modernes parlent (entre autres !) IPP, qui est (si je comprends bien) le protocole sous-jacent à CUPS. Enfin, je crois : elles répondent sur le port TCP 631 qui est le port traditionnel d'IPP, et y proposent une interface Web qui ne ressemble pas du tout à un serveur CUPS. Mais il y aussi un autre protocole qui écoute sur le port TCP 9100, et plein de manières dont une imprimante peut rendre publique son existence. Ajoutez à ça qu'un serveur CUPS peut parler à un autre serveur CUPS et ré-exporter les imprimantes qu'il y trouve : ça commence à devenir compliqué. Du coup, quand on demande la découverte des imprimantes sur le réseau local, on peut se retrouver avec plein de copies de la même imprimante, parce que celle-ci s'arrange pour être découvrable de plusieurs manières et que, par ailleurs, plusieurs ordinateurs du réseau peuvent l'avoir configurée et la ré-exporter à leur tour ; si on fait le mauvais choix, l'imprimante ne sera peut-être utilisable que tant que quelqu'un a laissé son ordinateur allumé.

Le niveau des filtres et pilotes d'impression est à l'avenant : il y a un million de façons de transformer un fichier PDF en PostScript, et on peut souvent fournir à l'imprimante soit du PCL, soit du PostScript, soit directement du PDF, avec des résultats aléatoirement différents (dans le genre de subtilités pénibles, le PostScript ne supporte pas le même modèle de transparence que le PDF, donc parfois on peut avoir un document PDF qui s'imprime très bien, sauf une page qui utilise de la transparence quelque part, que je ne sais quel filtre a décidé qu'il ne pouvait pas transformer en PostScript vectoriel à cause de ça, et a donc tout réduit en raster/bitmap sans connaître la résolution de l'imprimante, d'où une qualité épouvantable pour cette page précise — je précise que l'anecdote est vécue et que je me suis beaucoup arraché les cheveux pour comprendre). L'imprimante de mon poussinet, qui est chez nous, est censée comprendre le PostScript, mais apparemment pas complètement, et un jour l'impression s'est mise à ne plus marcher parce que GhostScript lui envoyait du PostScript trop compliqué pour elle : on a fini par résoudre le problème en lui faisant avaler du PCL à la place, mais enfin, tout ceci est un vrai labyrinthe.

Je me plaignais déjà de ce genre de choses il y a quatre ans.

(dimanche)

Le RAID n'est pas parfait

Il n'y a pas que mon poussinet qui a des tracas : les disques durs de mon PC ont eu une vapeur bizarre aujourd'hui : deux d'entre eux (sur quatre) se sont mis à rapporter des erreurs en pagaille. J'ai de fortes raisons de soupçonner (ne serait-ce que parce que la coïncidence que deux disques meurent exactement au même moment est un peu trop dingue, encore que ça pourrait être un problème d'alim, un choc ou une surtension, ou je ne sais quoi) qu'il s'agissait surtout d'une vapeur du chipset/contrôleur, toujours est-il qu'après reboot les disques durs en question semblent de nouveau se porter bien ; l'un d'entre eux a effectivement consigné des erreurs dans le SMART, mais elles ne riment à rien (les secteurs indiqués sont parfaitement lisibles, les erreurs elles-mêmes sont bizarres, et aucun secteur n'est indiqué réalloué), l'autre disque n'a rien enregistré du tout. Bref, je ne sais pas ce qui s'est passé.

Mais ça a quand même causé un certain désagrément à mes tableaux RAID. Comme je l'ai déjà expliqué, je fais du RAID 1, 6 ou 5 selon le niveau de redondance voulu (respectivement 3, 2 ou 1 disques de redondance sur 4). Le RAID6 a bien réagi : il a simplement marqué les deux disques comme défectueux et a continué à marcher sur les deux restants. Le RAID1 a fait quelque chose d'un peu bizarre : il a viré les deux disques censément défectueux, mais comme il est hyper-redondant, en fait, les deux disques virés formaient eux aussi un tableau cohérent, ça a dû embrouiller l'autodétection des tableaux, et au reboot suivant je me suis retrouvé avec deux tableaux RAID1 chacun dégradés à 2 disques sur 4, ce qui m'a causé une certaine confusion. Le RAID5, évidemment, n'a pas résisté à la mort de 2 disques sur 4 : mais le fait est qu'ils n'étaient pas vraiment morts, simplement ils avaient cessé de réagir, et les écritures avaient continué sur les 2 autres disques, du coup l'état du tableau était un peu bizarre ; heureusement, mdadm a une option --force qui permet de reconstruire le tableau bien que les membres prétendent être dans des états différents, j'ai pu faire ça et tout revérifier derrière, et il n'y avait rien eu de grave (bon, le fait est aussi que je m'en foutais un peu, c'était mon /tmp — oui, même mon /tmp est en RAID5 — mais c'était intéressant de voir ce qui se passerait).

Bref, j'intitule cette entrée le RAID n'est pas parfait, mais en fait il a plutôt bien rempli sa mission de protéger mes données contre, euh, contre une non-panne de disque dur ; en revanche, il y a eu un peu de confusion dans toute l'histoire, et j'ai quand même eu un peu peur.

Je ne sais pas si ça vaut la peine de changer les disques durs : d'un côté, tout semble indiquer que c'est le contrôleur qui a déconné et un test de surface ne retourne aucune erreur ; de l'autre j'ai tendance à prêcher l'attitude si on a la moindre bizarrerie sur un disque dur, on le change illico et sans se poser de question. Peut-être que je peux changer celui des deux qui a vraiment enregistré des erreurs dans le SMART, mais c'est un peu con, c'est le plus neuf des deux (en fait, c'est le Seagate de 2To qui apparaît dans cette histoire).

(mardi)

Suspend, ventilateurs, et petites crottes de ragondin

Un des buts de toutes mes mésaventures (finalement heureusement résolues) avec mon DreamPlug (entrées précédentes ici, , et ) était de pouvoir éteindre mon PC la nuit ou, plus exactement, le mettre en hibernation, pour qu'il ne fasse plus de bruit.

Hibernation, ce qui peut désigner deux choses, le suspend-to-RAM où la machine n'est pas vraiment éteinte mais seulement arrêtée et maintient sa mémoire vivante, ou le suspend-to-disk où la machine est techniquement éteinte et a recopié sa mémoire sur disque de manière à pouvoir redémarrer dans le même état. Ces deux modes d'hibernation sont censés être supportés par Linux mais, comme d'habitude, le support peut être aléatoire selon le type de matériel, d'autant plus qu'on parle ici d'un PC fixe et que l'hibernation est surtout testée sur des portables. Mon poussinet, par exemple, n'arrive pas à faire marcher le suspend-to-RAM sur sa machine, probablement à cause d'un problème dans la gestion de la carte graphique (le suspend-to-disk, en revanche, marche bien).

Initialement, j'ai trouvé que j'avais de la chance : le suspend-to-RAM semblait marcher parfaitement (le plus gros problème observé étant que l'horloge système se décale d'environ une seconde lors de l'opération, ce qui fait négligé mais est facile à corriger en reprenant l'heure correcte sur le réseau) ; le suspend-to-disk, lui, perd le contrôle du disque externe, ce qui est pénible mais pas catastrophique (il suffit de couper ce disque avant hibernation et le remettre après : comme ce disque ne me sert qu'à stocker des choses comme des musiques ou des films, pas à faire tourner des programmes, ce n'est pas trop gravement gênant), et il y a aussi un petit couac mineur avec le clavier (il faut refaire le mapping, c'est un bug bizarre, mais ça ne fait qu'une commande à taper).

Indépendamment de ça, je trouvais que le ventilateur de mon PC était devenu plus bruyant que d'habitude au redémarrage de l'hibernation : soit que ce soit le contraste avec le silence précédent qui cause cette illusion, soit que le ventilateur vieillisse et que le fait de l'allumer et de l'éteindre le rende plus bruyant. C'est là que j'ai commencé à regarder de plus près les réglages du BIOS parce que, après tout, mon ventilateur est censé être un modèle super silencieux et on ne pouvait pas dire qu'il le fût. Or il existe, dans ces réglages, deux modes de contrôle des ventilateurs : un mode PWM, c'est-à-dire Pulse Width Modulation, où le ventilateur est contrôlé par un signal spécial, et un mode DC où le ventilateur est bêtement contrôlé par la tension appliquée ; apparemment mon ventilateur ne supporte pas le contrôle PWM, et changer vers le mode DC a eu un effet énorme : au lieu de tourner constamment à 2400tr/min, il s'est mis à descendre à 1800tr/min lorsque la machine ne fait rien, ce qui peut ne pas sembler une différence énorme, mais ce qui représente pourtant une diminution considérable du bruit. Presque au point que l'hibernation n'ait plus d'intérêt.

Presque. Mais c'est là que le bât blesse : lorsque je configure les ventilateurs en mode silencieux (et avec le bon type de contrôle), c'est effectivement très confortable pour les oreilles, mais si jamais je mets l'ordinateur en suspend-to-RAM, au redémarrage, les ventilateurs reprennent leur profil de base (bruyant). Autrement dit, je ne peux pas avoir à la fois le réglage relativement silencieux des ventilateurs et le silence total du suspend-to-RAM de temps en temps. Bon, je peux encore faire un suspend-to-disk si je veux le silence complet sans perdre le silence relatif au réveil, mais outre les problèmes mineurs avec le disque externe et avec le clavier que j'ai signalés ci-dessus, le suspend-to-disk est lent (parce que j'ai 8Go de RAM) : quand je fais de l'insomnie et que je veux regarder un truc ou deux sur Internet avant de me recoucher, je n'ai pas envie d'attendre plusieurs minutes que la machine daigne se réveiller.

Je ne sais même pas si je dois attribuer ça à un bug (de l'ACPI) de ma carte mère (une Asus P5W64 WS Pro) ou de Linux. La carte mère et le BIOS doivent bien avoir des bugs puisqu'un suspend-to-RAM non seulement met les ventilateurs en mode bruyant, mais meme ce mode persiste après un reboot, il faut une extinction complète pour revenir en mode silencieux. Sinon, ce qui est sûr, c'est que Linux devrait être capable de régler lui-même la vitesse des ventilos, mais qu'il n'y arrive pas : il devrait même y avoir deux approches possibles, l'une passant par l'ACPI (module noyau asus-atk0110) et l'autre en parlant directement au matériel (module noyau w83627ehf), et qu'aucune des deux ne marche, dans les deux cas c'est apparemment la faute d'Asus : d'un côté je crois comprendre qu'il manque des interfaces dans l'ACPI, de l'autre je crois comprendre qu'ils n'ont pas publié les specs d'une puce utilisée sur cette carte mère. (J'avoue que l'idée de garder secrètes les spécifications détaillées de quelque chose d'aussi high-tech qu'une puce qui contrôle des putains de ventilos, ça m'échappe un peu : pensez à me rappeler de ranter contre les compagnies qui ont la culture du secret, comme ça, pour des trucs totalement débiles. Mais peut-être que j'ai mal compris.) Ou peut-être que Linux ne sait gérer que les ventilateurs utilisant le contrôle PWM, mais je ne vois pas pourquoi le BIOS arriverait à faire mieux, alors.

On est censé pouvoir désassembler le code de l'ACPI avec des outils comme acpidump, acpixtract et iasl, mais c'est assez chinois et je ne sais pas si je veux passer des heures à essayer d'y comprendre quelque chose, d'autant plus que le problème n'est peut-être même pas là.

J'ai parfois un peu tendance à penser que c'est encore plus frustrant quand l'informatique marche à 99% que quand elle marche à 0%, parce qu'à 99% on a l'impression qu'on pourrait y être, on a la vision du monde parfait qui nous nargue et qui reste cependant inaccessible, alors qu'à 0% au moins les choses sont claires. Le chemin de l'enfer est pavé de petites crottes de ragondin.

(lundi)

Séances de hacking réseau

Il ne faut jamais désespérer : malgré les différentes difficultés que j'ai eues avec mon DreamPlug (entrées précédentes ici, et ), qui se sont toutes plus ou moins résolues, j'ai maintenant réussi à en faire quelque chose d'utile, c'est-à-dire un routeur en amont du PC qui est chez moi (entre ce dernier et mon modem ADSL) avec point d'accès Wifi. Je n'ai pas encore pris toutes les dispositions pour pouvoir éteindre mon PC la nuit, mais au moins, s'il y a de nouvelles difficultés qui surviennent sur ce front-là, elles ne seront plus la faute du DreamPlug.

J'ai donc passé, essentiellement ce week-end, de longues séances de hacking réseau pour reconfigurer tout ce fatras, ostensiblement pout traquer les hypothèses que j'avais pu faire (que mon PC est aussi routeur) et qui seraient devenues erronées, et en réalité pour m'amuser à peaufiner les détails et à faire joujou avec la couche réseau de Linux, qui, il faut bien le dire, est assez ludique.

J'ai fait quelque chose d'un peu inhabituel (s'agissant de la configuration IPv4 ; la configuration IPv6 ne posait aucune difficulté particulière vu que les adresses sont en nombre essentiellement illimité), que je peux peut-être expliquer, histoire de signaler que c'est parfaitement possible et que ça ne pose pas de problème (vu que beaucoup de gens à qui j'ai posé la question en amont se sont montrés sceptiques), c'est de donner à mon PC, et pas au DreamPlug routeur que j'ai intercalé en amont, l'adresse IP publiquement visible de la connexion ADSL.

Je détaille. Il est bien connu que les adresses IPv4, contrairement aux v6, sont en nombre sévèrement limité. Un fournisseur d'accès Internet par ADSL vous donne une adresse IP(v4) publique, si tant est qu'il vous en donne une fixe (il y a quelques gros nuls qui n'ont même pas cette option), quel que soit le nombre de PC que vous mettiez derrière. Si on a plus qu'un PC sur la connexion, donc, ces PC (tous sauf au plus un) utiliseront des adresses « privées », c'est-à-dire qu'elles ne doivent pas circuler en-dehors du réseau local : typiquement ce sont des adresses en 192.168.y.z ou 10.x.y.z (je ne sais pas comment ces nombres ont été choisis historiquement, d'ailleurs, et je ne sais pas pourquoi les 192.168.y.z sont plus populaires alors qu'elles sont plus chiantes à taper). Lorsqu'un PC utilisant une de ces adresses privées envoie un paquet IP vers le monde extérieur, un routeur quelque part, typiquement le dernier routeur avant le modem ADSL (ces deux équipements étant réunis en un seul sous la forme des « *box » que la plupart des usagers possèdent, et qui sont en fait presque toujours des systèmes Linux), doit transformer l'adresse IP privée de l'émetteur en l'unique adresse IP publique de la connexion, qui seule peut circuler sur le réseau, et ce routeur doit également retenir cette opération (on parle de connection tracking) de façon à pouvoir convertir en sens inverse le paquet de retour, i.e., savoir à quelle IP privée il est destiné alors que formellement il est adressé à l'unique IP publique de la connexion. Ce mécanisme s'appelle le masquerading IP, ou plus formellement NAT (pour Network Address Translation) ; dans le monde Windows/Mac non technique, on parle de partage de connexion (ce qui décrit bien le but de l'opération, mais pas le mécanisme). Il s'accompagne de toutes sortes de problèmes, mais on n'a pas d'autre choix tant qu'on continue à utiliser IPv4.

Sous Linux, on met en place ce mécanisme au moyen d'iptables, en envoyant les paquets vers la cible SNAT (ou MASQUERADE ou éventuellement SAME, la différence étant assez peu importante) dans la chaîne POSTROUTING de la table nat. On peut aussi faire du NAT entrant, c'est-à-dire indiquer que certains types de paquets entrants sur l'adresse publique doivent être réécrits (typiquement en fonction de leur numéro de port de destination) pour aller vers telle ou telle IP privée interne : dans ce cas la cible est DNAT.

Comme je l'ai écrit, tous les PC derrière la connexion sauf au plus un doivent utiliser des IP privées. Il se peut que tous utilisent des IP privées, mais on peut donner à une machine l'IP publique de la connexion. Tous les guides de configuration vous préconiseront la même chose : que ce soit le routeur-masqueradeur (celui qui réécrit les adresses des paquets, donc) qui reçoive l'IP publique, et tous ceux qui sont derrière, des IP privées. En vérité, ce n'est absolument pas une obligation : le routeur peut très bien avoir une IP privée et faire de l'auto-masquerading, c'est-à-dire réécrire les paquets qu'il émet lui-même, alors qu'un autre PC aurait l'IP publique. La configuration est tout à fait la même, et cela ne pose pas de difficulté particulière[#] et n'introduit pas spécialement de complication (sauf peut-être dans la tête de celui qui essaie de comprendre ce qui se passe et qui est habitué au schéma le plus usuel). A priori, le PC ayant l'IP publique va recevoir tous les paquets entrants qui ne font pas partie d'une connexion déjà établie (certains outils de configuration appellent ça — à mon avis à tort — la machine DMZ) ; mais on peut évidemment choisir de les répartir différemment (avec la cible DNAT sous Linux).

Quel est l'intérêt ? Tout simplement de changer les choses le moins possible : jusqu'à présent, c'était mon PC qui avait l'adresse publique de ma connexion ADSL, 213.41.184.174, enregistrée dans le DNS sous le nom de vega.gro-tsen.net, je voulais toujours pouvoir utiliser ce nom-là, à la fois depuis l'intérieur et depuis l'extérieur de mon réseau local, pour accéder à ce PC, et si possible ne pas avoir à changer de configuration sur ce PC où j'aurais pu supposer implicitement que son IP était 213.41.184.174. La solution traditionnelle pour ça consiste à rediriger les paquets voulus sur cette machine, et à faire du DNS différencié (split-horizon), où les machines extérieures voient l'adresse 213.41.184.174 associée au nom DNS vega.gro-tsen.net, tandis que les machines intérieures voient l'IP privée qui lui aurait été affectée : je trouve ça beaucoup plus alambiqué que ce que j'ai choisi, qui est de tout simplement garder l'IP que j'avais avant, et de donner une IP privée au routeur.

(Soit dit en passant, comme je n'ai jamais vraiment eu l'occasion de regarder des *box commerciales, je ne sais pas bien ce qu'elles font dans ce domaine, et notamment ce qu'elles proposent pour l'attribution des IP du réseau interne.)

Mais bon, tout ça ça a pris très peu de temps à mettre en place. Le reste du temps a été occupé à lire les manuels et à m'émerveiller (oooooh, je peux faire ça avec les paquets ? mais c'est rigolo, il faut absolument que je trouve un prétexte pour m'en servir). Je vais sans doute faire encore un peu joujou avec le Wifi, d'ailleurs.

Quand les choses seront bien rôdées, j'installerai sans doute une configuration du même style chez mes parents (où, actuellement, c'est un vieux PC de récup[#2] qui sert de routeur : je pense que ce sera plus pratique — et plus efficace énergétiquement — de mettre un GuruPlug ou DreamPlug à la place).

[#] Bon, j'exagère, il y a une chose qui pose une petite difficulté : c'est que le démon pppd, qui gère la connexion ADSL, n'a pas d'option prévue pour lui dire lors de la négociation de la connexion, il faut que tu fasses semblant d'accepter l'adresse IP que t'attribuera le pair, mais en fait tu en prendras une autre (puisque le pair nous attribuera l'IP publique mais qu'en fait on veut en prendre une privée). Pour ma part, j'ai fait ça en ajoutant un petit script que j'ai appelé /etc/ppp/ip-up.d/0fixpppaddr et dont le contenu est essentiellement ceci :

#! /bin/sh
# Change the local endpoint address on the ppp link to 192.168.0.1
# despite what ppp itself negociated.
/bin/ip addr del "$4" peer "$5" dev "$1"
/bin/ip addr add "192.168.0.1" peer "$5" dev "$1"
# Reinstate default route which was deleted in the process:
/bin/ip route add default dev "$1"

[#2] Un bi-Pentium II 450. Et quand je dis bi, il a vraiment deux processeurs physiquement distincts. Ça c'est quelque chose qui ne se trouve plus trop, de nos jours, sauf à aller taper dans du matos vraiment cher. Du coup j'ai une certaine réticence à jeter cette machine, quand même.

(Saturday)

Finally some good news on the DreamPlug/Wifi front

The story so far: I bought a Marvell DreamPlug in the hope of using it, among other things, as a Wifi access point. The DreamPlug's own Wifi chipset does not work in access point mode, so I bought some Wifi USB dongles with an Atheros AR9271 chipset that reportedly works well under Linux. Which it does, except that I discovered that if the system is rebooted after Wifi driver has been initialized (by loading the kernel modules), then it gets stuck into a mode where it no longer works and the only way to correct this seems to be by physically removing and reinserting the dongle (every other attempt at provoking a USB reset has failed to do anything but perhaps confuse the system).

Well it turns out my analysis was a bit wrong, and the problem isn't as bad as I thought. What causes the dongle to enter this « stuck » state in which it can no longer be used except by unplugging and replugging it is actually if the system is reset after the driver has been initialized (e.g., modprobe ath9k_htc) but before the Wifi interface is activated (e.g., ip link set wlan0 up). Once the interface is activated, even if it is deactivated later on, or if the modules are removed, or even in case of a sudden reboot, whatever, things appear to be fine: trouble only happens if a reboot happens in the window between loading the module and activating the interface. So this is actually very benign: I can make sure I will always activate the interface immediately after loading the modules, and the probability that a reboot will happen just between the two events is almost negligible.

The reason I didn't understand the exact circumstances triggering the bug, of course, is that I made my tests with minimal intervention, i.e., just loading the modules, and I didn't for a second think that activating the Wifi could fix anything. And I have a hard time imagining how that sort of bug could be caused (I guess loading the module does part of the chipset initialization and activating the interface does another part, but why should a reboot create a problem when simply unloading the modules does not?). I still think it's really wrong that this kind of things could happen, it's probably the sign of sloppy writing or general flakiness, but it could also be the hardware that is buggy in various ways (and, of course, tested under a very limited set of conditions, i.e., an Intel-based PC under Windows or Mac OS, definitely not an ARM embedded device). Whether this will ever be fixed is anybody's guess.

Anyway, now I can turn my attention to the software part of the problem, i.e., how I should reconfigure my network to use this DreamPlug thingy as a router.

(Wednesday)

More bitter failures with Wifi

The story so far: I'd like to have a completely silent PC that can act, among other things, as a Wifi access point. The DreamPlug I bought is supposed to have a Wifi chipset, but—apparently due to Marvell's greed and/or stupidity—, Linux does not support it in access point mode. So I bought a Wifi USB dongle (TP-LINK model TL-WN422G) with a chipset (Atheros AR9271) that is known to be well supported by Linux (ath9k_htc module) even in access point mode. And, indeed, it works when I plug it in. End of the story? Nay, for a new villain now enters the scene: USB resets.

For here is the problem: I wrote that the dongle works when I plug it in. If, however, I reboot the DreamPlug while the dongle is plugged in (and if the latter has been initialized by Linux), Wifi no longer works after the reboot (ath9k_htc fails to initialize the dongle, providing the following uninformative error message: Target is unresponsive). When it gets into that state, no software operation I could try can get it to work again (hot or warm reboots, targeted USB resets, nothing will do): only physically unplugging and replugging the dongle, or power-cycling the DreamPlug, will make it work again. Completely reproducible.

It is maddening, in fact, and it makes little sense: if the ath modules are unloaded and loaded again, no problem is caused (that doesn't solve the problem, but it doesn't cause it either). However, if they have been loaded, even if they are properly unloaded before reboot, no matter how the reboot is performed short of a power-cycle, the dongle stops working. (At my lovebird's suggestion, I even tried kexec to see whether it amounts to a reset, but I was unable to get it to boot the kernel, so I can report nothing there.)

I have tried all conceivable ways to provoke a cold USB reset, ideally to suspend or power off the dongle (and the dongle alone), but a “simple” USB reset such as provided by this program does not help, and I've been unable to cause Linux to power off the dongle completely (I suspect the DreamPlug's USB controller isn't capable of power management of this sort, and this might, in fact, be a partial cause of the problem).

This is killing me. I felt so close to having something which I would be satisfied with, I was so happy to confirm the dongle worked… that when it stopped working I thought I had been cheated of a rightfully deserved victory over adversity (OK, I may be painting the picture a tad too colorful there, but I was—and I still am—furious).

I asked for help on the linux-wireless mailing-list, but I don't really think I'll get any: for one thing, it seems more of a USB problem than a Wifi problem (but I doubt anybody on the USB subsystem would be interested), and for another, the problem is too complicated to gather real attention (it's not it doesn't work, it's it doesn't work after a reboot and may be tied to a specific dongle or a specific USB host). And I'm pretty pessimistic as to whether anything can be done: if the USB host adapter is fucked up and does something weird on reset, it's fucked up, that's all there is to it and it can't be changed.

And I don't know what to do now. I've ordered another dongle having the same chipset, in the forlorn hope that maybe it's a problem with the USB interface of that specific dongle that will not occur with a different model, but I don't really believe it. I'm afraid it all I'll end up doing is to keep my noisy PC and stash the embarrassing DreamPlugs somewhere (in the vague hope that eventually Marvell might come to their senses and provide master mode support under Linux for their chipset).

Update: Turns out the problem isn't as bad as I thought: see a later entry for details.

(Saturday)

Wifi master mode on the DreamPlug, and why I want to murder someone

My adventures with the DreamPlug seemed suspiciously undisastrous, so I assumed there was something deeply wrong waiting to pounce on me. Indeed.

To explain what it is, I should first emphasize the following simple point about Wifi: a typical Wifi has two kinds of participants: one is called an access point and operates in master (or access point) mode, and basically controls the network, it could be said to be the Wifi server, whereas all other participants are clients and operate in managed (or station) mode. (This is much simplified, as complex networks can also have repeaters, and there are other kinds of networks such as ad hoc or mesh. But your typical Wifi network is as I just said, with the hotspot being the master and all computers connected to it being managed stations.)

Obviously, since I wish to use my DreamPlug as a Wifi server/switch (among other functions), I need master mode to work[#].

Now the bad news in general is that master mode almost never works under Linux. That is, there are dozens of families of Wifi chipsets around, most of them are said to be well supported by Linux, but that is something of a lie: in reality, they are well supported in client mode only, and almost no drivers support master mode. Basically only the Atheros chipsets work really well (ath5k and ath9k) (this page may give a different impression, but in reality nearly all the drivers having a yes in the master mode column are obsolete, not well integrated in the stock kernel, not supporting the present kernel API, or have some other major flaw about them).

This is something I was well aware of. I had done some research before buying the GuruPlugs and DreamPlugs, however, and believed to have learned that master mode was supported on their Wifi chipsets using a free software Linux driver written by Marvell (uap8xxx) which, although of dubious quality, is probably destined to be included in mainline Linux kernels eventually. I can certainly live with a subpar driver for some time. Also, I don't care much that the driver needs an opaque firmware blob to run[#2].

However, here's something I didn't know, and couldn't have discovered because there's almost no indication of it anywhere on the Web: there are two different Marvell Wifi chipsets found on these GuruPlugs and DreamPlugs: the SD8688 and the SD8787. My GuruPlugs have the former while my DreamPlugs have the latter (however, the distribution may not be along the GuruPlug/DreamPlug line in all cases, I don't know). Support for them in Linux is very different. The (older) SD8688 is supported in Wifi client mode using the libertas driver in stock kernels or a driver from Marvell called sd8xxx (whose source code was released); and it is also supported in master mode using the uap8xxx driver from Marvell (whose source code was also released). This is what I had learned and from which I thought it was safe to conclude I could use the Wifi on my DreamPlugs in master mode. The newer SD8787 is not the same chip, and apparently needs different drivers: it is also supported in client mode on stock kernels, the driver being then called mwifiex; however, this driver does not support master mode (just like nearly all Linux Wifi drivers, as I already pointed out). Merely to understand this fact cost me hours of my time, because I had no idea there were two different chipsets involved, and I was lost in a twisty maze of kernel modules whose functions I could not discern.

But then how can the DreamPlug claim to function as a Wifi access point? Now that's the part that really makes me want to murder someone: Marvell wrote a proprietary driver to support Wifi master mode. And apparently these assholes don't intend to release the source code (it seems they must believe that there's some kind of secret to be kept in the source code of a Wifi driver). Even leaving aside any question as to the desirability of free software in principle, their proprietary driver is hopelessly useless, because it works with exactly one kernel version, and that (very old) kernel version has so many known security holes in it that nobody in their right mind would use it on a computer connected to the Internet. Like, you know, a Wifi access point tends to be. I mean, I hate proprietary drivers, but if you're going to write one, you could at least do it the way nVidia does, providing some interface glue around a binary blob so you're not pinning the kernel to exactly one bloody version, especially, you know, one which is pretty much unusable. Oh, and it happens to be named 2.6.33.7-dirty, probably because dirty is exactly what describes the minds of whoever is responsable for such sheer idiocy.

To add insult to injury (I mean, apart from that insult of the kernel being called dirty), the proprietary driver in question, or at least one component of it, has the same name (sd8xxx) as the free driver they wrote for the other of the two chipsets. This means it is almost impossible to know what people are talking about, and very easy to be misled (as I was) into thinking that the DreamPlug supports master mode.

Now I don't know what hope I can have that the situation will evolve. The mwifiex driver (recall that this supports the SD8787 chipset I have, but only in client mode) is being developed by Marvell, so it's not like having two different versions, one with master mode and one without, were not intentional. I can hope that they'll eventually realize that keeping a fucking Wifi driver secret makes no sense whatsoever, but companies are notoriously bad at understanding their own stupidity. I don't know.

I also don't know how difficult it would be, in principle, to produce a driver which supports master mode from one which does not. My naïve view of things is that all a Wifi hardware driver should have to do is provide two functions, send packet and receive packet (OK, make that three with choose channel), and all the stuff about modes, associations, crypto and whatnot, could be handled (in software) in a generic, device-independent way. I'm aware that this is naïve, there's obviously some hardware support for crypto, possibly other stuff like MAC filtering, association lists, or I don't know what. But I still don't know why the hardware driver has to specifically support master mode rather than just accelerating it. Consequently, I have no idea how difficult it is to write that support, assuming, say, you only get to see the hardware specs necessary to write a driver supporting client mode.

In the mean time, it seems I have paid a couple of hundred bucks for a piece of equipment that is completely useless for what I wanted to do with it. Thanks a lot, Marvell!, I'll try to remember that next time I consider buying anything from you or advising someone about your products.

Update (): I decided the simplest way out of my conundrum was to give up on Marvell's crappy chipset and buy a couple of USB Wifi adapters that are known to work well (even in master mode) under Linux.

[#] Actually I'd like even more: I'd like it to be possible to have several virtual Wifi networks on the same channel and access point, so I could have both an open network and an encrypted one with different filtering rules. This is why I can't just take an embedded Wifi access point and plug it into my network. Along with the fact that embedded Wifi access points don't let you fine tune some of the parameters I'd like to fix, like the beacon rate or the rekey interval for group transient (aka broadcast/multicast) keys. But, hey, basic support for master mode would be a good start.

[#2] Depends on what the blob does, of course, but I don't have the same religious principles as Debian or the FSF on that matter: I'm willing to pretend the firmware is just some large data table or a magic number that needs to be inserted into the device for it to function. As long as the firmware doesn't run on my CPU, and activates all functions of the hardware, say.

(Wednesday)

Some notes on the DreamPlug

Update on the mess: I was finally able to compile a kernel for my DreamPlug that I'm happy with, and which can boot under any version of U-Boot.

I've written this to summarize some of my findings. Probably of no interest to regular readers of this blog, but it will help me remember what I've found, and it might be of use to someone stumbling on this page using Google.

(Sunday)

More mess: after the GuruPlug, the DreamPlug

One of my recurring, probably never-to-be-achieved, dreams, is to own a small, completely noiseless PC that I could leave running 24/7/365 for use as a router, Wifi access point, and server for some basic services (such as NTP and DNS), so as to turn off—or at least, suspend—my main desktop PC at night. The current fad in this area is currently the Raspberry Pi, which is undoubtedly a wonderful gadget, and I'll probably get one eventually, but it doesn't quite match my criteria. (As a matter of fact, there are zillions of similar embedded devices which come quite close to what I want, but never actually there. One of my more outrageous demands is that I want two gigabit Ethernet connectors plus Wifi, and that's where mostly everything fails, except for a few things which are build for use as switches but then they don't satisfy me for other reasons.)

My last attempt at substantiating this dream came in the form of the GuruPlug by GlobalScale Technologies. But I was pretty pissed off when it turned out that the gadget, while it matched my more difficult criteria (dual gigabit Ethernet plus Wifi, eSATA, yada yada) utterly failed in the simple but crucial condition of being silent. Seems it was a design error: they had hoped to make it fanless, but it was found to overheat, and they added the fan ex post facto, making the dang thing pretty much pointless. So, I have two of these GuruPlugs Server ExtraNoisy Deluxe on my hands and I still haven't found any use for them.

Well, later GlobalScale came to realize the evil of its ways and amended them by releasing a new product, the DreamPlug. It differs from its older sibling in two important respects: (1) this time it is truly fanless, hence noiseless, and (2) the internal NAND memory used for permanent storage has been replaced by a removable µSD card, making the device easier to unbrick[#] in case something goes wrong. I resisted buying this DreamPlug for some time, because I was really annoyed by the fiasco of my previous purchase at GlobalScale, but in the end resistance was futile and I bought myself a pair of DreamPlugs. They were delivered to me on Monday.

Well, I have no gripes with the hardware, now: the DreamPlug is, indeed, completely silent, and from what I have seen so far, it seems to work well. No gripes apart from the general fact that the ARM architecture is a chaotic mess: there seem to be a zillion kinds of ARMs, each with a zillion subtypes and sub-subtypes. And as a consequence of this fragmentation, I ran into a number of software problems which I may or may not be able to solve (but which will probably solve themselves on their own: that's the nice thing about software problems as opposed to hardware ones).

The DreamPlug comes with a Linux distro which is essentially Debian with a custom kernel, including a number of custom drivers (essentially for Wifi), and a custom bootloader. And a number of hastily bundled scripts which were installed by raping the Debian package manager with gravel. Anyway. It works. But I hate badly customized distros and customized kernels, so I'd like to reinstall a fresh Debian (or Ubuntu) on the box. But it's not that simple.

The bootloader (also serving some kind of BIOS functions) used to boot Linux on the ARM architecture is something known as U-Boot. Now Marvell provides a specifically patched U-Boot for this device, which has some annoying limitations, such as not being able to load files from ext2 filesystems: so I thought I'd try a more recent U-Boot provided by Debian (u-boot_2011.12-2_armel.deb), and which is said to support the DreamPlug. Reflashing U-Boot is ridiculously complicated (one takes control of the machine through JTAG using the OpenOCD program, but unfortunately OpenOCD cannot directly flash the particular kind of nonvolatile memory used on the DreamPlug — as opposed to the GuruPlug — so one must go through a strange process of loading the new U-Boot to RAM, booting it there, and using U-Boot itself to reflash itself); but I managed it. However, (1) the U-Boot taken from Debian is incapable of booting the kernel provided by Marvell (it just gets stuck after Uncompressing Linux... done, booting the kernel.), and (2) the Debian kernels for Kirkwood apparently do not support the DreamPlug (as such, they refuse to boot, complaining that they don't know the machine identifier 0xdde; and if I try to trick them in using identifier 0xa63 which is that of the GuruPlug, they fail a bit later on).

So Marvell must have patched both their U-Boot bootloader and kernel in a way that each is compatible only with the other. The details escape me, though it is obviously must have something to do with the annoying mechanism of machine identifiers used by the ARM architecture. And whatever the excuse of ARM being fucked up in the first place, Marvell must have fucked it up some more for their Linux kernel to be unbootable by a standard U-Boot (conversely, their patched U-Boot is said to be able to boot standard kernels, but only with a special option mainlineLinux option and by fiddling with the machine identifier): what a mess! And the enormity of having to use a specific bootloader to load a specific kernel is such that it defeats the whole purpose of a bootloader, namely: to boot more than one kernel.

I thought I'd step out of the mess by avoiding any Marvell patches altogether and using a recent mainline kernel to boot with the standard U-Boot. And when I say recent, I mean essentially today's snapshot of the ARM SoC tree (merged with the 3.3.0-rc7 fixes from the Linux tree). It is supposed to support the DreamPlug, according to this commit (and a couple of later ones): I really don't know why support for a device that has been commercialized for well over a year has only begun finding its way in the kernel a few weeks ago; but unfortunately another problem is that said support is taking the form not of recognizing the infamous machine ID (0xdde) but using something known as a flattened device tree which is a kind of machine description file: only this requires an even newer U-Boot, and it seems I have entered a world of pain.

So in the end, I wasted more than five hours first creating an ARM cross-compiler[#2] and then tediously configuring the kernel (the number of choices to be made is frightening; and even by merging several known configurations it was still a pain in the ass) to get a kernel that simply does not boot and I have no idea why (the most useful message I elicited from it was: Kernel panic - not syncing: ERROR: Failed to allocate 0x1000 bytes below 0x0. — and that's with Marvell's U-Boot because with the standard one it didn't even get that far).

The moral of this is that I probably should have stuck with the working system provided by Marvell, but I still hate it and hate the idea that the system needs specific patches to function. And judging by the patch needed to provide master mode support on the Wifi chipset (which is so obviously a badly fangled port of a Windows driver), I'd like to stay clear of any code of this sort.

The dust will settle eventually, I guess, and maybe someday Linux will run correctly on a device that was, after all, specifically made to run Linux. But in the mean time, I can't say its performance has been brilliant.

[#] Remind me to rant someday about the fact that it ought never to be possible to brick an electronic device of any kind by purely software means.

[#2] In case it's of value to anyone, here's more or less what I did:

mkdir /opt/arm-linux-gnueabi
mkdir /opt/arm-linux-gnueabi-tools
dpkg-deb -x libc6_2.13-27_armel.deb /opt/arm-linux-gnueabi
dpkg-deb -x libc6-dev_2.13-27_armel.deb /opt/arm-linux-gnueabi
dpkg-deb -x linux-libc-dev_3.2.6-1_armel.deb /opt/arm-linux-gnueabi
(cd /opt/arm-linux-gnueabi/usr ; tar cf - *) | (cd /opt/arm-linux-gnueabi ; tar xf -)
rm -rf /opt/arm-linux-gnueabi/usr
ln -s . /opt/arm-linux-gnueabi/usr
cd /tmp ; apt-get source binutils
cd binutils-2.22
./debian/rules patch
mkdir /tmp/binutils-build
cd /tmp/binutils-build
/tmp/binutils-2.22/configure --target=arm-linux-gnueabi --prefix=/opt/arm-linux-gnueabi-tools --enable-shared --enable-plugins --with-sysroot=/opt/arm-linux-gnueabi
make -j4 && make install
cd /tmp ; apt-get source gcc-4.6
cd gcc-4.6-4.6.3
DEB_CROSS_NO_BIARCH=yes ./debian/rules patch
mkdir /tmp/gcc-build
cd /tmp/gcc-build
/tmp/gcc-4.6-4.6.3/src/configure --target=arm-linux-gnueabi --prefix=/opt/arm-linux-gnueabi-tools --with-sysroot=/opt/arm-linux-gnueabi --enable-languages=c
make -j4 && make install

(mercredi)

Comment sauver le contenu de vieilles disquettes

Mon poussinet voulait lire des textes dont je lui avais parlé, que mon papa avait écrit quand j'avais dans les 12–14 ans (soit vers 1988–1990), les Life and Times of Altcee (mon père les écrivait pour se moquer de moi, j'en reparlerai dans une prochaine entrée [ajout : voir la suivante]). Problème : la seule copie de ces textes était, apparemment, sur une disquette 5¼″ de 360ko ; je pense que le fait qu'il n'y en ait pas eu d'autres copies est lié à un crash de disque dur que nous avons eu vers 1995, à une époque où les backups étaient rares et chers : déjà, c'est un peu un miracle que cette disquette ait survécu et qu'on ait pu la retrouver (sans parler du miracle que les données dessus n'aient pas été effacées par le passage de 22 années, mais je m'avance). La disquette étant rangée avec les archives de mon père, elle avait échappé à la grande séance de conversion de toutes mes disquettes en un seul CD (lui-même réarchivé depuis sur plusieurs disques durs) à laquelle je m'étais livré en 1999 quand je pressentais la disparition prochaine du format.

Mais alors essayez de trouver, de nos jours, un lecteur de disquettes 5¼″ : ce n'est pas une mince affaire. Déjà, un lecteur de 3½″ n'est pas évident, enfin, c'est encore vaguement faisable (quoique ce sera forcément un truc mal fabriqué qui va plutôt s'occuper de bouziller les supports que les lire), mais un 5¼″, c'est un peu comme chercher un grand-bi chez un marchand de vélos.

Mon poussinet en a emprunté un auprès d'un responsable informatique de la fac de Bordeaux (où il fait sa thèse). Un autre miracle en notre faveur est que les cartes mères même raisonnablement modernes continuent à fournir la connectique pour brancher un lecteur de disquettes, et heureusement cette connectique est formellement identique entre les lecteurs 5¼″ et les 3½″. Formellement, parce qu'en fait, même si la nappe est la même, la fiche n'est pas la même, et les nappes que j'avais n'avaient pas le connecteur pour les 5¼″. Bon, nous avons quand même trouvé, parmi nos amis, quelqu'un qui avait encore une nappe appropriée et un autre lecteur avec lequel tester en cas de problèmes avec le premier. Je passe sur une nouvelle difficultée due au fait que le câble ne se branchait pas bien dans la carte mère à cause d'un détrompeur trop proéminent.

Le BIOS des ordinateurs modernes, si tant est qu'il gère encore les lecteurs de disquettes, ne prévoit apparemment plus qu'on puisse y mettre un 5¼″. En tout cas, celui de mon poussinet n'offrait que deux options pour configurer le lecteur : 3½″ de 720ko ou bien 3½″ de 1440ko ; nous avons parié sur le fait que Linux arriverait quand même à faire quelque chose du lecteur, mais c'était loin d'être évident. Sur tous nos essais, il n'arrivait à lire que les premiers 4ko de données, c'est-à-dire un peu moins qu'une piste. Pour préciser les choses, les données sur une disquette sont organisées en cylindres concentriques, au nombre de 40 sur celles qui m'intéressent, chaque cylindre étant formé d'une piste sur chaque face de la disquette lorsque celle-ci est double-face, donc 80 pistes dans mon cas, et chaque piste étant divisée en un certain nombre de secteurs, ici 9, de 512 octets chacun : les 360ko de ma disquette sont donc 40×2×9×512 octets. Connaître cette géométrie était certainement un prérequis pour arriver à lire quoi que ce soit, mais quelle que fût la façon dont nous prétendions l'expliquer à Linux, il se limitait à lire les 8 premiers secteurs (sur 9, donc) de la première piste, et échouait avec des erreurs d'entrée/sortie sur tout le reste. Nous avons gardé espoir parce que ça semblait peu vraisemblable que toutes les disquettes de la boîte fussent abîmées exactement de la même façon, ou que les deux lecteurs eussent le meme défaut : et si le problème était logiciel, on devait pouvoir le contourner.

Finalement nous sommes tombés sur le programme fdrawcmd, qui permet d'envoyer des commandes bas niveau au lecteur de disquette : cet utilitaire prend beaucoup de paramètres incompréhensibles, et nous n'avons réussi à nous en servir qu'une fois tombés sur cette page qui nous a donné une clé qui nous manquait, à savoir que pour lire une disquette de 40 cylindres sur un lecteur en supportant 80, il faut demander de positionner la tête au cylindre numéro 2×i avant de lancer la lecture du cylindre numéro i. Si d'aventure ça pouvait servir, voici le script qui a fini par marcher :

#! /bin/sh
fdrawcmd drive=/dev/fd0 rate=1 readid 0 need_seek track=0
for i in `seq 0 39`; do
    fdrawcmd drive=/dev/fd0 seek 0 $((i*2))
    fdrawcmd drive=/dev/fd0 rate=1 read 0 $i 0 1 2 9 0x1b 0xff length=9216
done

Ceci étant fait, nous avons eu la bonne surprise de voir que toutes les disquettes étaient lisibles sans une erreur, malgré leur âge. Ensuite, je savais bien que Linux pouvait lire le système de fichiers du DOS, mais là où j'ai eu une nouvelle heureuse surprise c'est que LibreOffice savait lire le format WordPerfect5 de 1990 dans lequel le texte était écrit, y compris pour les notes en bas de page et quelques autres fioritures.

Toujours est-il que le fichier altcee.wp5 est maintenant parmi mes fichiers celui à la date de modification la plus ancienne ( : en termes informatiques, ce n'est pas tout à fait de la paléontologie, mais c'est au moins de l'archéologie).

(dimanche)

Perdu dans un labyrinthe de petites API toutes semblables

J'ai écrit une page web qui fait des calculs en JavaScript (il s'agit toujours d'animations de E8 mais peu importe), calculs que je voudrais faire exécuter hors du cadre d'un navigateur (en l'occurrence pour faire une nouvelle vidéo à mettre sur YouTube), si possible sans réécrire complètement le code en autre chose que JavaScript[#]. Bref, exporter les résultats de ces calculs, les sauvegarder dans un fichier (sous un format à peu près quelconque, typiquement un dump texte des résultats, que je saurai ensuite convertir assez facilement).

Je cherche donc la chose suivante : un environnement JavaScript « standalone », c'est-à-dire hors d'un navigateur (mais à la limite ce n'est pas bien grave si je dois lancer un navigateur) avec une simple fonction pour écrire un fichier (dans lequel je pourrai sauvegarder le résultat de mes calculs ; enfin, il me faudra ouvrir plusieurs fichiers différents parce que les résultats sont un peu longs, je voudrais faire un fichier par image d'une animation).

Pour résumer, je veux juste écrire du texte dans un fichier depuis JavaScript. Ça n'a pas l'air de demander beaucoup, n'est-ce pas ? C'est pourtant la porte d'entrée d'un labyrinthe cauchemardesque de presque-solutions toutes aussi décevantes les unes que les autres. Faisons un peu le tour.

Bon, après des heures et des heures à naviguer à tâtons dans ce labyrinthe, je crois avoir trouvé que ceci fonctionne avec Seed, pour écrire foobar dans le fichier monfichier, mais je ne comprends vraiment pas d'où vient cette API ni comment j'étais censé la deviner : var Gio = imports.gi.Gio; var file = Gio.file_new_for_path("monfichier"); var fstream = file.replace(); var dstream = new Gio.DataOutputStream.c_new(fstream); dstream.put_string("foobar"); fstream.close(); ; l'ennui c'est que je ne comprends rien à ce que je fais, je ne sais pas pourquoi ça ne marche que sous Seed et pas sous gjs alors qu'ils sont censés utiliser la même API, je ne sais pas ce que c'est que Gio et pourquoi il faut chercher imports.gi.Gio alors que cette page précédemment citée évoque imports.gi.GLib, bref, je ne comprends rien à ce que je fais. Qu'est-ce que c'est que cette fonction Gio.file_new_for_path et quel est son rapport avec ce qui est ici, ou ce qui est là ? Je suis vraiment perdu dans un labyrinthe.

[Ajout : Sous gjs, apparemment, il faut faire : var Gio = imports.gi.Gio; var file = Gio.file_new_for_path("monfichier"); var fstream = file.replace(null, false, 0, null); var dstream = new Gio.DataOutputStream.new(fstream); dstream.put_string("foobar", null); fstream.close(null); ; par ailleurs, la raison de ma confusion sur les API est qu'il existe à la fois une API IOChannel dans la GLib et aussi une API GIO, qui n'a rien à voir sauf qu'elle fait à peu près les mêmes choses de façon gratuitement et stupidement différentes, juste pour emmerder le programmeur. Et apparemment on ne peut pas utiliser les fonctions de manipulation de fichiers de la GLib depuis gjs/Seed, ou en tout cas je n'ai pas réussi, par exemple GLib.open() n'existe pas alors que logiquement il devrait. Tout ceci est incompréhensible.]

C'est un peu le problème des projets en logiciel libre où tout ce qui se fait un jour est rendu obsolète le jour suivant parce qu'ils ont décidé que ce n'était plus la bonne façon de faire, donc toutes les docs qu'on trouve sont obsolètes et on ne sait jamais ce qui a remplacé quoi. Quel chaos !

[#] Pas que JavaScript soit le langage le plus adapté du monde pour ce que j'ai à faire — loin de là — mais maintenant que le code est écrit, je n'ai pas envie de le réécrire complètement en Perl/Python/quidlibet.

(lundi)

Debian wheezy, gcc-4.3 et autres petites merdes

Acteur numéro 1 du drame : la distribution GNU/Linux Debian, qui sort une nouvelle version toutes les années bissextiles multiples de 27. Acteur numéro 2 : le compilateur gcc, qui sort des nouvelles versions assez souvent (enfin, quand on compare à Debian), et qui prend un plaisir malin à casser la compatibilité ascendante dès qu'ils le font. Résultat de l'interaction : chaque version de Debian inclut une demi-douzaine de versions de gcc. Comme leur main d'œuvre est limitée, leur support ne s'étend pas jusqu'aux versions de gcc du siècle précédent, i.e., de la version précédente de leur distribution.

En l'occurrence, la version de Debian en cours de préparation, wheezy (celle qui sortira en 2075 si on a de la chance), comprend les versions 4.4, 4.5 et 4.6 de gcc. La précédente, squeeze (celle qui est sortie autour de 1967), comprend les versions 4.1, 4.3 et 4.4 (je ne sais pas pourquoi la 4.2 n'a pas eu cet honneur, et je ne veux pas trop le savoir). Remarquez qu'on a de la chance : il y a une intersection non nulle (pas sûr que ça dure).

Maintenant, les choses se compliquent : quand on compile un noyau Linux, on doit tout compiler (tout, c'est-à-dire modules et noyau proprement dit) avec la même version de gcc (comme je disais, ils aiment bien casser la compatibilité ascendante, ce ne serait pas drôle de définir une fois pour toutes une ABI). Comme on se méfie de ce qui est à la pointe du progrès, les développeurs Debian ont décidé que pour le noyau qu'ils fournissent avec la distribution squeeze, ce serait le 4.3.

Le lecteur attentif aura remarqué que 4.3 n'apparaît pas dans la liste des gcc fournis par wheezy. Fournir le compilateur utilisé pour le noyau par la précédente version de notre distribution ? Vous n'y pensez pas, ma brave dame.

Normalement, on devrait pouvoir s'en sortir quand même : le système de packages est le même, après tout, et installer un package d'une version de la distribution sur la version immédiatement après ne devrait pas être rigoureusement impossible. Parfois ça marche, en effet. Mais là, manifestement, ce n'est pas possible (il y a vraisemblablement eu une incompatibilité dans une bibliothèque qui n'a pas été signalée par un changement de numéro de version, ce qui rend l'installation simultanée des versions 4.3.5 et 4.4.x de gcc impossible) ; problème qui devrait être résolu avec la version 4.3.6 de gcc, mais quelqu'un chez Debian a décidé que ça ne valait pas la peine de faire l'effort de packager ça (remarquez le tag wontfix dont la traduction en langage plus fleuri est : allez vous faire enculer à sec avec du gravier). Je viens de passer des heures — qui auraient aimé être employées à des activités plus utiles — à essayer de construire moi-même un package Debian pour gcc 4.3.6 sur Debian wheezy (à partir du package de gcc 4.3.5), sans succès, la montagne des patchs appliqués est beaucoup trop énorme pour qu'on puisse juste changer la version comme ça, et même si je fais toutes sortes d'horreurs pour la traverser quand même je tombe sur ce problème insoluble.

Bref, la seule façon de compiler des modules noyau pour une machine sous Debian squeeze, c'est d'avoir une autre machine sous Debian squeeze sous la main pour faire la compilation. Moi qui ai l'habitude d'installer la Debian stable (donc squeeze en ce moment, justement) précisément sur mes machines qui ne sont pas assez puissantes pour faire des compilations (parce que ce sont aussi celles sur lesquelles je n'ai pas envie de mettre à jour des packages tout le temps), me voilà bien puni d'avoir choisi cette distribution. Seule solution que je voie : tout réinstaller à zéro (par exemple dans une machine virtuelle).

(Tuesday)

IPv6, MTU woes, and a memo on packet sizes

My parents' Internet Provider (Orange) offers, as yet, no IPv6 connectivity, only IPv4, at least to non-business clients. (Did I mention how much I loathe the whole concept of having business or pro services?) Can you imagine that? IPv4 is soooo 20th-century. I kid, but I tend to think they legally shouldn't be allowed to call it Internet access if it doesn't include the v6 Internet: I'm sure if they had a choice between getting their act together and having to relabel their advertisements, they'd somehow discover the means to make it happen very fast. But I digress. I use IPv6 a lot because I have it at home and at work, and it really makes my life simpler when it comes to connecting to N different computers which are hidden behind a single v4 IP (at my parents' place, N≥6 not counting mobile phones and such, thanks to my father's technology buying sprees).

Up to recently, for my parents' access, I relied on 6to4 (the magic 2002::/16 space which provides every IPv4 with a septillion v6 addresses): 6to4 is really nice because it works without having to register anything: in one direction, you just encapsulate your v6 packets and send them to the magic v4 multicast address 192.88.99.1 and some good Samaritan sends them to the v6 Internet, and in the other direction, some other good Samaritan encapsulates packets sent to your 2002:xxyy:zztt::/48 space and delivers them to your v4 address. Exactly who these good Samaritans are, and how come they haven't closed everything down because of security concerns, beats me; but 6to4 is remarkably simple to set up, and allows anyone with a fixed IPv4 address not sitting behind a fascist firewall to gain IPv6 connectivity instantly. Neat. (In fact, it can even be useful to work around a stupidly configured firewall: the network administrators at my alma mater — I mean the ENS — refuse to learn anything about IPv6, they have stupid firewalls set up in various places, such as on the library Wifi or Ethernet, and these firewalls will let 6to4 happily through, which makes the whole thing a bit inane.)

But for some reason, Orange recently stopped routing to 192.88.99.1. Whether this is intentional is debatable; I don't know. But at any rate, I lost 6to4 because of this. I might have used some other (unicast) encapsulating Samaritan instead, like 194.95.109.1566to4.ipv6.fh-regensburg.de, but that didn't seem very robust or practical, so I decided to get a dedicated (static) tunnel instead.

Fortunately, a tunnel is available free of charge from Hurricane Electric. Actually, I'm pretty amazed at how simple it is: registering an account and setting up a tunnel only takes a few minutes, and they give you a /48 on demand (plus a /64 and a bonus /128). In contrast, the other tunnel provider I know of, SixXS, is really inquisitive, they practically ask for your grandmother's maiden name before you can get a tunnel (and you have to promise a lot of strange things, like keeping the tunnel up 24/7 — sort of bizarre, I don't see why they would care). Anyway, I got one for my parents, and I can really say I recommend Hurricane Electric.

But there is one thing which is the scourge of tunnels in general, and IPv6 tunnels in particular: MTU woes.

The MTU (Maximal Transmission Unit) is the maximal size of a network packet that can go through an interface. The typical value would be 1500, which is the MTU of a standard Ethernet interface (without the so-called jumbo frames extension). When a packet is too large to go through a network interface in a single piece, there are basically two possibilities: either a packet is returned to the sender with the datagram too large error (ICMP), or the packet is fragmented in smaller pieces. The latter is problematic for various reasons and tends to be avoided. The former is nice, except that various sorts of reasons, all a variant of the stupid network administrator kind, can cause ICMP packets (hence, the error) to be lost.

When a packet must go through a tunnel, things get worse: the tunnel appears as a single network interface, but it might not know what its own MTU is, because that depends on every intervening link on the tunnel's route (which might not even be constant). If the tunnel allows fragmentation, this is not really a problem (the MTU is then pretty arbitrary), but it typically doesn't, because fragmentation requires more work of the tunnel endpoints and causes inefficiency. If the tunnel does not allow fragmentation, it should, ideally, maintain its MTU dynamically by starting with some standard value, ajusting it whenever it receives a datagram too large error, and sometimes tentatively increasing it again in case the route has changed to something better. I'm afraid real tunnels rarely do this.

Hurricane Electric's tunnel won't fragment, and apparently autocratically sets its MTU to 1480: incoming packets larger than this receive a datagram too large ICMP message from HE's end of the tunnel, and smaller packets try to go through. But they may not succeed: and if they don't, even though they may receive a packet too large at the v4 layer supporting the tunnel, this won't be translated to the corresponding error at the v6 layer. So the tunnel is a black hole for packets with a size just below 1480 but larger than the true MTU (which should rather be called MRU, Maximal Reception Unit, in this context, since I am talking about packets which, seen from my end of the tunnel, are inbound).

This is unfortunately a very common problem. Its general consequence is that connections will simply freeze, because they are established without problem, but once an inbound packet is sent that is too large, it will never go through, and typical TCP hosts use no mechanism to dynamically adjust the path MTU (more about this in a minute).

In my case, my parents' Internet connection by ADSL seems to have an MTU of 1456 (measured at the PPP level). I don't know why it's so low: my own home Internet connection, also by ADSL, apparently has 1492, which is normal for PPPoE (the PPPoE protocol is used to communicate with the ADSL modem by encapsulating PPP data over Ethernet frames; for some reason I can't imagine, the modem does not decapsulate the Ethernet frames but rather sends them directly on the ATM link used by ADSL: it is thus more accurately PPPoEoA; since for some other reason I also can't imagine fragmentation of PPP data is also forbidden between Ethernet frames, the link MTU is limited by the Ethernet frame size, 1500, minus the PPPoE overhead, 8). The PPPoA protocol would give a better — higher — MTU, but there doesn't seem to be a way to use it while doing the PPP negociation on the PC rather than on the modem: I already complained about this a while ago.

The problem isn't specific to IPv6: the same problem can occur at the IPv4 level: my parents' Internet connection seems to lose packets of size greater than 1456 even at the v4 level (which is all Orange provides, anyway), with no kind of error packet being received. However, of course, Internet providers will do all that is necessary for ordinary IPv4 TCP connections to work: typically they will clamp the TCP maximal segment size to the right value. (This is maddeningly and mind-bogglingly stupid, when you think of it: instead of making sure they send out the right error messages when too large a packet is received, they prefer to mangle TCP connections.) They won't do that at the v6 level, so the subscriber has to do it.

In principle, there's a mechanism, suggested by RFC 4821, which explains how to work around MTU problems by letting the transport layer (typically TCP) discover the right path MTU by itself. Unfortunately, this mechanism (which is enabled under Linux by setting the sysctl net.ipv4.tcp_mtu_probing — despite its name, I'm told this also concerns IPv6) needs to be enabled at both ends of the connection for it to be of real use: and at any rate, since my problem is that my Internet connections won't receive datagrams that are too large, I would need it enabled on hosts that talk to me, and that I can't control. Bad luck.

Instead, one must resort to a hack called TCP MSS clamping (as I mentioned above, it seems that many Internet providers do it anyway, at the v4 level), which consists of letting the router alter TCP packets to make sure their maximal segment size (MSS) is low enough. Under Linux, this is done with something like: /sbin/ip6tables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu (this is necessary only on the router, for TCP connections that are being routed through it: for inbound or outbound TCP connections, the host will know the correct MSS anyway). Unsatisfactory, because it will not save SCTP, but as my father likes to say, you can't make a silk purse out of a sow's ear.

One of the annoying aspects of this tinkering with packet sizes is that every tool seems to measure packet size differently. The TCP maximal segment size, for example, is not equal to the MTU because of the overhead brought by IP and TCP headers. Every time I have to fight this battle, I must figure out the right constants. So, in an effort to save myself some efforts the next time, and perhaps be of use to someone else, here is something I wrote down:

IP packet size = IP header size (20 for IPv4, 40 for IPv6) + IP payload; IP packet size is bounded by interface MTU. For TCP: IP payload = TCP header size (20) + TCP segment size; TCP segment size = TCP segment payload + TCP options size (typ. 12), but TCP segment size (not payload) is bounded by MSS; so MSS is typically MTU−40 for IPv4, MTU−60 for IPv6. For ping: ping -s defines ICMP payload size; IP payload size = ICMP payload size + ICMP header size (8); so IP packet size is ICMP payload + 28 for IPv4, + 48 for IPv6. Ethernet frame: Ethernet header size (14) + IP packet size + Ethernet CRC (4) (but this size is hardly ever useful; 1500 is Ethernet standard MTU). Tunnel overheads: PPPoE adds 8 bytes (PPPoE headers (6) + PPP headers (2)); 6in4 adds 20 bytes (IPv4 payload of 6in4 = IPv6 total packet size).

(mercredi)

Comment se battre contre les programmeurs imbéciles de chez LCL

(Comment ça, ce blog est en train de devenir un blog de râlerie contre les banques ?)

Ayant ranimé un compte au CIC qui était dans le coma, je voulais me préparer la possibilité de faire des virements vers ce compte depuis mon compte LCL (pour les virements dans l'autre sens, on verra, euh, plus tard). L'interface en ligne de gestion des comptes de LCL permet de faire des virements, à condition d'avoir préalablement enregistré le RIB du compte destinataire. C'est une sécurité minimale qui ne me paraît pas absurde : on ne peut pas faire un virement vers n'importe où, il faut d'abord ajouter le RIB, on reçoit un courrier papier informant de ce fait (ce qui permet de crier au secours si c'est une tentative de vol), et quelques jours plus tard on peut faire les virements. Cependant, la sécurité du site en ligne a été améliorée de bidon à bidon++ (par exemple, maintenant pour saisir son code d'accès on ne peut plus le taper au clavier, il faut cliquer sur des petites images de chiffres — les non-voyants doivent adorer ça, c'est super pour l'accessibilité — et du coup n'importe qui qui voit l'écran voit le code, ce qui est assez bof au niveau sécurité). Maintenant, pour ajouter un RIB externe, il ne suffit pas de taper son code d'accès, il faut utiliser un certificat.

A priori, ça me plaît bien. Je suis cryptographe, j'aime bien la signature électronique. Mais le nombre de conneries auxquelles je suis confronté, et qui transforment la simple opération d'ajout d'un RIB en un véritable parcours du combattant, est effarant.

D'abord, la procédure est lourdingue au possible. Il faut : (1) se connecter au site pour faire une demande de certificat, (2) recevoir par courrier papier un code d'activation du certificat, (3) retourner sur le site pour « retirer » le certificat et (4) l'« activer ». C'est lourdingue mais ce n'est pas foncièrement idiot : l'étape (2) est une précaution minimale pour limiter les dommages si quelqu'un récupère les codes d'accès au site (ceci dit, s'il peut faire ça, il pourra probablement récupérer aussi l'accès au certificat, mais passons). L'étape (3) est celle où se fait la génération proprement dite, et il est possible qu'ils aient correctement fait les choses et qu'ils n'aient pas connaissance de la clé privée. Possible. L'étape (4) est une vérification dont je ne comprends pas bien le sens puisqu'ils signent eux-mêmes le certificat à l'étape (3), mais bon, ce n'est pas problématique en soi. Le problème est surtout qu'ils se sont chié dessus à tous les niveaux possibles.

Première connerie : utiliser Java côté client. C'est idiot, on peut tout faire en JavaScript (voir ceci, et penser aussi à la balise magique <keygen> du HTML), alors que Java dans un navigateur est lourdingue et marche atrocement mal. Mais admettons.

Premier problème pour moi : mon Java ne marche pas. Ça, je dois le reconnaître, ce n'est pas du tout la faute de LCL. C'est apparemment AdBlock Plus et/ou GreaseMonkey (outils malheureusement indispensables) qui empêchent le plugin Java de Firefox de fonctionner correctement (au moins sur mon Linux, je ne sais pas à quel point c'est général ; j'imagine que non, sinon le problème serait plus connu et probablement déjà résolu). Il faut les désactiver complètement (tous les deux) : il ne suffit pas de les désactiver sur le site, il faut vraiment relancer le navigateur sans ces extensions, si on veut que Java marche. Bon, deux bonnes heures de perdues à découvrir ça.

((Mise à jour () : On me souffle que seul le plugin Java de Sun Oracle souffre de ce problème. Si j'utilise le plugin Java IcedTea, il est, lui, compatible avec AdBlock Plus et GreaseMonkey (même si, en contrepartie, il semble beaucoup plus lent au démarrage). Comme c'est IcedTea qui est utilisé par Ubuntu, je suppose que c'est ça qui explique que le problème ne soit pas largement connu.))

Ayant enfin réussi à faire marcher mon Java, je retourne sur le site de ma banque, et j'arrive à retirer mon certificat. Maintenant, je veux m'en servir pour signer la demande d'ajout de RIB. Nouvelle applet Java, et celle-ci meurt immédiatement sans autre forme d'explication. Nouveau problème, donc : pourquoi ça ne marche pas ?

Je dois d'abord trouver le moyen d'ouvrir une console Java pour avoir quelques diagnostics. Pas évident de trouver la recette, mais une fois que c'est fait, la raison devient claire : non seulement ces andouilles croient indispensable d'utiliser Java, mais ils ne savent pas se débrouiller avec la bibliothèque standard de Java (qui fait pourtant tout en la matière, et surtout le café) : ils ont besoin d'un package à la con et non standard, com.dictao, dont la simple vue du site Web me laisse penser que c'est du bidon intégral. Mais le plus affligeant : pour faire une simple signature électronique, ils ont besoin non seulement d'un package Java externe, mais ils ont même besoin de bibliothèques natives. (Le lecteur non techniquement initié ne comprend sans doute pas un mot de ce que je raconte, mais c'est un peu comme si pour faire fonctionner une télé on prétendait devoir ouvrir mon compteur électrique et installer des choses dedans. C'est même pire que ça, tout le principe de Java est d'éviter d'avoir à utiliser du code natif !, et là ils arrivent à combiner les inconvénients des deux.)

Et évidemment, ces bibliothèques natives ne sont fournies que dans un petit nombre de versions : Windows 32-bits, Windows 64-bits, Mac OS (je ne sais pas exactement quelles architectures) et Linux 32-bits. Dommage pour ceux qui sont clients de LCL et qui utilisent FreeBSD, ou bien Linux sur un ARM (comme un téléphone mobile Android ?), ou n'importe quoi d'autre ; et dommage pour le principe de portabilité de Java. Dans mon cas, c'est Linux 64-bits, donc je suis baisé. Bon, il se trouve que j'ai un système 32-bits au chaud, donc une fois que j'ai compris le problème, j'ai pu m'en sortir. Tout de même, deux nouvelles heures de perdues ; et au passage, je ne suis pas spécialement content de laisser ces gens de Dictao, que je ne connais ni d'Ève ni des dents, faire tourner des bibliothèques que je ne maîtrise pas sur mon ordi. Ça aussi, c'est assez bof pour la sécurité.

Si quelqu'un veut analyser le truc, l'applet est ici : je serais bien curieux de savoir à quoi servent précisément toutes ces bibliothèques.

Ceci étant, je me rends compte, une fois que j'arrive à faire marcher l'applet de signature, que j'ai oublié l'étape d'« activation » du certificat que j'ai reçu. Celle-ci, apparemment, consiste en gros à refaire une connexion au site de la banque en s'authentifiant avec le nouveau certificat. Manque de chance, cette reconnexion constitue techniquement une renégociation SSL, ce qui est la base d'une vulnérabilité connue depuis deux ans, que tous les navigateurs vaguement décents, et en tout cas le mien, ont corrigé en interdisant le renégociation SSL. Du coup, cette étape ne marche pas (error ssl_error_renegotiation_not_allowed). Bon, heureusement, si on cherche un peu, on apprend que Firefox a des préférences permettant de lever cette interdiction (au cas par cas, ou globalement). Mais ça donne une idée du niveau de compétence en sécurité informatique des programmeurs qui ont pondu ce truc.

Au final j'ai bien réussi à activer mon certificat et à signer ma demande d'ajout de nouveau RIB… qui sera effective sous quelques jours, quand ils m'auront envoyé un nouveau courrier pour m'en avertir. Mais quel parcours semé d'embûches !

Ce que j'aimerais bien faire maintenant, c'est analyser ce que fait exactement cette applet Java, la reprogrammer moi-même, et contourner leur truc (par exemple avec GreaseMonkey) pour utiliser le mien à la place. Ça demanderait pas mal d'efforts, donc je ne sais pas si ça en vaut vraiment la peine, mais ça aurait quelque chose de jouissif de rendre public un tel script servant à réparer les idioties de LCL (et à le rendre accessible depuis n'importe quelle machine avec Firefox, pas seulement les Windows, Mac OS et Linux 32-bits).

Je pourrais aussi écrire une lettre à LCL en disant écoutez, je suis chercheur en crypto dans une grande école de télécommunications, et mon avis technique détaillé en tant que spécialiste de sécurité informatique est que vous êtes des quiches, mais je crois que je pourrais tout aussi bien pisser dans un violon que d'espérer pouvoir faire remonter mes critiques à ceux qui les méritent.

(jeudi)

Les détails de RAID6 et le choix d'un polynôme

Mon passage à RAID6 est essentiellement fini, mais comme j'aime bien connaître les détails de ce que j'utilise[#], j'ai voulu savoir un peu précisément comment il fonctionne (je sais ce que c'est qu'un code correcteur, bien sûr, mais je veux dire, savoir assez précisément comment les données sont organisées pour pouvoir reconstituer mes disques moi-même, ou aller y chercher n'importe quelle donnée, si jamais Linux cessait d'exister dans un pouf de logique).

L'idée de base est la suivante : à part les métadonnées dont je n'ai pas cherché à savoir comment elles sont organisées, un tableau RAID divise chaque disque (ou partition) du tableau en chunks (également appelés stripes), qui font par défaut 512ko. Si on a N disques dont Nk de données et k de redondance, alors un ensemble de N chunks au même emplacement sur chacun des disques s'appelle une stride, et une stride porte donc Nk chunks de données plus k chunks de redondance. Sur Nk disques (différents pour chaque chunk, comme je vais l'expliquer), les chunks contiennent les données de la stride : ce sont ces disques-là qui seront normalement lus, sauf erreur signalée (quand un disque accepte de lire un bloc, on peut considérer que les données sont correctes, parce qu'il y a des sommes de contrôle au niveau du disque). Les k disques restants contiennent des syndromes de contrôle, calculés octet par octet à partir des Nk chunks de données de la stride. Si j'écarte le RAID0, qui n'a aucune redondance, et le RAID1 qui pour lequel tous les disques sont de toute façon identiques, il reste uniquement k=1 pour le RAID5 et k=2 pour le RAID6. Pour le RAID5, la somme de contrôle s'appelle P, ou chunk de parité, et pour RAID6, les deux sommes de contrôle s'appellent P (la même que pour RAID5) et Q.

L'organisation d'un tableau RAID6 de 4 disques (en mode left-symmetric, le mode par défaut) ressemble à ceci, où chaque ligne représente une stride, chaque colonne un disque (ou partition) et chaque case un chunk :

Disque 0Disque 1Disque 2Disque 3
Stride 0QD0D1P
Stride 1D2D3PQ
Stride 2D5PQD4
Stride 3PQD6D7
Stride 4QD8D9P
Stride 5D10D11PQ
(etc., cycliquement)

Ici, D indique un chunk de données, P et Q des chunks de syndrome pour la stride. En l'absence d'erreur, les données se lisent donc en prenant le chunk 0 du disque 1 (ce qui donne D0, le premier chunk de données), puis le chunk 0 du disque 2 (ce qui donne D0), puis le 1 du disque 0 (D2), puis le 1 du disque 1 (D3), puis le 2 du disque 3 (D4) et le 2 du disque 0 (D5), et ainsi de suite, comme indiqué par ce tableau. Le rôle des disques est permuté cycliquement à chaque stride, ce qui assure qu'ils jouent tous le même rôle, et qu'il n'y en a pas un qui s'use prématurément (contraster avec RAID4, qui isole un disque uniquement pour la parité) ; la stride 0 attribue le syndrome Q au disque 0 et le syndrome P au dernier disque et les données aux autres disques dans l'ordre, et ensuite on décale cycliquement en décrémentant les numéros des disques. Pour du RAID5 on aurait une organisation semblable à ceci près qu'il n'y a pas de Q, donc la première stride attribue le syndrome P au dernier disque et les données aux autres, et la rotation se fait pareil (je parle toujours pour le mode mode left-symmetric : vous aurez sans doute deviné que right-symmetric tourne dans l'autre sens).

Le syndrome P est très facile à calculer : c'est simplement le XOR de tous les octets de données correspondants (c'est-à-dire que chaque octet d'un chunk P est le XOR des octets numérotés de la même manière dans chacun des chunks D de la même ligne) ; le syndrome Q, lui, est une combinaison linéaire des octets de données calculée dans le corps 𝔽256 à 256 éléments, dont les coefficients sont g0, g1, g2, etc., où g est un élément primitif de 𝔽256 et l'exposant est donné par le numéro du chunk de données à l'intérieur de la stride. Si je reprends le tableau précédent indiquant l'organisation du RAID6 sur 4 disques, ça fait :

Disque 0Disque 1Disque 2Disque 3
Stride 0D0⊕2⊛D1D0D1D0D1
Stride 1D2D3D2D3D2⊕2⊛D3
Stride 2D5D4D5D4⊕2⊛D5D4
Stride 3D6D7D6⊕2⊛D7D6D7
Stride 4D8⊕2⊛D9D8D9D8D9
Stride 5D10D11D10D11D10⊕2⊛D11
(etc., cycliquement)

J'ai noté ⊕ pour le XOR, qui est l'addition dans 𝔽256, et ⊛ pour la multiplication dans ce dernier, l'élément primitif étant g=2 avec une représentation de 𝔽256 de façon habituelle modulo un polynôme irréductible. Voyez ce document (temporairement indisponible sur kernel.org alors vous pouvez le consulter ici sur le cache Google) pour les détails. Mais sur le cas très simple de 4 disques, on se persuade très facilement qu'en connaissant deux quelconques des nombres u, v, uv et u⊕2⊛v, on retrouve toujours u et v.

Quel polynôme irréductible est choisi pour les calculs ? Le document précédent affirme que la représentation de 𝔽256 choisie est celle de AES/Rijndael, c'est-à-dire modulo x8+x4+x3+x2+1. J'ai sauté en l'air en voyant ça, parce que je sais très bien, pour faire faire ce genre d'exercice à mes étudiants, que le polynôme utilisé par AES/Rijndael n'est pas primitif (je veux dire, la classe de l'indéterminée modulo le polynôme, i.e., l'élément codé par 0x02, n'est pas d'ordre multiplicatif 255, mais 51). Du coup, ça voudrait dire que le RAID6 de Linux ne marche plus au-delà de 51 disques de données (ou du moins, ne peut pas corriger toutes les combinaisons de deux disques défaillants).

Heureusement, le polynôme d'AES/Rijndael est, en fait, x8+x4+x3+x+1, et c'est la première affirmation qui est fausse, la seconde est correcte, le RAID6 de Linux utilise bien x8+x4+x3+x2+1, qui est primitif, donc RAID6 marche comme annoncé (enfin, au moins mathématiquement — je n'ai pas 54 disques sous la main pour tester). M'enfin, ça reste une erreur et un sale coup du Club Contexte, d'avoir écrit ça. Et potentiellement dangereuse, si quelqu'un se précipite pour utiliser des implémentations matérielles optimisées des opérations AES afin d'accélérer le RAID6 ! J'ai écrit à Peter Anvin, qui a reconnu l'erreur (il avait bien remarqué que x8+x4+x3+x+1 n'était pas primitif et a cru à une faute de frappe, choisissant donc involontairement un polynôme non-standard) et m'a promis de la corriger.

Concrètement, donc, pour le choix x8+x4+x3+x2+1, calculer 2⊛v pour un octet v se fait en calculant soit 2v (la multiplication usuelle) soit 2v0x11d, lequel des deux est inférieur à 256. Ceci, parce que 0x11d est le nombre 28+24+23+22+1.

Vérification concrète sur un de mes tableaux RAID6 : les 32 premiers octets de chacun des quatre disques du tableau sont :

/dev/sdc20
00000000  aa 98 b9 a6 40 e0 da c2  c6 ca 5c 14 ad c0 ae e8  |....@.....\.....|
00000010  40 e8 d0 f2 40 ee c2 f2  40 ee d0 d2 c6 d0 40 e6  |@...@...@.....@.|
/dev/sda20
00000000  58 46 53 42 00 00 10 00  00 00 00 00 03 10 6c 00  |XFSB..........l.|
00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
/dev/sdd20
00000000  79 6f 75 72 20 70 65 61  63 65 2e 0a 57 68 61 74  |your peace..What|
00000010  20 74 68 79 20 77 61 79  20 77 68 69 63 68 20 73  | thy way which s|
/dev/sdb20
00000000  21 29 26 30 20 70 75 61  63 65 2e 0a 54 78 0d 74  |!)&0 puace..Tx.t|
00000010  20 74 68 79 20 77 61 79  20 77 68 69 63 68 20 73  | thy way which s|

Visiblement, le disque 1 (/dev/sda20, ne me demandez pas comment ils se sont retrouvés dans cet ordre dans le tableau) contient le début D0 des données (il s'agit d'un filesystem XFS, donc ça commence par XFSB), et le disque 2 (/dev/sdd20) contient aussi un chunk de données (D1, un bout d'un fichier[#2]). Le disque 3 (/dev/sdb20) contient le XOR de ces deux chunks, P=D0D1, ce qui est assez visible puisque comme D0 contient beaucoup de 0, sur ces octets-là il s'agit de la même chose que D1. Et enfin le disque 0 (/dev/sdc20) contient Q=D0⊕2⊛D1, ce qui comme D1 ne contient que des octets ASCII (donc <0x80), vaut en fait D0⊕2D1, et ça se voit par exemple au fait que beaucoup d'espaces (0x20) dans D1 deviennent des arrobas (0x40) dans Q (lorsque D0 contient 0). Ici, rien ne permet de vérifier qu'on a le bon polynôme. En revanche, si je considère la stride 2 (à l'offset 0x80000 parce que j'utilise des chunks de 256ko),

/dev/sdc20
00080000  f6 2a 28 86 e1 68 a8 fe  b3 63 2c 2d 26 a8 22 f8  |.*(..h...c,-&.".|
00080010  f2 13 c6 e4 9a 7c 55 3f  25 bf 75 48 7a db f7 8e  |.....|U?%.uHz...|
/dev/sda20
00080000  09 d5 d7 79 1e 97 57 01  4c 9c d3 d2 d9 57 dd 07  |...y..W.L....W..|
00080010  0d ec 39 1b 65 83 aa c0  da 05 0d 37 85 24 08 71  |..9.e......7.$.q|
/dev/sdd20
00080000  0e ab af ee 20 2f b2 1e  84 39 a7 a5 b3 b2 bb 12  |.... /...9......|
00080010  06 d9 6e 2a d6 07 55 81  b5 d9 92 ef 0b 54 0c fe  |..n*..U......T..|
/dev/sdb20
00080000  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00080010  ff ff ff ff ff ff ff ff  ff ba 78 7f ff ff ff ff  |..........x.....|

— cette fois on peut faire le calcul : sur le premier octet, par exemple, D4 contient 0xff, D5 contient 0xf6, on vérifie que P contient 0xff0xf6=0x09, et comme Q doit contenir 0xff⊕2⊛0xf6=0x0e, c'est que 2⊛0xf6=0xf1 et comme 2×0xf6=0x1ec, le polynôme utilisé est représenté par 0x1ec0xf1=0x11d, comme je l'annonçais (et ce n'est pas le polynôme de AES/Rijndael).

À ce stade-là, je m'estime satisfait dans le fait que j'ai compris comment les choses fonctionnent.

[#] En fait, cette affirmation est parfaitement fausse : en général, quand je regarde comment quelque chose fonctionne, surtout en informatique, je suis tellement dégoûté par ce que je découvre que je n'ose plus m'en servir.

[#2] Si vous voulez tout savoir, ce fichier contient des phrases complètement dénuées de sens dans un style assez pompeux : Jesus strong first whoredoms, where no bread along which is in your peace. What thy way which shall be killed. And when God. They are come to pass, the image with him: for thy mine eyes unto the Midian was the land whither the same there arose a man be fulfilled: But I spoken by you, and his tabernacle at the altar another: for the time of tempted in thing, the figunto thee: they believe it to them: but thou hast given me to be unto you the Shushan is with man's wife. Il s'agit du résultat du passage de dissociated press sur la bible du roi Jacques que j'avais fait il y a longtemps parce que je trouvais le résultat très amusant.

(mercredi)

J'essaie le RAID6

J'ai déjà dû raconter quelque part sur ce blog que je suis obsédé par la préservation de l'information. En particulier, l'idée de perdre des données informatiques est quelque chose contre quoi je veux me garder le plus sérieusement possible. Ça m'est déjà arrivé par le passé, à une époque où les disques durs coûtaient strictement plus qu'une bouchée de pain, et j'ai perdu des fichiers qui m'étaient précieux[#]. Pour mes données les plus précieuses, j'ai un système de sauvegarde où (1) les données sont répliquées par RAID entre plusieurs disques (cf. ci-dessous), (2) elles sont en plus répliquées chaque jour par rsync entre deux ordinateurs distants de 20km (et le point précédent s'applique sur chacun de ces ordinateurs), (3) sur l'un de ces ordinateurs, une copie est faite chaque nuit de tous les fichiers qui ont changé, histoire de pouvoir extraire de vieilles versions si je me rends compte que j'ai fait des changements malencontreux (ceci, en plus du fait que beaucoup de données sont de toute façon sous contrôle de git ; et le premier point s'applique aussi à ces copies), et (4) une fois par an au moins, je fais aussi une copie sur médias optiques, que j'archive. Avec tout ça, je me sens raisonnablement en sécurité.

Le problème, c'est qu'à côté de ces données de grande importante (très grossièrement, tous les fichiers que je crée moi-même), il y en a d'autres, qui ne méritent pas des précautions aussi importantes, ou surtout, qui ne les permettent pas parce que le volume de données est trop important, mais qu'il m'embêterait quand même assez sérieusement de perdre : des tas de choses que j'ai téléchargées sur Internet (ou dont l'effet de rayons cosmiques aléatoires frappant mon disque dur a causé l'apparition), ou encore des choses calculées par des ordinateurs au prix d'heures de calculs que je n'ai pas envie de refaire. Il me faut donc plusieurs niveaux intermédiaires entre les données les plus importantes et les moins importantes (voire, celles qui sont nettoyées automatiquement, comme le contenu de /tmp).

Et un autre facteur qu'il ne faut pas perdre de vue, c'est le temps passé à restaurer les données en cas de problème : parfois les données elles-mêmes n'ont pas vraiment de valeur (comme pour les partitions système : il s'agit d'exécutables Linux qui de toute façon sont disponibles publiquement), mais le temps passé à les récupérer ou à les remettre en place peut justifier qu'on utilise tel ou tel mécanisme de sauvegarde.

J'en viens à RAID : pour ceux qui ne connaissent pas, cet acronym signifie Redundant Array of Inexpensive Disks. L'idée est de partager des données entre plusieurs disques durs de façon soit à augmenter la capacité ou la vitesse, soit à diminuer les risques de pertes de données, soit les deux. En gros, vous avez N disques (ou partitions de même taille sur des disques différents), vous choisissez un niveau de redondance k qui vous protège contre la panne simultanée de k disques, et RAID vous présente l'ensemble comme si vous aviez un seul disque de la capacité totale de Nk disques, et qui peut résister à une défaillance de k disques. En clair, il existe les principaux niveaux suivants :

Lorsqu'on a 4 disques, toutes les possibilités sont représentées là : 0 disque de redondance pour RAID0, 1 pour RAID5, 2 pour RAID6 et 3 pour RAID1. (Je ne parle pas des autres niveaux de RAID, qui, à mon avis, ne sont pas très intéressants — par exemple le RAID10 est du RAID0 au-dessus de RAID1, qui entre 4 disques offre quelque part entre 1 et 2 disques de redondance vu qu'il peut subir la mort de 2 disques à condition que les 2 disques ne soient pas dans le même sous-tableau RAID1.)

En général, on ne choisit pas RAID1 entre un grand nombre de disques, ou, si on le fait, c'est pour des raisons différentes de la seule redondance (par exemple pour le fait que n'importe quel disque peut être lu pour trouver les données, ce qui peut être pratique lors du processus de démarrage). Certains peuvent se dire que RAID6, qui protège contre la panne simultanée de deux disques, est déjà un excès de précautions (quand un disque tombe en panne, on va le changer immédiatement, et il est peu vraisemblable qu'un autre disque tombe en panne pile à ce moment), mais c'est oublier que les pannes ne sont pas des événements indépendants : le même problème (un choc électrique ou mécanique, par exemple) peut causer la mort de plusieurs disques[#2], d'une part, et plus subtilement, l'utilisation du RAID lui-même peut causer la mort d'un disque (lorsqu'on remplace un disque dans un tableau RAID, il se produit une grande activité sur tout le tableau, qui peut accélérer la mort d'un disque) ; sans compter que si on a deux disques issus de la même série, ils peuvent avoir le même défaut de fabrication[#3]. Donc, deux disques de redondance, ce n'est pas forcément un luxe inutile.

Le RAID a aussi quelque chose de très agréable, c'est qu'il est complètement transparent. Si un disque fait une faute de lecture isolée, la couche RAID détecte la faute, lit les données à partir des autres disques, réécrit le secteur défectueux, ce qui cause sa réallocation par le firmware du disque (donc en pratique « la corrige »), et on ne voit qu'un léger délai. Si un disque meurt complètement, la couche RAID finit par se lasser, chasse le disque du tableau (qui devient alors dégradé), et tout continue à fonctionner, et quand vous achetez un nouveau disque pour le remplacer et que vous l'ajoutez au tableau, les données sont automatiquement copiées vers lui pour que le tableau cesse d'être dégradé. Pas besoin de s'embêter à retrouver où on a mis des copies de sauvegarde ou quoi que ce soit.

En contrepartie, RAID n'attrape pas tous les problèmes pour lesquels on fait des sauvegardes. Par exemple, si on efface un fichier malencontreusement, la couche RAID réplique l'effacement sur tous les disques, et ne vous protège pas du tout. Il existe des choses plus sophistiquées, comme des snapshots par copy-on-write (disponibles par exemple, sous Linux, dans BTRFS), mais cela, à son tour, ne vous protège pas contre des bugs du filesystem. Bref, il faut décider quelle assurance on veut, et contre quoi.

On a aussi parfois le choix entre le RAID logiciel ou matériel (c'est-à-dire que certaines cartes mères ou chipsets SATA sont capables de gérer le RAID de façon transparente et de ne présenter au système d'exploitation que l'apparence d'un seul disque). Mon choix est parfaitement clair, et c'est celui du RAID logiciel (celui de Linux : je ne suppose que Windows et Mac OS ont des choses semblables), qui est peut-être légèrement plus coûteux en ressources, mais qui m'offre beaucoup plus de finesse dans la gestion des choses, par exemple celle de convertir de RAID5 vers RAID6 (ou de lancer une vérification) sans passer des heures dans un outil du BIOS, et aussi la garantie que mes données sont stockées sur les disques dans un format connu et documenté, donc qu'elles ne vont pas devenir inaccessibles si ma carte mère meurt.

Comme je l'ai évoqué, il est possible de faire des conversions entre niveaux de RAID, ou entre nombres de disques. Ces conversions (de nouveau, sous Linux et en utilisant mdadm, je ne sais rien des autres OS) se font à chaud : le système continue de fonctionner normalement alors qu'on est en train de convertir, disons, un RAID5 entre 3 disques vers un RAID6 entre 4 disques (ce qui garde la même capacité, et ajoute un disque de redondance, mais nécessite de réorganiser toutes les données du tableau) ; les choses sont même prévues pour qu'on puisse interrompre l'opération et la reprendre plus tard (par contre, dans ce cas, le tableau cesse d'être disponible au moment où on interrompt). Enfin, ça c'est la théorie, parce que sur le noyau que j'utilise (un Linux 3.1.0-rc6[#4]), même si la conversion en elle-même se passe très bien, on ne peut pas dire que ça ne gêne pas le fonctionnement normal du système : j'ai des processus qui restent bloqués indéfiniment (et c'est probablement un bug, pas juste une attente disque devenue plus lente à cause de la conversion, parce que ça a l'air de toucher les processus un peu aléatoirement, et même quand on convertit des tableaux RAID absolument pas utiles au système ni utilisés par les processus qui bloquent). Enfin, ça reste utilisable, la preuve c'est que j'ai pu écrire tout ça sur la machine en question.

Moi je faisais du RAID5 entre 3 disques jusqu'à récemment, et comme j'ai vu qu'il y en a un qui commençait à montrer des faiblesses[#5] (ce qui, s'agissant de RAID5 veut dire qu'il faut le changer immédiatement), je me suis dit, plutôt que bêtement le remplacer, pourquoi ne pas ajouter un nouveau disque et faire du RAID6 sur 4 disques, et je virerai le disque qui faiblit quand il sera vraiment mort, pas au premier signe de faiblesse. En plus, ça me permet d'ajuster plus finement le niveau de RAID entre différentes partitions : il y en a pour lesquelles je reste à RAID5, mais sur 4 disques, pour gagner un peu de place, parce que ce sont des données vraiment peu importantes (un miroir Debian).

Et à part ça… c'est long… Mais qu'est-ce que c'est long ! La conversion du RAID5 sur N disques en RAID6 sur N+1 disques passe par un disque dur supplémentaire (il y a donc 5 disques impliqués dans l'affaire en ce qui me concerne, les détails sont là), vers lequel chacune des données du tableau doit être écrite, puis relue (ça va méchamment l'user, soit dit en passant — heureusement je m'en fous). Et ça se fait au rythme de 5.5Mo/s en moyenne. Et pour convertir 1To, au rythme de 5.5Mo/s, il faut… 50 heures. Voilà pourquoi, depuis maintenant une journée complète et sans doute pour encore aussi longtemps, j'ai 5 disques durs qui moulinent, qui moulinent, qui moulinent.

[#] En particulier, j'ai perdu des petits textes humoristiques que mon papa écrivait à mon sujet (c'est-à-dire, pour se foutre de moi), et qui s'appelaient The Adventures of Altcee : ça me fait de la peine, parce que j'aimerais bien les relire. Il semble qu'il en existe peut-être encore un exemplaire, mais il est sur une disquette 5″¼ et c'est devenu impossible de retrouver un lecteur 5″¼ de nos jours (ou en tout cas un lecteur 5″¼ dont on soit raisonnablement certain qu'il marche et qu'il ne risque pas d'endommager cette disquette si ce n'est pas déjà le cas !). [Ajout : elles ont maintenant été récupérées.]

[#2] J'ai un copain qui peut témoigner du risque lié au fait d'attacher les disques durs dans son boîtier avec des élastiques pour amortir les vibrations.

[#3] Raison pour laquelle j'essaie de faire des tableaux RAID entre disques de fabricants différents. Là, j'ai un Samsung, un Hitachi (le petit nouveau), un Seagate et un Western Digital.

[#4] Je n'aime pas utiliser des noyaux expérimentaux comme ça, mais en l'occurrence je n'avais pas le choix parce que j'étais coincé entre un bug USB des 2.6.38.x et un bug obscur dans le cache de routage dans les 3.0 qui cassait vraiment sérieusement ma config réseau, et pour lequel on ma donné un patch qui ne s'applique qu'au 3.1.

[#5] Dénonçons le coupable : c'est le Seagate. C'est un disque de 1To, et il en est à ~300 secteurs réalloués. Ceci dit, Western Digital mérite aussi un blâme dans l'histoire, pour des histoires expliquées ici par eux-mêmes (et dont l'explication technique détaillée est : ce sont des bouffons).

(samedi)

Pourquoi ne réussis-je pas à avoir de la 3D sous Linux ?

Un des domaines où Linux est incroyablement et obstinément nul, au point que ça en devient presque comique et en tout cas extrêmement embarrassant, c'est l'accélération graphique 3D. En fait, plutôt que comique, ça en devient très problématique, parce que de plus en plus de sites Web sont accessibles uniquement par les navigateurs supportant le WebGL (c'est-à-dire l'extension à l'élément <canvas> du HTML5 permettant d'accéder à l'accélération 3D depuis le navigateur). Par exemple l'extraordinaire site Web d'anatomie humaine bodybrowser.googlelabs.com. Or il n'y a quasiment aucune combinaison de matériel, pilote graphique et navigateur qui permette effectivement d'avoir du WebGL accéléré en matériel sous Linux.

Récapitulons pour ceux qui n'y connaissent rien. D'abord, quand je parle de 3D, il ne s'agit pas de ce qu'on aurait au cinéma en 3D (par vision stéréoscopique), mais de représentation 2D d'images 3D calculées par une technique dont je ne connais pas le nom (mais qui s'oppose à celle du raytracing) et qui consiste à trianguler (=décomposer en petits triangles) les surfaces à projeter et à faire des calculs de rendu de surface (ombres portées, textures, etc.) sur ces triangles pour les afficher finalement en 2D. Tous les jeux sur ordinateur modernes utilisent cette technique. Et l'enjeu est tellement important qu'on a développé des cartes graphiques (actuellement toutes les cartes graphiques) qui sont capables de faire en matériel les principaux calculs nécessaires pour cette technique : on appelle ça l'accélération 3D matérielle (et les cartes en question sont beaucoup, beaucoup plus rapides que le processeur principal dans leur domaine de compétence). Encore faut-il que le logiciel derrière soit capable de s'en servir, c'est-à-dire, d'avoir les bons pilotes, les bonnes bibliothèques, etc. (et éventuellement le bon navigateur s'il s'agit de WebGL et que c'est une page Web dynamique qui veut bénéficier de cette accélération).

Les principales cartes (ou puces) graphiques du marché se rangent en trois familles : celles des constructeurs nVidia, ATI qui a été racheté par AMD, et Intel (ce dernier se concentre plutôt sur les puces graphiques pour portables alors que nVidia et ATI/AMD font plutôt des cartes graphiques pour ordinateurs de bureau). Il y a sans doute des différences de vitesse entre ces différentes cartes, cruciales pour les gamerz qui comptent les fps (frames per second) comme d'autres comptent les centimètres de leur bite, mais pour quelqu'un comme moi qui voudrais juste pouvoir accéder à des sites WebGL assez basiques, cela n'a aucune importance, je veux juste quelque chose d'un peu plus rapide que de la 3D non-accélérée (=rendue en logiciel).

Autrefois, Linux avait une bonne excuse : les fabricants de cartes graphiques ne publiaient pas les spécifications de leurs cartes (ou du moins, seulement sous signature d'un accord de non-divulgation), parce qu'une idée parfaitement stupide abondait chez eux selon laquelle il valait mieux que leur matériel ne marchât pas du tout que d'en faire paraître le mode d'emploi avec lequel, horresco referens, on risquerait de, euh, je ne sais pas, de s'en servir je suppose. Sans spécifications, pas moyen d'écrire un pilote, et l'histoire s'arrêtait là. Maintenant, les choses ont un peu changé : si nVidia persiste dans cette stratégie grotesque, en revanche lorsque AMD a racheté ATI, ils ont inversé la politique et ont publié en 2007 de gros manuels de programmation de leurs puces graphiques (je crois que c'était pour les puces récentes). Quant à Intel, ils sont plutôt ouverts sur la question, même s'il y a des changements occasionnels comme on en a l'habitude avec ce genre de grosse compagnie. Toujours est-il que si j'ai applaudi lorsque ATI a libéré les spécifications de ses puces, j'espérais voir un pilote utilisable apparaître en un an ou deux. Ou trois. Mais quatre ans plus tard, c'est vraiment embarrassant à quel point le progrès est nul. (Et ce n'est pas faute de moyens : il y a des développeurs qui bossent vraiment dessus, y compris des développeurs payés par le constructeur.)

La première chose qui pose problème, c'est que plus Personne N'Y Comprend Rien®. Autrefois, pour faire de la 3D sous un Unix à la Linux, il y avait plusieurs approches possibles : (1) faire les calculs purement en logiciel (c'est-à-dire, sans accélération matérielle, donc sans besoin de matériel spécifique, mais en échange de quoi tout sera très lent), ce qui peut vouloir dire (1a) faire les calculs côté serveur (le serveur, dans la terminologie X11, étant l'ordinateur, ou le processus, qui affiche vraiment l'image sur l'écran) ou bien (1b) faire les calculs côté client (le client, dans la terminologie X11, étant l'ordinateur ou le processus qui fait tourner le programme graphique), la distinction étant pertinente parce que le système X11 est un protocole client-serveur, ce qu'on a tendance à oublier de nos jours ; ou bien (2) utiliser une accélération matérielle côté serveur, c'est-à-dire que le client (qui peut très bien tourner sur un ordinateur différent) fait passer au serveur des demandes d'affichage de triangles (ou je ne sais quoi d'autre) et le serveur les refile à la carte graphique rattachée à l'écran. Pour une raison d'efficacité, on a introduit une nouvelle possibilité, (3) le direct rendering, par laquelle le client graphique parle directement à la carte graphique sans passer par le serveur (il a juste demandé une sorte d'autorisation générale au serveur). Je crois que c'est quand on a introduit ça que tout a foutu le camp ; a commencer par la possibilité (2) d'avoir de l'accélération 3D matérielle en faisant tourner le client graphique sur une machine différente du serveur qui gère l'écran : personne n'est capable de me dire si cette possibilité existe encore sur les X.org/Linux modernes ; et je ne parle pas de la sécurité, parce que permettre à un programme non privilégié de parler à la carte graphique qui a un accès direct au bus mémoire et pas trop de notion de permissions, c'est ouvrir un trou de sécurité de la taille du Brésil dans le modèle de sécurité de l'ordinateur. Toujours est-il que l'idée de faire de l'accélération 3D matérielle sans ce direct rendering a l'air d'avoir complètement échappé à tout le monde (pourtant, j'en ai vu, ç'eut été possible).

Là-dessus, il y a toute une salade de sigles et de termes dont on ne sait pas ce qu'ils recouvrent au juste : il y a OpenGL, qui est une sorte de standard pour les primitives graphiques 3D, et qui a l'air atrocement mal foutu parce que personne n'a l'air d'accord sur ce qu'il contient exactement. Il y a Mesa, qui est apparemment l'implémentation libre d'OpenGL et qui a l'air de servir dans un sous-ensemble des cas (1a), (1b), (2) et (3) évoqués ci-dessus, mais c'est absolument impossible de savoir exactement lesquels (peut-être tous, mais rien n'est moins clair). Il y a des choses nébuleuses appelées libglu, libglut, libosmesa et encore d'autres, dont je n'ai aucune idée de ce qu'elles font (enfin, si, un peu : les deux premières sont des surcouches sur OpenGL, et la troisième permet de faire des calculs 3D offline, c'est-à-dire sans les afficher effectivement à l'écran). Et il y a des choses dans le noyau Linux et dans le serveur X.org qui parlent entre eux, et tout cela est ficelé de la façon habituelle en informatique, c'est-à-dire qu'on peut trouver des explications techniques très précises sur chacun des bouts, mais aucune documentation synthétique pour décrire comment les différentes pièces du puzzle s'assemblent.

Globalement, pour faire de la 3D accélérée sous Linux, au moins dans la solution (3) (les autres, comme je le disais, je ne sais pas s'ils existent encore), on a les possibilités suivantes : (α) avoir une carte nVidia avec le pilote propriétaire fourni par nVidia (qui souffre de quantité de défauts, par exemple de ne pas gérer correctement le XRandR, et de casser à chaque version de Linux, mais qui au moins marchouille) ; (β) avoir une carte nVidia avec le pilote libre Nouveau (non, ce n'est pas un nouveau pilote, enfin, si, ç'en est un, mais c'est surtout un pilote qui s'appelle Nouveau) ; (γ) avoir une carte graphique AMD/ATI avec le pilote libre Radeon ; ou (δ) avoir une puce graphique Intel (typiquement, mais pas exclusivement, sur portable) et le pilote libre qui va avec. (Il est possible qu'il y ait d'autres options, je ne les connais pas bien.) J'ai une machine avec chacune de ces possibilités, et je peux confirmer la chose suivante : rien ne marche. Enfin, (α) marche un peu, si d'une part on n'est pas un intégriste du logiciel libre (ou plus pragmatiquement si on est prêt à laisser nVidia prendre le contrôle de son ordi avec un énorme blob binaire dont on ne sait pas ce qu'il peut contenir) et si d'autre part on veut bien supporter leur politique de distribution vraiment pénible. Pour les gens qui veulent du libre, optez pour (β)–(δ), et là vous aurez vraiment la garantie que ça ne marche pas du tout.

Oh, il est censé y avoir des choses. Certains vous diront que, si, si, Nouveau fait maintenant de la 3D accélérée, ou que Radeon marche correctement, ou qu'ils n'ont pas de problème avec leur puce graphique Intel. Reste que les problèmes sont tellement nombreux et les pilotes tellement buggués que Firefox 4, qui a introduit le WebGL, décide de désactiver cette extension dans tous les pilotes Linux autres que le pilote propriétaire nVidia (ce que j'ai appelé (α)). On peut demander à la réactiver de force en lançant Firefox avec la variable MOZ_GLX_IGNORE_BLACKLIST=1 : j'ai essayé, et j'ai réussi à planter Firefox, à planter mon serveur X, mais jamais à avoir le moindre bout de WebGL qui marche — donc ce n'est pas une blague. Même son de cloche du côté de Chrome/Chromium. (Et je précise que j'essaie avec le noyau 2.6.38.3, X.org 7.6, Mesa 7.10, un pilote Nouveau de moins d'une semaine, et Firefox 4 ou Chromium 10.0.648.205.)

Certes, on peut quand même avoir du WebGL sans accélération (solution (1b)) : sous Firefox 4, il s'agit essentiellement d'installer la bibliothèque libosmesa version 6 et de configurer webgl.osmesalib pour en donner le chemin (typiquement /usr/lib/libOSMesa.so) ; mais c'est tellement lent que j'ai tout de suite craqué.

Mais le pire, c'est que non seulement l'accélération 3D ne marche pas, mais l'accélération 2D ne marche plus non plus. Autrefois ces choses étaient bien séparées : maintenant, la 3D est devenue tellement importante que les cartes graphiques rapportent tout à ça, tant et si bien que si on veut avoir de l'accélération 2D (pour voir un film, pour déplacer les fenêtres de façon fluide, etc.), il faut plus ou moins que la 3D marche. Sur celle de mes machines qui utilise le pilote Radeon ((γ) ci-dessus), par exemple, j'ai de l'accélération 2D, mais uniquement sur le premier serveur X que je lance : que je m'avise d'en ouvrir un second, et plus rien n'est accéléré (il paraît que la solution à ce problème consiste à utiliser KMS, mais tout ce que j'ai réussi à en tirer c'est un écran noir) ; quant au pilote Nouveau ((β)), il a l'air tellement peu accéléré que le simple avertissement visuel du terminal (XTerm a une option pour changer brièvement de couleur au lieu de bipper) est atrocement lent.

Finalement, l'accélération 3D marche mieux sur mon téléphone mobile que sur mon ordinateur.

(jeudi)

Mises à jour, Mac OS et Linux

Je suis de passage chez mes parents, et, comme à chaque fois que je suis de passage chez mes parents, j'en profite pour faire des mises à jour sur les différents ordinateurs que j'y administre, c'est-à-dire essentiellement des PC sous Linux à moi (enfin, un qui est vraiment à moi, plus le routeur de la maison) et le Mac de ma mère (qui est sous Mac OS 10.6 Snow Leopard).

Sur le Mac, en l'occurrence, cela voulait dire mettre à jour Adobe Reader (qui est bourré de trous de sécurité dès qu'on le laisse plus de deux jours sans s'en occuper), Firefox (pour passer à la version 4), VLC (qui avait également quelques trous de sécurité), et OpenOffice pour le remplacer par LibreOffice. Ah oui, et XQuartz-sous-le-nom-de-X11 pour le remplacer par XQuartz-sous-le-nom-de-XQuartz (je n'ai pas bien compris pourquoi il y en a deux variantes, mais en tout cas c'était une version plus récente). Enfin, peu importe.

Et ce qui me semble horriblement fastidieux, venant de Linux, c'est que pour chacun de ces programmes, il fallait trouve le site Web approprié, récupérer la nouvelle version, monter le fichier .dmg téléchargé, le copier dans le répertoire d'applications, effacer tout ce qui traîne (et vider la poubelle, ah, cette idée géniale de transposer au bureau d'un ordinateur ce qui est déjà une corvée à la maison), puis recommencer éventuellement pour des packs additionnels comme la traduction française. Rien n'est automatisé. (Ah si, Acrobat se mettait à jour tout seul, mais n'empêche qu'il fallait le lancer, trouver le menu où se cachait l'option pour vérifier les mises à jour… pas sûr que ce soit tellement plus simple, en fait.)

Sous Debian GNU/Linux, je tape juste sudo apt-get dist-upgrade et il me met à jour tout ce qu'il faut parmi les quelques 4000 packages installés, et de façon unifiée. Là je n'en avais qu'une petite douzaine, et ça a été nettement plus laborieux. Il n'y a aucun système centralisé connaissant tout ce qui est installé.

C'est d'autant plus bizarre que Mac OS a un système de packages, mais il n'a pas l'air de servir en vrai, apparemment parce qu'il est beaucoup trop limité. Des gens ont inventé d'autres trucs (comme Fink) pour suppléer ces limitations, mais du coup le système lui-même ne se met pas à jour avec les mêmes trucs donc ce n'est pas une vraie solution. Quant à l'App Store d'Apple, il ne contient apparemment ni Firefox, ni LibreOffice, ni XQuartz, ni VLC : autant dire que c'est complètement nul et que ça ne fait ne résout pas (voire, empire) le problème de manque d'un point central qui connaisse tout ce qui est installé sur l'ordinateur.

Ceci étant, ce n'est pas parce que le Mac est mauvais que les distributions Linux sont complètement satisfaisantes pour autant. Sous Debian, j'aurai peut-être un Firefox maintenu pour ce qui est des trous de sécurité, mais si je veux un Firefox récent, il faut chercher dans les packages expérimentaux, ou bien dans ceux distribués par des tiers (or ces derniers ne sont jamais parfaitement bien intégrés au système — et ça, j'ai tendance à penser que c'est une faiblesse de la distribution, et pas des tiers, si la création d'un package Debian ne s'impose pas comme une évidence), ou bien installer le programme hors du système de packages, ce qui redevient alors aussi merdique que sur le Mac. De surcroît, le fait que les N distributions Linux n'aient pas réussi à s'entendre sur un système de packages unifié (au moins pour tout ce qui ne fait pas partie du système de base, et au moins pour ce qui est des sources des packages en question) provoque une duplication totalement inutile d'efforts humains.

(Monday)

The Unix leap second mess

[Note (): This entry has been copied into its own standalone page, which I might update in the future.]

Since this is a very geeky topic, I'll be writing in English for a change.

Let me start with some background. I recently discussed the reason why the day is ever so slightly longer than 86400 SI seconds. One of the consequences of this is that there are several different time scales involved in accurate timekeeping (which I discuss in more detail here). One is TAI, which is a pure linear time scale, maintained by several atomic clocks across the globe and counting SI seconds on the geoid; it has been maintained since 1958 (though it can conceptually be extended back in the past as a variant of Terrestrial Time), it was initially synchronized with universal time and has now drifted away from it by approximately 34.136 seconds today. Another is Universal time UT1 (there are other variants of universal time such as UT2, but they will not concern us here): though there are subtleties, this is essentially the real mean solar time on Greenwich meridian, and it is the parameter of the real orientation of Earth in space. So as measured in UT1, one solar day is always 86400 seconds: conversely, this means that UT1 does not measure actual SI seconds, but rather some kind of angle parameter. This time scale makes sense very far back in the past.

(lundi)

Adobe Flash 10.1 et les navigateurs 64-bits

Comme Apple, je hais le Flash avec l'intensité de mille soleils brûlants, et tous les sites Web qui utilisent (et surtout abusent) du Flash, et j'espère que ce format disparaîtra le plus vite possible, et je suis prêt à pardonner beaucoup à Steve Jobs pour son petit coup de pouce dans ce combat. Malheureusement, le Flash, j'en suis aussi prisonnier, parce que, outre que j'aime de temps en temps regarder des vidéos sur VousTuyau (et que mon navigateur ne saura lire le format H.264 que quand les États-Unis auront enfin(?) supprimé les brevets logiciels, et le VP8 que dans un demi million d'années quand Debian se sera sorti les doigts du c**), bref, le site de carte bleue électronique de ma banque (=le truc qui me permet de leur faire gagner plus de temps et d'argent en augmentant la sécurité sur les transactions Visa qui devrait être leur problème— mais qui me fait aussi gagner en tranquillité, il faut bien l'admettre) est en Flash. Enfer et damnation.

Une des nombreuses raisons pour lesquelles je déteste Flash, c'est qu'il est bourré de trous de sécurité (ce n'est sans doute pas tellement la faute d'Adobe, qui a racheté une technologie complètement moisie, mais en tout cas c'est le cas). S'il y a une faille de sécurité béante dans les navigateurs de toutes les Madame Michu du monde, c'est Flash. La dernière version, la 10.1, corrige quelque chose comme 32 trous de sécurité connus. D'ailleurs, Adobe a tellement dû se presser pour le sortir qu'ils n'ont pas eu le temps de faire une version (bêta) 64-bits comme ils font d'habitude.

Manque de chance pour moi, j'ai un ordinateur, un OS, et un navigateur, entièrement 64-bits.

Solutions envisagées :

Je me suis rabattu sur cette dernière solution. Il faut admettre que NSPluginWrapper semble avoir fait des progrès depuis mes dernières tentatives pour en faire quelque chose ; malgré cela, c'est très pénible à installer (ne serait-ce que parce qu'il faut trouve des versions 32-bits des bibliothèques libidn, libnspr4, libnss3, libnssutil3, libplc4, libplds4, libsmime3, libssh2, libssl3, dont Flash a besoin, et aussi libcurl dont il a aussi besoin mais sans prévenir donc c'est un piège redoutable).

(samedi)

Ubuntu, mon touchpad, et la configurabilité

Tous mes ordinateurs tournent sous un OS basé sur Linux. Comme il faut, malgré tout, varier un petit peu les supplices, j'en ai quelques uns (essentiellement, mes serveurs) qui utilisent Debian (la distribution qui retire tout ce qui ressemble à de la documentation, histoire que vous soyez plus Libres), et quelques uns (mon Eee PC, ma machine de bureau) qui utilisent le dérivé de Debian beaucoup plus populaire que l'original, Ubuntu. Les maux sont différents : Debian, par exemple, prend un grand soin à ce que la version de Firefox distribuée ne s'appelle pas Firefox, mais Iceweasel (parce que Firefox n'est pas Libre[#]), et, comme il leur faut quelque chose comme deux ans pour rechercher et remplacer toutes les occurrences de Firefox par Iceweasel, on se retrouve avec une version bien ancienne sur le système. Avec Ubuntu, le problème est plutôt que dès que vous jouez à configurer ne serait-ce qu'epsilonesquement le système, vous êtes sûrs qu'à la prochaine version votre configuration sera partie à l'eau.

Tous les six mois, donc, j'installe la nouvelle Ubuntu, et tous les six mois je dois passer quelques jours à me battre contre la façon dont Ubuntu a décidé de m'empêcher de configurer mon système aux petits oignons[#2].

Le gag récurrent, c'est le touchpad de mon Eee PC. Je tiens à désactiver un truc affreux qui s'appelle le tapping (c'est-à-dire le fait que tapper simplement le touchpad, sans déplacer le doigt, simule un click de souris) : je trouve cette fonctionnalité insupportable parce qu'elle provoque des clicks intempestifs dès qu'on effleure le touchpad. En revanche, comme un touchpad n'a pas de molette, j'aime avoir une méthode de scrolling, soit en déplaçant le doigt au bord du touchpad (scrolling au bord), soit en déplaçant deux doigts n'importe où sur le touchpad (scrolling à deux doigts). À chaque nouvelle Ubuntu, donc, je dois trouver moyen de configurer le touchpad pour désactiver le tapping et activer le scrolling au bord et le scrolling à deux doigts (si possible, horizontal aussi bien que vertical).

Avec la Ubuntu 8.04, je faisais ma configuration du touchpad en mettant la section suivante dans le fichier xorg.conf :

Section "InputDevice"
       Identifier      "Synaptics Touchpad"
       Driver          "synaptics"
       Option          "SendCoreEvents"        "true"
       Option          "Device"                "/dev/psaux"
       Option          "Protocol"              "auto-dev"
       Option          "VertEdgeScroll"        "true"
       Option          "HorizEdgeScroll"       "true"
       Option          "UpDownScrolling"       "false"
       Option          "LeftRightScrolling"    "false"
       Option          "LeftEdge"              "53"
       Option          "RightEdge"             "1099"
       Option          "TopEdge"               "48"
       Option          "BottomEdge"            "720"
       Option          "PalmDetect"            "0"
       Option          "TapButton1"            "0"
       Option          "TapButton2"            "0"
       Option          "TapButton3"            "0"
       Option          "SHMConfig"             "true"
       Option          "RBCornerButton"        "0"
       Option          "RTCornerButton"        "0"
       Option          "MinSpeed"              "0.4"
       Option          "MaxSpeed"              "0.8"
       Option          "VertTwoFingerScroll"   "true"
       Option          "HorizTwoFingerScroll"  "true"
EndSection

Ubunut 8.10 a décidé que ce n'était plus ça la bonne façon de faire : il fallait maintenant passer par le démon HAL. J'ai donc dû réécrire ma config sous forme d'un fichier /etc/hal/fdi/policy/dmadore-elantech-touchpad.fdi, contenant :

<?xml version="1.0" encoding="UTF-8"?> <!-- -*- SGML -*- -->
<deviceinfo version="0.2">
  <device>
    <match key="info.product" string="ETPS/2 Elantech Touchpad">
      <!-- Elantech touchpad should be handled by Synaptics driver -->
      <merge key="input.x11_driver" type="string">synaptics</merge>
      <merge key="input.x11_options.Emulate3Buttons" type="string">true</merge>
      <merge key="input.x11_options.SHMConfig" type="string">true</merge>
      <merge key="input.x11_options.VertEdgeScroll" type="string">true</merge>
      <merge key="input.x11_options.HorizEdgeScroll" type="string">true</merge>
      <merge key="input.x11_options.UpDownScrolling" type="string">false</merge>
      <merge key="input.x11_options.LeftRightScrolling" type="string">false</merge>
      <merge key="input.x11_options.LeftEdge" type="string">53</merge>
      <merge key="input.x11_options.RightEdge" type="string">1099</merge>
      <merge key="input.x11_options.TopEdge" type="string">48</merge>
      <merge key="input.x11_options.BottomEdge" type="string">720</merge>
      <merge key="input.x11_options.PalmDetect" type="string">0</merge>
      <merge key="input.x11_options.TapButton1" type="string">0</merge>
      <merge key="input.x11_options.TapButton2" type="string">0</merge>
      <merge key="input.x11_options.TapButton3" type="string">0</merge>
      <merge key="input.x11_options.RBCornerButton" type="string">0</merge>
      <merge key="input.x11_options.RTCornerButton" type="string">0</merge>
      <merge key="input.x11_options.MinSpeed" type="string">0.4</merge>
      <merge key="input.x11_options.MaxSpeed" type="string">0.8</merge>
      <merge key="input.x11_options.VertTwoFingerScroll" type="string">true</merge>
      <merge key="input.x11_options.HorizTwoFingerScroll" type="string">true</merge>
    </match>
  </device>
</deviceinfo>

Avec la Ubuntu 9.04, miraculeusement, le touchpad a continué à fonctionner comme je le voulais. Avec la 9.10, il a de nouveau cassé : cette fois-ci, le coupable était le démon gnome-settings-daemon, qui venait écraser mes réglages. Vous allez me dire : que ne m'en réjouis-je ? Ubuntu/Gnome a enfin prévu une façon de régler le fonctionnement du touchpad par une interface graphique (et notamment de désactiver le tapping, hosanna alléluia gloria in excelcis Gnomo). Le problème est que cette interface graphique est nettement moins fine que tous les réglages que je viens de décrire, et ne permet notamment pas d'activer à la fois le scrolling au bord et le scrolling à deux doigts. Mais un ami a fini par me donner la solution : on peut désactiver sélectivement des bouts de gnome-settings-daemon, en l'occurrence en positionnant à faux la clé /apps/gnome_settings_daemon/plugins/mouse/active dans l'éditeur de configuration Gnome (=le mammouth qui est en train de se mettre à ressembler à la base de registres Windows).

Ubuntu 10.04 : les choses ont de nouveau cassé : le démon HAL, qui était le Brave New World il y a 1½ an est maintenant rejeté et banni : mon fichier /etc/hal/fdi/policy/dmadore-elantech-touchpad.fdi est maintenant sans effet. Maintenant il faut passer par le programme xinput et ajouter quelque chose comme ceci dans le .gnomerc ou ailleurs :

# Was: 2, 3, 0, 0, 1, 3, 2
xinput --set-prop "ETPS/2 Elantech Touchpad" "Synaptics Tap Action" 0 0 0 0 0 0 0
# Was: 75
xinput --set-prop "ETPS/2 Elantech Touchpad" "Synaptics Middle Button Timeout" 90
# Was: 1, 0, 0
xinput --set-prop "ETPS/2 Elantech Touchpad" "Synaptics Edge Scrolling" 1 1 0
# Was: 1, 0
xinput --set-prop "ETPS/2 Elantech Touchpad" "Synaptics Two-Finger Scrolling" 1 1
# Was: 0.400000, 0.700000, 0.036711, 40.000000
xinput --set-prop "ETPS/2 Elantech Touchpad" "Synaptics Move Speed" 0.4 0.8 0.04 40.0
# Was: 53, 1099, 48, 720
#xinput --set-prop "ETPS/2 Elantech Touchpad" "Synaptics Edges" 53 1099 48 720

(Je n'ai pas configuré exactement les mêmes choses que dans les exemples précédent, mais c'est l'idée.)

Bon sang, moi je m'en fous de comment on configure le touchpad, je suis d'accord pour écrire ce genre de trucs à la mains quand je veux une configuration plus fine que ce que l'interface graphique standard permet, et je suis même d'accord que le nouveau système est plutôt meilleur (beaucoup plus pratique à modifier au vol), mais, bordel de merde, est-ce vraiment indispensable que le mécanisme de configuration change tous les six mois ?

(Remarquez qu'il n'y a pas qu'Ubuntu qui joue à ça : je me suis aussi énervé, sur l'ordinateur de ma maman qui est un Mac, contre Apple qui s'est amusé à éliminer dans Mac OS 10.5 ou 10.6 la base de données NetInfo qui était censée être Le Grand Truc de Mac OS, et pareil pour la découverte des imprimantes par CUPS remplacée par Bonjour.)

[#] Ne cherchez pas, ce sont des psychorigides qui ont une notion de liberté à peu près aussi déconnectée de la réalité que l'est l'usage du mot ouvert quand Apple/Adobe (vous savez, les deux big brothers interchangeables qui se livrent une guéguerre de cour de récré) dit promouvoir les standards ouverts sur le Web.

[#2] Quand je raconte mes malheurs, les gens réagissent souvent soit en me disant ah ? moi je n'ai pas de problèmes, soit en me disant que c'est bien ma faute, je n'avais qu'à utiliser Windows / Mac OS / quidlibet. La seule conclusion à en tirer, c'est que les gens ne configurent pas le système comme moi : je n'ai jamais trouvé d'explication, par exemple, sur comment avoir une touche Compose convenable sous Windows ou Mac OS (de sorte que taper Compose+apostrophe+e donne un ‘é’, par exemple).

(vendredi)

Parfois, inexplicablement, les ordinateurs marchent

C'est devenu tellement habituel pour moi de me plaindre que les ordinateurs ne marchent pas que je devrais plutôt signaler les fois où quelque chose a — inexplicablement — marché. Aujourd'hui, il y en a eu deux.

La première, c'est le Wifi. C'est un peu malhonnête de dire que ça a marché pour dire que je n'ai passé que toute la journée à le faire marcher, mais, tout de même, ça a marché, et s'agissant du Wifi c'est quelque chose de vraiment exceptionnel.

Pour être plus précis, la carte Wifi de mon ordinateur (basée sur un chipset Atheros AR2414) est potentiellement gérée par deux pilotes différents sous Linux (deux pilotes dont, évidemment, on comprend mal les rapports de prime abord, surtout que ce sont les mêmes personnes qui s'occupent des deux) : l'un, ancien, compliqué et plus trop maintenu, s'appelle Madwifi (et qui contient un blob binaire, c'est-à-dire qu'on n'a pas le source de la totalité du pilote), et l'autre, censé être plus petit, plus propre et complètement ouvert, basé sur une réécriture à peu près complète des couches Wifi de Linux, s'appelle ath5k. Jusqu'à récemment, j'utilisais Madwifi (le vieux pilote, donc) : pour des raisons mystérieuses et qui le resteront, Madwifi s'est mis a marcher de moins en moins bien au fur et à mesure que le temps passait (de temps en temps, le réseau cessait complètement de répondre), au point que c'en était devenu vraiment insupportable. Donc j'avais bien envie de passer à ath5k (le nouveau pilote). Malheureusement, ma carte Wifi me sert de point d'accès, pas juste de station, et le mode point d'accès (ou maître) est ce que tous les pilotes semblent implémenter en dernier (voire, jamais) : et ath5k n'implémente officiellement pas encore ce mode point d'accès que j'attends avec impatience à chaque nouvelle version du noyau (il sera officiel dans les noyaux 2.6.31, donc dans environ quatre mois). Ou alors, il faut chercher la toute toute dernière version de l'arbre de développement des pilotes Wifi : c'est ce que j'ai fini par faire, pressé par mon poussinet qui voulait pouvoir utiliser un Wifi correct, et donc je me retrouve avec un noyau 2.6.30-rc8~wireless-testing et l'inquiétude qu'il me claque entre les doigts en détruisant mes systèmes de fichiers (et de fait, il me crache des messages d'erreurs très inquiétants du style WARNING: at fs/fs-writeback.c:292 __writeback_single_inode+0x4ab/0x4c0(), que je vais prier pour pouvoir ignorer parce que ça a l'air de vouloir dire que mes fichiers vont exploser dans un temps très bref).

Évidemment, juste comme ça, ça n'a pas marché. Le poussinet arrivait à se connecter au Wifi géré par le nouveau pilote ath5k, mais mon Eee PC, нет, il n'arrivait pas à s'associer. J'ai un autre copain chez qui j'ai le même problème : mon Eee PC n'arrive pas à s'associer au Wifi de sa *box, alors que lui n'a pas de problème et que le même Eee arrive à utiliser plein d'autres réseaux. Ça m'a sérieusement énervé, alors j'ai décidé que je comprendrais ce mystère coûte que coûte : j'ai fait afficher les trames d'association et j'ai essayé de les interpréter même sans connaître les détails des protocoles IEEE 802.11b/g :

00000000  00 00 30 01 00 1b 11 14  d5 0f 00 22 43 00 6c 54  |..0........"C.lT|
00000010  00 1b 11 14 d5 0f 80 1f  11 04 03 00 00 0a 44 61  |..............Da|
00000020  76 69 64 6f 75 6e 65 74  01 08 82 84 8b 96 0c 12  |vidounet........|
00000030  18 24 32 04 30 48 60 6c  dd 07 00 0c 43 06 00 00  |.$2.0H`l....C...|
00000040  00 01 00 00 0f ac 02 01  00 00 0f ac 04 01 00 00  |................|
00000050  0f ac 02 00 00                                    |.....|
00000055

(Oui, Davidounet c'est le SSID de mon Wifi.) Il manque les octets 30 14 (annonçant 0x14=20 octets de RSN IE) immédiatement avant l'octet 0x41 ! L'explication du problème était donc que le Eee envoyait des trames d'association mal formées et que, contrairement à Madwifi et certaines bornes d'accès qui, plus tolérants, devaient se contenter d'ignorer ce qu'ils ne comprennaient pas, le nouveau driver rejetait la trame complètement et il devenait impossible de s'associer.

Le Wifi, c'est quelque chose de vraiment aléatoire, qui fonctionne uniquement quand les mânes de Maxwell sont de bonne humeur : je déteste ce truc, mais il faut admettre que, quand ça marche, c'est bien pratique. En l'occurrence, le driver incriminé sur le Eee PC, un driver écrit par le fabricant (Ralink), était visiblement porté à la va-vite depuis Windows, et il n'est sans doute pas surprenant qu'il fût buggué. J'ai fini par me rendre compte que quelqu'un avait déjà corrigé le problème et j'ai fini par réussir à associer mon Eee PC à mon Wifi qui, depuis, s'obstine à fonctionner correctement.

[Capture d'écran i>TELE]La deuxième chose qui a marché, c'est un stick récepteur TNT qu'un ami m'a passé. Là, c'est vraiment incompréhensible : ce genre de choses n'aurait pas dû être si simple à utiliser. Il doit y avoir anguille sous roche.

(jeudi)

Ce qui m'insupporte avec les applications open source

J'ai reçu une nouvelle machine au bureau ; jusqu'à présent j'utilisais mon portable personnel, mais à peine âgé de 2½ ans c'est déjà un vieillard : le voilà donc remplacé par un Core 2 Quad (enfin, un Core 2 Duo pour l'instant parce que Dell a fait une erreur en livrant le mauvais processeur) avec 8Go de RAM qui m'offre un environnement de travail un peu plus confortable (par exemple j'ai pu y compiler Sage — mais je digresse). Bref, j'ai décidé d'y installer une Ubuntu (mais peu importe, ce que je vais dire s'appliquerait à n'importe quelle distribution Linux), et j'ai gagné le droit de batailler contre la configuration : comme d'habitude, obtenir un système qui est à 99% comme on voudrait prend cinq minutes, passer à 99.9% prend cinq jours, et passer à 100% prendrait l'éternité.

Une des doctrines (je cherche ici à traduire le mot anglais tenet) de l'open source, et aussi d'une certaine manière d'Unix, et spécifiquement des distributions Linux, c'est qu'on doit avoir plein de petits programmes qui sont comme les morceaux d'un puzzle et que ces morceaux s'assemblent pour former un système utile. Malheureusement, il y a plusieurs problèmes avec ça :

Premièrement, il arrive que le même morceau soit écrit de plusieurs façons différentes par plusieurs personnes indépendantes ; il arrive aussi qu'un morceau soit écrit, puis abandonné (rendu obsolète) à la faveur d'un autre mieux écrit ; ou encore, que deux morceaux fassent des choses semblables mais en fait différentes (et pas forcément incompatible) ; tout cela est très bien. Le problème, c'est qu'on manque complètent de carte pour expliquer comment les morceaux s'arrangent, du coup on est perdu dans un labyrinthe de petits programmes tous semblables dont les rapports entre eux ne sont expliqués nulle part.

Voici un exemple : il y a (au moins !) deux systèmes complètement différents d'économie d'écran dans une distribution Linux standard : le X screensaver et le Gnome screensaver (et peut-être aussi un analogue du côté de KDE) ; chacun de ces deux systèmes d'économie d'écran vient avec plusieurs dizaines d'économiseurs d'écrans (c'est-à-dire d'animations qu'on peut, concrètement, avoir sur l'écran), certains étant d'ailleurs communs aux deux, et par ailleurs les deux font appel à une même capacité sous-jacente du serveur X à éteindre l'écran. Bien sûr, les auteurs du Gnome screensaver prétendent que le X screensaver est obsolète et ceux du X screensaver prétendent que le Gnome screensaver est mauvais pour d'autres raisons. Les réglages du X screensaver et ceux du Gnome screensaver sont semblables mais subtilement différents. Il est tout à fait possible de ne pas savoir lequel on utilise, voire d'utiliser malencontreusement les deux à la fois (qui vont plus ou moins se marcher sur les pieds). Du coup, quand un utilisateur novice demandera de l'aide à un utilisateur un peu moins novice mais néanmoins ignorant de l'existence de deux systèmes différents d'économie d'écran, cela peut donner des jolis dialogues de sourds. Personnellement, j'ai compris l'existence des deux trucs quand j'ai essayé de régler mon X screensaver en utilisant les réglages du Gnome screensaver ce qui, évidemment, ne marchait pas, sans afficher le moindre message d'erreur compréhensible ; de même, je ne comprenais pas pourquoi mon poussinet avait une liste assez différent d'économiseurs d'écran que la mienne. Tout ceci réjouit immensément le Club Contexte mais pas forcément les utilisateurs. Personnellement, je n'ai rien contre l'existence de deux systèmes différents, à condition que chacun signale l'existence de l'autre et explique qu'il est différent sur tel ou tel point et dans quelle mesure ils sont compatibles, comment savoir lequel on utilise, etc.

Un autre exemple : pour placer l'ordinateur en sommeil (suspend-to-RAM) ou en hibernation (suspend-to-disk), il existe tout un tas de mécanismes : le noyau a des capacités dans ce sens (écrire mem ou disk dans /sys/power/state), mais il existe aussi des choses telles que uswsusp, hibernate, pm-utils, gnome-power-manager et j'en oublie certainement. Comment savoir ce qui dépend de quoi, ce qui remplace quoi, ce qui sert à quoi, ce qui obsolète quoi, et ce qui peut servir en supplément à quoi ? Les documentations vous diront toutes qu'il s'agit d'un truc pour placer l'ordinateur en sommeil ou en hibernation, pas comment le truc en question se relie aux autres trucs qui prétendent servir à la même chose. En fait, il s'avère que uswsusp est une sorte de béquille au code du noyau qui lui permet de faire marcher plus de configurations en reconnaissant des besoins spécifiques à certains périphériques, que hibernate (Linux-spécifique et peut-être obsolète) et pm-utils (plus général) sont des collections de scripts censés travailler à plus haut niveau et font appels soit au noyau soit à uswsusp s'il existe, et que gnome-power-manager est sans doute une interface graphique à pm-utils (comme il en existe forcément aussi dans KDE) ; mais cela, on ne peut l'apprendre qu'en passant des heures à essayer de démêler les fils — car chercher un des noms dans Google ne vous aidera pas à trouver le rapport avec les autres. Résultat, si vous avez un problème dans le suspend, vous ne savez pas qui incriminer, vous ne savez pas contre quel package envoyer un rapport de bug, vous ne savez pas où chercher des logs, vous ne savez pas si vous pouvez essayer un autre programme ou si le composant en question est le seul qui remplisse sa fonction. C'est un cauchemar.

Mais le pire de tout, c'est probablement les mécanismes d'impression. Là vous devez à la fois choisir le spooler (ou front end) d'impression (par exemple CUPS, qui est d'ailleurs une horreur) qui sert à dispatcher les jobs d'impression et le driver (ou back end) qui sert à convertir les jobs au format compris par l'imprimante. Du côté du spooler, il y a plein de morceaux qui s'emboîtent de façon très compliquée et nulle part expliquée (CUPS, par exemple, est un serveur, donc il y a des clients qui vont avec, mais aussi des clients CUPS qui font semblant d'être des clients LPR ce qui fait que vous ne comprendrez pas si vous aurez besoin de ça si vous utilisez CUPS et pas LPR). Du côté du driver, c'est encore pire, parce qu'il y a toujours Ghostscript qui intervient d'une façon ou d'une autre, mais il en existe des versions patchées, il en existe de nombreux drivers proprement dits, et évidemment il y a un nuage de scripts autour de tout ça et des fichiers PPD dont on ne sait jamais s'ils décrivent l'imprimante ou le driver ou autre chose. Pour compliquer le tout, il existe des sortes de méta-drivers comme Gutenprint ou GIMP-print (peut-être certains sont-ils obsolètes mais, justement, c'est impossible à savoir). Et il existe un métasblurgh qui englobe tout ça à la fois et qui s'appelle Foomatic. Si votre imprimante ne marche pas, vous n'aurez aucune chance de savoir si la faute en est à Foomatic, Gutenprint, GIMP-print, Ghostscript, un des drivers de celui-ci, ou CUPS ou autre chose ; et si vous interagissez avec des machines Windows, ajoutes Samba à l'affaire (pour Mac OS, par contre, c'est aussi du CUPS). Je ne reproche pas l'existence de cette multiplicité de systèmes, je reproche que les auteurs des différentes parties (ou personne, en fait) ne prennent pas le soin d'expliquer comment elles se connectent aux autres. Il y a un embryon d'explication sur linuxprinting.org, mais ce n'est qu'un embryon.

Évidemment, parfois les choses marchent toutes seules (et les distributions Linux font tout pour que ce soit le cas). Parfois ça ne marche pas. Ce n'est pas mon reproche. Mon reproche est que quand les choses ne marchent pas, c'est quasiment impossible de savoir à qui on a affaire.

Là je parlais avant tout des soucis liés à la multiplicité des éléments qui font la même chose, même si dans le cas de l'impression ça tire aussi sur le problème de la multiplicité des éléments qui s'emboîtent de façon incompréhensible. Un problème différent mais apparenté est celui de la multiplicité des éléments non documentés qui parlent entre eux de façon trop automagique.

Un exemple archétypique serait Gnome (ou KDE, mais je connais mieux Gnome, pas forcément que j'aime beaucoup plus). Gnome est un environnement graphique pensé pour être aussi convivial pour le débutant que les environnements proposés par Microsoft Windows ou Mac OS. Du coup, il faut qu'il y ait toutes sortes de de programmes et de démons qui fassent des choses magiques qui ne sont pas trop prévues par l'esprit ancestral d'Unix. Par exemple, quand on insère une clé USB, le noyau Linux va le dire (via le système de fichiers /sys et/ou via une socket netlink) à un démon appelé udev qui va lui-même le dire à un démon appelé hal et ensuite, en passant le message par l'intermédiaire d'un autre démon appelé dbus, toutes sortes de choses magiques vont se passer par les différentes couches de Gnome. L'ennui, c'est que si on ne veut pas que toute cette magie se passe (par exemple, si pour une raison quelconque je ne veux pas que mon ordinateur monte automatiquement les clés USB qu'on insère dedans), c'est très difficile : il faut comprendre par où elle passe pour pouvoir l'arrêter. Les rois mages udev, hal et dbus ont tellement envahi tout le fonctionnement de Linux qu'on ne peut plus se passer de les comprendre, et ils sont très complexes, mais au moins il faut admettre qu'il en existe des documentations au moins de certains aspects (et assez rébarbatives, il faut le dire), par exemple pour ce qui est de hal. La magie qui se déroule dans les entrailles de Gnome, en revanche, elle n'est expliquée nulle part, pas plus qu'une partie importante de son terrifiant mécanisme de configuration (qu'on peut naviguer avec gconf-editor).

Un autre exemple est toute la sauce des GNU autotools, dans les compilations : quand la compilation marche bien, on est content, mais si jamais quelque chose échoue, allez fouiller dans un Makefile généré à partir d'un Makefile.in lui-même généré à partir d'un Makefile.am pour comprendre d'où sortait la ligne de commande erronée et comment lui faire comprendre de passer telle option en plus au compilateur !

C'est très décevant pour les gens comme moi qui connaissent bien Unix de constater à quel point ces mécanismes pour faire de la magie deviennent sans arrêt plus complexes et moins bien documentés. Certes ils font des choses utiles, quand ils marchent ; mais quand on veut faire quelque chose qui les dépasse ou simplement quand ils cassent, on se rend compte qu'il n'y a aucune documentation, aucun log d'erreur, et que le source est labyrinthique (il n'est souvent même pas évident de savoir de quoi il faut chercher le source, d'ailleurs).

En plus, si on gagne en complexité, on ne gagne pas toujours en flexibilité : souvent, au prétexte qu'il faut que tel ou tel aspect du programme soit configurable par les utilisateurs novices, donc par une interface graphique simple, on se retrouve avec des outils extrêmement peu configurables. (Je pense notamment au gestionnaire de fenêtres de Gnome, Metacity, qui a remplacé le plus flexible Sawfish : j'ai l'impression qu'on ne peut même pas avoir deux racourcis clavier qui fassent le même effet, chose qui peut être souhaitable dans certains cas, sous prétexte qu'il faut que les utilisateurs novices puissent éditer leurs racourcis clavier avec une interface très simple où chaque action est associée à un racourci et un seul. Ainsi, si on veut avoir le eye candy moderne de Metacity ou Compiz, on est obligé de se passer de la puissance et de la flexibilité d'un Sawfish ou même Fvwm : c'est vraiment triste.)

Il y a cependant un programme auquel je tire mon chapeau, parce qu'il a réussi à combiner le meilleur de tout : à la fois très simple pour le novice et très puissant pour l'expert, constitué de milliers de composantes, extensible, et pourtant remarquablement bien documenté (ce ne fut pas toujours le cas, mais maintenant il est vraiment bon de ce côté-là), c'est Firefox.

(lundi)

Nouvel Eee PC

Un an après avoir acheté mon premier Eee PC (un modèle avec 8Go de SSD et 1Go de mémoire qui n'est bizarrement même pas référencé sur la liste censément complète des modèles), j'ai décidé d'acheter un nouveau modèle 901 pour avoir un écran plus grand, un processeur plus puissant et moins gourmand en énergie (c'est un Atom), un disque SSD plus gros, un support Bluetooth et un meilleur chipset Wifi. Comme je l'ai déjà raconté, acheter la machine n'a pas été facile : heureusement, une amie vivant en Angleterre a pu recevoir pour moi le colis de Amazon.co.uk (que je maudis mille fois) et le réexpédier en France — du coup j'aurai payé 380€ plus encore 40€ de frais de port (plus quelques euros pour un adapteur secteur) au lieu des 360€ annoncés ailleurs, mais au moins j'aurai un clavier plus agréable que les horribles AZERTY.

Je suis quand même assez fâché qu'un produit livré avec Linux ait un matériel aussi mal géré par Linux ! Ma première étape a été de recopier sur la nouvelle machine la distribution Linux de l'ancienne (une Ubuntu 8.04 Hardy Heron à laquelle j'avais déjà dû apporter quelques modifications pour que l'ancien Eee PC fonctionne complètement). Résultat : pas de réseau Ethernet, pas de Wifi, un touchpad qui ne marche pas correctement, et je n'ai même pas osé essayer les hotkeys (ni le suspend-to-RAM/disk ou d'autres choses susceptibles de casser). Pour l'Ethernet, c'est apparemment parce que Asus a pris la décision-à-la-con® d'utiliser un chipset Atheros/Attansic sur PCI Express : je me demande bien comment ils ont pu avoir une idée aussi saugrenue que d'utiliser un chipset Ethernet Gigabit sur PCIe pour un truc qui, finalement, ne peut faire que du 100Mbps ; quoi qu'il en soit, la version suivante d'Ubuntu (8.10 Intrepid Ibex) résout le problème, mais upgrader en l'absence de support réseau est pénible et par ailleurs c'est très long sur une machine aussi minimaliste (l'installeur me dit qu'il en a encore pour plus de deux heures…). Pour le Wifi, il paraît que le chipset Ralink sera plutôt un progrès par rapport au Atheros, mais j'attends d'avoir pu le faire fonctionner pour me prononcer.

Mais le touchpad, c'est vraiment la catastrophe. Actuellement il fonctionne, mais c'est pire que s'il ne fonctionnait pas : il n'y a pas moyen de désactiver cette fonctionnalité atroce qui s'appelle le tapping, c'est-à-dire le fait de pouvoir cliquer au touchpad sans utiliser les boutons (juste en tapant brièvement sur le touchpad). Je ne sais pas qui a pu inventer ce truc, mais pour moi c'est une abomination, ça rend le touchpad complètement inutilisable, pire, dangereux parce qu'il clique aléatoirement partout dès qu'on a le malheur de l'effleurer par erreur. L'ancien Eee PC avait aussi cette misfeature, mais on pouvait sans trop de mal la désactiver parce que le touchpad était un Synaptics, bien géré par Linux+X.org depuis longtemps ; sur le 901 ils ont encore pris une décision-à-la-con® en remplaçant le touchpad Synaptics par un Elantech, beaucoup moins commun, et actuellement non supporté par Linux+X.org : la seule solution pour désactiver le tapping (autrement qu'en désactivant complètement le touchpad, ce qui est peut-être le mieux, en fait) est d'utiliser ce patch encore expérimental qui devrait le faire apparaître comme un Synaptics.

Par curiosité, est-ce qu'il existe des ultraportables qui soient vraiment supportés par Linux ? (Quand je dis vraiment, je veux dire jusque dans les moindres détails par les distributions habituelles et sans les configurer bizarrement ni aller chercher des drivers sur des sites tiers ; et que tous les périphériques et toutes les fonctions marchent parfaitement : réseau, wifi, bluetooth, accélération 3D, son, détection du niveau de la batterie, suspend-to-quidlibet, configuration détaillée du touchpad, toutes les touches magiques du clavier, etc.) Car le Eee PC, il faut bien le dire, échoue encore lamentablement à ce test (et le MSI Wind doit être dans le même cas vu qu'il a, par exemple, le même touchpad).

(mardi)

Eee PC

[Mon Eee PC, ouvert]Pour mon propre cadeau de Noël, je me suis acheté un de ces ultraportables Asus (que j'ai mentionnés récemment), un Eee PC. Inutile que je m'appesantisse sur les caractéristiques matérielles, elles sont données partout : le processeur est un Celeron M à 630MHz (en fait, à 900MHz, mais il est par défaut underclocké à 630MHz par le BIOS) ; l'écran est de 800×480 ; il y a des connecteurs USB2 et Ethernet 100Mbps, des enceintes et un micro intégrés ainsi qu'une webcam et un lecteur de cartes SD et bien sûr un composant Wifi ; le disque dur est en fait un solid-state, ce qui a l'avantage d'éviter une partie mobile et d'assurer plus de résistance aux chocs en contrepartie d'une bien plus faible capacité. J'ai pris le modèle avec 8Go de « disque » et 1Go de RAM. Bref, c'est quelque chose d'intermédiaire entre un jouet (ou une calculatrice ?) et un ordinateur. Logiciellement, c'est un Linux basé sur Xandros (lui-même basé sur Debian) et configuré de façon à cacher autant que possible ce fait aux utilisateurs novices (je pense que le slogan easy to learn, easy to work, easy to play n'est pas trop usurpé mais bon, d'un autre côté, je ne suis pas un utilisateur novice). Le tout pèse moins de 1kg (920g précisément, me dit-on — je n'ai pas vérifié) pour des dimensions de 225mm×163mm×36mm, autrement dit c'est vraiment petit (en gros la moitié d'une feuille A4) ; l'autonomie des batteries est quelque part autour de 3h, mais je n'ai pas encore mesuré précisément (et évidemment ça dépend de ce qu'on en fait, par exemple de si le Wifi est activé ou non, de la luminosité de l'écran, de l'utilisation du processeur, etc.).

Si j'ai bien compris, la chose n'est pas encore en vente en France (j'avoue ne pas comprendre pourquoi ce genre de choses ne sortent pas dans le monde entier simultanément : manifestement la mondialisation a encore du chemin à faire !) et le sera d'ici un ou deux mois. Comme je n'avais ni envie d'attendre (l'utilité de la chose pour moi est notamment de me permettre de me connecter au Wifi des bâtiments de l'ENSTne se situe pas mon bureau, et ça urge un peu) ni envie d'avoir un clavier AZERTY (je déteste ça, même si de toute façon je vais taper à l'aveugle en QWERTY-us), je l'ai commandé depuis Taïwan : il y a des gens qui en vendent sur eBay (i.e., ils les rachètent là-bas et les réexpédient), ça m'a coûté 420€, peut-être un poil plus que le prix auquel ce sera vendu ici (je ne crois pas qu'on sache encore à combien sera le modèle 8Go), mais je ne crois pas avoir fait une mauvaise affaire (mon copain, pendant ce temps, il s'est acheté un VAIO, et ça lui a coûté, hum, plus cher). Par contre, je n'ai pas vraiment de garantie (enfin, il faudrait que je réexpédie à Taïwan, donc bof ; là aussi, je ne comprends pas l'intérêt de ne pas mondialiser ce service).

[Mon Eee PC, fermé]Parmi les choses qui me plaisent bien, il y a la vitesse de boot (une petite trentaine de secondes), et aussi le silence complet. Il y a certes un ventilateur (c'est la seule partie mobile), mais il se déclenche rarement, et tant qu'il ne tourne pas la machine n'émet aucun bruit, et même s'il se déclenche il est relativement discret (en revanche, il est vrai que c'est un bruit peu agréable, une sorte de crin-crin de moustique, et par ailleurs une fois qu'il démarre il ne s'arrête jamais jusqu'à ce qu'on éteigne ou suspende le PC). Et la petitesse et la légèreté, bien sûr, qui sont la raison première d'acheter une telle machine : c'est quand même génial, d'avoir un « vrai » PC de la taille d'un calepin (oui, je connais les Zaurus et les iPaq, merci).

L'intégration logicielle n'est pas mal faite ; et, une fois n'est pas coutume, on a l'assurance que le matériel sera bien supporté par Linux. Attention cependant : Linux n'est pas synonyme de logiciel libre ; par exemple, le pilote Wifi est un Madwifi, ce qui, déjà, veut dire, blurb binaire opaque dans le noyau, mais en plus, ici, le blurb binaire doit être spécialement adapté pour le chipset présent sur la machine… beurk ! (Bon, la partie binaire du driver Madwifi est en train d'être reverse-engineerée, peut-être qu'on finira par avoir un truc propre, mais pour l'instant ce n'est pas le cas.) Même pour ce qui est des trucs assez triviaux dans la distribution (comme le petit programme qui remplace init), Asus n'a pas montré une très grande volonté à donner des sources. Ils ont quand même consenti à le faire pour les choses pour lesquelles c'était (vraisemblablement) légalement obligatoire en raison des termes de la GPL, notamment pour ce qui est des patchs qu'ils ont apporté dans la gestion de l'ACPI, mais, à ce sujet, we are not impressed : même si Asus a fait le matériel, le BIOS, le patch au noyau et le logiciel qui l'utilise, ils ne sont pas foutus de donner l'usage de la batterie à mieux que 20% près, c'est ridicule ! Et puis c'est basé sur une Xandros, distribution dont on ne peut avoir accès aux packages qu'en payant (et qui se prétend incompatible avec Debian alors même qu'ils sont basés dessus — c'est pathétique — mais bon, en pratique, j'ai essayé, installer des packages de Debian marche sans problème).

Je ne veux pas donner l'impression de trop critiquer : dans l'ensemble c'est plutôt bien installé et configuré, on commence dans un mode facile dont les grosses icônes amicales rassureront les plus réfractaires à l'informatique (et aussi ceux qui ont du mal à viser avec le touchpad microscopique), mais on trouve rapidement comment passer dans un mode plus avancé sous lequel on a un KDE configuré pour le Eee et dont je suis très content. (De façon générale, ce wiki donne plein de trucs utiles aussi bien pour les novices que pour les connaisseurs.) L'outil graphique de configuration des réseaux (probablement une sorte de KNetworkManager, je n'ai pas regardé de trop près, mais il a peut-être été revu et corrigé par Xandros) est bien pratique, même pour quelqu'un, comme moi, normalement habitué à taper moi-même mes sudo ifup ppp1 et autres sudo iwconfig ath0 essid LeReseauDuFutur key s:glups — là il suffit de cliquer partout et ça marche. J'ai juste eu un petit problème avec une mise à jour du système d'input methods qui faisait segfaulter Firefox, mais j'ai vite pu corriger en virant le système SCIM (en revanche, pour quelqu'un qui ne connaît pas du tout, si cette mise à jour casse effectivement Firefox, c'est vrai que c'est problématique — apparemment je ne suis pas le seul à avoir eu ce souci).

[Le clavier du Eee PC]Le clavier est peu agréable mais, finalement, eu égard à sa taille, il n'est vraiment pas trop mal : au moins les lettres sont-elles bien placées et d'une taille raisonnable, je ne me plains donc pas trop qu'on leur ait sacrifié la touche control de droite, ou les touches home/end/page-up/page-down (remplacées par des combinaisons avec la touche Fn). Le touchpad, lui, est assez horripilant, mais bon, ça semblait difficile de faire mieux ; Asus le reconnaît implicitement en fournissant avec l'Eee une souris externe. Quant à l'écran, il est forcément très petit, par contre il est bien lumineux et très net. Tout ça donne finalement peu envie de taper des longs textes (par exemple, cette entrée-ci n'a été qu'en toute petite partie tapée sur l'Eee), mais pour regarder un peu le Web, lire son mail ou utiliser la machine comme calculatrice ou que sais-je encore, c'est sans problème.

(Si vous voulez voir largement plus de photos du Eee PC que ce que je mets pour décorer mon article, allez voir ici.)

Malheureusement, le Wifi, on est encore loin d'en trouver partout. Quand on en trouve, il est soit payant (j'enrage du nombre de réseaux qui vous promettent un truc gratuit ou ouvert dans leur ESSID et qui sont en fait une arnaque) et pas par micropaiements soit soumis à des limitations pénibles. (Un réseau purement et simplement ouvert ça n'existe décidément pas : partout vous aurez du NAT, une redirection de votre première page Web vers des conditions à la con, un filtrage pénible, une limitation en temps ou en débit, que sais-je encore.) Et je m'abstiens de commentaires sur ces pathétiques bouffons qui au nom du grotesque principe de précaution (lequel est maintenant dans la Constitution ! quelle blague) ont fait fermer certains des réseaux Wifi gratuits de la mairie de Paris sous prétexte qu'ils auraient eu des migraines : je m'y connais en hypocondrie alors je leur conseille de consulter un psy ou bien de prendre des cours de physique. Bref, le réseau, on ne l'a pas encore partout. (Ou alors il faut acheter une clé 3G : il paraît que ça marche bien même sous Linux ; mais c'est quand même un poil cher pour un débit pas terrible.)

L'idée que j'ai eue alors, c'est de chercher à me faire un outil de lecture offline de Wikipédia (après tout, si j'avais accès à un seul site, ce serait sans aucun doute celui-là). C'est-à-dire, mettre sur une clé USB ou sur le disque du Eee, la plus grande sélection possible d'articles pour pouvoir les consulter même sans connexion réseau sous la main. Pas une idée spécialement originale, mais aucune des solutions qui existent ne me satisfait : ce projet-là a une interface extrêmement agréable, mais une sélection d'articles beaucoup trop limitée pour être d'un quelconque intérêt (surtout eu égard à la place utilisée) ; la solution de ce Monsieur ne me convient pas, au contraire, parce qu'elle ne permet pas vraiment de sélectionner les articles et qu'elle demande trop de ressources (je ne veux pas mettre un serveur Apache avec PHP sur mon Eee !). Je suis en train de chercher à voir ce que je pourrais faire en mettant des dumps de ce genre sur un filesystem comprimé (peut-être du SquashFS, peut-être un truc spécifique à base de Fuse). Je vous tiens au courant si j'arrive à pondre quelque chose d'intéressant.

(samedi)

De la facilité d'installer une imprimante sous Linux

Mon copain m'a prêté son imprimante laser, une Brother HL-2030, et j'ai décidé de la faire fonctionner avec mon ordinateur qui tourne (encore) sous Debian GNU/Linux.

Sur à peu près n'importe quel autre système d'exploitation, on choisirait dans un quelconque panneau de configuration un onglet de gestion des imprimantes, on cliquerait sur ajouter imprimante (enfin add printer, parce que je déteste que les ordinateurs me parlent le petit nègre qui leur tient lieu de français), on choisirait la marque (Brother) et le modèle, on imprimerait une page de test, et ce serait fini.

Sous Linux, heureusement, c'est beaucoup plus simple. Ahem.

D'abord on prend le soin d'aller sur LinuxPrinting.org pour savoir si l'imprimante est gérée et ce qu'ils conseillent. On constate qu'elle n'est pas dans la base de données mais qu'il y a un modèle avec un nom très proche et qui est peut-être la même chose, ou peut-être pas. On constate également qu'il y a, sur cette description, pas moins de sept pilotes censés pouvoir faire marcher cette imprimante, sans compter le pilote propriétaire fourni par le fabricant, alors on se dit qu'on a peut-être une chance. (On découvrira plus tard qu'en fait certains de ces pilotes sont le même, et que d'autres ne semblent pas/plus exister, mais on n'y est pas encore.)

On passe rapidement sur le pilote propriétaire fourni par le fabricant : soit parce qu'on préfère ce qui est libre, soit parce qu'on trouve que des instructions qui demandent de faire dpkg -i --force-all trucmuche.i386.deb ne doivent pas être très propre surtout quand on est sur x86-64 et pas x86-32 (comme le .i386 l'indique), soit parce qu'on n'aime pas tel ou tel autre aspect du machin. Bref, on est brave et on se dit qu'on va utiliser des drivers libres.

Mais avant de commencer, il faut choisir un spooler d'impression. Parce que, comme je disais, sous n'importe quel autre OS, mettre en place une imprimante revient juste à choisir un pilote : sous Linux, on n'a pas seulement le choix du pilote, on a aussi le choix du spooler (= le démon qui s'occupe d'envoyer vos travaux d'impression au pilote, de les ordonnancer, etc.). Choix entre au moins CUPS, lpd, LPRng, PPR et pdq. Voire, pas de spooler du tout si on préfère. (Évidemment, tout ça est surtout drôle si on n'a pas encore compris que tous ces choix existent et sont mutuellement incompatibles et qu'on commence à suivre des instructions afférentes à deux choix contradictoires ; c'est encore plus drôle quand on sait que les différents spoolers ont tendance à inclure des programmes de compatibilité les uns avec les autres, qui ont donc les mêmes noms les uns que les autres.) Bon, mettons qu'on choisisse CUPS parce qu'on en a vaguement l'habitude ailleurs et qu'on se croit beaucoup plus fort qu'ESR.

Je passe sur la première difficulté qui est de trouver sous quel nom de package Debian se cache CUPS (le problème n'est pas tant de trouver un package, c'est de savoir exactement quoi installer, tant les descriptions des rapports entre les différents packages sont obscures) : en l'occurrence j'en savais déjà quelque chose, donc je n'ai pas trop hésité. CUPS propose ensuite une jolie interface Web (enfin, jolie, ça dépend des goûts, mais au moins une interface) pour ajouter une imprimante. Première surprise, il ne semble pas connaître quoi que ce soit aux imprimantes USB. On cherche un peu à tâtons : il y a des packages appelés foomatic-db ou foomatic-filters dont le rôle est parfaitement obscur (et plus encore le rapport à CUPS, Ghostscript et tout le bazar) ; il y en a un qui s'appelle printconf et qui semble prometteur, malheureusement il ne fait rien du tout. Après réflexion on se rend compte que c'est parce qu'on n'a pas chargé le module noyau qui gère les imprimantes USB : mais, même une fois ce module chargé, il prétend ne pas connaître l'imprimante en question. Dommage. Retour à l'interface de CUPS qui, maintenant que le module noyau est chargé et divers packages foomatic et gutenprint installés, est un peu plus loquace. Cependant, le modèle précis n'est décidément pas connu : le plus proche semble être le HL-2060, mais si on l'utilise comme pilote l'imprimante reçoit des données et s'active pendant un moment mais au final n'imprime rien.

Je reviens aux questions de pilote : il faut savoir (de nouveau, si on ne le sait pas, on va être totalement perdu dans une forêt d'explications contradictoires) qu'il y a aux moins deux séries principales de pilotes d'impression (libres) sous les Unixoïdes à la Linux : il y a la série Ghostscript (Ghostscript lui-même existe en au moins trois branches différentes, sinon ne ce serait pas drôle : il y a la branche GNU qui est en gros une version retardée de la branche Aladdin, et la branche ESP essentiellement par les gens de CUPS), et il y a la série Gutenprint qui se fut appelée Gimp-Print (changer de nom est une des grandes spécialités des logiciels libres : voyez le programme Phoenix, développé par un groupe appelé soit Netscape soit Mozilla, qui est devenu Firebird puis Firefox ; en l'occurrence, ils ont changé de nom parce que ça n'avait plus grand-chose à voir avec Gimp : bon). L'idée est que Ghostscript est un interpréteur PostScript qui possède différents formats de sortie, dont les langages de toutes sortes d'imprimantes, alors que Gutenprint doit plutôt fonctionner de façon bitmap. Pour rajouter un peu à la confusion, les pilotes Gutenprint peuvent aussi servir dans Ghostscript. Ou quelque chose comme ça. Bref, on commence à être sacrément perdu.

Le pilote que LinuxPrinting.org recommandait était le pilote hl1250 qui fait partie de la série Ghostscript (remarquons d'ailleurs que la page est très vieille puisqu'elle parle de patchs pour Ghostscript 5 alors que ma Debian pas spécialement bleeding edge fournit un Ghostscript 8.51 rien que dans la vieille version GNU). En admettant qu'on commence à avoir une certaine habitude d'Unix, on est capable de prononcer l'incantation mystique (gs -dNOPAUSE -dQUIET -sDEVICE=hl1250 -sOutputFile=/dev/usb/lp0 machinchose.ps) pour faire pondre un sortie de fichier brut (ce qu'il enverrait directement à l'imprimante) à ce pilote Ghostscript à partir d'un fichier PostScript et le balancer directement dans le périphérique d'impression. Ça marche plus ou moins, sauf que l'imprimante imprime deux exemplaires de la page chacune réduite à une demi-page en largeur : on devine confusément que c'est parce qu'elle essaie de faire du 1200dpi alors qu'elle n'en est pas capable, Au pif, on essaie le pilote hl1240 et là, apparemment, l'imprimante est contente.

Reste que dans CUPS ça ne fonctionne toujours pas. En regardant de plus près, il s'avère que c'est surout parce que CUPS ne semble vouloir utiliser que les pilotes Gutenprint et que ceux-ci (comme on peut le voir en leur faisant eux aussi sortir la sortie brute qu'ils envoient à l'imprimante) ne mettent pas des petites formules propitiatoires que l'imprimante semble vouloir entendre pour daigner cracher une feuille : ^[%-12345X@PJL JOB NAME="Truc"^M^J@PJL ENTER LANGUAGE=PCL^M^J et autres enjolivures ; si on les rajoute, ça marche, mais on ne sait vraiment pas comment forcer le pilote à rajouter ces borborygmes.

Du coup, on se dit qu'on va utiliser le pilote Ghostscript hl1240, puisqu'il semble donner ce qu'il faut. Malheureusement, quelqu'un a l'air d'avoir décidé que Gutenprint c'était mieux et que tout le monde devait utiliser ça dorénavant, et du coup il n'y a apparemment plus de façon simple de demander à CUPS de gérer une imprimante avec des pilotes Ghostscript. On est obligé de se farcir l'écriture d'un script shell contenant essentiellement l'incantation mystique déjà indiquée ci-dessus pour appeler Ghostscript avec les bons arguments, puis un fichier encore plus barbare, un fichier PPD, pour que CUPS consente à l'utiliser.

Avec tout ça, ça semble marcher à peu près. Le centrage n'est pas parfait et on n'ose même pas chercher à faire du recto-verso, mais bon…

Vous voyez que c'est vraiment plus simple que sous Mac OS, hein ? Non ? (Le plus ironique, d'ailleurs, c'est que Mac OS utilise CUPS en interne lui aussi.)

(Monday)

Debian is getting on my nerves

My first Linux distribution (back in '97) was Red Hat. When Red Has was discontinued, I didn't trust Fedora to be a worthy successor (a judgment which I now believe, in retrospect, was probably wrong): so I switched, with some reluctance, to Debian. At first it was a nightmare, but, after a time, I accustomed myself to the Debian way of doing things and I came to see some merit to it: Debian has a number of goodies, such as make-kpkg or debmirror, which I really like and which provide for a very nice overall integration of customized elements in the overall distribution.

But now I am becoming increasingly irritated at some of Debian's major defects and I am seriously contemplating switching to another distribution.

The worst offender is probably Debian's slowness at producing stable distributions. Basically, when using Debian, you have the choice between three releases: stable, testing and unstable. Now stable is hopelessly out-of-date: it works (more or less) and it is regularly maintained as far as security problems go, but the libraries and utilities are so incredibly old that you can't install any recent program on it—you're stuck with the set of programs you start with. I use stable on my computers which absolutely must not break: a router in my parents' house and my Web server (regulus.⁂.net), and even then it causes some problem (I needed Git, for example, and it was nearly impossible to install). The unstable Debian distribution, on the other hand, is bleeding-edge and, consequently, always broken: packages are uploaded to unstable as soon as they are build, essentially without any testing. Not a good idea! So it might seem that testing, which (confusingly) is intermediate between stable and unstable, is a reasonable compromise. Not so! This is what I use on most of my computers, but Debian has a religious rule that packages for the testing distribution can never be build directly for it, they must come from unstable after a certain period of testing in the latter. Sounds reasonable? Actually it isn't: it means that even if there is a serious security vulnerability, the problem cannot be fixed in testing until it has been fixed in unstable, tested there, and all the dependencies for the new package migrated to testing—so testing is a security nightmare. Sometimes, also, packages unexplainably vanish; a week ago, for example, a very serious security problem was found in the (proprietary) nVidia graphics drivers for Unix—now nVidia reacted reasonably fast and corrected the problem within 72 hours, but Debian reacted in its usual stupid way: presently the package has simply disappeared from the testing distribution. This is worse than just bad management! Debian is supposed to have some security maintenance, but it's only for the stable distribution despite an announcement sometime ago that they would do something about testing. The FAQ confirms this massive stupidity.

This is only the tip of the iceberg, however. The basic problem about Debian developers is that they are like religious fanatics: they have incredibly strict rules about everything and they refuse to ignore the rules even when it has utterly stupid consequences (such as removing vital parts of the distribution or of the documentation on the account that it is not free software for some rigid definition of the term which no sensible person gives a shit about). Strict rules can be a good thing in a computer context when it means we can rely on certain invariants, but when taken at a too high level it only causes problems. The Debian legal team, furthermore, is a bunch of sick weirdos who confuse real-life law with a game of Nomic and therefore can't understand that sometimes the only valid solution to a (purely theoretical) legal problem is ignore it. Another consequence of how anal Debian is about legal problems is that there isn't a single multimedia package of any kind in the distribution: you need to get those from another source which, being maintained by a very small team, doesn't benefit from the general Debian infrastructure and has all sorts of problems.

So I wonder what other Linux distribution I could use instead. The best candidate so far seems to be Ubuntu, which seems to benefit from many of Debian's strengths withouth being driven by ayatollahs (in fact, its motto is: Linux for human beings). Gentoo or Fedora might also be worthy of consideration, however.

(Tuesday)

A bit of hacking with the Linux kernel

I had wanted to write this patch for some time now… I'm glad to have gotten it done.

(Monday)

Blogging from my bed

I recently bought myself a birthday (or is it an un-birthday?) present, namely a laptop computer. For years I resisted the idea of getting one, arguing that I would rather have a desktop on every possible desk where I might be than one laptop: indeed, I considered (and perhaps still do) laptops to be expensive, easily prone to breaking, and generally troublesome. Still, my boyfriend pointed out to me that the luxury of having an Internet access from one's bed is not to be eschewed. ☺ So I was tempted and, when I found out I could have one of these little beasts for just under 600€, I went for it. So here I am, blogging from my bed, and trying to decide what I think of the tiny laptop keyboard and (to my fingers) alien touchpad. I guess I can get used to it.

It's an Acer Aspire 3633WLMi (with an Intel Celeron M 370 processor at 1.5GHz, 15.4″ WXGA screen, 60GB hard drive, 512MB RAM, DVD burner and WiFi: not a very powerful beast, but I still think it was a good bargain). It's called mizar (after a star in the big dipper: ζ Ursæ Majoris), also known as IPv6 2001:7a8:7171:37:216:36ff:fe2e:867f. And, of course, I use it under Linux… which is were I expected a great deal of trouble and got some (but not as much as I thought).

Here's a more detailed report of the extent to which the hardware works under (Debian) GNU/Linux:

Incidentally, I'm starting to find that Firefox isn't all that crappy (I've found ways to make it suit my needs — more or less). So I'm giving it a try on my laptop.

(samedi)

Télédéclaration d'impôts → foutage de gueule

Je me suis naïvement dit que j'allais télédéclarer mes impôts cette année, en passant par le serveur Web spécial. Erreur fatale ! Après deux heures et demie passées à lutter, je capitule.

Déjà, techniquement, leur système est d'une stupidité inimaginable. Au lieu de proposer bêtement un formulaire HTML, avec un peu de magie JavaScript pour aider, le tout transitant sur une connexion HTTPS, ce qui marcherait très bien, ils éprouvent le besoin de mettre en place un système beaucoup plus compliqué et qui pose toutes sortes de problèmes sans apporter aucun avantage : à savoir, générer d'abord un certificat cryptographique censé identifier le citoyen télédéclarant, puis faire signer la déclaration par ce certificat. Pourquoi ? Parce qu'une règle débile de l'administration (du Code général des impôts, je suppose) dit que la déclaration d'impôts doit être signée, et quelque andouille a décidé que pour interpréter ça dans le contexte d'une télédéclaration il fallait une signature cryptographique[#]. Toute personne ayant quelques notions de cryptographie verra immédiatement la connerie du système (qui apporte une illusion de sécurité sans rien apporter de réel) : la « signature » en question ne vaut que par la confiance qu'on accorde au certificat (c'est-à-dire, au fait que le certificat représente bien le télédéclarant), et cette confiance a pour source le fait qu'il est capable[#2] de donner son numéro de télédéclarant, son numéro fiscal, et son revenu fiscal de référence de l'an dernier ; ergo : ça n'apporte rigoureusement rien de plus de générer d'abord un certificat qui ne vaut que par cette ténue preuve d'identité et faire signer la déclaration à ce certificat que de joindre tout simplement les informations prouvant l'identité à la déclaration.

Enfin, admettons. Le système est idiot, mais jusqu'à ce point il n'est pas prouvé qu'il est mauvais. Évidemment, la complexité du mécanisme fait qu'ils ont besoin de Java, et même d'une bibliothèque Java ad hoc, un module cryptographique pour signer la déclaration à partir du certificat (vous suivez ?). Java étant assez mal foutu, l'installation d'une bibliothèque Java va échouer sur plein de systèmes (notamment à peu près n'importe quel Unix ou bien un Windows quand on utilise un compte non-administrateur et qu'on a fait un peu attention aux permissions) parce qu'il va tenter d'installer la bibliothèque à un endroit où il n'a pas le droit d'écrire (au lieu de créer un répertoire chez l'utilisateur et le rajouter au classpath). Cette fois-ci, ce n'est pas l'administration française qu'on peut accuser d'idiotie, c'est Sun. Mais ce point est mineur, on peut facilement le contourner (en donnant à l'utilisateur le droit d'écrire dans les répertoires de la JVM, par exemple en en créant une pour lui).

Mais au bout du compte, ça ne marche toujours pas. J'obtiens le message d'erreur suivant :

Votre demande n'a pas pu aboutir.

L'accès au service est momentanément indisponible. Veuillez nous excuser pour la gêne occasionnée. Nous nous efforçons de rétablir le service dans les meilleurs délais.
Merci de bien vouloir vous reconnecter ultérieurement.

Pour plus d'informations, le service d'assistance est accessible selon la modalité de votre choix (assistance téléphonique, mél…).

Pour retourner à la page d'accueil du site, veuillez cliquer sur le bouton situé en haut de cette page.

Il est possible que leur site soit simplement saturé ou qu'ils aient un bête problème technique avec leur serveur. Mais il est aussi possible que ce soit autre chose : j'ai appris que l'an dernier des gens ont rencontré la même erreur et simplement changeant de navigateur (pour passer de Mozilla à Internet Explorer, sous Mac OS) le système a fonctionné. Autrement dit, au moins l'an dernier, ce message d'erreur était un pur mensonge et signifiait : Vous n'utilisez pas un navigateur qui nous plaît. J'ignore si c'est encore le cas cette année, mais je ne suis pas sûr de pouvoir prendre le risque d'attendre voir si le site se remet à marcher et voir ainsi passer la date limite pour la déclaration papier, sachant que si le « problème » est de mon côté (i.e., avec Mozilla ou Firefox sous Linux ça ne marche jamais) je peux toujours rêver que ça tombe en marche. Joie.

Alors bon, après tellement de temps passé à lutter contre les âneries du ministère et de Sun pour finalement tomber sur un message d'erreur douteux, je crois que je comprends pourquoi la télédéclaration ne remporte pas beaucoup de succès.

[#] Si vous voulez savoir, ce qu'on « signe » en fait, dans le cadre d'une télédéclaration, c'est un fichier pipo-XML (ce n'est pas du XML bien-formé, même si ça y ressemble) qui commence quelque chose comme ceci (évidemment je suis aller fouiller dans les données qu'échangent leurs immondes programmes Java et JavaScript, donc j'ai vu quel était le cœur de la déclaration) : <?xml version="1.0" encoding="ISO-8859-1"?> <FORM_XML VALUE=1-1-2042-2004> <?xml version="1.0" encoding="ISO-8859-1"?> <F2042> <REG_IMP>1</REG_IMP> <NUM_TRT>12</NUM_TRT> <TYPESAISIE> </TYPESAISIE> <CHANGEMENT_ADR> </CHANGEMENT_ADR> <ETATCIVIL> <NOMPRENOM>M MADORE, DAVID</NOMPRENOM>, et ainsi de suite. Quelque part j'ai du mal à imaginer que le fait d'ajouter la signature cryptographique par un certificat ad hoc et sans valeur sur un tel fichier pas très human-readable aurait une valeur juridique supérieure à celle de soumettre un formulaire Web ordinaire en cochant une case je certifie l'exactitude des renseignements ci-dessus.

[#2] Déjà, j'ai un problème, là : je ne vois aucune indication, où que ce soit, du fait que l'une quelconque de ces trois données soit censée être secrète. Autrement dit, je ne vois pas où on me conseille de ne pas publier sur mon blog, par exemple, mon numéro de télédéclarant, mon numéro fiscal, et mon revenu fiscal de référence. Dans ces circonstances, avoir le culot d'utiliser ces informations pour identifier quelqu'un, et prétendre ainsi authentifier son identité, est sacrément audacieux.

(Wednesday)

Linux double network interface µHOWTO

This took me a while to figure out, so I might as well post it here in case it's of use to anyone. Assume you have two network interfaces, say eth0 and ppp0, with two totally unrelated IP addresses, say 257.42.0.18 for eth0 (yes, I know, 257 is impossible, I'm just choosing this to represent a totally arbitrary address) and 333.64.17.29 for ppp0. You wish to use one interface for certain connections and the other for others (there can be plenty of different reasons for that: maybe one connection is faster but has a stupid firewall so it can't be used always). Now if you can decide which connection goes where in function of the destination host('s IP address or network), then it's easy: just configure your routing tables appropriately. But what happens if you wish, for example, all outbound connections to TCP port 80 to go through eth0 and all others to go through ppp0? We need a little more work there, and a little magic, but thanks to the mutant features of the Linux network stack, using iptables and iproute2, it is possible. Here's a sample of the command lines that might be useful (just a guideline, of course: don't ever copy them blindly, please learn about the programs and understand what each line does), at least if the host is not a router:

# Ordinary route is via ppp0 (this should probably be done as pppd starts):
route add defaut gw 333.64.17.1 dev ppp0
# Routing table 201 (say) is through eth0 (gateway is 257.42.0.1, say):
ip route add 257.42.0.0/24 dev eth0 scope link src 257.42.0.18 table 201
ip route add default via 257.42.0.1 dev eth0 table 201
# Use routing table 201 for marked packets:
ip rule add fwmark 1 table 201
# Now set up iptable rule to mark packets destined for eth0:
iptables -t mangle -A OUTPUT -p tcp -m tcp --dport 80 -j MARK --set-mark 1
# Lastly, we need to do some self-masquerading:
iptables -t nat -A POSTROUTING -s 333.64.17.29 -o eth0 -j SNAT --to-source 257.42.0.18

The last line probably deserves extra comments, because it is not at all obvious: it is needed because otherwise an outbound connection from the local host on port 80 will have local address 333.64.17.29 (as it appears on the ordinary routing table) whereas it is sent through the eth0 device, and this can't work (any router down the stream will reject it as not being meant for this route, or at best the return packets will come through the wrong interface).

If you're also trying to open listening (server) sockets on the eth0 interface, you also need something probably like this:

# Turn off entry route verification on incoming packets:
sysctl -w net.ipv4.conf.eth0.rp_filter=0
# Also mark local packets destined for eth0:
iptables -t mangle -A OUTPUT -s 257.42.0.18 -j MARK --set-mark 1

If your box also acts as a router (through some third interface eth1, say), then at the very least you need to duplicate the OUTPUT rules (for the mangle table) as PREROUTING ones and broaden the source address match on the rules that have one, but more complicated are probably desirable (of course, it all depends on what kind of addresses you have on eth1; I'll leave as an exercise for the interested reader the case where eth1 has private addresses and you wish to masquerade on forwarding…).

(vendredi)

Linux install party

On a fait une Linux[#] install party à l'ENS ce soir (moi-même je n'étais que très marginalement impliqué, mais je suis venu jeter un œil et donner un coup de main[#2]). Je ne pensais pas que ça aurait autant de succès (en terme de nombre de participants), en fait — et je ne pensais pas non plus que tant de gens avait un portable (il est vrai que le concept favorise nettement les portables, parce qu'apporter son fixe, forcément, c'est moins facile ; il y en avait toutefois quelques-uns).

En terme de réussite des installations, je ne suis pas sûr que ça soit un tel succès, en revanche. Pas tellement la faute de Linux, certes : il y a tellement de matériel PC complètement exotique, non standardisé, ou (cas qui me semble malheureusement de plus en plus fréquent) dont les spécifications sont gardées secrètes… Le pire, je pense, ce sont les cartes graphiques — quoique, les cartes réseau ont aussi tendance à être embêtantes, maintenant. La faute est aux fabricants de matériel, mais je ne crois pas que ça fasse bonne presse pour Linux / les Unixoïdes / les logiciels libres / <insérez ici votre catégorie préférée>.

À vrai dire, moi, je ne suis plus du tout prosélyte (je l'ai été), ni pour Linux, ni pour le logiciel libre, ni pour quoi que ce soit d'autre que j'utilise (à la rigueur Mozilla). Je ne recommande à personne de passer sous un Unix : je préfère que les gens restent sous Windows pour pouvoir leur dire non, je ne connais rien à ce truc, je ne peux pas répondre à ta question et ne pas avoir à expliquer comment éditer un /etc/fstab à la main (simplement parce que je ne connais pas les outils inventés pour le faire de façon user-friendly) pour voir mon interlocuteur hausser les yeux au ciel façon qu'est-ce que c'est que ce truc de geeks, vraiment.

[#] Oui, Sam : une GNU/Linux install party.

[#2] Métaphore croisée, j'ai bien peur. Je vous rassure, je n'ai pas balancé mes globes oculaires et donné des baffes. ☺

(jeudi)

Une petite mise à jour (informatique) s'impose

Il serait temps que je mette un peu à jour mon environnement informatique, parce que ça commence à faire un peu vieillot. Je pense principalement à deux choses.

D'abord, ma connexion Internet. Mon fournisseur d'accès ADSL est Nerim (sous prétexte qu'ils sont les plus compétents techniquement : de fait, ce sont par exemple les seuls à offrir explicitement une plage IPv6 — je ne comprends pas pourquoi les autres ne le font pas, d'ailleurs, alors que, si ça n'intéresse personne, ça ne coûte vraiment rien non plus, tous les routeurs modernes gérant l'IPv6). Mais ma formule chez eux (Nerim Base à 512kbps) est tellement vieille qu'elle n'est même plus listée nulle part sur leur site (ah, oui, c'est compliqué : il y a une différence entre le Pack Nerim Base, que je n'ai pas, et la Formule Nerim Base, que j'ai, et qui n'est plus proposée).

Y rester est d'autant plus absurde que je peux avoir un débit supérieur pour un prix inférieur. L'ennui, c'est surtout que j'ai peur que changer de quelque façon que ce soit m'impose une interruption de service de plus que quelques heures (soit parce que je devrais rendre le modem que je loue actuellement à France Telecom dans le cadre de Netissimo 1, soit parce que la ligne serait effectivement coupée pendant un certain temps. Et il me serait beaucoup plus gênant de faire sans ADSL pendant un jour (surtout que je n'ai plus de modem RTC qui fonctionne) que de payer plus pour un débit moindre pendant un temps assez important — mais, à la longue, ça finit par ne plus être vrai. Enfin bon. Aussi, je suis perplexe de voir que sur les offres Nerim leur offre à 8Mbps n'est pas encore disponible en version dégroupée, et en version non-dégroupée c'est quand même un peu cher (et surtout, ça voudra dire une nouvelle interruption pour passer en dégroupé). C'est quand même pénible, tout ça. Il va falloir appeler le service clients, s'expliquer avec (et espérer qu'ils se souviennent encore de l'existence de ma formule préhistorique) : que de tracas !

Deuxième chose, mon ordinateur lui-même : c'est pour l'instant un bi-processeur Pentium II à (deux fois, donc) 450MHz (enfin, ça c'est ce que j'ai à Paris chez moi ; chez mes parents à Orsay j'ai un Pentium III à 600MHz, il serait aussi peut-être temps de penser à le changer). Je me dis qu'il serait temps d'avoir un truc un peu plus rapide. Mais il y a quelques contraintes. D'abord, j'ai pris goût au bi-processeur (c'est quand même sacrément mieux pour tout ce qui est vaguement temps-réel : Linux était assez mauvais pour la latence à la commutation des tâches, on sent la différence quand on écoute de la musique en même temps qu'on fait autre chose ; et puis, pour envoyer des bug-reports à des gens comme quoi leur makefile ne marche pas avec -j2, c'est excellent). Ensuite, de nos jours, il faut de la RAM ECC parce que j'ai la faiblesse de ne pas vouloir que des corruptions aléatoires apparaissent dans mes fichiers (et j'ai assez donné dans les tests mémoires et les demandes à Linux de démapper des pages parce qu'elles ont un bit buggué). Ça complique un peu la mise à jour, tout ça : le PC moyen qu'on trouve chez Carrefour, ce n'est pas un bi-processeur avec de la RAM ECC, non, vraiment (et c'est bien dommage, d'ailleurs), et même chez le Taïwanais du 12e ce n'est pas complètement évident à trouver. Bon, et puis, par ailleurs, j'aimerais bien un 64-bits (jeu d'opcodes AMD64 / Intel ia32e, je veux dire : le Intel ia64 ça a vraiment l'air d'être n'importe quoi), parce que les limitations débiles à 4Go (qui débutent dès qu'on veut mettre plus de 1Go de mémoire, sous Linux, en fait, à moins de patchs ad hoc) elles commencent à bien faire. Ça ce n'est pas si dur à trouver (un tantinet cher, c'est tout), c'est juste que ma distribution Linux supporte mal la chose et j'ai médiocrement envie d'en changer (encore !).

Je crois en fait que la grande difficulté est plutôt de trouver la carte mère idéale, qui supporte, disons, un bi-optéron et autour de 2Go de RAM en gérant le ECC et si possible qui donne le tout pour significativement moins de 3000€ (y'a des limites au gaspillage, aussi). Le reste de la machine, je le garde, notamment le ¼To de disques durs, sauf peut-être pour un petit disque système que je rachèterai si je prends un ensemble sans SCSI (je ne me ferai pas arnaquer une nouvelle fois par le SCSI), ou encore la carte graphique Radeon 7500, qui a l'intérêt d'être à peu près la seule carte graphique existante qui soit complètement gérée (accélérations 3D et vidéo comprises) sous X11 par des pilotes libres (enfin, le fait qu'ils soient libres m'importe assez peu, en fait, c'est juste que les pilotes propriétaires fournis par les constructeurs pour d'autres cartes graphiques (1) sont buggués et ont tendance à faire planter Linux et (2) teintent le noyau).

Bon, j'ai un copain qui me dit que je cherche vraiment les ennuis (notamment à cause du 64-bits : c'est vrai que c'est un peu pénible que ça soit toujours vaguement expérimental sous Linux). Il n'a pas forcément tort, je suppose.

(Wednesday)

More Linux woes

I don't know how (or even exactly when) it started, but my computer has this strange problem which causes it to unpredictably replace certain parts of random files by null bytes (always a multiple of 256 bytes, it seems, and aligned at such multiples; typically around 2 kilobytes in a given file). As one can expect, this causes all sorts of horrendous difficulties, and it tends to be pretty damn hard to find out where the problem lies (even knowing that this behavior occurs, finding exactly which file has been altered to cause a given malfunction is not an easy task).

So far none of my personal data has been affected, it seems—only various system files, which I have been able to recover. But the nagging doubt is always present: what if one of my important files gets corrupted and I don't notice it and make backups of it in various places, and really end up screwing everything? I'd like to have my peace of mind back.

The trouble is that I have no idea what causes the problem. It's probably not a hardware flaw: I have good reasons to believe that memory, CPU and hard drives are sane. I suspect a bug in the Linux kernel, in the ReiserFS layer, perhaps occurring only in SMP boxen, and perhaps starting only with the 2.6.6 or 2.6.5 version. But the bug has proven remarkably elusive: I tried all sorts of intensive stress-testing on the filesystem (creating a small number of large files, a large number of small files, simultaneously writing and reading, and all sorts of variants, with RC4 streams), and found no way to reproduce the corruption in vitro if I may say. So I can't write any kind of bug report that would be of any use, and I don't know which Linux version I should downgrade to (or even whether the problem is really in the kernel and not, for example, some obscure part of the C library).

I'm rather annoyed at this, but I really don't know what to do. If I had just a little more knowledge about the problem I could post on the linux-kernel mailing-list, but as things are this would be pretty useless.

(Thursday)

arc4gen

My entry for today is a program that I wrote tonight (took me longer than expected, I'm afraid—like, all night). Not an interesting program by any means: just a pseudo-random number generator, an ARC4 stream, to be precise; it can be downloaded here: arc4gen.c (instructions for use and compilation are contained in the comments within the program itself; Public Domain), and there is also a Debian package for the same.

(What's the point of writing a self-standing random number generator, you ask? Well, one possible use is this: you generate a huge file from the ARC4 stream with a given key, and then you check it repeatedly against the stream generated anew from the same key—which should be the same since the generator is deterministic. Any CPU or RAM or filesystem malfunction is pretty likely to be noticed in the process. In fact, that's exactly the reason I wrote this thing: I suspect there's something wrong somewhere on my PC, and I intend to make sure.)

(dimanche)

Je hais les ordinateurs

Ce n'est pas comme si j'avais eu des plans particuliers pour ce soir ou pour demain. Mais j'aurais quand même vaguement aimé pouvoir me coucher un moment ou un autre. Sauf que non.

Je viens de découvrir que mkisofs, l'un des programmes qui sert à effectuer la gravure de DVD sous Linux, a un bug très gênant : il remplace aléatoirement certains secteurs de l'image ISO 9660 qu'il produit par des secteurs vides (pleins de 0xffff, pour être précis). Enfin, c'est peut-être mon noyau Linux qui est buggué (peut-être une interaction obscure entre le support SMP — ma machine est un bi-processeur — et la fonction mmap() ?) et qui produit cet effet. Ou peut-être que c'est autre chose encore, je ne sais pas (ceci dit, je ne soupçonne pas trop, pour une fois, une RAM défectueuse) ; mais je m'en fous, le résultat est là : je donne des fichiers valides à mkisofs et il me pond une image ISO 9660 bugguée.

Évidemment, c'était la seule opération de la chaîne de gravage que je n'avais pas vérifiée : je m'assurais soigneusement de l'intégrité des fichiers avant de les mettre dans l'image, je vérifiais soigneusement que l'image gravée est bien celle produite par mkisofs (en recalculant le hash md5), mais je ne contrôlais pas (ou en tout cas pas plus que sur un petit nombre de fichiers) que mkisofs n'avait pas saboté son travail.

Bilan : tous les DVD que j'ai gravés jusqu'à présent doivent avoir autour d'un ou deux fichiers corrompus, je n'ai plus qu'à les mettre à la poubelle. Perte financière d'une trentaine d'euros : mais ça je m'en fous, c'est le temps passé à préparer ces DVD, et qu'il faut complètement refaire, qui m'ennuie, d'autant plus que je vais devoir maintenant être encore beaucoup plus soigneux en produisant les disques, vérifier l'intégrité des fichiers à chaque étape, et quand on le fait, cela prend des heures (calculer le md5 de quatre gigas de données, sur un Pentium II 450, c'est long).

En tout cas, deux conclusions s'imposent : primo, je hais les ordinateurs ; secundo, Linux est un OS de merde écrit par des singes qui tapent au hasard sur des machines à écrire. (Et on peut féliciter la concurrence d'avoir réussi à faire encore pire.)

Et bien sûr, j'en ai pour toute la nuit à vérifier des intégrités de fichiers.

(Sunday)

Computers, computers, computers

Another day mostly devoured by the activity of computer hacking. I managed to get MPlayer to play the BBC's RealAudio streams (thanks, Joël), so I'll finally be able to get a daily dose of exposure to correct English. I recompiled the Lizard so my non-breaking spaces now work again; but the developers refuse to incorporate the patch in the official source (see the Bugzilla discussion for more details). I discovered the wonders of Unix ACLs, which are even available under Linux now, and which help mitigate the standard Unix permissions' lack of expressivity.

(Saturday)

DVD±R[W]—and Linux

Acting upon a sudden uncontrolled impulse, because I had some time and some money to waste this afternoon and since I was walking through the 12th arrondissement of Paris (where all the Chinese computer hardware retailers are located), I bought myself a DVD±R[W] drive (burner, I mean). A Plextor PX-708A, to be precise (whose maximal burning speeds are: 8× for DVD+R, 4× for DVD+RW, 4× for DVD−R, 2× for DVD−RW, 40× for CD-R and 12× for CD-RW; reading speeds are 12× for DVD-ROM and 40× for CD-ROM); I've always bought Plextor burners previously and I've been quite satisfied, so I think I can recommend them.

The difference between ‘+’ and ‘−’ was completely unintelligible to me, and still isn't perfectly clear, but here is a (partial) explanation. (Unfortunately, Google isn't of much help here, since it doesn't distinguish "dvd+r" from "dvd-r", say.) Basically, ‘+’ is less compatible with existing DVD-ROM drives, but in counterpart can be written incrementally and without risk of buffer underrun or such annoyances, whereas ‘−’ is much closer to CD-R[W]. Incidentally, ‘−’ is supported by the people who came up with the DVD (same DVD logo), whereas ‘+’ is sponsored by a different group (and the logo on disks is different). Apart from that, the disks have the same size and—except for an explicit marking—are not recognizable (both have the same purplish hue, for example, for Verbatim disks with AZO-based dyes; strangely enough, their DVD−R are made in Taiwan whereas their DVD+R are made in India). Their capacity is the same (around 4.4 gigabytes—meaning around 4.7 billion bytes—for single-sided single-layer disks) and the price also seems to be precisely the same.

To burn DVDs under Linux, I've tried DVD+RW-tools, and they seem to work (although I've had some strange symptoms here or there); despite the name, they will also work with DVD−R[W], not just ‘+’. And the name (growisofs) is also ridiculously unintuitive, but the program in question is also able to, say, record a cramfs image on the medium, not just grow an ISO9660 filesystem. Plain old cdrecord won't work; and although there is a special different version (cdrecord-prodvd) which will, I don't recommend using it, were it only for the fact that it has a highly obnoxious (and non-free) license—you need a “key” of some sort to do the writing, and you don't get access to the source code, and you might not even be able to use it commercially. There is also a free fork of cdrtools (the kit which includes cdrecord) called dvdrtools which might be useful, but I haven't tried it yet.

Anyhow, it seems to work. Well, the DVDs I've recorded (whether ‘+’ or ‘−’) weren't readable by my DVD-ROM drive, but it's very old and mostly broken anyway, so I'm not really surprised. The burner itself is able to read the disks it wrote (I checked them thoroughly), which is what I mostly care about because I intend to use DVDs for backups.

(mardi)

Fin du calvaire ?

[600e entrée dans ce 'blog ! Hourra, hourra, hourra ! Hourra, hourra, hourra !]

Cette fois-ci, normalement, c'est bon, les désagréments sont temporairement écartés : tous mes PC ont été mis à jour (c'est-à-dire, celui que j'ai à Paris, celui que j'ai à Orsay chez mes parents, et celui qui sert de routeur chez mes parents). J'espère que je vais enfin pouvoir faire autre chose de mes journées.

Quant au plantage mystérieux (qui signifiait entre autres qu'on ne pouvait plus poster de commentaires ici), je ne sais pas à quoi il était dû. Sans doute les noyaux Linux 2.6 ne sont-ils pas aussi stables qu'on le prétend.

(Wednesday)

Reinstallation nightmare

So I've begun the full reinstallation of my computer system under Debian GNU/Linux (“Sarge”). I did realize it might be no fun, but in my deepest nightmares I had not foreseen how bad it would turn out. Or rather: I think I had more or less correctly assessed the amount of work it would be—weeks of it—but I had not considered the fact that I could not afford to wait for entire weeks to have a usable system. Maybe I should have set things up to be able to dual boot under the old system or the new one while the latter was being configured, which would then have made it possible for me to take my time at it; but as such, I have to work fast, because there are plenty of things for which I direly need a working system, and for the moment I do not have it.

I won't go through the detail of all the problems I've encountered. It took me all day yesterday, staying up until 6AM, to get a bootable system with a reasonably correct network configuration (it is true that my network setup is a bit baroque). The fact that the Debian Sarge snapshot CD was quite buggy did not help. Today, I spent all day trying to get a decent graphical environment and desktop—with partial success. In principle this should take minutes: in practice, hours were wasted getting my USB trackball to work (all right: the fact that I have a trackball and a mouse attached to the computer might have made it a bit more difficult than necessary), until I understood that the mousedev module had to be loaded (not just hid, input and possibly usbmouse). More hours were wasted working through the stupidity of the Gnome desktop policy decisions: understanding, for example, how to replace the entirely worthless but now default Metacity window manager by the acceptable Sawmill, and then how to work around a stupid limitation of Gnome by adding the cryptic line (define-special-variable viewport-dimensions '(3 . 3)) to my .sawfishrc file. (Needless to say, there is absolutely no kind of documentation anywhere that tells you to add this line, or why you need it.)

I think from now on I'll urgently discourage people who ask me for advice from trying Linux. Basically the problem is this: Linux (I mean the whole program suite included in a given distribution, not merely the operating system or the kernel) is really powerful insofar as it is highly configurable. Incredibly configurable, in fact. But once one starts customizing the penguin to one's tastes, one becomes accustomed to this specially tailored configuration and one can't live without it: and since any upgrade is liable to break bits and pieces of configuration and force one to rewrite whole configuration files, one can waste an unimaginable amount of time on it.

Basically, I'm on the verge of a nervous breakdown.

Update (2004-03-24T28:02+0100): On the other hand, I can now re-enable the comments system, which turned out to be comparatively easy to upgrade (to Apache 2.0.48 and PostgreSQL 7.4.2).

(Sunday)

I'll be using Debian

Some time ago, I asked whether I should be ugrading my Red Hat distributions or move to Debian. It seems that the problem has cured itself since Red Hat Linux has ceased to exist.

So I'll be switching to Debian. Very reluctantly, but it seems that I don't have much of a choice.

(Sunday)

How should I upgrade my Linux boxen?

My home computers currently run Red Hat Linux 7.3 “Valhalla”, except for my router in Orsay which is still on Red Hat Linux 7.1 “Seawolf” (see here for explanations on Red Hat release names if it sounds very mysterious) and a lone FreeBSD box somewhere that doesn't do much but sit idle (an archaic computer with an archaic version of FreeBSD, anyway). This can't go on forever, though, because Red Hat 7.3 is now getting quite old: lots of software pieces presently require newer versions of this-or-that package or library; but, more importantly, Red Hat is only maintaining these versions until the end of the year (as far as security vulnerabilities are concerned, I mean), so I'll have to consent to change before the end of December.

What I'm worried about is that this upgrade will not be as seamless as I wish it to be. Every system upgrade entails changing the version of hundreds of programs and libraries, sometimes in a not entirely forward-compatible way: configuration file formats change, programs behaviors vary. As usual with these things:

The first 75% of the work take 75% of the time.

The last 25% of the work also take 75% of the time.

(And so on recursively. ☹) So, typically, installation proceeds without a glitch, and almost everything works fine. But there's always a dozen irritating quirks: maybe the Mozilla fonts are suddenly ever-so-slightly wrong (or aren't anti-aliased); maybe my ICQ client randomly segfaults at start; maybe Emacs suddenly decides to handle accented characters in a strange way; maybe Perl prints a warning message that I can't understand upon launching certain scripts; maybe my Web server refuses to run cgi-bin scripts; maybe my NTP timekeeper refuses to synchronize on the prescribed servers; maybe control-C mysteriously ceases to function in console (text) mode; maybe Xvideo won't function; maybe ssh keys just won't function; maybe my PostgreSQL database doesn't handle permissions properly; maybe Gnome refuses to take into account this-or-that keystroke shortcut; maybe my printer daemon refuses to let distant computers connect. Or something. There are millions of things which can go wrong, and almost none of them do. But every time I've upgraded my Linux installation, I've encountered a few of these microscopic problems which rarely cause any serious damage but just irritate you endlessly while they aren't solved—and take forever to solve if you decide to discover the deep reason for this-or-that misbehavior. And since I haven't upgraded in a long time, I fear I'll encounter a good number of such glitches next time I do.

Hence the reticence. But there is also the following dilemma: Red Hat or Debian? So far I've always been faithful to Red Hat, but their increasing commercialism, and a couple of not-too-easily forgivable problems (and acts of pure stupidity), have tempered my good opinion of them. So, should I upgrade to Red Hat 10 when it comes out, or, uh, sidegrade to Debian something-or-other? But there are things that worry me about Debian, also: their “stable” release is unreasonably archaic, for one, and I'm not sure how security-aware their “testing” release is—but I want both the latest bells and whistles and a reasonable tracking of security and stability issues. I also consider the Gentoo Linux distribution, but I've heard mixed reports about it.

Without doubt, computers can consume an unbelievable amount of time needlessly.