summaryrefslogtreecommitdiff
path: root/src/resolve/resolved-link.c
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2021-12-08 03:48:46 +0900
committerYu Watanabe <watanabe.yu+github@gmail.com>2021-12-08 18:34:08 +0900
commit214db8eb5d109cade4f4cb6046dc248f8e23bf27 (patch)
treeafec75f862258b77a81bc4cc77fe337e49bb0df0 /src/resolve/resolved-link.c
parent8e0bacab6eedbc790bb7ed3218da2e929ebfdab1 (diff)
downloadsystemd-214db8eb5d109cade4f4cb6046dc248f8e23bf27.tar.gz
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.
Diffstat (limited to 'src/resolve/resolved-link.c')
-rw-r--r--src/resolve/resolved-link.c38
1 files changed, 27 insertions, 11 deletions
diff --git a/src/resolve/resolved-link.c b/src/resolve/resolved-link.c
index 0013cd0b7f..6c910498a2 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;