uevent从内核发送到用户空间(udev)

Sam*_*Sam 18 linux udev linux-kernel

我知道udev在linux系统上播放,它接收通过netlink socket从内核发送的uevent.

但是,我的问题是:

  1. 内核如何发送事件?它必须是通过添加/删除设备触发的内容,然后将事件发送到udev.内核如何做到这一点?(我能找到任何代码示例吗?)

  2. udev只通过netlink socket接收这些uevent.这是udev做到的唯一方法.它是否正确?

  3. 当uevent从内核发出时,我知道它可以进行广播.但是,它可以做单播吗?

感谢您的任何反馈.

Ale*_*oba 38

  1. 它发送名为uevent的netlink消息.uevent只是通过netlink socket发送的一些特殊格式的字符串.例:

    "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
    
    Run Code Online (Sandbox Code Playgroud)

    实际发送uevent的内核函数是kobject_uevent_env在许多地方kobject_uevent调用的包装器.

  2. 是的,udev通过从netlink socket接收uevent来工作.但是有一个选项 - 内核可以调用usermode helper.在这种情况下,内核会为每个hotplug事件生成一个进程,为每个描述该特定hotplug事件的新进程提供环境变量.如果您看一下,kobject_uevent_env您将看到netlink消息实际上是#ifdef'ed,默认操作是调用该usermode帮助器

  3. 在理论上的netlink消息可以被广播,多播和单播,但内核发送广播消息netlink_broadcast_filtered呼叫.无论如何,该消息进入NETLINK_KOBJECT_UEVENT家庭的插座.你可以看到netlink socket创建uevent_net_init.

  4. 回答你的评论问题.你不会send在内核中看到任何函数.send是一个系统调用 - 它是内核提供给用户空间的接口,但内核本身不使用任何系统调用.有一长串函数调用(在net/netlink/af_netlink.cnet/core/dev.c中)从kobject_uevent_env最终发送到不包含任何send- 在内核中发送skb(套接字缓冲区)就像放置缓冲区在队列中然后调用调度程序来传递该缓冲区并通知正在syscall上等待的用户空间recv

资源:

  1. LIB/kobject_uevent.c
  2. https://www.kernel.org/doc/pending/hotplug.txt - 具有监听uevents并打印它的用户空间程序.
  3. https://bootlin.com/doc/legacy/udev/udev.pdf

  • 感谢您的回复。你介意回答我在评论中添加的另一个问题吗? (2认同)
  • 更新了评论问题的答案。 (2认同)