]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
udevd: also use sd_device_monitor_start() in worker_main()
authorYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 8 Nov 2018 06:48:38 +0000 (15:48 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Sat, 17 Nov 2018 12:45:03 +0000 (21:45 +0900)
src/udev/udevd.c

index a14c4c3a9c7536afc149baf10b7894729da92477..4e407b4e9ab3a1dafd39fd69e3e3644f83c6a1f1 100644 (file)
@@ -440,14 +440,34 @@ static int worker_process_device(Manager *manager, sd_device *dev) {
         return 0;
 }
 
+static int worker_device_monitor_handler(sd_device_monitor *monitor, sd_device *dev, void *userdata) {
+        Manager *manager = userdata;
+        int r;
+
+        assert(dev);
+        assert(manager);
+
+        r = worker_process_device(manager, dev);
+        if (r < 0)
+                log_device_warning_errno(dev, r, "Failed to process device, ignoring: %m");
+
+        /* send processed event back to libudev listeners */
+        r = device_monitor_send_device(monitor, NULL, dev);
+        if (r < 0)
+                log_device_warning_errno(dev, r, "Failed to send device, ignoring: %m");
+
+        /* send udevd the result of the event execution */
+        r = worker_send_message(manager->worker_watch[WRITE_END]);
+        if (r < 0)
+                log_device_warning_errno(dev, r, "Failed to send signal to main daemon, ignoring: %m");
+
+        return 1;
+}
+
 static int worker_main(Manager *_manager, sd_device_monitor *monitor, sd_device *first_device) {
         _cleanup_(sd_device_unrefp) sd_device *dev = first_device;
         _cleanup_(manager_freep) Manager *manager = _manager;
-        _cleanup_close_ int fd_signal = -1, fd_ep = -1;
-        struct epoll_event ep_signal = { .events = EPOLLIN };
-        struct epoll_event ep_monitor = { .events = EPOLLIN };
-        int fd_monitor, r;
-        sigset_t mask;
+        int r, ret;
 
         assert(manager);
         assert(monitor);
@@ -455,80 +475,46 @@ static int worker_main(Manager *_manager, sd_device_monitor *monitor, sd_device
 
         unsetenv("NOTIFY_SOCKET");
 
-        /* Clear unnecessary data form worker in Manager object.*/
-        manager_clear_for_worker(manager);
-
-        sigfillset(&mask);
-        fd_signal = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
-        if (fd_signal < 0)
-                return log_error_errno(errno, "error creating signalfd %m");
-        ep_signal.data.fd = fd_signal;
-
-        fd_monitor = device_monitor_get_fd(monitor);
-        ep_monitor.data.fd = fd_monitor;
-
-        fd_ep = epoll_create1(EPOLL_CLOEXEC);
-        if (fd_ep < 0)
-                return log_error_errno(errno, "error creating epoll fd: %m");
-
-        if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_signal, &ep_signal) < 0 ||
-            epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_monitor, &ep_monitor) < 0)
-                return log_error_errno(errno, "fail to add fds to epoll: %m");
+        assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, -1) >= 0);
 
         /* Reset OOM score, we only protect the main daemon. */
         r = set_oom_score_adjust(0);
         if (r < 0)
                 log_debug_errno(r, "Failed to reset OOM score, ignoring: %m");
 
-        for (;;) {
-                r = worker_process_device(manager, dev);
-                if (r < 0)
-                        log_device_warning_errno(dev, r, "Failed to process device, ignoring: %m");
+        /* Clear unnecessary data in Manager object.*/
+        manager_clear_for_worker(manager);
 
-                /* send processed event back to libudev listeners */
-                r = device_monitor_send_device(monitor, NULL, dev);
-                if (r < 0)
-                        log_device_warning_errno(dev, r, "Failed to send device to udev event listeners, ignoring: %m");
+        r = sd_event_new(&manager->event);
+        if (r < 0)
+                return log_error_errno(r, "Failed to allocate event loop: %m");
 
-                /* send udevd the result of the event execution */
-                r = worker_send_message(manager->worker_watch[WRITE_END]);
-                if (r < 0)
-                        log_device_warning_errno(dev, r, "Failed to send result to main daemon: %m");
+        r = sd_event_add_signal(manager->event, NULL, SIGTERM, NULL, NULL);
+        if (r < 0)
+                return log_error_errno(r, "Failed to set SIGTERM event: %m");
+
+        r = sd_device_monitor_attach_event(monitor, manager->event);
+        if (r < 0)
+                return log_error_errno(r, "Failed to attach event loop to device monitor: %m");
+
+        r = sd_device_monitor_start(monitor, worker_device_monitor_handler, manager);
+        if (r < 0)
+                return log_error_errno(r, "Failed to start device monitor: %m");
 
-                dev = sd_device_unref(dev);
+        (void) sd_event_source_set_description(sd_device_monitor_get_event_source(monitor), "worker-device-monitor");
 
-                /* wait for more device messages from main udevd, or term signal */
-                while (!dev) {
-                        struct epoll_event ev[4];
-                        int fdcount;
-                        int i;
+        /* Process first device */
+        (void) worker_device_monitor_handler(monitor, dev, manager);
 
-                        fdcount = epoll_wait(fd_ep, ev, ELEMENTSOF(ev), -1);
-                        if (fdcount < 0) {
-                                if (errno == EINTR)
-                                        continue;
-                                return log_error_errno(errno, "failed to poll: %m");
-                        }
+        r = sd_event_loop(manager->event);
+        if (r < 0)
+                return log_error_errno(r, "Event loop failed: %m");
 
-                        for (i = 0; i < fdcount; i++) {
-                                if (ev[i].data.fd == fd_monitor && ev[i].events & EPOLLIN) {
-                                        (void) device_monitor_receive_device(monitor, &dev);
-                                        break;
-                                } else if (ev[i].data.fd == fd_signal && ev[i].events & EPOLLIN) {
-                                        struct signalfd_siginfo fdsi;
-                                        ssize_t size;
-
-                                        size = read(fd_signal, &fdsi, sizeof(struct signalfd_siginfo));
-                                        if (size != sizeof(struct signalfd_siginfo))
-                                                continue;
-                                        switch (fdsi.ssi_signo) {
-                                        case SIGTERM:
-                                                return 0;
-                                        }
-                                }
-                        }
-                }
-        }
+        r = sd_event_get_exit_code(manager->event, &ret);
+        if (r < 0)
+                return log_error_errno(r, "Failed to get exit code: %m");
+
+        return ret;
 }
 
 static int worker_spawn(Manager *manager, struct event *event) {