web-dev-qa-db-fra.com

uevent envoyé du noyau vers l'espace utilisateur (udev)

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:

  1. 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?)

  2. udev reçoit ces uevents uniquement via la socket netlink. C'est la seule façon pour udev de le faire. Est-ce correct?

  3. Quand uevent est envoyé depuis le noyau, je savais qu'il pouvait diffuser. Cependant, peut-il faire unicast?

Merci pour tout commentaire.

17
Sam
  1. 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/2­2/2­2: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 .

  2. 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

  3. 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 .

  4. 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:

  1. lib/kobject_uevent.c
  2. https://www.kernel.org/doc/pending/hotplug.txt - possède un programme d'espace utilisateur qui écoute les événements et l'imprime.
  3. https://bootlin.com/doc/legacy/udev/udev.pdf
36
Alexander Dzyoba