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 virtuel 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
pour créer un nœud de périphérique avec un nombre majeur
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és 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-124/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-2.6.24.7, 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-2.6.24.7, 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.
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.12, “Création de liens symboliques personnalisés vers les périphériques” et Section 11.13, “Configurer le script network” pour des exemples.
Des documentations supplémentaires sont disponibles sur les sites suivants :
A Userspace Implementation of devfs
http://www.kroah.com/linux/talks/ols_2003_udev_paper/Reprint-Kroah-Hartman-OLS2003.pdf
(NdT : Une implémentation en espace utilisateur de devfs)
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
)