Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- 그럼 호출되는 것이 ueventd_main 함수이다.
- int ueventd_main(int argc, char **argv)
- {
- struct pollfd ufd;
- int nr;
- char tmp[32];
- /* Prevent fire-and-forget children from becoming zombies.
- * If we should need to wait() for some children in the future
- * (as opposed to none right now), double-forking here instead
- * of ignoring SIGCHLD may be the better solution.
- */
- signal(SIGCHLD, SIG_IGN);
- open_devnull_stdio();
- klog_init();
- INFO(“starting ueventd\n”);
- /* Respect hardware passed in through the kernel cmd line. Here we will look
- * for androidboot.hardware param in kernel cmdline, and save its value in
- * hardware[]. */
- import_kernel_cmdline(0, import_kernel_nv);
- get_hardware_name(hardware, &revision);
- ueventd_parse_config_file(“/ueventd.rc”);
- snprintf(tmp, sizeof(tmp), “/ueventd.%s.rc”, hardware);
- ueventd_parse_config_file(tmp);
- device_init();
- ufd.events = POLLIN;
- ufd.fd = get_device_fd();
- while(1) {
- ufd.revents = 0;
- nr = poll(&ufd, 1, -1);
- if (nr <= 0)
- continue;
- if (ufd.revents == POLLIN)
- handle_device_fd();
- }
- }
- 여기서 중요한 함수는 ueventd_parse_config_file와 device_init함수이다.
- ueventd_parse_config_file함수는 ueventd.rc파일과 ueventd.%hardware%.rc 파일을 읽어 디바이스 노드 파일을 만드는 정보를 얻는다
- 여기에 저장되어 있는 정보는 device 이름, permission, gid, uid 이다.
- 저장되어 있지 않는 device는 디폴트로 600, 0, 0이 세팅된다.
- device_init함수는 uevent_socket을 열고 coldboot 함수를 실행한다.
- 여기서 연 소켓은 uevent를 보낼때 쓰이는 것이 아니라 나중에 발생한 uevent를 받을때 쓰인다.
- void device_init(void)
- {
- suseconds_t t0, t1;
- struct stat info;
- int fd;
- /* is 64K enough? udev uses 16MB! */
- device_fd = uevent_open_socket(64*1024, true);
- if(device_fd < 0)
- return;
- fcntl(device_fd, F_SETFD, FD_CLOEXEC);
- fcntl(device_fd, F_SETFL, O_NONBLOCK);
- if (stat(coldboot_done, &info) < 0) {
- t0 = get_usecs();
- coldboot(“/sys/class”);
- coldboot(“/sys/block”);
- coldboot(“/sys/devices”);
- t1 = get_usecs();
- fd = open(coldboot_done, O_WRONLY|O_CREAT, 0000);
- close(fd);
- log_event_print(“coldboot %ld uS\n”, ((long) (t1 – t0)));
- } else {
- log_event_print(“skipping coldboot, already done\n”);
- }
- }
- 호출 되는 coldboot는 내부적으로 do_coldboot를 호출한다.
- static void do_coldboot(DIR *d)
- {
- struct dirent *de;
- int dfd, fd;
- dfd = dirfd(d);
- fd = openat(dfd, “uevent”, O_WRONLY);
- if(fd >= 0) {
- write(fd, “add\n”, 4);
- close(fd);
- handle_device_fd();
- }
- while((de = readdir(d))) {
- DIR *d2;
- if(de->d_type != DT_DIR || de->d_name[0] == ‘.’)
- continue;
- fd = openat(dfd, de->d_name, O_RDONLY | O_DIRECTORY);
- if(fd < 0)
- continue;
- d2 = fdopendir(fd);
- if(d2 == 0)
- close(fd);
- else {
- do_coldboot(d2);
- closedir(d2);
- }
- }
- }
- 디바이스 노드를 생성하지 못한 디바이스가 저장한 /sys 밑의 각각의 해당 폴더를 들어가 uevent 파일에 “add” 메시지를 써넣어 강제로 uevent를 발생시킨다
- 그후 handle_device_fd 함수를 통해 uevent 를 파싱해 디바이스 노드를 만든다. 이 과정에서 ueventd_parse_config_file에서 얻어온 정보를 사용한다.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement