udev: create /run/udev/queue file earlier

When udevd received a uevent or inotify event, we will queue or trigger
synthesized events. To minimize the race between processing these events
by udevd and user invocation of 'udevadm settle', let's create /run/udev/queue
file earlier.
On some errors, no event may be queued, but in that case, the file will
be removed by the post event source if nothing queued. See on_post().

Hopefully mitigate the issue #40499.
This commit is contained in:
Yu Watanabe
2026-02-03 21:25:01 +09:00
parent b7363d3330
commit dc709eff0b
3 changed files with 24 additions and 8 deletions
+21 -8
View File
@@ -969,14 +969,6 @@ static int event_queue_insert(Manager *manager, sd_device *dev) {
TAKE_PTR(event);
log_device_uevent(dev, "Device is queued");
if (!manager->queue_file_created) {
r = touch("/run/udev/queue");
if (r < 0)
log_warning_errno(r, "Failed to touch /run/udev/queue, ignoring: %m");
else
manager->queue_file_created = true;
}
return 0;
}
@@ -1075,6 +1067,9 @@ static int manager_deserialize_events(Manager *manager, int *fd) {
n++;
}
if (n > 0)
(void) manager_create_queue_file(manager);
log_debug("Deserialized %"PRIu64" events.", n);
return 0;
}
@@ -1085,6 +1080,8 @@ static int on_uevent(sd_device_monitor *monitor, sd_device *dev, void *userdata)
DEVICE_TRACE_POINT(kernel_uevent_received, dev);
(void) manager_create_queue_file(manager);
device_ensure_usec_initialized(dev, NULL);
r = event_queue_insert(manager, dev);
@@ -1263,6 +1260,22 @@ static int on_sighup(sd_event_source *s, const struct signalfd_siginfo *si, void
return 1;
}
int manager_create_queue_file(Manager *manager) {
int r;
assert(manager);
if (manager->queue_file_created)
return 0;
r = touch("/run/udev/queue");
if (r < 0)
return log_warning_errno(r, "Failed to touch /run/udev/queue: %m");
manager->queue_file_created = true;
return 0;
}
static int manager_unlink_queue_file(Manager *manager) {
assert(manager);
+2
View File
@@ -93,3 +93,5 @@ int manager_reset_kill_workers_timer(Manager *manager);
bool devpath_conflict(const char *a, const char *b);
int manager_requeue_locked_events_by_device(Manager *manager, sd_device *dev);
int manager_create_queue_file(Manager *manager);
+1
View File
@@ -290,6 +290,7 @@ static int manager_process_inotify(Manager *manager, const struct inotify_event
log_device_debug(dev, "Received inotify event of watch handle %i.", e->wd);
(void) manager_create_queue_file(manager);
(void) manager_requeue_locked_events_by_device(manager, dev);
(void) synthesize_change(manager, dev);
return 0;