summaryrefslogtreecommitdiff
path: root/src/udev/udevd.c
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2018-11-08 15:48:38 +0900
committerYu Watanabe <watanabe.yu+github@gmail.com>2018-11-17 21:45:03 +0900
commite2130348ef4f1937f3c0cbabd054d649b4069b97 (patch)
treea8eeca338d9a02722297e3aad8721793f7f35f67 /src/udev/udevd.c
parentf00d2b6dd2551351e46599185d963429ea3b208e (diff)
downloadsystemd-e2130348ef4f1937f3c0cbabd054d649b4069b97.tar.gz
systemd-e2130348ef4f1937f3c0cbabd054d649b4069b97.tar.bz2
systemd-e2130348ef4f1937f3c0cbabd054d649b4069b97.zip
udevd: also use sd_device_monitor_start() in worker_main()
Diffstat (limited to 'src/udev/udevd.c')
-rw-r--r--src/udev/udevd.c120
1 files changed, 53 insertions, 67 deletions
diff --git a/src/udev/udevd.c b/src/udev/udevd.c
index a14c4c3a9c..4e407b4e9a 100644
--- a/src/udev/udevd.c
+++ b/src/udev/udevd.c
@@ -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) {