Linux-Mandrake:
Guide de l'utilisateur
et Manuel de référence

MandrakeSoft

 
 
Janvier 2000
http://www.linux-mandrake.com


Suivant : Le système de fichiers /proc
Précédent : Organisation de l'arborescence des fichiers
Retour

(Retour à la table des matières)

Chapitre 4 : Le système de fichiers de Linux: ext2fs (EXTended 2 FileSystem)


Le Guide de l'utilisateur a introduit les concepts de propriété des fichiers et les droits d'accès, mais pour vraiment comprendre le système de fichiers de Linux, il faut redéfinir la notion même de fichier. Une raison en est que:

Tout est fichier

Ici, « tout » veut dire vraiment tout. Un disque dur, une partition sur un disque dur, un port parallèle, une connexion à un site web, une carte Ethernet, tous ces éléments sont des fichiers. Même les répertoires sont des fichiers. Linux reconnaît plusieurs types de fichiers, en plus des fichiers réguliers et des répertoires. Notez que par type de fichier ici, nous ne faisons pas référence au type du contenu du fichier: pour Linux et pour tout système Unix, un fichier, qu'il soit une image GIF, un fichier binaire ou autre, est juste une suite d'octets. La différenciation des fichiers en fonction de leur contenu est laissé aux applications.

Si vous vous souvenez, quand vous tapez ls -l, le caractère avant les droits d'accès représente le type du fichier. Nous avons déjà vu deux types de fichiers: les fichiers réguliers (-) et les répertoires (d). Vous pouvez aussi tomber sur les suivants si vous vous baladez dans l'arborescence et listez le contenu des répertoires:

Voici un exemple de chacun de ces fichiers:

$ ls -l /dev/null /dev/sda  /etc/rc.d/rc3.d/S20random /proc/554/maps \
  /tmp/ssh-fg/ssh-510-agent
crw-rw-rw-    1 root     root       1,   3 mai  5  1998 /dev/null
brw-rw----    1 root     disk       8,   0 mai  5  1998 /dev/sda
lrwxrwxrwx    1 root     root           16 déc  9 19:12 /etc/rc.d/rc3.d/S20random ->
../init.d/random*
pr--r--r--    1 fg       fg              0 déc 10 20:23 /proc/554/maps|
srwx------    1 fg       fg              0 déc 10 20:08
/tmp/ssh-fg/ssh-510-agent=
$

On devrait ajouter que ext2fs, comme tous les autres systèmes de fichiers Unix, stocke les fichiers, quel que soit leur type, dans une table des i-noeuds. Une particularité est qu'un fichier n'est pas identifié par son nom, mais par un numéro d'i-noeud. En fait, certains fichiers n'ont pas de noms. Les noms sont juste une conséquence d'une notion plus large:

Les liens

Le meilleur moyen de comprendre ce qui se cache derrière cette notion de liens est de prendre un exemple. Créons un fichier (régulier):

$ pwd
/home/fg/exemple
$ ls
$ touch a
$ ls -il a
  32555 -rw-rw-r--    1 fg       fg              0 déc 10 08:12 a

L'option -i de la commande ls affiche le numéro d'i-neud, qui est le premier champ dans la sortie. Comme vous pouvez le voir, avant que nous ayons créé le fichier a, il n'y avait aucun fichier dans le répertoire. L'autre champ intéressant est le troisième, qui est le compteur de liens pour le fichier.

En fait, on peut séparer la commande touch a en deux actions distinctes:

Mais maintenant, si nous faisons:

$ ln a b
$ ls -il a b
  32555 -rw-rw-r--    2 fg       fg              0 déc 10 08:12 a
  32555 -rw-rw-r--    2 fg       fg              0 déc 10 08:12 b
$

nous avons créé un autre lien vers le même i-noeud. Comme vous pouvez le voir, nous n'avons créé aucun fichier nommé b, mais au lieu de cela nous avons ajouté un autre lien vers l'i-noeud de numéro 32555 dans le même répertoire nommé b. Vous pouvez voir dans la deuxième sortie de ls -l que le compteur de liens est maintenant 2 et non plus 1.

Maintenant, si nous faisons:

$ rm a
$ ls -il b
  32555 -rw-rw-r--    1 fg       fg              0 déc 10 08:12 b
$

nous voyons que même si nous avons effacé le « fichier original », l'i-noeud existe encore. Mais maintenant le seul lien vers cet i-noeud est /home/fg/exemple/b.

Donc, un i-noeud est lié si et seulement si il est référencé par un nom au moins une fois dans un répertoire quelconque[15]. Les répertoires eux-mêmes sont aussi stockés dans des i-noeuds, mais leur compteur de liens, contrairement à tous les autres types de fichiers, est leur nombre de sous-répertoires. Il y a au moins deux liens par répertoire: le répertoire lui-même (.) et son répertoire parent (..).

Des exemples typiques de fichiers qui ne sont pas liés (c'est-à-dire qu'ils n'ont pas de noms) sont les connexions réseau: vous ne verrez jamais le fichier correspondant à votre connexion à www.linux-mandrake.com dans votre arborescence, quel que soit le répertoire que vous essayiez. De façon similaire, quand vous utilisez un tube dans le shell, le fichier correspondant au tube existe bien, mais il n'est pas lié.

Tubes « anonymes » et tubes nommés

Revenons à l'exemple des tubes, car il est très intéressant et c'est également une bonne illustration de la notion de liens. Quand vous utilisez un tube dans une ligne de commande, le shell crée le tube pour vous et fait en sorte que la commande avant le tube écrit dans celui-ci, tandis que la commande après le tube y lit ses données. Tous les tubes, qu'ils soient anonymes (comme ceux utilisés par le shell) ou nommés (voyez ci-dessous), fonctionnent selon le principe FIFO (First In, First Out, "premier arrivé, premier servi"). Nous avons déjà vu des exemples sur l'utilisation des tubes avec le shell, mais prenons-en un dans un but d'illustration:

$ ls -d /proc/[0-9] | head -6
/proc/1/
/proc/2/
/proc/3/
/proc/4/
/proc/5/

Une chose que vous ne remarquez pas dans cet exemple (parce que cela se passe trop vite) est que les écritures sur le tube sont bloquantes. Cela veut dire que quand la commande ls écrit dans le tube, elle est bloquée jusqu'à ce qu'un processus à l'autre bout lise depuis le tube. Pour visualiser cet effet, vous pouvez créer des tubes nommés, qui, contrairement aux tubes utilisés par le shell, ont des noms (donc ils sont liés, tandis que les tubes utilisés par le shell ne le sont pas). La commande pour créer de tels tubes est mkfifo:

$ mkfifo un_tube
$ ls -il
total 0
    169 prw-rw-r--    1 fg       fg              0 déc 10 14:12 un_tube|
  #
  # Vous pouvez voir que le compteur de liens est 1, et que la sortie
  # montre  que le fichier est un tube ('p').
  #
  # Vous pouvez aussi utiliser ln ici :
  #
$ ln un_tube le_même_tube
$ ls -il
total 0
    169 prw-rw-r--    2 fg       fg              0 déc 10 15:37 un_tube|
    169 prw-rw-r--    2 fg       fg              0 déc 10 15:37 le_même_tube|
$ ls -d /proc/[0-9] >un_tube
  #
  # Le processus est bloqué, comme il n'y a pas de lecteurs à l'autre
  # bout. Tapez C-z pour suspendre le processus...
  #
zsh: 3452 suspended  ls -d /proc/[0-9] > un_tube
  #
  # ...Puis mettez-le en tâche de fond :
  #
$ bg
[1]  + continued  ls -d /proc/[0-9] > un_tube
  #
  # Maintenant lisez depuis le tube...
  #
$ head -6 <le_même_tube
  #
  # ...le processus écrivain se termine :
  #
[1]  + 3452 done       ls -d /proc/[0-9] > un_tube
/proc/1/
/proc/2/
/proc/3/
/proc/4/
/proc/5/
$

De la même façon, les lectures sont bloquantes. Si nous exécutons les commandes ci-dessus dans l'ordre inverse, nous observons que head est bloqué, en attendant qu'un processus lui donne quelque chose à lire:

$ head -6 <un_tube
  #
  # Le processus est bloqué, suspendez-le : C-z
  #
zsh: 741 suspended  head -6 < un_tube
  #
  # Mettez-le en tâche de fond...
  #
$ bg
[1]  + continued  head -6 < un_tube
  #
  # ...Et donnez-lui à manger :)
  #
$ ls -d /proc/[0-9] >le_même_tube
$ /proc/1/
/proc/2/
/proc/3/
/proc/4/
/proc/5/
[1]  + 741 done       head -6 < un_tube
$

Vous pouvez aussi voir un effet indésirable dans cet exemple: la commande ls a fini son exécution avant que la commande head prenne le relais. La conséquence est que vous êtes retourné(e) au prompt immédiatement, mais head ne s'est exécuté qu'après. Donc il a effectué sa sortie seulement après que vous ayez récupéré le prompt :)

Les fichiers « spéciaux »: fichiers en mode bloc et caractère

Comme il a déjà été dit, de tels fichiers sont soit des fichiers créés par le système, soit bien des périphériques de votre machine. Nous avons aussi mentionné que le contenu des fichiers en mode bloc était gardé en mémoire alors que tel n'était pas le cas des fichiers en mode caractère. Pour illustrer ceci, insérez une disquette quelconque dans le lecteur et tapez la commande suivante deux fois de suite:

$ dd if=/dev/fd0 of=/dev/null

Vous pouvez observer la chose suivante: tandis que, la première fois que la commande a été lancée, tout le contenu de la disquette a été lu, la deuxième fois il n'y a eu aucun accès au lecteur de disquette. C'est simplement parce que le contenu de la disquette a été gardé en mémoire quand vous avez lancé la commande la première fois --- et que vous n'avez pas changé de disquette entre temps.

Mais maintenant, si vous voulez imprimer un gros fichier de cette façon (si, ça fonctionne):

$ cat /un/gros/fichier/imprimable/quelque/part >/dev/lp0

la commande prendra autant de temps que vous la tapiez une, deux ou cinquante fois. Ceci est dû au fait que /dev/lp0 est un fichier en mode caractère, et son contenu n'est pas gardé en mémoire.

Le fait que le contenu des fichiers en mode bloc soit gardé en mémoire a un effet de bord agréable: non seulement les lectures sont gardées en mémoire, mais c'est aussi le cas des écritures. Cela autorise les écritures sur disque à être asynchrones: quand vous écrivez un fichier sur disque, l'opération d'écriture elle-même ne sera pas faite immédiatement. Elle n'aura lieu que quand Linux le décidera.

Enfin, chacun de ces fichiers spéciaux possède un numéro majeur et un numéro mineur. Sur la sortie d'un ls -l, ils apparaissent en lieu et place de la taille, étant donné que la taille pour de tels fichiers est hors de propos:

$ ls -l /dev/hda /dev/lp0
brw-rw----    1 root     disk       3,   0 mai  5  1998 /dev/hda
crw-rw----    1 root     daemon     6,   0 mai  5  1998 /dev/lp0

Ici, les numéros majeur et mineur de /dev/hda sont respectivement 3 et 0, tandis que ce sont respectivement 6 et 0 pour /dev/lp0. Notez que ces numéros sont uniques par catégorie de fichier, ce qui veut dire qu'il peut exister un fichier en mode caractère ayant 3 pour majeur et 0 pour mineur (un tel fichier existe : c'est /dev/ttyp0), et de la même façon il peut y avoir un fichier en mode bloc ayant 6 pour majeur et 0 pour mineur. Ces nombres existent pour une raison bien simple: cela permet à Linux d'associer les bonnes opérations aux fichiers (donc aux péripériques auxquels ces fichiers se réfèrent). On ne contrôle pas un lecteur de disquettes de la même façon que, par exemple, un disque dur SCSI.

Les liens symboliques et la limitation des liens « en dur »

Ici nous avons à faire face à une incompréhension très courante, même parmi les utilisateurs d'Unix, qui est principalement due au fait que les liens tels que nous les avons vus jusque là (faussement appelés liens « en dur ») sont seulement associés aux fichiers réguliers (et nous avons vu que ce n'est pas le cas --- même les liens symboliques sont « liés »). Mais cela requiert que nous expliquions d'abord ce que sont les liens symboliques[16].

Les liens symboliques sont des fichiers d'un type particulier dont le seul contenu est une chaîne de caractères arbitraire, qui peut ou non pointer sur un vrai nom de fichier. Quand vous mentionnez un lien symbolique sur la ligne de commande ou dans un programme, vous accédez en fait au fichier sur lequel pointe le lien, s'il existe. Par exemple:

$ echo Bonjour >monfichier
$ ln -s monfichier monlien
$ ls -il
total 4
    169 -rw-rw-r--    1 fg       fg              6 déc 10 21:30 monfichier
    416 lrwxrwxrwx    1 fg       fg              6 déc 10 21:30 monlien -> monfichier
$ cat monfichier
Bonjour
$ cat monlien
Bonjour

Vous pouvez voir que le type du fichier monlien est 'l'. Les droits d'accès pour un lien symbolique n'ont aucune signification: ils seront toujours rwxrwxrwx. Vous pouvez également voir que c'est un fichier différent de monfichier, parce que son numéro d'i-noeud est différent. Mais il se réfère au fichier monfichier de façon symbolique, donc quand vous tapez cat monlien, vous affichez en fait le contenu du fichier monfichier. Pour démontrer qu'un lien symbolique contient une chaîne arbitraire, nous pouvons faire la chose suivante:

$ ln -s "Je n'existe pas" unautrelien
$ ls -il unautrelien
    747 lrwxrwxrwx    1 fg       fg             15 déc 15 18:01 unautrelien -> Je n'existe pas
$ cat unautrelien
cat: unautrelien: Aucun fichier ou répertoire de ce type
$

Mais les liens symboliques existent parce qu'ils s'affranchissent de plusieurs limitations des liens normaux:

Donc les liens symboliques sont très utiles dans plusieurs cas, et très souvent, les gens tendent à les utiliser pour lier des fichiers même quand un lien normal est possible. Un avantage des liens normaux, pourtant, est que vous ne perdez pas le fichier si vous effacez l'« original » :)

Enfin, si vous avez observé attentivement, vous savez à quoi correspond la taille d'un lien symbolique: c'est tout simplement la taille de la chaîne de caractères.

Les attributs des fichiers

De même que la FAT a des attributs de fichiers (archive, fichier système, invisible), ext2fs a aussi les siens propres, mais ils sont différents. Non en parlons pour être complet, mais ils sont très peu utilisés. Toutefois, si vous voulez un système vraiment sécurisé, continuez la lecture.

Il existe deux commandes pour manipuler les attributs: ce sont lsattr(1) et chattr(1). Vous l'aurez deviné, lsattr LiSte les attributs, et chattr les CHange. Ces attributs s'appliquent seulement aux répertoires et aux fichiers réguliers. Ce sont les suivants:

Vous pouvez, par exemple, placer l'attribut 'i' sur des fichiers système essentiels pour éviter les mauvaises surprises. Pensez aussi à l'attribut 'A' pour les pages de manuel par exemple: cela évitera beaucoup d'activité disque, et, en particulier, cela prolongera la durée de vie de la batterie sur les portables.


Suivant : Le système de fichiers /proc
Précédent : Organisation de l'arborescence des fichiers
Retour

Copyright © 2000 MandrakeSoft