1
0
mirror of https://github.com/systemd/systemd.git synced 2024-11-02 19:21:53 +03:00

udevd: also use sd_device_monitor_start() in worker_main()

This commit is contained in:
Yu Watanabe 2018-11-08 15:48:38 +09:00
parent f00d2b6dd2
commit e2130348ef

View File

@ -440,47 +440,13 @@ static int worker_process_device(Manager *manager, sd_device *dev) {
return 0; return 0;
} }
static int worker_main(Manager *_manager, sd_device_monitor *monitor, sd_device *first_device) { static int worker_device_monitor_handler(sd_device_monitor *monitor, sd_device *dev, void *userdata) {
_cleanup_(sd_device_unrefp) sd_device *dev = first_device; Manager *manager = userdata;
_cleanup_(manager_freep) Manager *manager = _manager; int r;
_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;
assert(manager);
assert(monitor);
assert(dev); assert(dev);
assert(manager);
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");
/* 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); r = worker_process_device(manager, dev);
if (r < 0) if (r < 0)
log_device_warning_errno(dev, r, "Failed to process device, ignoring: %m"); log_device_warning_errno(dev, r, "Failed to process device, ignoring: %m");
@ -488,47 +454,67 @@ static int worker_main(Manager *_manager, sd_device_monitor *monitor, sd_device
/* send processed event back to libudev listeners */ /* send processed event back to libudev listeners */
r = device_monitor_send_device(monitor, NULL, dev); r = device_monitor_send_device(monitor, NULL, dev);
if (r < 0) if (r < 0)
log_device_warning_errno(dev, r, "Failed to send device to udev event listeners, ignoring: %m"); log_device_warning_errno(dev, r, "Failed to send device, ignoring: %m");
/* send udevd the result of the event execution */ /* send udevd the result of the event execution */
r = worker_send_message(manager->worker_watch[WRITE_END]); r = worker_send_message(manager->worker_watch[WRITE_END]);
if (r < 0) if (r < 0)
log_device_warning_errno(dev, r, "Failed to send result to main daemon: %m"); log_device_warning_errno(dev, r, "Failed to send signal to main daemon, ignoring: %m");
dev = sd_device_unref(dev); return 1;
}
/* wait for more device messages from main udevd, or term signal */ static int worker_main(Manager *_manager, sd_device_monitor *monitor, sd_device *first_device) {
while (!dev) { _cleanup_(sd_device_unrefp) sd_device *dev = first_device;
struct epoll_event ev[4]; _cleanup_(manager_freep) Manager *manager = _manager;
int fdcount; int r, ret;
int i;
fdcount = epoll_wait(fd_ep, ev, ELEMENTSOF(ev), -1); assert(manager);
if (fdcount < 0) { assert(monitor);
if (errno == EINTR) assert(dev);
continue;
return log_error_errno(errno, "failed to poll: %m");
}
for (i = 0; i < fdcount; i++) { unsetenv("NOTIFY_SOCKET");
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)); assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, -1) >= 0);
if (size != sizeof(struct signalfd_siginfo))
continue; /* Reset OOM score, we only protect the main daemon. */
switch (fdsi.ssi_signo) { r = set_oom_score_adjust(0);
case SIGTERM: if (r < 0)
return 0; log_debug_errno(r, "Failed to reset OOM score, ignoring: %m");
}
} /* Clear unnecessary data in Manager object.*/
} manager_clear_for_worker(manager);
}
} r = sd_event_new(&manager->event);
if (r < 0)
return log_error_errno(r, "Failed to allocate event loop: %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");
(void) sd_event_source_set_description(sd_device_monitor_get_event_source(monitor), "worker-device-monitor");
/* Process first device */
(void) worker_device_monitor_handler(monitor, dev, manager);
r = sd_event_loop(manager->event);
if (r < 0)
return log_error_errno(r, "Event loop failed: %m");
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) { static int worker_spawn(Manager *manager, struct event *event) {