udevd: replace udev_monitor by sd_device_monitor
This commit is contained in:
parent
7443654e5f
commit
7f2e3a1409
113
src/udev/udevd.c
113
src/udev/udevd.c
|
@ -34,6 +34,7 @@
|
||||||
#include "cgroup-util.h"
|
#include "cgroup-util.h"
|
||||||
#include "cpu-set-util.h"
|
#include "cpu-set-util.h"
|
||||||
#include "dev-setup.h"
|
#include "dev-setup.h"
|
||||||
|
#include "device-monitor-private.h"
|
||||||
#include "device-private.h"
|
#include "device-private.h"
|
||||||
#include "device-util.h"
|
#include "device-util.h"
|
||||||
#include "event-util.h"
|
#include "event-util.h"
|
||||||
|
@ -81,7 +82,7 @@ typedef struct Manager {
|
||||||
|
|
||||||
sd_netlink *rtnl;
|
sd_netlink *rtnl;
|
||||||
|
|
||||||
struct udev_monitor *monitor;
|
sd_device_monitor *monitor;
|
||||||
struct udev_ctrl *ctrl;
|
struct udev_ctrl *ctrl;
|
||||||
struct udev_ctrl_connection *ctrl_conn_blocking;
|
struct udev_ctrl_connection *ctrl_conn_blocking;
|
||||||
int fd_inotify;
|
int fd_inotify;
|
||||||
|
@ -135,7 +136,7 @@ enum worker_state {
|
||||||
struct worker {
|
struct worker {
|
||||||
Manager *manager;
|
Manager *manager;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
struct udev_monitor *monitor;
|
sd_device_monitor *monitor;
|
||||||
enum worker_state state;
|
enum worker_state state;
|
||||||
struct event *event;
|
struct event *event;
|
||||||
};
|
};
|
||||||
|
@ -180,7 +181,7 @@ static void worker_free(struct worker *worker) {
|
||||||
assert(worker->manager);
|
assert(worker->manager);
|
||||||
|
|
||||||
hashmap_remove(worker->manager->workers, PID_TO_PTR(worker->pid));
|
hashmap_remove(worker->manager->workers, PID_TO_PTR(worker->pid));
|
||||||
udev_monitor_unref(worker->monitor);
|
sd_device_monitor_unref(worker->monitor);
|
||||||
event_free(worker->event);
|
event_free(worker->event);
|
||||||
|
|
||||||
free(worker);
|
free(worker);
|
||||||
|
@ -198,7 +199,7 @@ static void manager_workers_free(Manager *manager) {
|
||||||
manager->workers = hashmap_free(manager->workers);
|
manager->workers = hashmap_free(manager->workers);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int worker_new(struct worker **ret, Manager *manager, struct udev_monitor *worker_monitor, pid_t pid) {
|
static int worker_new(struct worker **ret, Manager *manager, sd_device_monitor *worker_monitor, pid_t pid) {
|
||||||
_cleanup_free_ struct worker *worker = NULL;
|
_cleanup_free_ struct worker *worker = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
@ -213,8 +214,8 @@ static int worker_new(struct worker **ret, Manager *manager, struct udev_monitor
|
||||||
|
|
||||||
worker->manager = manager;
|
worker->manager = manager;
|
||||||
/* close monitor, but keep address around */
|
/* close monitor, but keep address around */
|
||||||
udev_monitor_disconnect(worker_monitor);
|
device_monitor_disconnect(worker_monitor);
|
||||||
worker->monitor = udev_monitor_ref(worker_monitor);
|
worker->monitor = sd_device_monitor_ref(worker_monitor);
|
||||||
worker->pid = pid;
|
worker->pid = pid;
|
||||||
|
|
||||||
r = hashmap_ensure_allocated(&manager->workers, NULL);
|
r = hashmap_ensure_allocated(&manager->workers, NULL);
|
||||||
|
@ -293,7 +294,7 @@ static void manager_clear_for_worker(Manager *manager) {
|
||||||
manager_workers_free(manager);
|
manager_workers_free(manager);
|
||||||
event_queue_cleanup(manager, EVENT_UNDEF);
|
event_queue_cleanup(manager, EVENT_UNDEF);
|
||||||
|
|
||||||
manager->monitor = udev_monitor_unref(manager->monitor);
|
manager->monitor = sd_device_monitor_unref(manager->monitor);
|
||||||
manager->ctrl_conn_blocking = udev_ctrl_connection_unref(manager->ctrl_conn_blocking);
|
manager->ctrl_conn_blocking = udev_ctrl_connection_unref(manager->ctrl_conn_blocking);
|
||||||
manager->ctrl = udev_ctrl_unref(manager->ctrl);
|
manager->ctrl = udev_ctrl_unref(manager->ctrl);
|
||||||
|
|
||||||
|
@ -439,8 +440,8 @@ static int worker_process_device(Manager *manager, sd_device *dev) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int worker_main(Manager *_manager, struct udev_monitor *monitor, struct udev_device *first_device) {
|
static int worker_main(Manager *_manager, sd_device_monitor *monitor, sd_device *first_device) {
|
||||||
_cleanup_(udev_device_unrefp) struct udev_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;
|
_cleanup_close_ int fd_signal = -1, fd_ep = -1;
|
||||||
struct epoll_event ep_signal = { .events = EPOLLIN };
|
struct epoll_event ep_signal = { .events = EPOLLIN };
|
||||||
|
@ -463,7 +464,7 @@ static int worker_main(Manager *_manager, struct udev_monitor *monitor, struct u
|
||||||
return log_error_errno(errno, "error creating signalfd %m");
|
return log_error_errno(errno, "error creating signalfd %m");
|
||||||
ep_signal.data.fd = fd_signal;
|
ep_signal.data.fd = fd_signal;
|
||||||
|
|
||||||
fd_monitor = udev_monitor_get_fd(monitor);
|
fd_monitor = device_monitor_get_fd(monitor);
|
||||||
ep_monitor.data.fd = fd_monitor;
|
ep_monitor.data.fd = fd_monitor;
|
||||||
|
|
||||||
fd_ep = epoll_create1(EPOLL_CLOEXEC);
|
fd_ep = epoll_create1(EPOLL_CLOEXEC);
|
||||||
|
@ -480,22 +481,21 @@ static int worker_main(Manager *_manager, struct udev_monitor *monitor, struct u
|
||||||
log_debug_errno(r, "Failed to reset OOM score, ignoring: %m");
|
log_debug_errno(r, "Failed to reset OOM score, ignoring: %m");
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
r = worker_process_device(manager, dev->device);
|
r = worker_process_device(manager, dev);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
log_device_warning_errno(dev->device, r, "Failed to process device, ignoring: %m");
|
log_device_warning_errno(dev, r, "Failed to process device, ignoring: %m");
|
||||||
|
|
||||||
/* send processed event back to libudev listeners */
|
/* send processed event back to libudev listeners */
|
||||||
r = udev_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->device, r, "Failed to send device to udev event listeners, ignoring: %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 */
|
/* 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->device, r, "Failed to send result of seq %llu to main daemon: %m",
|
log_device_warning_errno(dev, r, "Failed to send result to main daemon: %m");
|
||||||
udev_device_get_seqnum(dev));
|
|
||||||
|
|
||||||
dev = udev_device_unref(dev);
|
dev = sd_device_unref(dev);
|
||||||
|
|
||||||
/* wait for more device messages from main udevd, or term signal */
|
/* wait for more device messages from main udevd, or term signal */
|
||||||
while (!dev) {
|
while (!dev) {
|
||||||
|
@ -512,7 +512,7 @@ static int worker_main(Manager *_manager, struct udev_monitor *monitor, struct u
|
||||||
|
|
||||||
for (i = 0; i < fdcount; i++) {
|
for (i = 0; i < fdcount; i++) {
|
||||||
if (ev[i].data.fd == fd_monitor && ev[i].events & EPOLLIN) {
|
if (ev[i].data.fd == fd_monitor && ev[i].events & EPOLLIN) {
|
||||||
dev = udev_monitor_receive_device(monitor);
|
(void) device_monitor_receive_device(monitor, &dev);
|
||||||
break;
|
break;
|
||||||
} else if (ev[i].data.fd == fd_signal && ev[i].events & EPOLLIN) {
|
} else if (ev[i].data.fd == fd_signal && ev[i].events & EPOLLIN) {
|
||||||
struct signalfd_siginfo fdsi;
|
struct signalfd_siginfo fdsi;
|
||||||
|
@ -532,21 +532,24 @@ static int worker_main(Manager *_manager, struct udev_monitor *monitor, struct u
|
||||||
}
|
}
|
||||||
|
|
||||||
static int worker_spawn(Manager *manager, struct event *event) {
|
static int worker_spawn(Manager *manager, struct event *event) {
|
||||||
_cleanup_(udev_monitor_unrefp) struct udev_monitor *worker_monitor = NULL;
|
_cleanup_(sd_device_monitor_unrefp) sd_device_monitor *worker_monitor = NULL;
|
||||||
struct worker *worker;
|
struct worker *worker;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
/* listen for new events */
|
/* listen for new events */
|
||||||
worker_monitor = udev_monitor_new_from_netlink(NULL, NULL);
|
r = device_monitor_new_full(&worker_monitor, MONITOR_GROUP_NONE, -1);
|
||||||
if (!worker_monitor)
|
if (r < 0)
|
||||||
return -errno;
|
return r;
|
||||||
|
|
||||||
/* allow the main daemon netlink address to send devices to the worker */
|
/* allow the main daemon netlink address to send devices to the worker */
|
||||||
udev_monitor_allow_unicast_sender(worker_monitor, manager->monitor);
|
r = device_monitor_allow_unicast_sender(worker_monitor, manager->monitor);
|
||||||
r = udev_monitor_enable_receiving(worker_monitor);
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Worker: could not enable receiving of device: %m");
|
return log_error_errno(r, "Worker: Failed to set unicast sender: %m");
|
||||||
|
|
||||||
|
r = device_monitor_enable_receiving(worker_monitor);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Worker: Failed to enable receiving of device: %m");
|
||||||
|
|
||||||
r = safe_fork(NULL, FORK_DEATHSIG, &pid);
|
r = safe_fork(NULL, FORK_DEATHSIG, &pid);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
|
@ -555,7 +558,7 @@ static int worker_spawn(Manager *manager, struct event *event) {
|
||||||
}
|
}
|
||||||
if (r == 0) {
|
if (r == 0) {
|
||||||
/* Worker process */
|
/* Worker process */
|
||||||
r = worker_main(manager, worker_monitor, TAKE_PTR(event->dev));
|
r = worker_main(manager, worker_monitor, sd_device_ref(event->dev->device));
|
||||||
log_close();
|
log_close();
|
||||||
_exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
|
_exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
@ -573,20 +576,19 @@ static int worker_spawn(Manager *manager, struct event *event) {
|
||||||
static void event_run(Manager *manager, struct event *event) {
|
static void event_run(Manager *manager, struct event *event) {
|
||||||
struct worker *worker;
|
struct worker *worker;
|
||||||
Iterator i;
|
Iterator i;
|
||||||
|
int r;
|
||||||
|
|
||||||
assert(manager);
|
assert(manager);
|
||||||
assert(event);
|
assert(event);
|
||||||
|
|
||||||
HASHMAP_FOREACH(worker, manager->workers, i) {
|
HASHMAP_FOREACH(worker, manager->workers, i) {
|
||||||
ssize_t count;
|
|
||||||
|
|
||||||
if (worker->state != WORKER_IDLE)
|
if (worker->state != WORKER_IDLE)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
count = udev_monitor_send_device(manager->monitor, worker->monitor, event->dev);
|
r = device_monitor_send_device(manager->monitor, worker->monitor, event->dev->device);
|
||||||
if (count < 0) {
|
if (r < 0) {
|
||||||
log_error_errno(errno, "worker ["PID_FMT"] did not accept message %zi (%m), kill it",
|
log_device_error_errno(event->dev->device, r, "Worker ["PID_FMT"] did not accept message, killing the worker: %m",
|
||||||
worker->pid, count);
|
worker->pid);
|
||||||
(void) kill(worker->pid, SIGKILL);
|
(void) kill(worker->pid, SIGKILL);
|
||||||
worker->state = WORKER_KILLED;
|
worker->state = WORKER_KILLED;
|
||||||
continue;
|
continue;
|
||||||
|
@ -762,7 +764,7 @@ static void manager_exit(Manager *manager) {
|
||||||
manager->fd_inotify = safe_close(manager->fd_inotify);
|
manager->fd_inotify = safe_close(manager->fd_inotify);
|
||||||
|
|
||||||
manager->uevent_event = sd_event_source_unref(manager->uevent_event);
|
manager->uevent_event = sd_event_source_unref(manager->uevent_event);
|
||||||
manager->monitor = udev_monitor_unref(manager->monitor);
|
manager->monitor = sd_device_monitor_unref(manager->monitor);
|
||||||
|
|
||||||
/* discard queued events and kill workers */
|
/* discard queued events and kill workers */
|
||||||
event_queue_cleanup(manager, EVENT_QUEUED);
|
event_queue_cleanup(manager, EVENT_QUEUED);
|
||||||
|
@ -935,22 +937,31 @@ static int on_worker(sd_event_source *s, int fd, uint32_t revents, void *userdat
|
||||||
}
|
}
|
||||||
|
|
||||||
static int on_uevent(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
|
static int on_uevent(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
|
||||||
|
_cleanup_(udev_device_unrefp) struct udev_device *udev_device = NULL;
|
||||||
|
_cleanup_(sd_device_unrefp) sd_device *dev = NULL;
|
||||||
Manager *manager = userdata;
|
Manager *manager = userdata;
|
||||||
struct udev_device *dev;
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(manager);
|
assert(manager);
|
||||||
|
|
||||||
dev = udev_monitor_receive_device(manager->monitor);
|
r = device_monitor_receive_device(manager->monitor, &dev);
|
||||||
if (dev) {
|
if (r <= 0)
|
||||||
udev_device_ensure_usec_initialized(dev, NULL);
|
return 1;
|
||||||
r = event_queue_insert(manager, dev);
|
|
||||||
if (r < 0)
|
device_ensure_usec_initialized(dev, NULL);
|
||||||
udev_device_unref(dev);
|
|
||||||
else
|
udev_device = udev_device_new(NULL, dev);
|
||||||
/* we have fresh events, try to schedule them */
|
if (!udev_device)
|
||||||
event_queue_start(manager);
|
return 1;
|
||||||
}
|
|
||||||
|
r = event_queue_insert(manager, udev_device);
|
||||||
|
if (r < 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
udev_device = NULL;
|
||||||
|
|
||||||
|
/* we have fresh events, try to schedule them */
|
||||||
|
event_queue_start(manager);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1298,7 +1309,7 @@ static int on_sigchld(sd_event_source *s, const struct signalfd_siginfo *si, voi
|
||||||
udev_device_delete_db(worker->event->dev);
|
udev_device_delete_db(worker->event->dev);
|
||||||
udev_device_tag_index(worker->event->dev, NULL, false);
|
udev_device_tag_index(worker->event->dev, NULL, false);
|
||||||
/* forward kernel event without amending it */
|
/* forward kernel event without amending it */
|
||||||
udev_monitor_send_device(manager->monitor, NULL, worker->event->dev_kernel);
|
device_monitor_send_device(manager->monitor, NULL, worker->event->dev_kernel->device);
|
||||||
}
|
}
|
||||||
|
|
||||||
worker_free(worker);
|
worker_free(worker);
|
||||||
|
@ -1567,17 +1578,17 @@ static int manager_new(Manager **ret, int fd_ctrl, int fd_uevent, const char *cg
|
||||||
if (fd_ctrl < 0)
|
if (fd_ctrl < 0)
|
||||||
return log_error_errno(fd_ctrl, "Failed to get udev control fd: %m");
|
return log_error_errno(fd_ctrl, "Failed to get udev control fd: %m");
|
||||||
|
|
||||||
manager->monitor = udev_monitor_new_from_netlink_fd(NULL, "kernel", fd_uevent);
|
r = device_monitor_new_full(&manager->monitor, MONITOR_GROUP_KERNEL, fd_uevent);
|
||||||
if (!manager->monitor)
|
if (r < 0)
|
||||||
return log_error_errno(EINVAL, "error taking over netlink socket");
|
return log_error_errno(r, "Failed to initialize device monitor: %m");
|
||||||
|
|
||||||
(void) udev_monitor_set_receive_buffer_size(manager->monitor, 128 * 1024 * 1024);
|
(void) sd_device_monitor_set_receive_buffer_size(manager->monitor, 128 * 1024 * 1024);
|
||||||
|
|
||||||
r = udev_monitor_enable_receiving(manager->monitor);
|
r = device_monitor_enable_receiving(manager->monitor);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to bind netlink socket; %m");
|
return log_error_errno(r, "Failed to bind netlink socket; %m");
|
||||||
|
|
||||||
fd_uevent = udev_monitor_get_fd(manager->monitor);
|
fd_uevent = device_monitor_get_fd(manager->monitor);
|
||||||
if (fd_uevent < 0)
|
if (fd_uevent < 0)
|
||||||
return log_error_errno(fd_uevent, "Failed to get uevent fd: %m");
|
return log_error_errno(fd_uevent, "Failed to get uevent fd: %m");
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue