From 214db8eb5d109cade4f4cb6046dc248f8e23bf27 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 8 Dec 2021 03:48:46 +0900 Subject: [PATCH] resolve: do not re-read settings from networkd if link state file is unmodified 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 | 38 ++++++++++++++++++++++++++----------- src/resolve/resolved-link.h | 3 +++ 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/resolve/resolved-link.c b/src/resolve/resolved-link.c index 0013cd0b7fb..6c910498a25 100644 --- a/src/resolve/resolved-link.c +++ b/src/resolve/resolved-link.c @@ -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; diff --git a/src/resolve/resolved-link.h b/src/resolve/resolved-link.h index 3c364866f6d..f65718ce310 100644 --- a/src/resolve/resolved-link.h +++ b/src/resolve/resolved-link.h @@ -1,6 +1,8 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once +#include + #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; -- 2.47.3