From 206c0897a28e185f648dd3c7cdefdbe7680b0528 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Tue, 3 May 2022 13:54:49 +0200 Subject: [PATCH] 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. --- src/libsystemd/sd-network/sd-network.c | 37 ++++++++++++++------------ 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/src/libsystemd/sd-network/sd-network.c b/src/libsystemd/sd-network/sd-network.c index a5612ab2d3..408c0a1f47 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; + } } } -- 2.25.1