static struct udev_ctrl *udev_ctrl;
static struct udev_monitor *monitor;
static int worker_watch[2] = { -1, -1 };
static struct udev_ctrl *udev_ctrl;
static struct udev_monitor *monitor;
static int worker_watch[2] = { -1, -1 };
static sigset_t sigmask_orig;
static UDEV_LIST(event_list);
static UDEV_LIST(worker_list);
static sigset_t sigmask_orig;
static UDEV_LIST(event_list);
static UDEV_LIST(worker_list);
udev_monitor_allow_unicast_sender(worker_monitor, monitor);
udev_monitor_enable_receiving(worker_monitor);
udev_monitor_allow_unicast_sender(worker_monitor, monitor);
udev_monitor_enable_receiving(worker_monitor);
free(worker);
worker_list_cleanup(udev);
event_queue_cleanup(udev, EVENT_UNDEF);
free(worker);
worker_list_cleanup(udev);
event_queue_cleanup(udev, EVENT_UNDEF);
ep_signal.events = EPOLLIN;
ep_signal.data.fd = fd_signal;
fd_monitor = udev_monitor_get_fd(worker_monitor);
ep_signal.events = EPOLLIN;
ep_signal.data.fd = fd_signal;
fd_monitor = udev_monitor_get_fd(worker_monitor);
ep_monitor.events = EPOLLIN;
ep_monitor.data.fd = fd_monitor;
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) {
ep_monitor.events = EPOLLIN;
ep_monitor.data.fd = fd_monitor;
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) {
udev_monitor_send_device(worker_monitor, NULL, dev);
/* send udevd the result of the event execution */
udev_monitor_send_device(worker_monitor, NULL, dev);
/* send udevd the result of the event execution */
if (err != 0)
msg.exitcode = err;
msg.pid = getpid();
send(worker_watch[WRITE_END], &msg, sizeof(struct worker_message), 0);
if (err != 0)
msg.exitcode = err;
msg.pid = getpid();
send(worker_watch[WRITE_END], &msg, sizeof(struct worker_message), 0);
event->state = EVENT_RUNNING;
udev_list_node_append(&worker->node, &worker_list);
children++;
event->state = EVENT_RUNNING;
udev_list_node_append(&worker->node, &worker_list);
children++;
- log_error("worker [%u] did not accept message %zi (%m), kill it\n", worker->pid, count);
+ log_error("worker [%u] did not accept message %zi (%m), kill it", worker->pid, count);
kill(worker->pid, SIGKILL);
worker->state = WORKER_KILLED;
continue;
kill(worker->pid, SIGKILL);
worker->state = WORKER_KILLED;
continue;
- udev_queue_export_device_queued(udev_queue_export, dev);
- log_debug("seq %llu queued, '%s' '%s'\n", udev_device_get_seqnum(dev),
+ log_debug("seq %llu queued, '%s' '%s'", udev_device_get_seqnum(dev),
udev_device_get_action(dev), udev_device_get_subsystem(dev));
event->state = EVENT_QUEUED;
udev_device_get_action(dev), udev_device_get_subsystem(dev));
event->state = EVENT_QUEUED;
log_set_max_level(i);
udev_set_log_priority(udev, i);
worker_kill(udev);
}
if (udev_ctrl_get_stop_exec_queue(ctrl_msg) > 0) {
log_set_max_level(i);
udev_set_log_priority(udev, i);
worker_kill(udev);
}
if (udev_ctrl_get_stop_exec_queue(ctrl_msg) > 0) {
- log_debug("udevd message (ENV) received, set '%s=%s'\n", key, val);
+ log_debug("udevd message (ENV) received, set '%s=%s'", key, val);
ev = (struct inotify_event *)(buf + pos);
dev = udev_watch_lookup(udev, ev->wd);
if (dev != NULL) {
ev = (struct inotify_event *)(buf + pos);
dev = udev_watch_lookup(udev, ev->wd);
if (dev != NULL) {
strscpyl(filename, sizeof(filename), udev_device_get_syspath(dev), "/uevent", NULL);
strscpyl(filename, sizeof(filename), udev_device_get_syspath(dev), "/uevent", NULL);
- log_error("worker [%u] exit with return code %i\n", pid, WEXITSTATUS(status));
+ log_error("worker [%u] exit with return code %i",
+ pid, WEXITSTATUS(status));
- log_error("worker [%u] terminated by signal %i (%s)\n",
- pid, WTERMSIG(status), strsignal(WTERMSIG(status)));
+ log_error("worker [%u] terminated by signal %i (%s)",
+ pid, WTERMSIG(status), strsignal(WTERMSIG(status)));
pid, worker->event->devpath);
worker->event->exitcode = -32;
pid, worker->event->devpath);
worker->event->exitcode = -32;
- if (read_one_line_file("/proc/cmdline", &line) < 0)
+ r = proc_cmdline(&line);
+ if (r < 0)
+ log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
+ if (r <= 0)
return;
FOREACH_WORD_QUOTED(w, l, line, state) {
return;
FOREACH_WORD_QUOTED(w, l, line, state) {
monitor = udev_monitor_new_from_netlink(udev, "kernel");
if (monitor == NULL) {
fprintf(stderr, "error initializing netlink socket\n");
monitor = udev_monitor_new_from_netlink(udev, "kernel");
if (monitor == NULL) {
fprintf(stderr, "error initializing netlink socket\n");
if (udev_monitor_enable_receiving(monitor) < 0) {
fprintf(stderr, "error binding netlink socket\n");
if (udev_monitor_enable_receiving(monitor) < 0) {
fprintf(stderr, "error binding netlink socket\n");
rc = 3;
goto exit;
}
if (udev_ctrl_enable_receiving(udev_ctrl) < 0) {
fprintf(stderr, "error binding udev control socket\n");
rc = 3;
goto exit;
}
if (udev_ctrl_enable_receiving(udev_ctrl) < 0) {
fprintf(stderr, "error binding udev control socket\n");
- udev_monitor_set_receive_buffer_size(monitor, 128*1024*1024);
-
- /* create queue file before signalling 'ready', to make sure we block 'settle' */
- udev_queue_export = udev_queue_export_new(udev);
- if (udev_queue_export == NULL) {
- log_error("error creating queue file\n");
- goto exit;
- }
+ udev_monitor_set_receive_buffer_size(monitor, 128 * 1024 * 1024);
fd_inotify = udev_watch_init(udev);
if (fd_inotify < 0) {
fprintf(stderr, "error initializing inotify\n");
fd_inotify = udev_watch_init(udev);
if (fd_inotify < 0) {
fprintf(stderr, "error initializing inotify\n");
fd_signal = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
if (fd_signal < 0) {
fprintf(stderr, "error creating signalfd\n");
fd_signal = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
if (fd_signal < 0) {
fprintf(stderr, "error creating signalfd\n");
/* unnamed socket from workers to the main daemon */
if (socketpair(AF_LOCAL, SOCK_DGRAM|SOCK_CLOEXEC, 0, worker_watch) < 0) {
fprintf(stderr, "error creating socketpair\n");
/* unnamed socket from workers to the main daemon */
if (socketpair(AF_LOCAL, SOCK_DGRAM|SOCK_CLOEXEC, 0, worker_watch) < 0) {
fprintf(stderr, "error creating socketpair\n");
ep_worker.events = EPOLLIN;
ep_worker.data.fd = fd_worker;
fd_ep = epoll_create1(EPOLL_CLOEXEC);
if (fd_ep < 0) {
ep_worker.events = EPOLLIN;
ep_worker.data.fd = fd_worker;
fd_ep = epoll_create1(EPOLL_CLOEXEC);
if (fd_ep < 0) {
goto exit;
}
if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_ctrl, &ep_ctrl) < 0 ||
goto exit;
}
if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_ctrl, &ep_ctrl) < 0 ||
epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_signal, &ep_signal) < 0 ||
epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_netlink, &ep_netlink) < 0 ||
epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_worker, &ep_worker) < 0) {
epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_signal, &ep_signal) < 0 ||
epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_netlink, &ep_netlink) < 0 ||
epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_worker, &ep_worker) < 0) {
cg_kill(SYSTEMD_CGROUP_CONTROLLER, udev_cgroup, SIGKILL, false, true, NULL);
} else {
/* kill idle or hanging workers */
cg_kill(SYSTEMD_CGROUP_CONTROLLER, udev_cgroup, SIGKILL, false, true, NULL);
} else {
/* kill idle or hanging workers */
+ timeout = 3 * MSEC_PER_SEC;
+ }
+
+ /* tell settle that we are busy or idle */
+ if (!udev_list_node_is_empty(&event_list)) {
+ int fd;
+
+ fd = open("/run/udev/queue", O_WRONLY|O_CREAT|O_CLOEXEC|O_TRUNC|O_NOFOLLOW, 0444);
+ if (fd >= 0)
+ close(fd);
+ } else {
+ unlink("/run/udev/queue");
fdcount = epoll_wait(fd_ep, ev, ELEMENTSOF(ev), timeout);
if (fdcount < 0)
continue;
fdcount = epoll_wait(fd_ep, ev, ELEMENTSOF(ev), timeout);
if (fdcount < 0)
continue;
- if ((now(CLOCK_MONOTONIC) - worker->event_start_usec) > 30 * 1000 * 1000) {
- log_error("worker [%u] %s timeout; kill it\n", worker->pid,
+ if ((now(CLOCK_MONOTONIC) - worker->event_start_usec) > 30 * USEC_PER_SEC) {
+ log_error("worker [%u] %s timeout; kill it", worker->pid,
worker->event ? worker->event->devpath : "<idle>");
kill(worker->pid, SIGKILL);
worker->state = WORKER_KILLED;
worker->event ? worker->event->devpath : "<idle>");
kill(worker->pid, SIGKILL);
worker->state = WORKER_KILLED;
- log_error("seq %llu '%s' killed\n",
- udev_device_get_seqnum(worker->event->dev), worker->event->devpath);
+ log_error("seq %llu '%s' killed", udev_device_get_seqnum(worker->event->dev), worker->event->devpath);
if (worker_watch[WRITE_END] >= 0)
close(worker_watch[WRITE_END]);
udev_monitor_unref(monitor);
if (worker_watch[WRITE_END] >= 0)
close(worker_watch[WRITE_END]);
udev_monitor_unref(monitor);