summaryrefslogtreecommitdiff
path: root/src/udev
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2022-04-21 17:47:51 +0900
committerYu Watanabe <watanabe.yu+github@gmail.com>2022-05-04 17:16:23 +0900
commit34458dbbe795c20442f6262875c74a679c5957e0 (patch)
treec39c7e13f92189e26c8ec3764248b8286c9bc258 /src/udev
parenta1af9668ec78fc11a2e7ac942397eac0c8fceced (diff)
downloadsystemd-34458dbbe795c20442f6262875c74a679c5957e0.tar.gz
udev: also make uevent blocked by events for the same device node
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.
Diffstat (limited to 'src/udev')
-rw-r--r--src/udev/udevd.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/src/udev/udevd.c b/src/udev/udevd.c
index b2291c85ca..8a06d08c4a 100644
--- a/src/udev/udevd.c
+++ b/src/udev/udevd.c
@@ -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,
};