Mknod

De wiki.nexiat.fr
Aller à la navigation Aller à la recherche
Fiche express
Domaine Fichiers spéciaux / périphériques
Commande mknod
Contexte Créer un fichier spécial : tube nommé (FIFO), périphérique bloc ou caractère
Voir aussi Mkfifo (raccourci dédié aux FIFO)

mknod crée un fichier spécial dans le système de fichiers : un tube nommé (FIFO), ou un fichier de périphérique bloc ou caractère. C'est la commande bas niveau derrière ces trois types de fichiers — pour le cas particulier du tube nommé, mkfifo est un raccourci plus lisible, strictement équivalent à mknod nom p.

Les trois types de fichiers spéciaux

  • p — tube nommé (FIFO, First In First Out). Aucun contenu sur le disque, sert de point de rendez-vous entre un écrivain et un lecteur.
  • b — périphérique en mode bloc (disques, partitions…), accès par blocs avec mise en cache.
  • c — périphérique en mode caractère (terminaux, /dev/null, /dev/random, ports série…), accès séquentiel octet par octet, sans cache.

Syntaxe

mknod NOM TYPE [MAJEUR MINEUR]

Le couple majeur/mineur n'a de sens que pour b et c : un tube nommé (p) n'en prend jamais, puisqu'il ne correspond à aucun pilote de périphérique. Autre différence pratique : créer un b ou un c exige les droits root (ou la capability CAP_MKNOD), alors que créer un p ne demande aucun privilège particulier — un simple utilisateur peut créer son propre tube nommé.

Périphériques bloc et caractère : majeur et mineur

Le majeur identifie le pilote (le type de périphérique : disque SCSI, terminal, port série…), le mineur identifie l'instance précise au sein de ce pilote (quel disque, quel port). La liste des pilotes chargés et de leurs majeurs s'obtient avec cat /proc/devices ; pour un périphérique déjà présent dans /dev, ls -l affiche directement son majeur et son mineur à la place de la taille :

ls -l /dev/sda1
# brw-rw---- 1 root disk 8, 1 ... /dev/sda1        (majeur 8, mineur 1)

Recréer ce même nœud à la main (par exemple dans un chroot, un conteneur minimal, ou après restauration d'une sauvegarde qui n'a pas préservé /dev) :

mknod /dev/sda1 b 8 1
mknod /dev/ttyUSB0 c 188 0

Sur un système moderne, udev/devtmpfs peuple et met à jour /dev automatiquement au fil des branchements/démarrages : mknod pour des périphériques bloc/caractère reste un outil de dernier recours (conteneurs, chroots, images de sauvegarde, exports NFS particuliers), pas un geste courant d'administration.

Créer un tube nommé (FIFO)

mknod monPipe p --mode 666

--mode fixe les permissions dès la création, ce qui évite un chmod séparé. Pour ce cas précis (un simple tube nommé, sans majeur/mineur), l'équivalent plus idiomatique est mkfifo monPipe (ou mkfifo -m 666 monPipe) — voir cette page pour le détail du comportement bloquant, SIGPIPE et d'autres exemples d'usage.

Exemple : un tube nommé entre deux compressions en parallèle

mknod monPipe p --mode 666

gzip < monPipe > toto.tgz &
gzip < monPipe > toto2.tgz &

cat file.txt > monPipe

Le tube nommé est ici créé, puis ouvert en lecture par deux processus gzip lancés en arrière-plan avant même qu'il y ait quoi que ce soit à lire — c'est nécessaire, car un tube reste bloquant tant qu'il n'a ni lecteur ni écrivain. Le cat final écrit ensuite le contenu de file.txt dans le tube.

Point important à ne pas manquer : un tube nommé n'est pas un mécanisme de diffusion (broadcast). Quand plusieurs processus le lisent en même temps, le noyau ne duplique pas les données vers chaque lecteur : chaque octet écrit est délivré une seule fois, au lecteur qui se présente en premier pour le lire. Avec deux gzip en lecture concurrente sur le même tube, le flux de file.txt se retrouve donc réparti de façon arbitraire entre les deux — chacun ne recevant qu'une partie imprévisible des données — et non recopié à l'identique dans les deux archives. Le résultat : toto.tgz et toto2.tgz contiennent chacun un fragment tronqué, pas une copie complète.

Pour obtenir deux copies identiques du même flux vers deux consommateurs, l'outil adapté est tee, pas un tube nommé partagé par plusieurs lecteurs :

cat file.txt | tee >(gzip > toto.tgz) >(gzip > toto2.tgz) > /dev/null

Un tube nommé garde son intérêt propre dès qu'il y a exactement un écrivain et un lecteur qui doivent se rencontrer via un chemin du système de fichiers (au lieu d'un pipe anonyme |, utilisable uniquement entre processus d'une même ligne de commande) — voir Mkfifo pour ce cas d'usage.

Nettoyage

Un fichier spécial créé par mknod reste sur le disque tant qu'il n'est pas supprimé explicitement, comme un fichier normal : rm monPipe.

Voir aussi

  • Mkfifo — raccourci dédié aux tubes nommés, avec les subtilités de blocage et de SIGPIPE