Chacun connaît le répertoire /dev et ces quelques 1500 entrées (noeuds). L'arrivée du kernel 2.4 marque peut-être la fin, pour la plupart d'entre nous, de l'utilisation classique de cette collection de points d'entrée vers le matériel ...
Le principe ayant conduit à la création du système de fichiers des périphériques est simple : la récurrence des informations est mauvaise pour le fonctionnement et la maintenance d'un système. En effet, il est nécessaire de garder une correspondance manuellement ou pseudo-manuellement (avec MAKDEV) entre les valeurs Majeurs/Mineurs du kernel et les entrées dans /dev. Dans le même esprit, il est absolument nécessaire de garder une unicité de chaque couple Majeur/Mineur, ce qui oblige à procéder à un harassant travail quasi administratif. Une très bonne raison pour justifier la recherche d'une autre manière de voir et de gérer /dev est le nombre d'entrées inutiles dans ce répertoire. En effet, qui peut bien prétendre utiliser 300 ou 400 de ces noeuds sur son système ? Personne, sans doute.
Enfin, une raison plus technique est avancée par Richard Gooch dans la FAQ livrée avec le kernel. Il s'agit d'une question de vitesse et, en particulier, à propos des périphériques divers en mode caractère. Lorsque vous accédez à un noeud dans /dev, une recherche est faite pour trouver le pilote correspondant à partir des numéros Majeur/Mineur définis par le noeud. Pour l'heure, ces recherches sont faites sur des tables de 128 entées (8 bits) chacune. Mais le jour viendra où cette table ne sera plus suffisante et il faudra passer sur des numérotations à 16 bits. Ceci porterait les tableaux à 65536 entrées, soit, en toute logique, une recherche 512 fois plus lente ...
Le principe
Pour éviter les désagréments actuels et à venir, devfs n'utilise pas le principe des combinaisons Majeur/Mineur. Avec devfs, les connexions sont créées au moment où vous entrez dans le répertoire /dev. Lorsque l'on souhaite enregistrer un périphérique, une entrée dans une table interne est créée. Si cette entrée dans le cache ne possède pas encore de noeud, celui-ci est également créé. En revanche, si l'entrée est déjà présente dans le cache, aucune opération n'est nécessaire et, de ce fait, aucune recherche n'est effectuée. Dans ce cache ne se trouveront que des entrées pour des périphériques existants réellement sur votre système. Les recherches dans le cache seront donc rapides.
Cette manière de procéder possède, en outre, un autre avantage intéressant. En effet, si un périphérique que vous savez présent dans la machine n'est pas listé dans /dev, c'est le signe d'un mauvais fonctionnement du périphérique ... Un autre avantage concerne les systèmes de fichier en lecture seule, comme certaines stations diskless. Le répertoire /dev n'ayant pas d'existant physique, vous pouvez modifier les permissions à loisir sur les noeuds. Un bel exemple est, bien sûr, un système GNU/Linux complet sur CD-Rom. Avec devfs, vous n'êtes plus obligés de passer par un ramdisk.
Mais devfs va encore plus loin. Il est par exemple possible d'envoyer des messages au démon devfsd lors d'événements tels que l'ouverture ou la création d'une entrée. Il est ainsi possible d'associer des scripts à ces événements pour, par exemple, automatiquement monter un système de fichiers ou garder une trace de l'accès à un périphérique.
Installation
Vous vous en doutez, ceci est une fonctionnalité du kernel 2.4, il est donc impératif de prévoir tous les changements nécessaires au passage vers cette version avant d'envisager l'utilisation de devfs. Il est même fortement conseillé de démarrer et de bien tester un nouveau kernel sans devfs afin de s'assurer que toutes les dépendances sont respectées.
Avant de préparer et de compiler le kernel utilisant devfs, vous devez posséder sur votre système le démon devfsd prêt à être utilisé. Il vous est donc nécessaire d'en récupérer les sources (les plus récentes possibles) sur le site de Richard Gooch, http://www.atnf.csiro.au/~rgooch/linux/.
L'archive fait quelques dizaines de kilo-octets. Après décompression, vous pourrez compiler les sources à l'aide d'un simple "make". Avec les sources est livré un fichier de configuration devfsd.conf. Celui-ci permet de conserver une compatibilité avec l'ancienne implémentation de /dev. Les valeurs par défauts présentes dans ce fichier ne doivent pas être changées. Celles-ci doivent parfaitement fonctionner sur votre système et si vous désirez prendre le risque d'y faire des changements, faites-le après avoir testé les valeurs d'origine. Ce fichier de configuration prendra place dans votre répertoire /etc et le binaire devfsd dans /sbin.
Il vous faut à présent modifier votre script de démarrage initial afin de lancer /sbin/devfsd /dev durant les toutes premières étapes du démarrage. Il est impératif que cette ligne soit ajoutée avant n'importe quelle vérification des disques locaux. Selon votre distribution, la ligne est à ajouter dans un script placé dans le répertoire /etc/rc.d/, /sbin/init.d/ ou encore /etc/rc/. Nous avons fait nos tests sur un système basé, à l'origine, sur une distribution SuSE 6.2. Nous avons donc ajouté notre ligne concernant devfsd dans /etc/rc.d/boot, juste après le montage de /proc. Ceci n'est, bien sûr, pas à prendre pour argent comptant. Assurez-vous de la correcte exécution de la ligne en testant avec un simple
echo -n "--- COUCOU ICI SERA DEVFSD ---"
Après cette ultime vérification et la mise en place effective du lancement de devfsd via votre bootscript, votre système est prêt à accueillir une version du kernel 2.4 utilisant devfs. Recompilez donc celui-ci avec le support qui vous intéresse.
Pour les petits curieux : Mais comment fera le système pour démarrer avec comme racine la partition adéquate puisque les entrées dans /dev n'existent pas encore ? En réalité, le kernel ne fait pas référence aux entrées de /dev lors du démarrage. En précisant root=<périph> sur la ligne de commande du kernel, c'est en fait le bootloader qui interprétera ce paramètre. Il placera dans un emplacement mémoire une valeur correspondante au périphérique dont le kernel se servira. Ce dernier n'utilise donc pas /dev mais uniquement la valeur passée par le bootloader.
Attention : ne redémarrez pas le système avant d'avoir lu la partie qui va suivre !
Problèmes et solutions
L'un des modules PAM est utilisé pour la définition des terminaux "sûrs". Le fichier /etc/securetty contient la liste des terminaux via lequel, par exemple, l'utilisateur root peut se connecter. On y trouve habituellement ceci :
tty1
tty2
tty3
tty4
tty5
tty6
Afin d'éviter les éventuels problèmes d'authentification, ajoutez ceci au fichier :
1
2
3
4
5
6
7
8
Cela permettra de faire fonctionner devfs mais ouvrira une porte vers l'extérieur puisque, dans ce cas, un login root sera autorisé depuis le réseau (à condition d'avoir le mot de passe, bien sûr). Si vous pensez qu'il s'agit là d'un problème pour la sécurité de votre système, oubliez devfs.
Redémarrage
Lors du premier démarrage avec le support devfs, le kernel va se lancer et la procédure de boot va commencer. Si, comme nous, vous avez lancez le démon devfsd juste après le montage de /proc, vous devez voir apparaître un message du démon vous informant de son exécution :
Started device management daemon for /dev
La procédure de boot continuera alors normalement jusqu'à la demande de login. Loggez-vous et, ne résistant sans doute pas à la tentation, faites un tour dans le répertoire /dev. Vous constaterez alors de nombreux changements. Dans le cadre de nos tests, le nombre d'entrées à la racine de /dev est passé de 1786 à 426. Force est de constater qu'un grand nombre de ces entrées ne servaient effectivement à rien.
Autre constatation majeure, /dev est maintenant organisé sous la forme d'une arborescence élaborée et des liens symboliques permettent une compatibilité avec les applications et utilitaires faisant usage de l'ancienne organisation. Ainsi, on retrouve toutes nos partitions, nos disques et notre lecteur CD-Rom :
hda -> ide/host0/bus0/target0/lun0/disc hda1 -> ide/host0/bus0/target0/lun0/part1 hda2 -> ide/host0/bus0/target0/lun0/part2 hdc -> ide/host0/bus1/target0/lun0/disc hdc1 -> ide/host0/bus1/target0/lun0/part1 hdc2 -> ide/host0/bus1/target0/lun0/part2 hdc3 -> ide/host0/bus1/target0/lun0/part3 hdc4 -> ide/host0/bus1/target0/lun0/part4 hdd -> ide/host0/bus1/target1/lun0/cd
Tout fonctionne parfaitement, si ce ne sont les périphériques /dev/vcs* avec lesquels mingetty semblait avoir des problèmes. Ces périphériques correspondent à la mémoire d'affichage des consoles virtuelles. Elles permettent d'utiliser la séquence de touches MAJ+PageHaut. Malheureusement, nous n'avons pas eu le temps d'approfondir le sujet mais nous soupçonnons que le problème vienne de mingetty. En effet, celui-ci tenterait d'ouvrir les /dev/vcs* avant /dev/vcs.
Compatibilité
Le support devfs utilise la convention de nommage du kernel. Ceci signifie que les entrées dans /dev ne seront pas organisées de la même manière et, selon le noeud, ne porteront pas le même nom qu'avec l'ancien /dev. La configuration par défaut de devfsd permet de conserver une compatibilité avec l'ancien /dev sous la forme de liens symboliques. Cependant, il existe une autre manière de conserver une compatibilité. Celle-ci consiste à utiliser la nouvelle convention de nommage avec les kernels utilisant devfs mais également ceux qui ne l'utilisent pas.
Ainsi, vous pouvez vous passer de la compatibilité offerte par devfsd en utilisant la convention de nommage du kernel ou en créant votre propre système de nommage. Attention cependant, la convention de nommage du kernel (sous la forme d'arborescence) peut paraître séduisante mais n'oubliez pas tout ce que cela implique :
Note sur la convention de nommage du kernel
Comme nous venons de l'évoquer, le kernel utilise un schéma bien défini pour référencer les périphériques : autrement dit, une convention de nommage ou, encore plus simplement, une manière logique de donner un nom aux périphériques et de les classer. devfs vous permet d'avoir une représentation de ce schéma. En voici quelques exemples :
Chaque disque (IDE, SCSI, ou autre) est référencé par un lien symbolique dans /dev/discs/. On trouvera ici tous les disques sous la forme du répertoire disc0, disc1, etc. Ces liens symboliques pointent vers un répertoire représentant l'organisation des contrôleurs/disques/partitions sous la forme :
type/contrôleur/bus/cible/lun
Exemples :
SCSI: scsi/host1/bus2/target3/lun4
Le périphérique est présent sur le second contrôleur, chaîne 3, ID 3, LUN (Logical Unit Number) 4.
IDE: ide/host0/bus1/target0/lun0/part2
Sur le premier contrôleur réside un disque en secondary (bus1) master (target0) où réside une seconde partition (part2).
Ceci peut rendre de grands services. N'oubliez pas que seuls les périphériques supportés par le kernel sont présents dans devfs. Ainsi, pour connaître le nombre de périphériques présents sur le premier contrôleur SCSI, vous n'avez qu'à lister son répertoire.
Dans chacun de ces répertoires on trouvera une entrée pour le disque entier (disc) et pour chacune des partitions (part*). Les liens symboliques pointant sur ces entrées sont nombreux. Ainsi, si vous possédez un ou plusieurs lecteurs CD-Rom, ils seront également symbolisés par /dev/cdroms/cdrom0, /dev/cdroms/cdrom1, etc.
Nouveau nom Ancien nom Description /dev/tts/{0,1,...} /dev/ttyS{0,1,...} Ports série /dev/cua/{0,1,...} /dev/cua{0,1,...} Périphérique d'appel /dev/vc/{0,1,...} /dev/tty{0,1,...} Consoles Virtuelles /dev/vcc/{0,1,...} /dev/vcs{0,1,...} Mémoire des Consoles Virtuelles /dev/pty/m{0,1,...} /dev/ptyp?? PTY maîtres /dev/pty/s{0,1,...} /dev/ttyp?? PTY esclaves
Comme vous pouvez le voir, l'organisation générale reste assez simple. Il en va de même pour les périphériques comme les ramdisk ou encore le loopback.
Plus intéressant, l'organisation des entrées concernant le support des cartes son. Ici, un répertoire /dev/sound fournit une information sur les fonctionnalités du matériel installé. Ainsi, notre répertoire /dev/sound contient sur notre architecture de test :
audio
dspW
sequencer
sequencer2
Configuration
Une fois vous être assuré que tout fonctionnait correctement avec votre nouveau kernel supportant devfs, vous devez être en mesure de personnaliser le fichier de configuration du démon devfsd. En cas d'erreur dans ce fichier, vous aurez toujours la possibilité de démarrer sur un système de secours (CD ou disquette) pour revenir à l'ancienne version du fichier.
La modification et l'ajout d'options dans /etc/devfs.conf est relativement simple. Une page de manuel étant fournie avec les sources de devfsd, nous n'allons pas nous lancer ici dans la description des options. Sachez simplement que par l'intermédiaire de ce fichier de configuration, vous pouvez non seulement enregistrer de nouveaux périphériques de manière manuelle, mais également mettre en oeuvre un grand nombre de fonctionnalités très intéressantes. C'est ici, par exemple, que vous pourrez définir avec précision quel comportement adopter lors d'un événement survenant sur l'une des entrées de /dev. L'événement en question pourra être l'un des suivants :
En réponse à ces événements, un certain nombre d'actions peuvent être exécutées. Parmi les plus intéressantes, on remarque :
Nous arrivons au terme de cet article. Je tiens à préciser encore une fois que le support devfs du kernel 2.4 est encore à l'état expérimental. Il s'agit d'une fonctionnalité les plus remarquables du nouveau noyau et, n'en doutons pas, il semble bien que cela deviendra un standard pour les futures générations de système GNU/Linux.
Un grand nombre de sujets concernant devfs n'ont pas été abordés ici. Il est donc conseillé de lire attentivement la documentation livrée avec le kernel à ce sujet et de vous inscrire à la liste de diffusion du kernel pour trouver des informations à jour.
Liens
Homepage de Richard Gooch
http://www.atnf.csiro.au/~rgooch/linux/
Documentation du kernel
http://www.atnf.csiro.au/~rgooch/linux/docs/
FAQ de la mailing list du kernel Linux
http://www.tux.org/lkml/