uevent & netlink(KOBJECT_UEVENT)

uevent通过netlink socket向用户进程传递消息,应用于接收组播。在用户空间,uevent处理位于libcutils.so中;在内核中,uevent的实现包括uevent_net_init用于创建socket,kobject_uevent和kobject_uevent_env负责发送uevent到用户空间,netlink_broadcast_filtered广播netlink消息,用户空间程序由call_usermodehelper_setup和call_usermodehelper_exec调用来处理uevent消息。
摘要由CSDN通过智能技术生成
uevent

/android/system/core/libcutils/uevent.c
uevent 是通过netlink socket发送消息给用户进程,这里的应用单纯接收组播消息。

android/system/extras/tests/uevents

 ./uevents                                     
change@/devices/platform/disp ACTION=change DEVPATH=/devices/platform/disp SUBSYSTEM=platform VSYNC0=73280292536 DRIVER=disp MODALIAS=platform:disp SEQNUM=5044 
change@/devices/platform/disp ACTION=change DEVPATH=/devices/platform/disp SUBSYSTEM=platform VSYNC0=73297201120 DRIVER=disp MODALIAS=platform:disp SEQNUM=5045 
change@/devices/platform/disp ACTION=change DEVPATH=/devices/platform/disp SUBSYSTEM=platform VSYNC0=73314112620 DRIVER=disp MODALIAS=platform:disp SEQNUM=5046 
change@/devices/platform/disp ACTION=change DEVPATH=/devices/platform/disp SUBSYSTEM=platform VSYNC0=73331023036 DRIVER=disp MODALIAS=platform:disp SEQNUM=5047 
change@/devices/platform/disp ACTION=change DEVPATH=/devices/platform/disp SUBSYSTEM=platform VSYNC0=73347935120 DRIVER=disp MODALIAS=platform:disp SEQNUM=5048 
change@/devices/platform/disp ACTION=change DEVPATH=/devices/platform/disp SUBSYSTEM=platform VSYNC0=73364849703 DRIVER=disp MODALIAS=platform:disp SEQNUM=5049 
change@/devices/platform/disp ACTION=change DEVPATH=/devices/platform/disp SUBSYSTEM=platform VSYNC0=73381759411 DRIVER=disp MODALIAS=platform:disp SEQNUM=5050 
change@/devices/platform/disp ACTION=change DEVPATH=/devices/platform/disp SUBSYSTEM=platform VSYNC0=73398670578 DRIVER=disp MODALIAS=platform:disp SEQNUM=5051 
change@/devices/platform/disp ACTION=change DEVPATH=/devices/platform/disp SUBSYSTEM=platform VSYNC0=73415581370 DRIVER=disp MODALIAS=platform:disp SEQNUM=505
enum kobject_action {
   
    KOBJ_ADD,
    KOBJ_REMOVE,
    KOBJ_CHANGE,
    KOBJ_MOVE,                    //更改了目录结构。
    KOBJ_ONLINE,                  //设备上线/下线事件,常表示使能或者去使能。
    KOBJ_OFFLINE,
    KOBJ_MAX
};

static const char *kobject_actions[] = {
   
    [KOBJ_ADD] =        "add",
    [KOBJ_REMOVE] =        "remove",
    [KOBJ_CHANGE] =        "change",
    [KOBJ_MOVE] =        "move",
    [KOBJ_ONLINE] =        "online",
    [KOBJ_OFFLINE] =    "offline",
};
用户空间 libcutils.so

./core/libcutils/uevent.c
打开 uevent socket

//netlink socket
int uevent_open_socket(int buf_sz, bool passcred)
{
   
    struct sockaddr_nl addr;
    int on = passcred;
    int s;

    memset(&addr, 0, sizeof(addr));
    addr.nl_family = AF_NETLINK;  
    addr.nl_pid = getpid();
    //可以接收所有的family消息 , 单播设置0
    addr.nl_groups = 0xffffffff;
//地址族(Address Family) PF_NETLINK
//协议号NETLINK_KOBJECT_UEVENT
//数据传输方式/socket类型 SOCK_DGRAM | SOCK_CLOEXEC
    s = socket(PF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_KOBJECT_UEVENT);
    if(s < 0)
        return -1;

    setsockopt(s, SOL_SOCKET, SO_RCVBUFFORCE, &buf_sz, sizeof(buf_sz));
  //SO_PEERCRED 远端的资格
    setsockopt(s, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on));

    if(bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
   
        close(s);
        return -1;
    }

    return s;
}
/**
 * Like recv(), but checks that messages actually originate from the kernel.
 */
ssize_t uevent_kernel_multicast_recv(int socket, void *buffer, size_t length)
{
   
    uid_t uid = -1;
    return uevent_kernel_multicast_uid_recv(socket, buffer, length, &uid);
}

/**
 * Like the above, but passes a uid_t in by pointer. In the event that this
 * fails due to a bad uid check, the uid_t will be set to the uid of the
 * socket's peer.
 *
 * If this method rejects a netlink message from outside the kernel, it
 * returns -1, sets errno to EIO, and sets "user" to the UID associated with the
 * message. If the peer UID cannot be determined, "user" is set to -1."
 */
ssize_t uevent_kernel_multicast_uid_recv(int socket, void *buffer, size_t length
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值