diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2021-12-08 03:48:46 +0900 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2021-12-08 18:34:08 +0900 |
commit | 214db8eb5d109cade4f4cb6046dc248f8e23bf27 (patch) | |
tree | afec75f862258b77a81bc4cc77fe337e49bb0df0 /src/resolve/resolved-link.c | |
parent | 8e0bacab6eedbc790bb7ed3218da2e929ebfdab1 (diff) | |
download | systemd-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.c | 38 |
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; |