mirror of
https://github.com/systemd/systemd
synced 2026-04-26 08:54:50 +02:00
Compare commits
6 Commits
b626f6959b
...
bdb2d3c688
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bdb2d3c688 | ||
|
|
968680b23d | ||
|
|
9c96c89bb3 | ||
|
|
5f994fffb9 | ||
|
|
9a390e86b7 | ||
|
|
4d8b09e4b8 |
2
.github/workflows/build_test.yml
vendored
2
.github/workflows/build_test.yml
vendored
@ -33,6 +33,6 @@ jobs:
|
|||||||
env: ${{ matrix.env }}
|
env: ${{ matrix.env }}
|
||||||
steps:
|
steps:
|
||||||
- name: Repository checkout
|
- name: Repository checkout
|
||||||
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
|
uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b
|
||||||
- name: ${{ format('Build check ({0}-{1}-{2}-{3})', env.COMPILER, env.COMPILER_VERSION, env.LINKER, env.CRYPTOLIB) }}
|
- name: ${{ format('Build check ({0}-{1}-{2}-{3})', env.COMPILER, env.COMPILER_VERSION, env.LINKER, env.CRYPTOLIB) }}
|
||||||
run: sudo -E .github/workflows/build_test.sh
|
run: sudo -E .github/workflows/build_test.sh
|
||||||
|
|||||||
2
.github/workflows/codeql-analysis.yml
vendored
2
.github/workflows/codeql-analysis.yml
vendored
@ -40,7 +40,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
|
uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b
|
||||||
|
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@28eead240834b314f7def40f6fcba65d100d99b1
|
uses: github/codeql-action/init@28eead240834b314f7def40f6fcba65d100d99b1
|
||||||
|
|||||||
2
.github/workflows/coverity.yml
vendored
2
.github/workflows/coverity.yml
vendored
@ -25,7 +25,7 @@ jobs:
|
|||||||
CURRENT_REF: "${{ github.ref }}"
|
CURRENT_REF: "${{ github.ref }}"
|
||||||
steps:
|
steps:
|
||||||
- name: Repository checkout
|
- name: Repository checkout
|
||||||
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
|
uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b
|
||||||
# https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-commands-for-github-actions#setting-an-environment-variable
|
# https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-commands-for-github-actions#setting-an-environment-variable
|
||||||
- name: Set the $COVERITY_SCAN_NOTIFICATION_EMAIL env variable
|
- name: Set the $COVERITY_SCAN_NOTIFICATION_EMAIL env variable
|
||||||
run: echo "COVERITY_SCAN_NOTIFICATION_EMAIL=$(git log -1 ${{ github.sha }} --pretty=\"%aE\")" >> "$GITHUB_ENV"
|
run: echo "COVERITY_SCAN_NOTIFICATION_EMAIL=$(git log -1 ${{ github.sha }} --pretty=\"%aE\")" >> "$GITHUB_ENV"
|
||||||
|
|||||||
4
.github/workflows/linter.yml
vendored
4
.github/workflows/linter.yml
vendored
@ -23,13 +23,13 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Repo checkout
|
- name: Repo checkout
|
||||||
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
|
uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b
|
||||||
with:
|
with:
|
||||||
# We need a full repo clone
|
# We need a full repo clone
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Lint Code Base
|
- name: Lint Code Base
|
||||||
uses: github/super-linter/slim@3792fe5373cf2f5b22d590fcbbc4533d735c573e
|
uses: github/super-linter/slim@ae4e373c56efad95924d9cc6b89624fdb2333007
|
||||||
env:
|
env:
|
||||||
DEFAULT_BRANCH: main
|
DEFAULT_BRANCH: main
|
||||||
MULTI_STATUS: false
|
MULTI_STATUS: false
|
||||||
|
|||||||
2
.github/workflows/mkosi.yml
vendored
2
.github/workflows/mkosi.yml
vendored
@ -48,7 +48,7 @@ jobs:
|
|||||||
release: 9-stream
|
release: 9-stream
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
|
- uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b
|
||||||
- uses: systemd/mkosi@93098e2406e12ea7f06f962d4808952b8a06d345
|
- uses: systemd/mkosi@93098e2406e12ea7f06f962d4808952b8a06d345
|
||||||
|
|
||||||
- name: Install
|
- name: Install
|
||||||
|
|||||||
2
.github/workflows/unit_tests.yml
vendored
2
.github/workflows/unit_tests.yml
vendored
@ -30,7 +30,7 @@ jobs:
|
|||||||
cryptolib: gcrypt
|
cryptolib: gcrypt
|
||||||
steps:
|
steps:
|
||||||
- name: Repository checkout
|
- name: Repository checkout
|
||||||
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
|
uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b
|
||||||
- name: Install build dependencies
|
- name: Install build dependencies
|
||||||
run: sudo -E .github/workflows/unit_tests.sh SETUP
|
run: sudo -E .github/workflows/unit_tests.sh SETUP
|
||||||
- name: Build & test (${{ matrix.run_phase }}-${{ matrix.cryptolib }})
|
- name: Build & test (${{ matrix.run_phase }}-${{ matrix.cryptolib }})
|
||||||
|
|||||||
@ -2358,6 +2358,19 @@ static int generic_array_bisect(
|
|||||||
uint64_t *ret_offset,
|
uint64_t *ret_offset,
|
||||||
uint64_t *ret_idx) {
|
uint64_t *ret_idx) {
|
||||||
|
|
||||||
|
/* Given an entry array chain, this function finds the object "closest" to the given needle in the
|
||||||
|
* chain, taking into account the provided direction. A function can be provided to determine how
|
||||||
|
* an object is matched against the given needle.
|
||||||
|
*
|
||||||
|
* Given a journal file, the offset of an object and the needle, the test_object() function should
|
||||||
|
* return TEST_LEFT if the needle is located earlier in the entry array chain, TEST_RIGHT if the
|
||||||
|
* needle is located later in the entry array chain and TEST_FOUND if the object matches the needle.
|
||||||
|
* If test_object() returns TEST_FOUND for a specific object, that object's information will be used
|
||||||
|
* to populate the return values of this function. If test_object() never returns TEST_FOUND, the
|
||||||
|
* return values are populated with the details of one of the objects closest to the needle. If the
|
||||||
|
* direction is DIRECTION_UP, the earlier object is used. Otherwise, the later object is used.
|
||||||
|
*/
|
||||||
|
|
||||||
uint64_t a, p, t = 0, i = 0, last_p = 0, last_index = UINT64_MAX;
|
uint64_t a, p, t = 0, i = 0, last_p = 0, last_index = UINT64_MAX;
|
||||||
bool subtract_one = false;
|
bool subtract_one = false;
|
||||||
Object *array = NULL;
|
Object *array = NULL;
|
||||||
|
|||||||
@ -493,7 +493,6 @@ static int next_for_match(
|
|||||||
|
|
||||||
int r;
|
int r;
|
||||||
uint64_t np = 0;
|
uint64_t np = 0;
|
||||||
Object *n;
|
|
||||||
|
|
||||||
assert(j);
|
assert(j);
|
||||||
assert(m);
|
assert(m);
|
||||||
@ -569,12 +568,12 @@ static int next_for_match(
|
|||||||
|
|
||||||
assert(np > 0);
|
assert(np > 0);
|
||||||
|
|
||||||
r = journal_file_move_to_object(f, OBJECT_ENTRY, np, &n);
|
if (ret) {
|
||||||
if (r < 0)
|
r = journal_file_move_to_object(f, OBJECT_ENTRY, np, ret);
|
||||||
return r;
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
if (ret)
|
|
||||||
*ret = n;
|
|
||||||
if (offset)
|
if (offset)
|
||||||
*offset = np;
|
*offset = np;
|
||||||
|
|
||||||
@ -633,7 +632,6 @@ static int find_location_for_match(
|
|||||||
|
|
||||||
} else if (m->type == MATCH_OR_TERM) {
|
} else if (m->type == MATCH_OR_TERM) {
|
||||||
uint64_t np = 0;
|
uint64_t np = 0;
|
||||||
Object *n;
|
|
||||||
|
|
||||||
/* Find the earliest match */
|
/* Find the earliest match */
|
||||||
|
|
||||||
@ -652,12 +650,12 @@ static int find_location_for_match(
|
|||||||
if (np == 0)
|
if (np == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
r = journal_file_move_to_object(f, OBJECT_ENTRY, np, &n);
|
if (ret) {
|
||||||
if (r < 0)
|
r = journal_file_move_to_object(f, OBJECT_ENTRY, np, ret);
|
||||||
return r;
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
if (ret)
|
|
||||||
*ret = n;
|
|
||||||
if (offset)
|
if (offset)
|
||||||
*offset = np;
|
*offset = np;
|
||||||
|
|
||||||
|
|||||||
@ -591,28 +591,6 @@ int network_load(Manager *manager, OrderedHashmap **networks) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool stats_by_path_equal(Hashmap *a, Hashmap *b) {
|
|
||||||
struct stat *st_a, *st_b;
|
|
||||||
const char *path;
|
|
||||||
|
|
||||||
assert(a);
|
|
||||||
assert(b);
|
|
||||||
|
|
||||||
if (hashmap_size(a) != hashmap_size(b))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
HASHMAP_FOREACH_KEY(st_a, path, a) {
|
|
||||||
st_b = hashmap_get(b, path);
|
|
||||||
if (!st_b)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!stat_inode_unmodified(st_a, st_b))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
int network_reload(Manager *manager) {
|
int network_reload(Manager *manager) {
|
||||||
OrderedHashmap *new_networks = NULL;
|
OrderedHashmap *new_networks = NULL;
|
||||||
Network *n, *old;
|
Network *n, *old;
|
||||||
|
|||||||
@ -34,6 +34,7 @@
|
|||||||
#include "set.h"
|
#include "set.h"
|
||||||
#include "signal-util.h"
|
#include "signal-util.h"
|
||||||
#include "socket-util.h"
|
#include "socket-util.h"
|
||||||
|
#include "stat-util.h"
|
||||||
#include "string-util.h"
|
#include "string-util.h"
|
||||||
#include "strv.h"
|
#include "strv.h"
|
||||||
#include "syslog-util.h"
|
#include "syslog-util.h"
|
||||||
@ -556,6 +557,27 @@ int config_parse_many_nulstr(
|
|||||||
ret_stats_by_path);
|
ret_stats_by_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int config_get_dropin_files(
|
||||||
|
const char* const* conf_file_dirs,
|
||||||
|
const char *dropin_dirname,
|
||||||
|
char ***ret) {
|
||||||
|
|
||||||
|
_cleanup_strv_free_ char **dropin_dirs = NULL;
|
||||||
|
const char *suffix;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(conf_file_dirs);
|
||||||
|
assert(dropin_dirname);
|
||||||
|
assert(ret);
|
||||||
|
|
||||||
|
suffix = strjoina("/", dropin_dirname);
|
||||||
|
r = strv_extend_strv_concat(&dropin_dirs, (char**) conf_file_dirs, suffix);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
return conf_files_list_strv(ret, ".conf", NULL, 0, (const char* const*) dropin_dirs);
|
||||||
|
}
|
||||||
|
|
||||||
/* Parse each config file in the directories specified as strv. */
|
/* Parse each config file in the directories specified as strv. */
|
||||||
int config_parse_many(
|
int config_parse_many(
|
||||||
const char* const* conf_files,
|
const char* const* conf_files,
|
||||||
@ -568,23 +590,128 @@ int config_parse_many(
|
|||||||
void *userdata,
|
void *userdata,
|
||||||
Hashmap **ret_stats_by_path) {
|
Hashmap **ret_stats_by_path) {
|
||||||
|
|
||||||
_cleanup_strv_free_ char **dropin_dirs = NULL;
|
|
||||||
_cleanup_strv_free_ char **files = NULL;
|
_cleanup_strv_free_ char **files = NULL;
|
||||||
const char *suffix;
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
suffix = strjoina("/", dropin_dirname);
|
assert(conf_file_dirs);
|
||||||
r = strv_extend_strv_concat(&dropin_dirs, (char**) conf_file_dirs, suffix);
|
assert(dropin_dirname);
|
||||||
if (r < 0)
|
assert(sections);
|
||||||
return r;
|
assert(table);
|
||||||
|
|
||||||
r = conf_files_list_strv(&files, ".conf", NULL, 0, (const char* const*) dropin_dirs);
|
r = config_get_dropin_files(conf_file_dirs, dropin_dirname, &files);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
return config_parse_many_files(conf_files, files, sections, lookup, table, flags, userdata, ret_stats_by_path);
|
return config_parse_many_files(conf_files, files, sections, lookup, table, flags, userdata, ret_stats_by_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int config_get_stats_by_path_one(
|
||||||
|
const char* conf_file,
|
||||||
|
const char* const* conf_file_dirs,
|
||||||
|
Hashmap *stats_by_path) {
|
||||||
|
|
||||||
|
_cleanup_strv_free_ char **files = NULL;
|
||||||
|
_cleanup_free_ char *dropin_dirname = NULL;
|
||||||
|
struct stat st;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(conf_file);
|
||||||
|
assert(conf_file_dirs);
|
||||||
|
assert(stats_by_path);
|
||||||
|
|
||||||
|
/* Unlike config_parse(), this does not support stream. */
|
||||||
|
|
||||||
|
r = path_extract_filename(conf_file, &dropin_dirname);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
if (r == O_DIRECTORY)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (!strextend(&dropin_dirname, ".d"))
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
r = config_get_dropin_files(conf_file_dirs, dropin_dirname, &files);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
/* First read the main config file. */
|
||||||
|
r = RET_NERRNO(stat(conf_file, &st));
|
||||||
|
if (r >= 0) {
|
||||||
|
r = hashmap_put_stats_by_path(&stats_by_path, conf_file, &st);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
} else if (r != -ENOENT)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
/* Then read all the drop-ins. */
|
||||||
|
STRV_FOREACH(fn, files) {
|
||||||
|
if (stat(*fn, &st) < 0) {
|
||||||
|
if (errno == ENOENT)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = hashmap_put_stats_by_path(&stats_by_path, *fn, &st);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int config_get_stats_by_path(
|
||||||
|
const char *suffix,
|
||||||
|
const char *root,
|
||||||
|
unsigned flags,
|
||||||
|
const char* const* dirs,
|
||||||
|
Hashmap **ret) {
|
||||||
|
|
||||||
|
_cleanup_hashmap_free_ Hashmap *stats_by_path = NULL;
|
||||||
|
_cleanup_strv_free_ char **files = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(suffix);
|
||||||
|
assert(dirs);
|
||||||
|
assert(ret);
|
||||||
|
|
||||||
|
r = conf_files_list_strv(&files, suffix, root, flags, dirs);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
stats_by_path = hashmap_new(&path_hash_ops_free_free);
|
||||||
|
if (!stats_by_path)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
STRV_FOREACH(f, files) {
|
||||||
|
r = config_get_stats_by_path_one(*f, dirs, stats_by_path);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ret = TAKE_PTR(stats_by_path);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool stats_by_path_equal(Hashmap *a, Hashmap *b) {
|
||||||
|
struct stat *st_a, *st_b;
|
||||||
|
const char *path;
|
||||||
|
|
||||||
|
if (hashmap_size(a) != hashmap_size(b))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
HASHMAP_FOREACH_KEY(st_a, path, a) {
|
||||||
|
st_b = hashmap_get(b, path);
|
||||||
|
if (!st_b)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!stat_inode_unmodified(st_a, st_b))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static void config_section_hash_func(const ConfigSection *c, struct siphash *state) {
|
static void config_section_hash_func(const ConfigSection *c, struct siphash *state) {
|
||||||
siphash24_compress_string(c->filename, state);
|
siphash24_compress_string(c->filename, state);
|
||||||
siphash24_compress(&c->line, sizeof(c->line), state);
|
siphash24_compress(&c->line, sizeof(c->line), state);
|
||||||
|
|||||||
@ -114,6 +114,15 @@ int config_parse_many(
|
|||||||
void *userdata,
|
void *userdata,
|
||||||
Hashmap **ret_stats_by_path); /* possibly NULL */
|
Hashmap **ret_stats_by_path); /* possibly NULL */
|
||||||
|
|
||||||
|
int config_get_stats_by_path(
|
||||||
|
const char *suffix,
|
||||||
|
const char *root,
|
||||||
|
unsigned flags,
|
||||||
|
const char* const* dirs,
|
||||||
|
Hashmap **ret);
|
||||||
|
|
||||||
|
bool stats_by_path_equal(Hashmap *a, Hashmap *b);
|
||||||
|
|
||||||
typedef struct ConfigSection {
|
typedef struct ConfigSection {
|
||||||
unsigned line;
|
unsigned line;
|
||||||
bool invalid;
|
bool invalid;
|
||||||
|
|||||||
@ -40,6 +40,7 @@ struct LinkConfigContext {
|
|||||||
LIST_HEAD(LinkConfig, configs);
|
LIST_HEAD(LinkConfig, configs);
|
||||||
int ethtool_fd;
|
int ethtool_fd;
|
||||||
usec_t network_dirs_ts_usec;
|
usec_t network_dirs_ts_usec;
|
||||||
|
Hashmap *stats_by_path;
|
||||||
};
|
};
|
||||||
|
|
||||||
static LinkConfig* link_config_free(LinkConfig *config) {
|
static LinkConfig* link_config_free(LinkConfig *config) {
|
||||||
@ -71,6 +72,8 @@ static void link_configs_free(LinkConfigContext *ctx) {
|
|||||||
if (!ctx)
|
if (!ctx)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
ctx->stats_by_path = hashmap_free(ctx->stats_by_path);
|
||||||
|
|
||||||
LIST_FOREACH(configs, config, ctx->configs)
|
LIST_FOREACH(configs, config, ctx->configs)
|
||||||
link_config_free(config);
|
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) {
|
int link_load_one(LinkConfigContext *ctx, const char *filename) {
|
||||||
_cleanup_(link_config_freep) LinkConfig *config = NULL;
|
_cleanup_(link_config_freep) LinkConfig *config = NULL;
|
||||||
|
_cleanup_hashmap_free_ Hashmap *stats_by_path = NULL;
|
||||||
_cleanup_free_ char *name = NULL;
|
_cleanup_free_ char *name = NULL;
|
||||||
const char *dropin_dirname;
|
const char *dropin_dirname;
|
||||||
size_t i;
|
size_t i;
|
||||||
@ -254,16 +258,23 @@ int link_load_one(LinkConfigContext *ctx, const char *filename) {
|
|||||||
dropin_dirname = strjoina(basename(filename), ".d");
|
dropin_dirname = strjoina(basename(filename), ".d");
|
||||||
r = config_parse_many(
|
r = config_parse_many(
|
||||||
STRV_MAKE_CONST(filename),
|
STRV_MAKE_CONST(filename),
|
||||||
(const char* const*) CONF_PATHS_STRV("systemd/network"),
|
NETWORK_DIRS,
|
||||||
dropin_dirname,
|
dropin_dirname,
|
||||||
"Match\0"
|
"Match\0"
|
||||||
"Link\0"
|
"Link\0"
|
||||||
"SR-IOV\0",
|
"SR-IOV\0",
|
||||||
config_item_perf_lookup, link_config_gperf_lookup,
|
config_item_perf_lookup, link_config_gperf_lookup,
|
||||||
CONFIG_PARSE_WARN, config, NULL);
|
CONFIG_PARSE_WARN, config, &stats_by_path);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r; /* config_parse_many() logs internally. */
|
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) {
|
if (net_match_is_empty(&config->match) && !config->conditions) {
|
||||||
log_warning("%s: No valid settings found in the [Match] section, ignoring file. "
|
log_warning("%s: No valid settings found in the [Match] section, ignoring file. "
|
||||||
"To match all interfaces, add OriginalName=* in the [Match] section.",
|
"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;
|
_cleanup_strv_free_ char **files = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
link_configs_free(ctx);
|
assert(ctx);
|
||||||
|
|
||||||
/* update timestamp */
|
link_configs_free(ctx);
|
||||||
paths_check_timestamp(NETWORK_DIRS, &ctx->network_dirs_ts_usec, true);
|
|
||||||
|
|
||||||
r = conf_files_list_strv(&files, ".link", NULL, 0, NETWORK_DIRS);
|
r = conf_files_list_strv(&files, ".link", NULL, 0, NETWORK_DIRS);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@ -332,7 +342,18 @@ int link_config_load(LinkConfigContext *ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool link_config_should_reload(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) {
|
Link *link_free(Link *link) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user