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

问题描述 投票:0回答:1

我知道udev在linux系统上运行,它通过netlink套接字接收从内核发送的uevents。

但是,我的问题是:

  1. 内核如何发送事件?它必须是通过添加/删除设备触发的,然后向 udev 发送事件。内核是如何做到这一点的? (有没有可以找到的代码示例?)

  2. udev 仅通过 netlink 套接字接收这些 uevent。这是 udev 执行此操作的唯一方法。这是正确的吗?

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

感谢您的任何反馈。

linux linux-kernel udev
1个回答
52
投票
  1. 它发送称为 uevent 的 netlink 消息。 uevent 只是通过 netlink 套接字发送的某种特殊格式的字符串。示例:

     "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
    

    实际发送 uevent 的内核函数是

    kobject_uevent_env
    ,它的包装器
    kobject_uevent
    在很多地方被称为

  2. 是的,udev 通过从 netlink 套接字接收 uevent 来工作。但有一个选项 - 内核可以调用用户模式助手。在这种情况下,内核为每个热插拔事件生成一个进程,为描述该特定热插拔事件的每个新进程提供环境变量。如果您查看

    kobject_uevent_env
    ,您会看到 netlink 消息 实际上是
    #ifdef
    'ed
    ,默认操作是调用该用户模式助手

  3. 理论上,netlink 消息可以是广播、多播和单播,但内核 通过 netlink_broadcast_filtered

     调用发送广播消息
    。无论如何,该消息会发送到
    NETLINK_KOBJECT_UEVENT
    系列的套接字。您可以在
    uevent_net_init
    中看到netlink套接字创建。

  4. 回答您的评论问题。您将不会在内核中看到任何

    send
    函数。
    send
    是一个系统调用 - 它是内核向用户空间提供的接口,但内核本身不使用任何系统调用。从 kobject_uevent_env 到最终发送,有一个很长的函数调用链(在 net/netlink/af_netlink.c
    net/core/dev.c
    中),不包含任何
    send
    - 在内核发送中skb(套接字缓冲区)类似于将缓冲区放入队列中,然后调用调度程序来传递该缓冲区并通知正在等待系统调用的用户空间
    recv

资源:

  1. lib/kobject_uevent.c
  2. https://www.kernel.org/doc/pending/hotplug.txt - 具有监听 uevent 并打印它的用户空间程序。
  3. https://bootlin.com/doc/legacy/udev/udev.pdf
© www.soinside.com 2019 - 2024. All rights reserved.