summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2022-04-15 09:42:15 +0900
committerYu Watanabe <watanabe.yu+github@gmail.com>2022-09-12 01:23:08 +0900
commitcd66f972d105c443f4ab89cc9d3406a2fc88f974 (patch)
tree108b9740af44aae883ba70bfb522625db03fab6c
parentea8213dc47312e6091b38db2a783c594ebee4f5f (diff)
downloadsystemd-cd66f972d105c443f4ab89cc9d3406a2fc88f974.tar.gz
udev: ignore IN_IGNORED inotify event earlier
-rw-r--r--src/udev/udevd.c26
1 files changed, 18 insertions, 8 deletions
diff --git a/src/udev/udevd.c b/src/udev/udevd.c
index 2574844ed7..25496975d5 100644
--- a/src/udev/udevd.c
+++ b/src/udev/udevd.c
@@ -1447,23 +1447,33 @@ static int on_inotify(sd_event_source *s, int fd, uint32_t revents, void *userda
_cleanup_(sd_device_unrefp) sd_device *dev = NULL;
const char *devnode;
+ /* Do not handle IN_IGNORED here. Especially, do not try to call udev_watch_end() from the
+ * main process. Otherwise, the pair of the symlinks may become inconsistent, and several
+ * garbage may remain. The old symlinks are removed by a worker that processes the
+ * corresponding 'remove' uevent;
+ * udev_event_execute_rules() -> event_execute_rules_on_remove() -> udev_watch_end(). */
+
+ if (!FLAGS_SET(e->mask, IN_CLOSE_WRITE))
+ continue;
+
r = device_new_from_watch_handle(&dev, e->wd);
if (r < 0) {
+ /* Device may be removed just after closed. */
log_debug_errno(r, "Failed to create sd_device object from watch handle, ignoring: %m");
continue;
}
- if (sd_device_get_devname(dev, &devnode) < 0)
+ r = sd_device_get_devname(dev, &devnode);
+ if (r < 0) {
+ /* Also here, device may be already removed. */
+ log_device_debug_errno(dev, r, "Failed to get device node, ignoring: %m");
continue;
-
- log_device_debug(dev, "Inotify event: %x for %s", e->mask, devnode);
- if (e->mask & IN_CLOSE_WRITE) {
- (void) event_queue_assume_block_device_unlocked(manager, dev);
- (void) synthesize_change(dev);
}
- /* Do not handle IN_IGNORED here. It should be handled by worker in 'remove' uevent;
- * udev_event_execute_rules() -> event_execute_rules_on_remove() -> udev_watch_end(). */
+ log_device_debug(dev, "Received inotify event for %s.", devnode);
+
+ (void) event_queue_assume_block_device_unlocked(manager, dev);
+ (void) synthesize_change(dev);
}
return 0;