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:
+21
-8
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user