summaryrefslogtreecommitdiff
path: root/src/udev/net
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2022-04-22 12:33:15 +0900
committerDaan De Meyer <daan.j.demeyer@gmail.com>2022-05-03 10:26:22 +0200
commitbdb2d3c6889408c7f26c2eeddbe9021ac53f962c (patch)
treeb7fde0f15e2665ed9f195aa9f5e50239365f76f0 /src/udev/net
parent968680b23d1629d33deeea98b4f2b5fd106075b5 (diff)
downloadsystemd-bdb2d3c6889408c7f26c2eeddbe9021ac53f962c.tar.gz
udev: check stats of .link files and their drop-in files
Fixes #23128.
Diffstat (limited to 'src/udev/net')
-rw-r--r--src/udev/net/link-config.c33
1 files changed, 27 insertions, 6 deletions
diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
index 2de172a67a..42745b6c59 100644
--- a/src/udev/net/link-config.c
+++ b/src/udev/net/link-config.c
@@ -40,6 +40,7 @@ struct LinkConfigContext {
LIST_HEAD(LinkConfig, configs);
int ethtool_fd;
usec_t network_dirs_ts_usec;
+ Hashmap *stats_by_path;
};
static LinkConfig* link_config_free(LinkConfig *config) {
@@ -71,6 +72,8 @@ static void link_configs_free(LinkConfigContext *ctx) {
if (!ctx)
return;
+ ctx->stats_by_path = hashmap_free(ctx->stats_by_path);
+
LIST_FOREACH(configs, config, ctx->configs)
link_config_free(config);
}
@@ -207,6 +210,7 @@ static int link_adjust_wol_options(LinkConfig *config) {
int link_load_one(LinkConfigContext *ctx, const char *filename) {
_cleanup_(link_config_freep) LinkConfig *config = NULL;
+ _cleanup_hashmap_free_ Hashmap *stats_by_path = NULL;
_cleanup_free_ char *name = NULL;
const char *dropin_dirname;
size_t i;
@@ -254,16 +258,23 @@ int link_load_one(LinkConfigContext *ctx, const char *filename) {
dropin_dirname = strjoina(basename(filename), ".d");
r = config_parse_many(
STRV_MAKE_CONST(filename),
- (const char* const*) CONF_PATHS_STRV("systemd/network"),
+ NETWORK_DIRS,
dropin_dirname,
"Match\0"
"Link\0"
"SR-IOV\0",
config_item_perf_lookup, link_config_gperf_lookup,
- CONFIG_PARSE_WARN, config, NULL);
+ CONFIG_PARSE_WARN, config, &stats_by_path);
if (r < 0)
return r; /* config_parse_many() logs internally. */
+ if (ctx->stats_by_path) {
+ r = hashmap_move(ctx->stats_by_path, stats_by_path);
+ if (r < 0)
+ log_warning_errno(r, "Failed to save stats of '%s' and its drop-in configs, ignoring: %m", filename);
+ } else
+ ctx->stats_by_path = TAKE_PTR(stats_by_path);
+
if (net_match_is_empty(&config->match) && !config->conditions) {
log_warning("%s: No valid settings found in the [Match] section, ignoring file. "
"To match all interfaces, add OriginalName=* in the [Match] section.",
@@ -316,10 +327,9 @@ int link_config_load(LinkConfigContext *ctx) {
_cleanup_strv_free_ char **files = NULL;
int r;
- link_configs_free(ctx);
+ assert(ctx);
- /* update timestamp */
- paths_check_timestamp(NETWORK_DIRS, &ctx->network_dirs_ts_usec, true);
+ link_configs_free(ctx);
r = conf_files_list_strv(&files, ".link", NULL, 0, NETWORK_DIRS);
if (r < 0)
@@ -332,7 +342,18 @@ int link_config_load(LinkConfigContext *ctx) {
}
bool link_config_should_reload(LinkConfigContext *ctx) {
- return paths_check_timestamp(NETWORK_DIRS, &ctx->network_dirs_ts_usec, false);
+ _cleanup_hashmap_free_ Hashmap *stats_by_path = NULL;
+ int r;
+
+ assert(ctx);
+
+ r = config_get_stats_by_path(".link", NULL, 0, NETWORK_DIRS, &stats_by_path);
+ if (r < 0) {
+ log_warning_errno(r, "Failed to get stats of .link files: %m");
+ return true;
+ }
+
+ return !stats_by_path_equal(ctx->stats_by_path, stats_by_path);
}
Link *link_free(Link *link) {