summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2020-09-29 21:03:49 +0200
committerLennart Poettering <lennart@poettering.net>2020-10-09 13:22:25 +0200
commite13d96ca2c956d4b8660a3b30d716316265de7b7 (patch)
treedeb100a3d59d291b4443243f19f6bbb26951d05b /src
parentMerge pull request #17289 from keszybz/two-coverity-fixes (diff)
downloadsystemd-e13d96ca2c956d4b8660a3b30d716316265de7b7.tar.xz
systemd-e13d96ca2c956d4b8660a3b30d716316265de7b7.zip
udev-util: ignore remove events, we care about initialization after all
Diffstat (limited to 'src')
-rw-r--r--src/shared/udev-util.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/src/shared/udev-util.c b/src/shared/udev-util.c
index b8c5bdc4b8..98bbfb2ae3 100644
--- a/src/shared/udev-util.c
+++ b/src/shared/udev-util.c
@@ -154,6 +154,22 @@ static int device_monitor_handler(sd_device_monitor *monitor, sd_device *device,
assert(data->sysname || data->devlink);
assert(!data->device);
+ /* Ignore REMOVE events here. We are waiting for initialization after all, not de-initialization. We
+ * might see a REMOVE event from an earlier use of the device (devices by the same name are recycled
+ * by the kernel after all), which we should not get confused by. After all we cannot distinguish use
+ * cycles of the devices, as the udev queue is entirely asynchronous.
+ *
+ * If we see a REMOVE event here for the use cycle we actually care about then we won't notice of
+ * course, but that should be OK, given the timeout logic used on the wait loop: this will be noticed
+ * by means of -ETIMEDOUT. Thus we won't notice immediately, but eventually, and that should be
+ * sufficient for an error path that should regularly not happen.
+ *
+ * (And yes, we only need to special case REMOVE. It's the only "negative" event type, where a device
+ * ceases to exist. All other event types are "positive": the device exists and is registered in the
+ * udev database, thus whenever we see the event, we can consider it initialized.) */
+ if (device_for_action(device, DEVICE_ACTION_REMOVE))
+ return 0;
+
if (data->sysname && sd_device_get_sysname(device, &sysname) >= 0 && streq(sysname, data->sysname))
goto found;