我知道udev在linux系统上播放,它接收通过netlink socket从内核发送的uevent。
但是,我的问题是:
内核如何发送事件?它必须是通过添加/删除设备触发的内容,然后将事件发送到udev。内核如何做到这一点? (我能找到任何代码示例吗?)
udev仅通过netlink套接字接收这些uevent。这是udev做到的唯一方法。这是对的吗?
当uevent从内核发出时,我知道它可以进行广播。但是,它可以单播吗?
感谢您的反馈。
答案 0 :(得分:34)
它发送名为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
称为in many places。
是的,udev通过从netlink socket接收uevent来工作。但是有一个选项 - 内核可以调用usermode helper。在这种情况下,内核会为每个hotplug事件生成一个进程,为每个描述该特定hotplug事件的新进程提供环境变量。如果您查看kobject_uevent_env
,您会看到netlink消息is actually #ifdef
'ed,默认操作是调用该用户模式助手
理论上,netlink消息可以是广播,多播和单播,但内核sends broadcast message可以调用netlink_broadcast_filtered
。无论如何,该消息转到NETLINK_KOBJECT_UEVENT
家庭的套接字。您可以在uevent_net_init
中看到netlink套接字创建。
回答您的评论问题。你不会在内核中看到任何send
函数。 send
是一个系统调用 - 它是内核提供给用户空间的接口,但内核本身不使用任何系统调用。在内核发送skb(套接字缓冲区)中,有一长串函数调用(net/netlink/af_netlink.c和net/core/dev.c)从kobject_uevent_env
到最终发送,不包含任何send
)就像在队列中放置缓冲区然后调用调度程序来传递缓冲区并通知正在等待系统调用的用户空间recv
资源: