]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-network: Keep inotify watch if watch descriptor didn't change
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Tue, 3 May 2022 11:54:49 +0000 (13:54 +0200)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 3 May 2022 22:00:56 +0000 (07:00 +0900)
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

index a5612ab2d3bc3b6cea5a54d0afb4b32925e57f4a..408c0a1f471e9c95c81749e4b185e1f52abf6188 100644 (file)
@@ -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;
+                        }
                 }
         }