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

我知道udev在linux系统上播放,它通过netlink socket接收内核发来的uevents。

不过,我的问题是:

  1. 内核如何发送事件? 它必须是由添加/删除设备触发的事件,然后发送事件给udev。 内核如何做到这一点? (有没有我能find的代码示例?)

  2. udev只通过netlink套接字接收这些事件。 这是udev做的唯一方法。 它是否正确?

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

感谢您的任何反馈。

Solutions Collecting From Web of "uevent从内核发送到用户空间(udev)"

  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/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 

    实际上发送uevent的内核函数是kobject_uevent_env ,它是在很多地方调用的包装函数kobject_uevent_env

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

  3. 理论上,netlink消息可以是广播,多播和单播,但内核使用netlink_broadcast_filtered调用发送广播消息 。 无论如何,该消息去NETLINK_KOBJECT_UEVENT家庭的套接字。 你可以在uevent_net_init看到netlink套接字的创建。

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

资源:

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