Je savais que udev joue sur le système linux et qu'il reçoit les uevents envoyés depuis le noyau via la socket netlink.
Cependant, mes questions sont:
Comment le noyau envoie l'événement? Cela doit être déclenché par l'ajout/la suppression de périphérique, puis envoie des événements à udev. Comment le noyau fait-il cela? (Puis-je trouver un exemple de code?)
udev reçoit ces uevents uniquement via la socket netlink. C'est la seule façon pour udev de le faire. Est-ce correct?
Quand uevent est envoyé depuis le noyau, je savais qu'il pouvait diffuser. Cependant, peut-il faire unicast?
Merci pour tout commentaire.
Il envoie un message netlink appelé uevent. uevent est juste une chaîne d'un format spécial qui est envoyée via une socket netlink. Exemple:
"add@/class/input/input9/mouse2\0 // message
ACTION=add\0 // action type
DEVPATH=/class/input/input9/mouse2\0 // path in /sys
SUBSYSTEM=input\0 // subsystem (class)
SEQNUM=1064\0 // sequence number
PHYSDEVPATH=/devices/pci0000:00/0000:00:1d.1/usb2/22/22:1.0\0 // device path in /sys
PHYSDEVBUS=usb\0 // bus
PHYSDEVDRIVER=usbhid\0 // driver
MAJOR=13\0 // major number
MINOR=34\0", // minor number
La fonction du noyau qui envoie réellement uevent est kobject_uevent_env
et son enveloppe kobject_uevent
qui s'appelle dans de nombreux endroits .
Oui, udev fonctionne en recevant les uevents de la socket netlink. Mais il y a une option - le noyau peut appeler helper en mode utilisateur. Dans ce cas, le noyau génère un processus par événement hotplug, fournissant des variables d'environnement à chaque nouveau processus décrivant cet événement hotplug particulier. Si vous regardez kobject_uevent_env
vous verrez ce message netlink est en fait #ifdef
'ed et l'action par défaut consiste à appeler cet assistant de mode utilisateur
En théorie, les messages netlink peuvent être diffusés, en multidiffusion et en monodiffusion, mais le noyau envoie un message de diffusion avec netlink_broadcast_filtered
appel. Quoi qu'il en soit, ce message va à la socket de NETLINK_KOBJECT_UEVENT
famille. Vous pouvez voir la création de socket netlink dans uevent_net_init
.
Répondre à votre question de commentaire. Vous ne verrez aucune fonction send
dans le noyau. send
est un appel système - c'est l'interface que le noyau fournit à l'espace utilisateur, mais le noyau lui-même n'utilise aucun appel système. Il y a une longue chaîne d'appels de fonctions (dans net/netlink/af_netlink.c et net/core/dev.c ) de kobject_uevent_env
à l'envoi final qui ne contient pas send
- dans le noyau, l'envoi skb (socket buffer) est quelque chose comme placer le tampon dans la file d'attente puis appeler le planificateur pour délivrer ce tampon et notifier l'espace utilisateur qui attend syscall recv
Ressources: