Dans Installing Basic System Software, nous avons installé le paquet Udev. Avant d'aller dans les détails concernant son fonctionnement, un bref historique des méthodes précédentes de gestion des périphériques est nécessaire.
Les systèmes Linux en général utilisent traditionnellement une
méthode de création de périphériques statiques avec laquelle un grand
nombre de nœuds périphériques est créé sous /dev
(quelque fois des milliers de nœuds),
que le matériel correspondant existe ou pas. Ceci se fait typiquement
avec un script MAKEDEV,
qui contient des appels au programme mknod avec les numéros de
périphériques majeurs et mineurs pour chaque périphérique possible
qui pourrait exister dans le monde.
En utilisant la méthode udev, seuls les périphériques détectés par le
noyau obtiennent des nœuds périphériques créés pour eux. Comme
ces nœuds périphériques seront créés à chaque lancement du
système, ils seront stockés dans un tmpfs
(un système de fichiers qui réside
entièrement en mémoire). Les nœuds périphériques ne requièrent
pas beaucoup d'espace disque, donc la mémoire utilisée est
négligeable.
En février 2000, un nouveau système de fichiers appelé devfs
a été intégré au noyau 2.3.46 et rendu
disponible pour la série 2.4 des noyaux stables. Bien qu'il soit
présent dans le source du noyau, cette méthode de création
dynamique de périphérique n'a jamais reçu un support inconditionnel
des développeurs du noyau.
Le principal problème de l'approche adopté par devfs
était la façon dont il gérait la
détection, la création et le nommage des périphériques. Ce dernier
problème, le nommage des périphériques, était peut-être le plus
critique. Il est généralement accepté que s'il est possible de
configurer les noms des périphériques, alors la politique de
nommage des périphériques revient à l'administrateur du système, et
du coup n'est pas imposée par un ou des développeur(s) en
particulier. Le système de fichiers devfs
souffre aussi de conditions particulières
inhérentes à son concept et ne peut pas être corrigé sans une revue
importante du noyau. Il a aussi été marqué comme obsolète à cause
d'un manque de maintenance.
Avec le développement du noyau instable 2.5, sorti ensuite en tant
que la série 2.6 des noyaux stables, un nouveau système de fichiers
virtuel appelé sysfs
est arrivé. Le
rôle de sysfs
est d'exporter une
vue de la configuration matérielle du système pour les processus en
espace utilisateur. Avec cette représentation visible de l'espace
utilisateur, la possibilité de voir un remplacement de l'espace
utilisateur pour devfs
est devenu
beaucoup plus réaliste.
Le système de fichier sysfs
. On
pourrait se demander comment sysfs
connaît les périphériques présents sur
un système et quels numéros de périphériques devraient être
utilisés. Les pilotes qui ont été compilés directement dans le
noyau enregistrent leur objet avec sysfs
quand ils sont détectés par le noyau.
Pour les pilotes compilés en tant que modules, cet enregistrement
surviendra quand le module sera chargé. Une fois que le système
de fichier sysfs
est monté (sur
/sys
), les données enregistrées par
les pilotes internes avec sysfs
sont disponibles pour les processus en espace utilisateur ainsi
qu'à udev pour la
création des nœuds périphériques.
Le script de démarrage S10udev s'occupe de créer les
nœuds périphériques au lancement de Linux. Le script
supprime la gestion des uevents de /sbin/hotplug par défaut. On
fait cela car le noyau n'a plus besoin de faire appel à un
binaire externe. À la place, udevd écoutera sur une socket
netlink les uevents que le noyau fait apparaître. Puis, le script
de démarrage copie les nœuds des périphériques statiques
qui existent dans /lib/udev/devices
vers /dev
. Cela est nécessaire car
certains périphériques, répertoires et liens symboliques sont
requis avant que les processus de gestion du périphérique
dynamique ne soient disponibles pendant les premières étapes du
démarrage d'un système. La création des nœuds statiques
dans /lib/udev/devices
fournit
aussi un environnement de travail facile pour les périphériques
qui ne sont pas supportés par l'infrastructure de gestion des
périphériques en dynamique. Ensuite le script de démarrage lance
le démon Udev, udevd, qui agira sur tous les
uevents qu'il reçoit. Enfin, le script de démarrage oblige le
noyau à répéter des uevents pour chaque périphérique qui a été
déjà enregistré puis attend que udevd les gère.
Pour obtenir le bon nombre majeur ou mineur d'un périphérique,
Udev s'appuie sur les informations fournies par sysfs
dans /sys
. Par exemple, /sys/class/tty/vcs/dev
contient la chaîne
“7:0”. Cette chaîne est
utilisée par udevd
7 et un nombre mineur
0. Les noms et les droits
des nœuds sous le répertoire /dev
sont déterminés par des règles spécifiées
dans des fichiers à l'intérieur du répertoire /etc/udev/rules.d/
. Celles-ci sont numérotées
d'une façon similaire au paquet CLFS-Bootscripts. Si udevd ne peut trouver une règle
pour le périphérique qu'il est en train de créer, il attribuera
par défaut des droits 660
et la propriété à root:root. La documentation sur la
syntaxe des fichiers de configuration des règles Udev est
disponible dans /usr/share/doc/udev/writing_udev_rules/index.html
Il se peut que les pilotes des périphériques compilés en module
aient des aliases compilés en eux. Les aliases sont visibles dans
la sortie du programme modinfo et sont souvent liés
aux identifiants spécifiques au bus des périphériques supportés
par un module. Par exemple, le pilote snd-fm801 supporte les périphériques
PCI ayant l'ID fabricant 0x1319 et l'ID de périphérique 0x0801,
et il a un alias qui est “pci:v00001319d00000801sv*sd*bc04sc01i*”.
Pour la plupart des périphériques, le pilote du bus définit
l'alias du pilote qui gérerait le périphérique via sysfs
. Par exemple, le fichier /sys/bus/pci/devices/0000:00:0d.0/modalias
pourrait contenir la chaîne “pci:v00001319d00000801sv00001319sd00001319bc04sc01i00”.
Il résultera des règles par défaut fournies avec Udev que
udevd fera appel à
/sbin/modprobe avec
le contenu de la variable d'environnement de l'uevent
MODALIAS
(qui devrait être la même que
le contenu du fichier modalias
dans
sysfs), donc chargera tous les modules dont les alias
correspondent à cette chaîne après les expansions génériques.
Dans cet exemple, cela signifie que, outre snd-fm801, le pilote forte obsolète (et non désiré) sera chargé s'il est disponible. Voir ci-dessous les moyens d'empêcher le chargement des modules indésirables.
Le noyau lui-même est aussi capable de charger des modules de protocole réseau, de support pour des systèmes de fichiers et des NLS sur demande.
Quand vous connectez un périphérique, comme un lecteur MP3 USB (Universal Serial Bus), le noyau reconnaît que le périphérique est maintenant connecté et génère un uevent. Cet uevent est alors géré par udevd comme décrit ci-dessus.
Il existe quelques problèmes connus pour la création automatique des nœuds périphériques :
Udev ne chargera un module que s'il a un alias spécifique au bus
et si le pilote du bus envoie correctement les alias nécessaires
vers sysfs
. Sinon, il faut
organiser le chargement de modules par d'autres moyens. Avec
Linux-3.4.17, Udev est connu pour charger les pilotes
correctement écrits pour les périphériques INPUT, IDE, PCI, USB,
SCSI, SERIO et FireWire.
Pour déterminer si le pilote du périphérique dont vous avez
besoin a le support nécessaire pour Udev, lancez modinfo avec le nom du module
comme argument. Puis, essayez de localiser le répertoire du
périphérique sous /sys/bus
et
vérifiez s'il y a un fichier modalias
là-bas.
Si le fichier modalias
existe dans
sysfs
, alors le pilote supporte
le périphérique et peut lui parler directement, mais s'il n'a pas
d'alias, c'est un bogue dans le pilote. Chargez le pilote sans
l'aide d'Udev et attendez que le problème soit corrigé plus tard.
S'il n'y a pas de fichier modalias
dans le bon répertoire sous /sys/bus
, cela signifie que les développeurs du
noyau n'ont pas encore ajouté de support modalias à ce type de
bus. Avec Linux-3.4.17, c'est le cas pour les bus ISA. Attendez
que ce problème soit réparé dans les versions ultérieures du
noyau.
Udev n'a pas du tout pour but de charger des pilotes “wrappers” (qui emballent un autre pilote) comme snd-pcm-oss et des pilotes non matériels comme loop.
Si le module “wrapper”
n'améliore que la fonctionnalité fournie par un autre module
(comme snd-pcm-oss
améliore la fonctionnalité de snd-pcm en rendant les cartes son
disponibles pour les applications OSS), configurez la commande
modprobe pour
charger le wrapper après qu'Udev ait chargé le module emballé.
Pour cela, ajoutez une ligne “install” dans /etc/modprobe.conf
. Par exemple :
install snd-pcm /sbin/modprobe -i snd-pcm ; \
/sbin/modprobe snd-pcm-oss ; true
Si le module en question n'est pas un emballage et s'avère utile
en tant que tel, configurez le script de démarrage S05modules pour charger ce
module sur le système de démarrage. Pour cela, ajoutez le nom du
module au fichier /etc/sysconfig/modules
sur une ligne séparée.
Cela fonctionne aussi pour les modules emballage, mais ce n'est
pas optimal dans ce cas.
Ne compilez pas le module, ou mettez-le en liste noire dans le
fichier /etc/modprobe.conf
comme
cela est fait avec le module forte dans l'exemple ci-dessous :
blacklist forte
Les modules en liste noire peuvent toujours être chargés manuellement avec la commande explicite modprobe.
Cela se produit habituellement si une règle correspond à un périphérique de façon imprévue. Par exemple, une règle écrite avec des lacunes peut correspondre à un disque SCSI (comme désiré) et au périphérique générique SCSI correspondant (de façon incorrecte) du fabricant. Trouvez la règle défectueuse et rendez-la plus précise à l'aide de udevadm info.
Cela peut être une autre manifestation du problème précédent.
Sinon, et si votre règle utilise les attributs de sysfs
, il se peut que ce soit un problème de
timing du noyau, sur le point d'être corrigé dans les noyaux
ultérieurs. Pour le moment, vous pouvez contourner en créant une
règle qui attend l'attribut sysfs
utilisé et en la mettant dans le fichier /etc/udev/rules.d/10-wait_for_sysfs.rules
.
Merci d'informer la liste de développement de CLFS si vous faites
ainsi et que cela vous aide.
Le texte ci-après assume que le pilote est compilé de manière statique dans le noyau ou qu'il est déjà chargé comme module, et que vous avez déjà vérifié qu'Udev ne crée pas de périphérique mal nommé.
Udev n'a pas besoin d'information pour créer un nœud
périphérique si le pilote du noyau n'envoie pas ses données vers
sysfs
. C'est ce qu'il y a de plus
courant avec les pilotes de tierces parties à l'extérieur de
l'arborescence du noyau. Créez un nœud de périphérique
statique dans /lib/udev/devices
avec les numéros majeurs/mineurs appropriés (voir le fichier
devices.txt
dans la documentation
du noyau ou la documentation fournie par le fabricant du pilote
tierce partie). Le nœud du périphérique statique sera copié
vers /dev
par le script de
démarrage S10udev.
Cela est dû au fait que Udev, par nature, gère les uevents et charge les modules en parallèle, donc dans un ordre imprévisible. Cela ne sera jamais “corrigé”. Vous ne devriez pas espérer que les noms des périphériques du noyau sont stables. Créez plutôt vos propres règles qui rendent les liens symboliques stables basés sur des attributs stables du périphérique, comme une série de nombre ou la sortie de divers utilitaires *_id installés par Udev. Voir Section 11.7, “Création de liens symboliques personnalisés vers les périphériques” et Networking Configuration pour des exemples.
Des documentations supplémentaires sont disponibles sur les sites suivants :
The sysfs
Filesystem
http://www.kernel.org/pub/linux/kernel/people/mochel/doc/papers/ols-2005/mochel.pdf
(NdT : Le système de fichier sysfs
)