diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2022-04-15 09:42:15 +0900 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2022-09-12 01:23:08 +0900 |
commit | cd66f972d105c443f4ab89cc9d3406a2fc88f974 (patch) | |
tree | 108b9740af44aae883ba70bfb522625db03fab6c | |
parent | ea8213dc47312e6091b38db2a783c594ebee4f5f (diff) | |
download | systemd-cd66f972d105c443f4ab89cc9d3406a2fc88f974.tar.gz |
udev: ignore IN_IGNORED inotify event earlier
-rw-r--r-- | src/udev/udevd.c | 26 |
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; |