ueventd
⚬ ueventd creates and 'poll' netlink socket.
ueventd_main [init/ueventd.c]
⚬ read kernel event message -> parse -> handle
handle_device_event [init/devices.c]
-> device_changed [init/init.c]
-> queue_device_triggers [init/init_parser.c]
|
+---------------+
|
v
: search action list to know what to do for this event.
searching action which name is device-added/removed-[device node].
[device node] is from 'DEVPATH' variable of uevent message.
⚬ action list : list declared at [init_parser.c]
• builtin action (added by 'queue_builtin_action [init/init_parser.c]')
ex. property_init, wait_for_coldboot_done etc.
• from script (added by 'parse_action [init/init_parser.c]')
section "on device-added-[device path] / on device-removed-[device path]"
ex.
[init.rc]
on device-added-/dev/block/mmcblk0p18
exec /system/bin/sh /system/bin/hello_mmc.sh
⚫ other daemons (ex usbd)
⚬ create and 'poll' netlink socket.
The following code below in the device driver sends a UEVENT to the
udev to create nodes.
/* seend uevents to udev, so it'll create the /dev node*/
class_device_create(memory_class, NULL, dev_num, NULL, "memory%d", 1);
Sample Code for capturing the UEVENTS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <linux/types.h>
#include <linux/netlink.h>
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];
// Open hotplug event netlink socket
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 root\n");
// Listen to netlink socket
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");
// Print the data to stdout.
i = 0;
while (i<len) {
printf("%s\n", buf+i);
i += strlen(buf+i)+1;
}
}
die("poll\n");
// Dear gcc: shut up.
return 0;
}
Print from the above code:
add@/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1
ACTION=add
DEVPATH=/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1
SUBSYSTEM=usb
MAJOR=189
MINOR=1
DEVNAME=bus/usb/001/002
DEVTYPE=usb_device
PRODUCT=4e8/6860/216
TYPE=0/0/0
BUSNUM=001
DEVNUM=002
SEQNUM=2112
libudev
����(
(
X
w��'��
UDEV_LOG=3
ACTION=add
DEVPATH=/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1
SUBSYSTEM=usb
DEVNAME=/dev/bus/usb/001/002
DEVTYPE=usb_device
PRODUCT=4e8/6860/216
TYPE=0/0/0
BUSNUM=001
DEVNUM=002
SEQNUM=2112
MAJOR=189
MINOR=1
ID_MTP_DEVICE=1
ID_MEDIA_PLAYER=samsung_galaxy-s2
DEVLINKS=/dev/libmtp-1-1
ID_VENDOR=unknown
ID_VENDOR_ENC=unknown
ID_VENDOR_ID=04e8
ID_MODEL=AOSP_on_Maguro
ID_MODEL_ENC=AOSP\x20on\x20Maguro
ID_MODEL_ID=6860
ID_REVISION=0216
ID_SERIAL=unknow�A{��
add@/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.0
ACTION=add
DEVPATH=/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.0
SUBSYSTEM=usb
DEVTYPE=usb_interface
PRODUCT=4e8/6860/216
TYPE=0/0/0
INTERFACE=255/255/0
MODALIAS=usb:v04E8p6860d0216dc00dsc00dp00icFFiscFFip00
SEQNUM=2113
add@/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.1
ACTION=add
DEVPATH=/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.1
SUBSYSTEM=usb
DEVTYPE=usb_interface
PRODUCT=4e8/6860/216
TYPE=0/0/0
INTERFACE=255/66/1
MODALIAS=usb:v04E8p6860d0216dc00dsc00dp00icFFisc42ip01
SEQNUM=2114
libudev
����(
(
w��� Ge
UDEV_LOG=3
ACTION=add
DEVPATH=/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.1
SUBSYSTEM=usb
DEVTYPE=usb_interface
PRODUCT=4e8/6860/216
TYPE=0/0/0
INTERFACE=255/66/1
MODALIAS=usb:v04E8p6860d0216dc00dsc00dp00icFFisc42ip01
SEQNUM=2114
libudev
����(
(
w��� Ge
UDEV_LOG=3
ACTION=add
DEVPATH=/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.0
SUBSYSTEM=usb
DEVTYPE=usb_interface
PRODUCT=4e8/6860/216
TYPE=0/0/0
INTERFACE=255/255/0
MODALIAS=usb:v04E8p6860d0216dc00dsc00dp00icFFiscFFip00
SEQNUM=2113
Device Model and Vendor ID and Product ID
ID_MTP_DEVICE=1
ID_MEDIA_PLAYER=samsung_galaxy-s2
DEVLINKS=/dev/libmtp-1-1
ID_VENDOR=unknown
ID_VENDOR_ENC=unknown
ID_VENDOR_ID=04e8
ID_MODEL=AOSP_on_Maguro
ID_MODEL_ENC=AOSP\x20on\x20Maguro
ID_MODEL_ID=6860
ID_REVISION=0216
thanks, this sample code save my life.
ReplyDeleteBTW, the messes such as
'libudev ����('
was generated by udev.
sudo service udev stop
udev stop/waiting
world is more clear.