Vous êtes sur le blog de David Madore, qui, comme le
reste de ce site web, parle de tout et
de n'importe quoi (surtout de n'importe quoi, en fait),
des maths à
la moto et ma vie quotidienne, en passant
par les langues,
la politique,
la philo de comptoir, la géographie, et
beaucoup de râleries sur le fait que les ordinateurs ne marchent pas,
ainsi que d'occasionnels rappels du fait que
je préfère les garçons, et des
petites fictions volontairement fragmentaires que je publie sous le
nom collectif de fragments littéraires
gratuits. • Ce blog eut été bilingue à ses débuts (certaines
entrées étaient en anglais, d'autres en français, et quelques unes
traduites dans les deux langues) ; il est
maintenant presque exclusivement en
français, mais je ne m'interdis pas d'écrire en anglais à
l'occasion. • Pour naviguer, sachez que les entrées sont listées par
ordre chronologique inverse (i.e., celle écrite en dernier est en
haut). Certaines de mes entrées sont rangées dans une ou plusieurs
« catégories » (indiqués à la fin de l'entrée elle-même), mais ce
système de rangement n'est pas très cohérent. Cette page-ci rassemble
les entrées de la catégorie Linux :
il y a une liste de toutes les catégories à la fin de cette page, et
un index de toutes les entrées.
Le permalien de chaque entrée est dans la date, et il est aussi
rappelé avant et après le texte de l'entrée elle-même.
You are on David Madore's blog which, like the rest of this web
site, is about everything and
anything (mostly anything, really),
from math
to motorcycling and my daily life, but
also languages, politics,
amateur(ish) philosophy, geography, lots of
ranting about the fact that computers don't work, occasional reminders
of the fact that I prefer men, and
some voluntarily fragmentary fictions that I publish under the
collective name of gratuitous literary
fragments. • This blog used to be bilingual at its beginning
(some entries were in English, others in French, and a few translated
in both languages); it is now almost
exclusively in French, but I'm not ruling out writing English blog
entries in the future. • To navigate, note that the entries are listed
in reverse chronological order (i.e., the latest written is on top).
Some entries are classified into one or more “categories” (indicated
at the end of the entry itself), but this organization isn't very
coherent. This page lists entries in
category Linux: there is a list of
all categories at the end of this page, and
an index of all entries. The
permalink of each entry is in its date, and it is also reproduced
before and after the text of the entry itself.
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.
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 :
on peut faire de la 3D émulée (c'est-à-dire, non accélérée), et
pour ça, il y a deux approches :
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),
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) ;
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) ;
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 rendering
Direct 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.
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_mutex
— source
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.
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.
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 :
Sous Debian, on peut choisir la version stable ou la
version testing/unstable (la politique officielle de
Debian est que seule la stable existe, la testing/unstable — la
différence est très mineure — n'étant là qu'à des fins de
développement interne, et si vous l'utilisez c'est à vos risques et
périls).
La stable marche globalement très bien, et bien maintenue question
sécurité. Mais elle est déjà obsolète le jour où elle sort, et
tellement archaïque le jour où la suivante sort, qu'il est
essentiellement impossible d'y installer un petit sous-ensemble de
packages de la distribution testing (le graphe de dépendances est
tellement touffu qu'installer un seul package de la testing sur la
stable vous entraîne toute la testing avec) ; il est même difficile
d'y compiler des choses (comme toutes les bibliothèques de la
distribution sont vieilles, on se retrouve à recompiler la moitié de
l'univers, donc à recréer sa propre distribution, et du coup on perd
tout bénéfice des mises à jour de sécurité). Et surtout, aucun bug
n'est corrigé sauf les bugs de sécurité : donc si par malchance vous
tombez sur un bug d'un programme qui le rend quasi inutilisable, vous
avez le choix entre attendre des années que la stable suivante sorte,
ou faire vous-même le bugfix (puisque le package où le bug est corrigé
appartient à la testing et que vous ne pouvez pas l'installer ni le
recompiler sans vous retrouver englué dans les dépendances), et
encore, il faudra apprendre à contourner
les limitations
hallucinantes du système de package pour convaincre celui-ci de
préférer votre version.
La testing ne marche pas trop mal, et a l'avantage d'être une
distrib raisonnablement à jour. En contrepartie, elle demande des
mises à jour à un rythme invraisemblable ; et si l'écrasante majorité
de ces mises à jour se fait sans problème, de temps en temps il faut
passer la journée à essayer de comprendre, par exemple, pourquoi tel
package dépend de quelque chose qui n'existe pas (de temps en temps
des packages disparaissent de testing parce qu'ils sont considérés
comme cassés, et alors il faut les chercher dans unstable, mais il
faut comprendre soi-même quel bout du graphe de dépendances aller
prendre là-bas). Par ailleurs, la politique de sécurité sont
douteuses (la règle de migration des packages est très stricte, donc
même un package corrigeant un trou de sécurité béant devra incuber un
certain temps dans unstable avant de passer dans testing, et pendant
ce temps votre machine est vulnérable). Ou alors on choisit la
unstable, mais ça signifie qu'on reçoit des packages absolument pas
testés, et ce sont encore d'autres problèmes qui se posent.
Ubuntu a un rythme de mises à jour qui me semble réaliser un
excellent compromis entre la Debian stable et la Debian testing : une
nouvelle version de la distribution tous les six mois, dont une sur
quatre est marquée comme maintenue à long terme (Long
Term Support), ça donne quelque chose de raisonnablement récent
avec un rythme de mises à jour supportable.
Mais ce que je déteste avec Ubuntu, c'est que censément pour rendre
leur distribution conviviale pour l'utilisateur inexpérimenté, ils
imposent un nombre invraisemblable de choix douteux, rendent toute
modification de configuration quasiment impossible : dès que vous
sortez des clous des deux-trois cases à cocher qu'ils consentent à
vous laisser, vous devrez vous battre avec des fichiers de config
introuvables et non documentés et avec des démons obscurs au rôle mal
spécifié — et, pire encore, à chaque changement de version, vous
pouvez être sûr que tout ce que vous aurez peiné à comprendre cessera
d'être vrai (voyez tout le mal que
j'ai eu à faire marcher comme je voulais le touchpad de mon
portable).
Parce qu'Ubuntu souffre à un niveau délirant d'un problème déjà
assez répandu dans l'informatique libre en général et dans tout ce qui
gravite autour de Linux en particulier : ils n'arrêtent pas
d'introduire des nouveaux mécanismes pour faire les choses,
puis de décider six mois plus tard que ce mécanisme est maintenant
obsolète et qu'il faut utiliser tel autre à la place. (Et du
coup, quand on cherche de l'aide en ligne, il est très difficile de
savoir ce qui est encore applicable ou ce qui a été remplacé par le
nouveau démon qui lave plus propre.)
[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 là ;
et là
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 :
les administrateurs (root en jargon Unix), qui ont un
accès complet à la machine,
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,
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.
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.
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).
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, là, là
et là) é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.
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, là
et là), 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.
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.
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.
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.
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.
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
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).
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.
Firefox fournit une version standalone de son moteur
JavaScript SpiderMonkey, et une autre de son
moteur Rhino (et tous deux sont packagés par Debian),
sous les noms smjs et rhino respectivement.
Mais aucune API ne semble disponible pour ouvrir un
fichier (il y a eu
un truc
dans ce sens, mais il fallait l'activer spécialement et de toute
façon il est marqué comme obsolète sans aucune indication de ce
qui le remplace, merci bien).
Il y avait un projet
appelé JSlibs, qui semblait faire exactement ce que
je voulais (=fournir une interface JavaScript pour un certain nombre
de bibliothèques usuelles), mais ce projet a l'air mort et a
probablement bitroté. Inutile donc d'essayer de comprendre comment on
est censé l'installer.
Il y a un projet
appelé CommonJS
qui prétend définir un standard sur la manière d'appeler différentes
bibliothèques depuis JavaScript, et qui a certainement ce que je veux.
Mais bon, c'est un standard, pas une implémentation, donc ça ne m'aide
pas tant que ça. Il prétend
avoir un grand nombre
d'implémentations, mais quand je regarde la plupart d'entre elles,
soit je ne comprends rien, soit le projet est mort, soit il a l'air
abominable à installer, soit la partie implémentée est juste un module
particulier et pas celui qui permet d'ouvrir un fichier, bref, je ne
vois rien qui me convienne. Sauf peut-être :
Node.js, dont j'entends
énormément parler, est un cadre général pour écrire des serveurs Web
en JavaScript : ils ont forcément de quoi ouvrir un bête fichier et
écrire du texte dedans. Mais d'après ce que je comprends çà et là,
Node.js utilise un mécanisme d'entrées-sorties asynchrones, basées sur
des événements, quelque chose de probablement approprié pour écrire un
serveur Web, mais complètement inadapté pour simplement écrire du
texte dans un fichier. Si je mets le doigt dedans, je vais sans doute
souffrir.
On me souffle qu'il est possible
d'utiliser
le moteur JavaScript V8 de Google depuis du code C++, et
certainement de donner au code JavaScript de quoi communiquer avec le
C++ pour y faire ce que je veux. Bon, mais C++ est le
langage de programmation dont je ne connais rien du tout et dont je ne
veux surtout rien connaître. Dommage.
On me souffle aussi que mon problème serait très simple sous
Windows. Bon, mais je n'ai pas accès à un Windows (sauf un
vieux XP dans une machine virtuelle, je doute que ça
convienne vraiment).
Sinon, le projet Gnome est
réputé exporter toutes ses API (dont certainement ce
qu'il faut pour écrire un fichier…) sous une forme telle qu'elles
soient utilisables dans un grand nombre de langages de programmation.
Il y a même un cadre général pour faire ça de façon
automatisée : GObjectIntrospection.
Et il y a non pas un mais deux interpréteurs JavaScript
(subtilement différents et confusants) qui font plus ou moins partie
du projet Gnome : l'un
s'appelle gjs,
l'autre s'appelle Seed.
C'est très certainement ce que je veux : pour programmer des petites
choses simples en JavaScript qui interagissent avec mon environnement
graphique ou mon système d'exploitation, des bindings Gnome semblent
idoines. Le problème est l'absence complète de documentation de
l'utilisation des API dans le cadre de ces deux projets :
je trouve vaguement un exemple
utilisant gjs (pour ouvrir une fenêtre), je
trouve cette
page de doc dont je ne sais même pas d'où elle sort, mais
inexplicablement il n'y a aucune méthode contenant le mot file
(et si j'essaie d'utiliser GLib.io_channel_new_file()
comme il semble logique
d'après l'API
C, ça n'existe pas),
les exemples Seed que
je trouve ici semblent avoir essentiellement disparu,
les traces
que j'en retrouve
néanmoins par
exemple là ne marchent pas.
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.
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).
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.156
≡ 6to4.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).
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.
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 N−k 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 N−k chunks de données
plus k chunks de redondance. Sur N−k
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 N−k 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 0
Disque 1
Disque 2
Disque 3
Stride 0
Q
D0
D1
P
Stride 1
D2
D3
P
Q
Stride 2
D5
P
Q
D4
Stride 3
P
Q
D6
D7
Stride 4
Q
D8
D9
P
Stride 5
D10
D11
P
Q
(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 0
Disque 1
Disque 2
Disque 3
Stride 0
D0⊕2⊛D1
D0
D1
D0⊕D1
Stride 1
D2
D3
D2⊕D3
D2⊕2⊛D3
Stride 2
D5
D4⊕D5
D4⊕2⊛D5
D4
Stride 3
D6⊕D7
D6⊕2⊛D7
D6
D7
Stride 4
D8⊕2⊛D9
D8
D9
D8⊕D9
Stride 5
D10
D11
D10⊕D11
D10⊕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, u⊕v
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
2v⊕0x11d, 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 :
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=D0⊕D1,
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),
— 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 0xff⊕0xf6=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 0x1ec⊕0xf1=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.
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 N−k disques, et qui peut résister à une
défaillance de k disques. En clair, il existe les
principaux niveaux suivants :
RAID0, qui ne crée aucune redondance
(k=0) : vos données sont réparties entre les N
disques et il n'y a aucune protection contre les défaillances, bien au
contraire, si un disque quelconque a un problème, toutes les données
sont perdues. Ceci n'est donc utile que pour des données temporaires,
ou très peu précieuses. L'avantage, c'est qu'on gagne en capacité et
en vitesse de transfert (la capacité totale, comme la vitesse de
transfert, est en gros celle de N disques).
RAID1, qui est l'extrême inverse : la
redondance est totale (k=N−1) : tous les disques
contiennent une copie complète des données, ils sont miroirs les uns
des autres. Même si tous les disques sauf un tombent en panne, les
données sont sauves, puisque n'importe lequel permet de tout
reconstituer.
RAID5, qui est intermédiaire entre 0 et 1 (non,
les numéros n'ont aucune logique, je suppose que c'est juste l'ordre
d'introduction) : on a une redondance de k=1 disque.
Autrement dit, RAID5 vous protège contre la panne
d'un disque mais si deux disques tombent simultanément en panne, vos
données sont perdues. En contrepartie, si vous avez N
disques, vous avez la capacité de N−1 disques (et également
un gain en vitesse, sur lequel je n'approfondis pas). Bien
sûr, RAID5 n'a de sens que pour N≥3
disques (si on n'a que deux disques, soit on fait de la redondance et
c'est du RAID1, soit on n'en fait pas et c'est
du RAID0).
RAID6, qui est aussi intermédiaire entre 0 et
1, mais plus proche du 1 que ne l'est le 5 : cette fois, on a une
redondance de k=2 disques. Autrement
dit, RAID5 vous protège contre la panne simultanée
de deux disques (mais pas trois). En contrepartie, si vous
avez N disques, vous avez la capacité de N−2
disques (et également un gain en vitesse, sur lequel je n'approfondis
pas). Et RAID6 n'a de sens que pour N≥4
disques.
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).
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.
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.
[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.
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 :
Me passer de Flash. Malheureusement impossible.
Utiliser la vieille version de Flash. Trop dangereux.
Utiliser la vieille version de Flash, mais ne l'activer que quand
j'ai besoin d'aller sur un site Web qui en a besoin (et auquel je fais
confiance pour ne pas exploiter les trous de sécurité du truc, comme
le site de ma banque). Faisable, mais très pénible (relancer un
navigateur quand je veux aller sur un site comme ça, c'est vraiment
lourd).
Utiliser un navigateur 32-bits. Problématique à cause de la
façon dont tout le système est 64-bits.
Utiliser un remplacement (libre) de
Flash, Lightspark :
ça a l'air prometteur pour l'avenir, mais dans l'immédiat, c'est une
horreur à compiler et installer, et de toute façon ça ne marche pas
(la version 0.4.1 prétend arriver plus ou moins à lire les vidéos
YouTube, mais je n'ai pas eu ce succès).
Utiliser un des autres remplacements (libres aussi) de
Flash : Gnash
ou SWFdec :
ces projets ont l'air morts ou moribonds (Gnash, par exemple, décode
en gros la version 7 du format Flash, on en est à la 10).
Utiliser NSPluginWrapper
pour faire tourner un plugin 32-bits dans un navigateur 64-bits.
C'est ce que j'utilisais avant que Flash sorte en version 64-bits, et
c'était une grosse source de tracas (plantages aléatoires fréquents du
plugin (qui, il est vrai, n'entraîne pas toujours le navigateur avec
lui, c'est déjà ça), fenêtres Flash grises, sites rendus complètement
non-fonctionnels parce que le Flash vient se glisser au-dessus de
tout, etc.).
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).
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 :
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 :
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 :
(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).
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 :
(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.
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.
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 là
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.
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).
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'ENST où ne 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).
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 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.
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.)
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.
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 AcerAspire 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 IPv62001: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:
A number of things worked (sometimes unexpectedly) fine out of the
box: the graphics hardware (Silicon Integrated Systems [SiS]
661/741/760/761 PCI/AGP VGA Display Adapter, says
lspci) and the sound system (Silicon Integrated
Systems [SiS] AC'97 Sound Controller (rev a0)) were among the
pleasant surprises (the system has no accelerated 3D, but I don't
think the hardware has it anyway; however, it does have accelerated 2D
and video, which is good). That the Ethernet controller,
USB ports, hard drives and other very common hardware
works is of course less of a surprise, but still nice; I didn't try
burning DVD's, but I expect no difficulty there, and
reading them certainly works. The touchpad has this really cool driver which is
configurable in unbelievably many ways.
I did have a little more trouble with the battery status
indicator. This is probably because the BIOS ships
with broken ACPI tables or code. However, using a
sufficiently recent Linux kernel version (2.6.17.7) solves the
problem, so I didn't look into it.
WiFi probably does not work. The hardware appears to be
an Atheros Communications, Inc. AR5005G 802.11abg NIC (rev 01),
and it's about the only chipset that the MadWifi driver does not support, so no
luck there (and the error message is annoyingly cryptic: unable to
attach hardware: 'Hardware revision not supported' (HAL status
13)). Then I tried this cruft which is
intended to make it possible to use Windows drivers on Linux: I had
some trouble locating the
appropriate driver in the first place, and now I think it
still doesn't work, but it's not entirely clear. The driver seems to
detect the hardware (it succeeds in reading the hardware address) and
creates the network device, but then it fails while scanning access
points: now it could be simply because there is no access
point to be found (indeed, unless one of my neighbors has WiFi at
home, there should be none), but the obscure error message
(ndiswrapper (set_scan:1167): scanning failed (C0010011))
probably indicates a more serious problem… I don't know for
sure, though. If necessary, I can buy some external
PCMCIA WiFi card which would is known to be
supported.
Update (): Actually, MadWifi
works better than described above. The problem was that the laptop
has a radio kill switch in front which needs to be pressed to
activate the receiver. Now I can at least detect access points around
me. However, I still didn't manage to actually get any packet
throught (but it may be due to the peculiar nature of the network I'm
trying this on).
Update (): OK, finally it
works. I had to play with iwpriv ath0 authmode 2 and
similar arcane commands. Urgh…
Suspend to disk seems to works. This is unexpected: I thought
doing a suspend to disk under any kind of Unix was inherently
impossible and the best they could achieve would be some horrible and
unworkable hack — well, it is a hack, but it seems to
work pretty well at least under certain circumstances. (In fact, as
is often the case, there are confusingly many different
ways to
suspend, and I only tried uswsusp a bit.) I was logged in
graphically and had various programs open when I tried suspending to
disk, and all was restored correctly. (Well, in truth, the Network
Time Protocol daemon was confused: but that daemon certainly does not
expect to run on a laptop!) I didn't try suspending to
RAM, yet.
Update (): Suspend to
RAM also works, but causes a few difficulties with
the graphics state.
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.
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.
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…).
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.
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.
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.
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.)
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.
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.
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.
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.
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).
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.
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.