mirror of
https://github.com/systemd/systemd.git
synced 2024-11-02 10:51:20 +03:00
udevd: also use sd_device_monitor_start() in worker_main()
This commit is contained in:
parent
f00d2b6dd2
commit
e2130348ef
118
src/udev/udevd.c
118
src/udev/udevd.c
@ -440,14 +440,34 @@ static int worker_process_device(Manager *manager, sd_device *dev) {
|
|||||||
return 0;
|
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) {
|
static int worker_main(Manager *_manager, sd_device_monitor *monitor, sd_device *first_device) {
|
||||||
_cleanup_(sd_device_unrefp) sd_device *dev = first_device;
|
_cleanup_(sd_device_unrefp) sd_device *dev = first_device;
|
||||||
_cleanup_(manager_freep) Manager *manager = _manager;
|
_cleanup_(manager_freep) Manager *manager = _manager;
|
||||||
_cleanup_close_ int fd_signal = -1, fd_ep = -1;
|
int r, ret;
|
||||||
struct epoll_event ep_signal = { .events = EPOLLIN };
|
|
||||||
struct epoll_event ep_monitor = { .events = EPOLLIN };
|
|
||||||
int fd_monitor, r;
|
|
||||||
sigset_t mask;
|
|
||||||
|
|
||||||
assert(manager);
|
assert(manager);
|
||||||
assert(monitor);
|
assert(monitor);
|
||||||
@ -455,80 +475,46 @@ static int worker_main(Manager *_manager, sd_device_monitor *monitor, sd_device
|
|||||||
|
|
||||||
unsetenv("NOTIFY_SOCKET");
|
unsetenv("NOTIFY_SOCKET");
|
||||||
|
|
||||||
/* Clear unnecessary data form worker in Manager object.*/
|
assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, -1) >= 0);
|
||||||
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. */
|
/* Reset OOM score, we only protect the main daemon. */
|
||||||
r = set_oom_score_adjust(0);
|
r = set_oom_score_adjust(0);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
log_debug_errno(r, "Failed to reset OOM score, ignoring: %m");
|
log_debug_errno(r, "Failed to reset OOM score, ignoring: %m");
|
||||||
|
|
||||||
for (;;) {
|
/* Clear unnecessary data in Manager object.*/
|
||||||
r = worker_process_device(manager, dev);
|
manager_clear_for_worker(manager);
|
||||||
if (r < 0)
|
|
||||||
log_device_warning_errno(dev, r, "Failed to process device, ignoring: %m");
|
|
||||||
|
|
||||||
/* send processed event back to libudev listeners */
|
r = sd_event_new(&manager->event);
|
||||||
r = device_monitor_send_device(monitor, NULL, dev);
|
if (r < 0)
|
||||||
if (r < 0)
|
return log_error_errno(r, "Failed to allocate event loop: %m");
|
||||||
log_device_warning_errno(dev, r, "Failed to send device to udev event listeners, ignoring: %m");
|
|
||||||
|
|
||||||
/* send udevd the result of the event execution */
|
r = sd_event_add_signal(manager->event, NULL, SIGTERM, NULL, NULL);
|
||||||
r = worker_send_message(manager->worker_watch[WRITE_END]);
|
if (r < 0)
|
||||||
if (r < 0)
|
return log_error_errno(r, "Failed to set SIGTERM event: %m");
|
||||||
log_device_warning_errno(dev, r, "Failed to send result to main daemon: %m");
|
|
||||||
|
|
||||||
dev = sd_device_unref(dev);
|
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");
|
||||||
|
|
||||||
/* wait for more device messages from main udevd, or term signal */
|
r = sd_device_monitor_start(monitor, worker_device_monitor_handler, manager);
|
||||||
while (!dev) {
|
if (r < 0)
|
||||||
struct epoll_event ev[4];
|
return log_error_errno(r, "Failed to start device monitor: %m");
|
||||||
int fdcount;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
fdcount = epoll_wait(fd_ep, ev, ELEMENTSOF(ev), -1);
|
(void) sd_event_source_set_description(sd_device_monitor_get_event_source(monitor), "worker-device-monitor");
|
||||||
if (fdcount < 0) {
|
|
||||||
if (errno == EINTR)
|
|
||||||
continue;
|
|
||||||
return log_error_errno(errno, "failed to poll: %m");
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < fdcount; i++) {
|
/* Process first device */
|
||||||
if (ev[i].data.fd == fd_monitor && ev[i].events & EPOLLIN) {
|
(void) worker_device_monitor_handler(monitor, dev, manager);
|
||||||
(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));
|
r = sd_event_loop(manager->event);
|
||||||
if (size != sizeof(struct signalfd_siginfo))
|
if (r < 0)
|
||||||
continue;
|
return log_error_errno(r, "Event loop failed: %m");
|
||||||
switch (fdsi.ssi_signo) {
|
|
||||||
case SIGTERM:
|
r = sd_event_get_exit_code(manager->event, &ret);
|
||||||
return 0;
|
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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user