]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
resolve: do not re-read settings from networkd if link state file is unmodified 21667/head
authorYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 7 Dec 2021 18:48:46 +0000 (03:48 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 8 Dec 2021 09:34:08 +0000 (18:34 +0900)
If many interface creation/deletion occurs continuously, then resolved
becomes easily busy. Let's slightly optimize the event triggered by
sd-network.

src/resolve/resolved-link.c
src/resolve/resolved-link.h

index 0013cd0b7fb3983d232d132847c631616409509c..6c910498a2579bb29725f9aa0b61d65f434f2bdc 100644 (file)
@@ -16,6 +16,7 @@
 #include "resolved-llmnr.h"
 #include "resolved-mdns.h"
 #include "socket-netlink.h"
+#include "stat-util.h"
 #include "string-util.h"
 #include "strv.h"
 #include "tmpfile-util.h"
@@ -568,27 +569,42 @@ static int link_is_managed(Link *l) {
         return !STR_IN_SET(state, "pending", "initialized", "unmanaged");
 }
 
+static void link_enter_unmanaged(Link *l) {
+        assert(l);
+
+        /* If this link used to be managed, but is now unmanaged, flush all our settings — but only once. */
+        if (l->is_managed)
+                link_flush_settings(l);
+
+        l->is_managed = false;
+}
+
 static void link_read_settings(Link *l) {
+        struct stat st;
         int r;
 
         assert(l);
 
         /* Read settings from networkd, except when networkd is not managing this interface. */
 
-        r = link_is_managed(l);
-        if (r < 0) {
-                log_link_warning_errno(l, r, "Failed to determine whether the interface is managed: %m");
+        r = sd_network_link_get_stat(l->ifindex, &st);
+        if (r == -ENOENT)
+                return link_enter_unmanaged(l);
+        if (r < 0)
+                return (void) log_link_warning_errno(l, r, "Failed to stat() networkd's link state file, ignoring: %m");
+
+        if (stat_inode_unmodified(&l->networkd_state_file_stat, &st))
+                /* The state file is unmodified. Not necessary to re-read settings. */
                 return;
-        }
-        if (r == 0) {
 
-                /* If this link used to be managed, but is now unmanaged, flush all our settings — but only once. */
-                if (l->is_managed)
-                        link_flush_settings(l);
+        /* Save the new stat for the next event. */
+        l->networkd_state_file_stat = st;
 
-                l->is_managed = false;
-                return;
-        }
+        r = link_is_managed(l);
+        if (r < 0)
+                return (void) log_link_warning_errno(l, r, "Failed to determine whether the interface is managed, ignoring: %m");
+        if (r == 0)
+                return link_enter_unmanaged(l);
 
         l->is_managed = true;
 
index 3c364866f6d274d2da9dbd5f6ca71761775f083f..f65718ce310ca6d50a81147d4734ec4d158210e5 100644 (file)
@@ -1,6 +1,8 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 #pragma once
 
+#include <sys/stat.h>
+
 #include "sd-netlink.h"
 
 #include "in-addr-util.h"
@@ -65,6 +67,7 @@ struct Link {
         DnsScope *mdns_ipv4_scope;
         DnsScope *mdns_ipv6_scope;
 
+        struct stat networkd_state_file_stat;
         bool is_managed;
 
         char *ifname;