]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
udev: also make uevent blocked by events for the same device node 23088/head
authorYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 21 Apr 2022 08:47:51 +0000 (17:47 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 4 May 2022 08:16:23 +0000 (17:16 +0900)
Even if the device node is the same, devnum (thus, device ID) and
syspath may be different. If a 'remove' and 'add' events for the same
device node but with different devnum and syspath are queued,
previously, we might process them in parallel. And, udev_watch_end() for
the 'remove' event and udev_watch_begin() for the 'add' event may
interfere each other.

src/udev/udevd.c

index b2291c85cae78c87e66137ba72bb75857f46fd7b..8a06d08c4a515507158cf63e5d4b81c44d16e75f 100644 (file)
@@ -134,6 +134,7 @@ typedef struct Event {
         const char *id;
         const char *devpath;
         const char *devpath_old;
+        const char *devnode;
         usec_t retry_again_next_usec;
         usec_t retry_again_timeout_usec;
 
@@ -917,6 +918,9 @@ static int event_is_blocked(Event *event) {
                     devpath_conflict(event->devpath, loop_event->devpath_old) ||
                     devpath_conflict(event->devpath_old, loop_event->devpath))
                         break;
+
+                if (event->devnode && streq_ptr(event->devnode, loop_event->devnode))
+                        break;
         }
 
         assert(loop_event);
@@ -1064,7 +1068,7 @@ static int event_queue_assume_block_device_unlocked(Manager *manager, sd_device
 }
 
 static int event_queue_insert(Manager *manager, sd_device *dev) {
-        const char *devpath, *devpath_old = NULL, *id = NULL;
+        const char *devpath, *devpath_old = NULL, *id = NULL, *devnode = NULL;
         sd_device_action_t action;
         uint64_t seqnum;
         Event *event;
@@ -1097,6 +1101,10 @@ static int event_queue_insert(Manager *manager, sd_device *dev) {
         if (r < 0 && r != -ENOENT)
                 return r;
 
+        r = sd_device_get_devname(dev, &devnode);
+        if (r < 0 && r != -ENOENT)
+                return r;
+
         event = new(Event, 1);
         if (!event)
                 return -ENOMEM;
@@ -1109,6 +1117,7 @@ static int event_queue_insert(Manager *manager, sd_device *dev) {
                 .id = id,
                 .devpath = devpath,
                 .devpath_old = devpath_old,
+                .devnode = devnode,
                 .state = EVENT_QUEUED,
         };