Portages ] [ Debian GNU/Hurd ] [ Actualité ] [ Configuration ] [ CD Hurd ] [ Documentation ] [ Développement ] [ Contact ]

Debian GNU/Hurd

Traducteurs

Concept

Avant d'étudier en détail les traducteurs, voyons le fonctionnement d'un système de fichiers traditionnel. Un système de fichiers est une zone de données organisée en un arbre hiérarchique de répertoires et de fichiers. Ces répertoires et fichiers sont désignés par une chaîne de caractères spéciale, le chemin. D'autres données que de simples fichiers ou répertoires peuvent être présents dans cet arbre :

Malgré les grandes différences qui existent entre ces objets, ils partagent certaines propriétés générales, par exemple, ils ont tous un propriétaire et un groupe qui leur est associé, ainsi que des droits d'accès (permissions). Ces informations sont conservées dans des inodes. Voilà encore une propriété partagée : chacun de ces objets a exactement un inode qui lui est associé (à l'exception des liens physiques qui sont plusieurs à partager le même inode). Quelques fois, l'inode contient un peu plus d'informations. Par exemple, il peut contenir la destination d'un lien symbolique.

Cependant, ces ressemblances ne sont généralement pas exploitées dans les implémentations, malgré une interface de programmation commune. On peut accéder à tous les inodes par des appels POSIX standards, par exemple read() et write(). Mais pour ajouter un nouveau type d'objet (par exemple un nouveau type de lien) sur un noyau unix monolithique classique, il faut modifier le code de chaque système de fichiers séparément.

Avec GNU/Hurd, les choses sont différentes. Bien sûr, lorsqu'un système de fichiers particulier (comme ext2fs) ajoute à un objet standard (comme le lien symbolique) une propriété particulière (comme le lien rapide), GNU/Hurd l'implémente dans un serveur de système de fichiers spécifique. Mais sa grande force est de posséder une interface générique permettant d'ajouter de telles fonctionnalités sans modifier le code existant.

L'astuce consiste à permettre à un programme de s'insérer entre le contenu effectif du fichier et l'utilisateur qui accède à ce fichier. Un tel programme s'appelle un traducteur, parce qu'il est capable de traiter et transformer des requêtes de plein de façons différentes. En d'autres termes, un traducteur est un serveur Hurd qui implémente l'interface de base des système de fichiers.

Les traducteurs ont des propriétés très intéressantes. Vu du noyau, ce ne sont que des processus comme les autres, qui peuvent être lancés par n'importe quel utilisateur. Vous n'avez pas besoin des privilèges de root pour installer ou modifier un traducteur, il suffit des droits d'accès à l'inode auquel est rattaché ce traducteur. De nombreux traducteurs n'ont pas besoin d'un fichier concret pour fonctionner, ils fournissent des informations par leurs propres moyens. C'est pourquoi les informations sur les traducteurs sont associées aux inodes.

Un traducteur a pour responsabilité de répondre à toutes les requêtes de système de fichiers qui agissent sur l'inode auquel il est rattaché. Comme il n'est pas limité aux objets habituels (lien, fichier spécial de périphérique, etc.), il est libre de retourner tout ce qui peut avoir un sens. On pourrait imaginer un traducteur qui se comporte comme un répertoire lorsqu'on y accède par cd ou ls et en même temps comme un fichier lorsqu'on y accède par cat.

Exemples

Point de montage

Un point de montage peut être vu comme un inode avec un traducteur spécial qui lui est rattaché. Son utilité est de traduire les opérations de système de fichiers sur le point de montage en opérations sur d'autres données, par exemple une autre partition.

C'est en effet ainsi que les systèmes de fichiers sont implémentés sur GNU/Hurd. Un système de fichiers est un traducteur. Ce traducteur prend en argument un périphérique de stockage, et effectue de façon transparente toutes les opérations de système de fichiers.

Fichier spécial de périphérique

Il existe de très nombreuses sortes de fichiers de périphérique, et dans un système avec un noyau monolithique, ils sont tous gérés par le noyau lui-même. Dans GNU/Hurd, tous les fichiers de périphérique sont gérés par des traducteurs. Un même traducteur peut gérer de nombreux fichiers de périphériques similaires, par exemple toutes les partitions de disques durs. Ainsi, le nombre réel de traducteurs nécessaires est réduit. En revanche, chaque fois qu'un fichier de périphérique est utilisé, un nouveau thread est lancé dans le traducteur. Comme GNU/Hurd est hautement multithread, cette opération n'est pas coûteuse du tout.

Lorsqu'il doit accéder à du matériel, un traducteur se met à communiquer avec le noyau pour transférer des données. Mais si aucun accès au matériel n'est nécessaire, le noyau n'est plus du tout concerné. Par exemple, /dev/zero ne nécessite aucun accès matériel, donc il est entièrement implémenté dans l'espace utilisateur.

Lien symbolique

Un lien symbolique peut être vu comme un traducteur. L'accès à un lien symbolique lancerait le traducteur, qui ferait suivre les requêtes vers le système de fichiers contenant le fichier vers lequel le lien pointe.

Cependant, pour de meilleures performances, les systèmes de fichiers qui ont un support natif des liens symboliques peuvent en tirer avantage et les implémenter différemment. En interne, l'accès à un lien symbolique ne lance pas un nouveau thread de traducteur, mais pour l'utilisateur tout se passe comme si un traducteur passif était présent (voyez plus bas pour une explication sur les traducteurs passifs).

Comme GNU/Hurd fournit un traducteur de lien symbolique, tout serveur de système de fichiers qui supporte les traducteurs supporte automatiquement les liens symboliques (et les firmlinks, et les fichiers de périphériques, etc.) ! Cela signifie que vous pouvez faire tourner un nouveau type de système de fichiers très rapidement, et ajouter le support natif des liens symboliques et d'autres fonctionnalités plus tard.

Traducteur passif, traducteur actif

Il y a deux types de traducteurs, les traducteurs passifs, et les traducteurs actifs. Ce sont réellement deux choses différentes, qu'il ne faut pas mélanger, mais ces deux types des traducteurs sont en étroite relation.

Traducteur actif

Un traducteur actif est un processus de traducteur qui tourne, comme expliqué plus haut. Vous pouvez ajouter ou retirer un traducteur actif en utilisant la commande settrans -a. L'option -a est nécessaire pour indiquer à settrans que vous désirez agir sur un traducteur actif.

La commande settrans prend trois catégories d'arguments. Premièrement, les options propres à la commande settrans elle-même, comme -a pour modifier le traducteur actif. Ensuite, vous précisez l'inode à modifier. Rappelez-vous qu'un traducteur est toujours rattaché à un inode dans une hiérarchie de répertoires. Vous ne pouvez modifier qu'un seul inode à la fois. Si vous n'indiquez pas plus d'arguments, settrans essayera d'enlever le traducteur existant. L'énergie qu'il y mettra dépend des options spécifiées (si le traducteur est en cours d'utilisation, vous aurez un message d'erreur « device or resource busy » à moins de forcer sa suppression).

Mais si vous précisez d'autres arguments, ils seront interprétés comme une ligne de commande de lancement du traducteur. Cela signifie que l'argument qui suit est le nom de l'exécutable du traducteur et que les suivants sont ses options, et non celles de la commande settrans.

Par exemple, pour monter une partition ext2fs, il suffit de lancer settrans -a -c /mnt /hurd/ext2fs /dev/hd2s5. L'option -c créera le point de montage s'il n'existe pas déjà. Notez que ce point de montage n'est pas nécessairement un répertoire. Pour démonter cette partition, il suffit de faire settrans -a /mnt.

Traducteur passif

Un traducteur passif est positionné ou modifié par la même syntaxe que pour un traducteur actif (il suffit de retirer le -a), donc tout ce qui a été dit précédemment est applicable aux traducteurs passifs. Cependant, il y a une différence : les traducteurs passifs ne sont pas lancés immédiatement.

Cela correspond finalement au sens que vous voulez donner à un traducteur. Vous ne voulez pas que la partition soit montée à moins d'accéder réellement à cette partition. Vous ne voulez pas lancer le réseau tant qu'il n'y a pas de trafic, etc.

Au lieu de cela, au premier accès au traducteur passif, un traducteur actif est lancé à partir de la ligne de commande stockée dans l'inode. Ce mécanisme est un peu similaire à l'automounter de Linux. La différence, c'est qu'il ne s'agit pas d'un petit plus à mettre en place manuellement, mais d'une partie intégrante du système. La mise en place de traducteurs passifs repousse donc le lancement de ces traducteurs au moment où ils seront réellement nécessaires. Par ailleurs, si un traducteur actif meurt pour une quelconque raison, il est relancé au premier accès qui suit à l'inode.

Il y a une autre différence : les traducteurs actifs peuvent mourir ou se perdre. Dès qu'un traducteur est tué (par exemple, parce que la machine est réamorcée), il est perdu pour toujours. Les traducteur passifs sont conservés dans les inodes pendant les réamorçages jusqu'à ce que vous les modifiiez par le programme settrans, ou que vous effaciez les inodes auxquels ils sont attachés. Cela signifie que vous n'avez pas de fichier de configuration à tenir à jour pour vos points de montage.

Un dernier point : même si vous avez mis en place un traducteur passif, vous pouvez toujours lancer un traducteur actif différent. Ce n'est que dans le cas où aucun traducteur n'est actif au moment où l'inode est utilisé qu'un traducteur est lancé automatiquement par le traducteur passif.

Gestion des traducteurs

Comme indiqué plus haut, vous pouvez utiliser settrans pour lancer ou modifier les traducteurs passifs et actifs. Il existe de nombreuses options pour changer le comportement de settrans en cas d'erreur, ou pour conditionner son action. Voici quelques utilisations classiques :

Vous pouvez utiliser la commande showtrans pour voir si un traducteur est attaché à un inode. Cette commande n'affichera cependant que le traducteur passif.

Vous pouvez changer les options d'un traducteur actif (de système de fichiers), avec la commande fsysopts sans le relancer. C'est vraiment pratique. Par exemple, vous pouvez faire l'équivalent d'un « remontage de partition en lecture seule » sous Linux en lançant simplement fsysopts /point_de_montage --readonly. Le traducteur actif changera son comportement dans la mesure du possible. fsysopts /point_de_montage sans autre paramètre affiche l'état courant du traducteur.

Exemples

Je vous recommande de commencer par lire la commande /bin/mount, c'est juste un petit script. Comme la mise en place de traducteurs de systèmes de fichiers est similaire au montage de partitions, vous pourrez ainsi facilement maîtriser ce concept. Faites une image d'un système de fichiers avec dd if=/dev/zero of=dummy.fs bs=1024k count=8; mke2fs dummy.fs et montez-la avec settrans -c dummy /hurd/ext2fs `pwd`/dummy.fs. Notez que le traducteur n'est pas encore lancé, il n'y a pas de nouveau processus ext2fs qui tourne (vérifiez avec ps Aux). Vérifiez que tout est correct en utilisant showtrans.

Maintenant, tapez ls dummy, vous remarquerez un court délai pendant que le traducteur démarre. Après cela, il n'y aura plus de délais pour accéder à dummy. Sous Linux, on aurait dit que vous avez automonté un système de fichiers loop. Vérifiez avec ps Aux qu'il y a un processus ext2fs dummy qui tourne. Maintenant, mettez quelques fichiers dans ce nouveau répertoire. Essayez de passer ce système de fichier en lecture seule avec fsysopts. Notez que de nouvelles tentatives d'écriture échouent maintenant. Essayez de tuer le traducteur actif avec settrans -g.

Vous devriez commencer à comprendre ce qui se passe. Maintenant, rappelez-vous, ce n'est qu'un seul serveur, le serveur Hurd ext2fs. Il existe de nombreux autres serveurs dans le répertoire /hurd. Certains sont pour des systèmes de fichiers. Certains sont nécessaires pour des fonctionnalités des systèmes de fichiers, comme les liens. Certains sont nécessaires pour les fichiers de périphériques. Certains sont nécessaires pour le réseau. Imaginez que vous montez un serveur FTP avec settrans et que vous téléchargez des fichiers en utilisant simplement la commande cp standard, ou bien que vous éditez votre site web avec la commande emacs /ftp/homepage.my.server.org/index.html !