在Ubuntu16.04环境下实验:
今天看到linux2.6之后隔离策略和机制的一个方法,udev采用从netlink消息中获取创建设备信息,对于热插拔事件的设备,这个较容易理解,他们会在插拔时被系统检测到并发送netlink消息,但是冷插拔设备怎么做的,从书上看到一个实验,系统是会往sysfs中的uevent节点发送“add”从而导致内核发送netlink,这样就能获取设备信息,于是便手撸书上的代码:
#include <linux/netlink.h>
#include <linux/socket.h>
#include <string.h>
#include <stdlib.h>
#include <poll.h>
#include <sys/socket.h>
#include <sys/types.h>
static void die(char* s)
{
write(2, s, strlen(s));
exit(1);
}
int main(int argc, char *argv[])
{
struct sockaddr_nl nls;
struct pollfd pfd;
char buf[512];
memset(&nls, 0, sizeof(struct sockaddr_nl));
nls.nl_family = AF_NETLINK;
nls.nl_pid = getpid();
nls.nl_groups = -1;
pfd.events = POLLIN;
pfd.fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
if(pfd.fd == -1)
{
die("Not roo\n");
}
if(bind(pfd.fd, (void*)&nls, sizeof(struct sockaddr_nl)))
{
die("Bind failed\n");
}
while(-1 != poll(&pfd, 1, -1))
{
int i, len = recv(pfd.fd, buf, sizeof(buf), MSG_DONTWAIT);
if(len == -1)
{
die("recv\n");
}
i = 0;
while(i < len)
{
printf("%s\n", buf+i);
i += strlen(buf + i) + 1;
}
}
die("poll\n");
return 0;
}
然后切换到root用户,sudo su
运行编译的程序 gcc -o test_uevent test.c
./test_uevent
在root下给mouse设备发送一个add:
echo add > /sys/module/mousedev/uevent
结果果然在程序运行的控制台打印处理事件返回的消息:
ACTION=add
DEVPATH=/module/mousedev
SUBSYSTEM=module
SYNTH_UUID=0
SEQNUM=15204
libudev
����(
(
n
8��
ACTION=add
DEVPATH=/module/mousedev
SUBSYSTEM=module
SYNTH_UUID=0
SEQNUM=15204
USEC_INITIALIZED=1022767482345
中间的libudev有乱码,现在还不明白,后面慢慢了解了再来补充吧。
参考:
代码拷贝了《Linux设备驱动开放详解》宋宝华 中的第5章117页