Dans Installing Basic System Software, nous avons installé le paquet Udev comme composant de systemd. Avant d'entrer 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.
Traditionnellement, les systèmes Linux utilisaient une méthode de
création de périphériques statiques avec laquelle un grand nombre
de nœuds de périphériques étaient créés sous /dev
(quelques fois littéralement des milliers
de nœuds), que le matériel correspondant existait ou non. Ceci
était fait le plus souvent 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 février 2000, un nouveau système de fichiers appelé
devfs
, qui créait dynamiquement
des nœuds de périphérique lorsque des périphériques étaient
trouvés par le noyau, 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 les sources du noyau, cette méthode de création
dynamique des périphériques 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 non imposée par quelque développeur. Le système de
fichiers devfs
souffrait aussi de
restrictions particulières inhérentes à sa conception et qui ne
pouvaient être corrigées sans une revue importante du noyau. Il a
aussi été marqué comme obsolète avec la publication de la série
2.6 et supprimé complètement avec la version 2.6.18.
Avec le développement de la branche instable 2.5 du noyau, sortie
ensuite avec 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. Les pilotes qui sont
compilés dans le noyau enregistrent directement leurs objets avec
sysfs
lorsqu'ils sont détectés
par le noyau. Pour les pilotes compilés en modules, cette
enregistrement a lieu au chargement du module. Une fois que le
système de fichiers sysfs
est
monté (sur /sys
), les données
enregistrés par les pilotes avec sysfs
sont visibles pour les processus en
espace utilisateur. Avec cette représentation visible en espace
utilisateur, la possibilité de développer un remplacement en
espace utilisateur de devfs
est
devenu beaucoup plus réaliste.
Peu de temps après l'introduction de sysfs
, le travail a commencé sur un programme
appelé Udev pour en profiter. Le démon udev appelait mknod()
pour créer des nœuds de périphériques
dans /dev
dynamiquement, en
fonction des informations de sysfs
dans /sys
. Par exemple, /sys/class/tty/vcs/dev
contient la chaîne
« 7:0 ». Cette chaîne était utilisée par
udev pour créer un
nœud de périphérique avec le nombre majeur 7 et mineur 0.
Le noyau 2.6.32 a introduit un nouveau système de fichiers
virtuel nommé devtmpfs
, une
version améliorée de devfs
. Cela
permet aux nœuds de périphériques une fois de plus d'être créés
dynamiquement par le noyau, sans les nombreux problèmes de
devfs
. Dans sa version 176, Udev
ne crée plus lui-même les nœuds de périphériques, et délègue
plutôt la tâche à devtmpfs
.
En 2010, le développement de systemd a démarré, une implémentation alternative d'init. À partir d'Udev 183, l'arborescence des sources d'Udev a été fusionnée avec celle de systemd. Plusieurs développeurs de Gentoo qui n'étaient pas d'accord avec cette fusion ont annoncés un fork du projet appelé Eudev en décembre 2012, créé en extrayant le code d'Udev de systemd. Un des but d'Eudev est de permettre une meilleure installation et utilisation de udevd sans avoir besoin du reste de systemd.
Par défaut, les nœuds de périphériques créés par le noyau dans un
devtmpfs
appartiennent à
root:root et ont les
permissions 600.
udevd peut modifier
l'appartenance et les permissions des nœuds dans le répertoire
/dev
et peut aussi créer des liens
supplémentaires, en fonction de règles spécifiées dans les fichiers
de /etc/udev/rules.d
, /lib/udev/rules.d
et /run/udev/rules.d
. Les noms de ces fichiers
commencent par un nombre, pour indiquer l'ordre dans lequel ils
doivent être lancés, et ils ont une extension .rules
(udevd ignorera les fichiers avec
une autre extension). Tous ces fichiers de règles de ces
répertoires sont combinés en une liste unique, triés par nom de
fichiers, et lancés dans cette ordre. En cas de conflit, où un
fichier de règle avec le même nom existe dans deux ou plus de ces
répertoires, les règles dans /etc
sont prioritaires, puis les fichiers de règles dans /run
et enfin /lib
.
Tout périphérique pour qui une règle est introuvable sera
simplement ignoré par udevd et laissé avec les valeurs
par défaut définies par le noyau, comme décrit ci-dessus. Pour plus
de détails sur l'écriture de règles Udev, voir /usr/share/doc/systemd-233/udev.html
.
Les pilotes de périphériques compilés en tant que modules peuvent
avoir des alias. Les alias sont visibles dans la sortie du
programme modinfo et
sont souvent liés aux identifiants de bus des périphériques
supportés par un module. Par exemple, le pilote snd-fm801 supporte les périphériques PCI
avec l'ID de fabricant 0x1319 et l'ID de matériel 0x0801, et a un
alias de « pci:v00001319d00000801sv*sd*bc05sc01i* ».
Pour la plupart des périphériques, le pilote de bus exporte l'alias
d'un pilote que pourrait gérer le périphérique via sysfs
. Par exemple, le fichier /sys/bus/pci/devices/0000:00:0d.0/modalias
contient la chaîne « pci:v00001319d00000801sv00001319sd00001319bc04sc01i00 ».
Les règles par défaut fournies par Udev font qu'udevd appellera /sbin/modprobe avec le contenu de
la variable d'environnemnt MODALIAS
d'uevent (qui devrait contenir la même chose que le fichier
modalias
dans sysfs), ce qui fait
qu'il chargera les modules dont les alias correspondent à cette
chaîne après l'expansion de l'astérisque.
Dans cet exemple, cela signifie que, en plus de snd-fm801, le pilote obsolète (et indésirable) forte sera chargé s'il est disponible. Voyez plus bas pour des manières d'éviter le chargement de modules indésirables.
Le noyau lui-même peut charger des modules pour les protocoles réseau, les systèmes de fichiers et le support NLS à la demande.
Il y peut y avoir quelques problèmes concernant la création de périphériques automatique.
Udev ne chargera un module que s'il a un alias spécifique au bus
et que le pilote de bus exporte correctement les alias
nécessaires dans sysfs
. Si ce
n'est pas le cas, on peut charger les modules autrement. Avec
Linux-4.9.21, Udev est connu pour charger les pilotes bien écrits
pour les périphériques INPUT, IDE, PCI, SCSI, SERIO et FireWire.
Pour déterminer si un pilote de périphérique dont vous avez
besoin a le support nécessaire pour Udev, lancez modinfo avec le nom du module
en argument. Maintenant essayez de trouver le répertoire du
périphérique dans /sys/bus
et
vérifiez s'il y a un fichier modalias
.
Si le fichier modalias
existe dans
sysfs
, que le pilote support le
périphérique et peut lui parler directement, mais n'a pas
l'alias, c'est un bogue du pilote. Chargez le pilote sans l'aide
d'Udev et attendez que le problème soit corrigé.
S'il n'y a pas de fichier modalias
dans le répertoire pertinent de /sys/bus
, cela signifie que les développeurs du
noyau n'ont pas encore ajouté le support de modalias dans ce type
de bus. Avec Linux-4.9.21, cela est le cas pour les bus ISA.
Attendez que le problème soit corrigé dans une future version du
noyau.
Udev n'est pas prévu pour charger des pilotes « enveloppes » comme snd-pcm-oss et les pilotes pour des périphériques virtuels comme loop.
Si le module « enveloppe » ne fait qu'améliorer les
fonctionnalités fournies par d'autres modules (par exemple
snd-pcm-oss améliore les
fonctionnalités de snd-pcm
en rendant les cartes sons compatibles avec les applications
OSS), configurez modprobe pour charger
l'enveloppe après qu'Udev charge le module enveloppé. Pour cela,
ajoutez une ligne « install » dans un fichier dans
/etc/modprobe.d
. Par exemple :
install snd-pcm /sbin/modprobe -i snd-pcm ; \
/sbin/modprobe snd-pcm-oss ; true
Si le module en question n'est pas une enveloppe et est utilisé
seul, configurez le script de démarrage S05modules pour charger ce
module au démarrage du système. Pour cela, ajoutez le nom du
module dans le fichier /etc/sysconfig/modules
sur une ligne séparée.
Cela fonctionne pour les modules enveloppes aussi, mais est
sous-optimal pour ce cas.
La solution est soit de ne pas construire le module, soit de le
blacklister dans /etc/modprobe.d
comme pour le module forte
dans l'exemple suivant :
blacklist forte
Les modules blacklistés peuvent toujours être chargés manuellement avec la commande modprobe explicite.
Cela arrive en général si une règle correspond à un appareil inattendu. Par exemple, une règle mal écrite peut correspondre à un disque SCSI (comme voulu) et au périphérique SCSI générique correspondant (incorrectement) par fabriquant. Trouvez la règle incriminée et rendez-la plus spécifique, à l'aide de udevadm info.
Cela peut être une autre manifestation du problème précédent.
Sinon, si vos règles utilisent les attributs sysfs
, cela peut venir d'un problème de
timing dans le noyau, qui sera corrigé plus tard. Pour l'instant,
vous pouvez contourner le problème en créant une règle qui attend
l'attribut sysfs
utilisé et
l'ajouter au fichier /etc/udev/rules.d/10-wait_for_sysfs.rules
.
Veuillez notifier la liste de développement CLFS si cela vous a
aidé.
Cela est dû au fait que Udev, par conception, gère les uevents et charge les modules en parallèle, et donc dans un ordre imprédictible. Cela ne sera jamais « corrigé ». Vous ne devriez pas vous fier à la stabilité des noms des périphériques du noyau. Créez plutôt vos propres règles qui créent des liens symboliques avec des noms stables basés sur des attributs stable du périphérique, comme un numéro de série ou la sortie des divers utilitaires *_id installés par Udev. Voyez Section 11.6, « Création de liens symboliques personnalisés vers les appareils » et Networking Configuration pour des exemples.
De la documentation utile supplémentaire est disponible sur les sites suivants :
Une implémentation en espace utilisateur de devfs
http://www.kroah.com/linux/talks/ols_2003_udev_paper/Reprint-Kroah-Hartman-OLS2003.pdf
Le système de fichier sysfs
http://www.kernel.org/pub/linux/kernel/people/mochel/doc/papers/ols-2005/mochel.pdf