From: Daan De Meyer Date: Tue, 3 May 2022 11:54:49 +0000 (+0200) Subject: sd-network: Keep inotify watch if watch descriptor didn't change X-Git-Tag: v251-rc2~21 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=206c0897a28e185f648dd3c7cdefdbe7680b0528;p=thirdparty%2Fsystemd.git sd-network: Keep inotify watch if watch descriptor didn't change In sd_network_monitor_flush(), we shouldn't remove the inotify watch for the current directory if the directory the network monitor is waiting for wasn't created yet. inotify_add_watch() returns the same unique watch descriptor if a path is already being watched. Let's return the watch descriptor from monitor_add_inotify_watch() so we can check if it's the same as the watch descriptor of the inotify event. If they are equal, we're still watching the same path and we don't need to remove the inotify watch just yet. --- diff --git a/src/libsystemd/sd-network/sd-network.c b/src/libsystemd/sd-network/sd-network.c index a5612ab2d3b..408c0a1f471 100644 --- a/src/libsystemd/sd-network/sd-network.c +++ b/src/libsystemd/sd-network/sd-network.c @@ -413,25 +413,25 @@ static sd_network_monitor* FD_TO_MONITOR(int fd) { } static int monitor_add_inotify_watch(int fd) { - int k; + int wd; - k = inotify_add_watch(fd, "/run/systemd/netif/links/", IN_MOVED_TO|IN_DELETE); - if (k >= 0) - return 0; + wd = inotify_add_watch(fd, "/run/systemd/netif/links/", IN_MOVED_TO|IN_DELETE); + if (wd >= 0) + return wd; else if (errno != ENOENT) return -errno; - k = inotify_add_watch(fd, "/run/systemd/netif/", IN_CREATE|IN_ISDIR); - if (k >= 0) - return 0; + wd = inotify_add_watch(fd, "/run/systemd/netif/", IN_CREATE|IN_ISDIR); + if (wd >= 0) + return wd; else if (errno != ENOENT) return -errno; - k = inotify_add_watch(fd, "/run/systemd/", IN_CREATE|IN_ISDIR); - if (k < 0) + wd = inotify_add_watch(fd, "/run/systemd/", IN_CREATE|IN_ISDIR); + if (wd < 0) return -errno; - return 0; + return wd; } int sd_network_monitor_new(sd_network_monitor **m, const char *category) { @@ -470,7 +470,7 @@ sd_network_monitor* sd_network_monitor_unref(sd_network_monitor *m) { int sd_network_monitor_flush(sd_network_monitor *m) { union inotify_event_buffer buffer; ssize_t l; - int fd, k; + int fd; assert_return(m, -EINVAL); @@ -486,13 +486,16 @@ int sd_network_monitor_flush(sd_network_monitor *m) { FOREACH_INOTIFY_EVENT(e, buffer, l) { if (e->mask & IN_ISDIR) { - k = monitor_add_inotify_watch(fd); - if (k < 0) - return k; + int wd; + + wd = monitor_add_inotify_watch(fd); + if (wd < 0) + return wd; - k = inotify_rm_watch(fd, e->wd); - if (k < 0) - return -errno; + if (wd != e->wd) { + if (inotify_rm_watch(fd, e->wd) < 0) + return -errno; + } } }