1
0
mirror of https://github.com/systemd/systemd synced 2026-04-26 08:54:50 +02:00

Compare commits

...

6 Commits

Author SHA1 Message Date
Yu Watanabe
bdb2d3c688 udev: check stats of .link files and their drop-in files
Fixes #23128.
2022-05-03 10:26:22 +02:00
Lennart Poettering
968680b23d
Merge pull request #23135 from DaanDeMeyer/journal-move
journal: Only move to object if requested
2022-05-03 10:01:39 +02:00
dependabot[bot]
9c96c89bb3 build(deps): bump github/super-linter from 4.9.1 to 4.9.2
Bumps [github/super-linter](https://github.com/github/super-linter) from 4.9.1 to 4.9.2.
- [Release notes](https://github.com/github/super-linter/releases)
- [Changelog](https://github.com/github/super-linter/blob/main/docs/release-process.md)
- [Commits](3792fe5373...ae4e373c56)

---
updated-dependencies:
- dependency-name: github/super-linter
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-03 05:51:41 +03:00
dependabot[bot]
5f994fffb9 build(deps): bump actions/checkout from 3.0.0 to 3.0.2
Bumps [actions/checkout](https://github.com/actions/checkout) from 3.0.0 to 3.0.2.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](a12a3943b4...2541b1294d)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-03 05:50:11 +03:00
Daan De Meyer
9a390e86b7 journal: Document generic_array_bisect()
It's not trivial to figure out that this function does not search
for an exact match for the given needle, but whichever object in
the given direction that's closest to the needle.

Let's add a documentation blurb to explain how the function works
for to help future developers looking at this function.
2022-04-20 23:58:39 +02:00
Daan De Meyer
4d8b09e4b8 journal: Only move to object if requested 2022-04-20 22:16:06 +02:00
12 changed files with 200 additions and 54 deletions

View File

@ -33,6 +33,6 @@ jobs:
env: ${{ matrix.env }}
steps:
- 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) }}
run: sudo -E .github/workflows/build_test.sh

View File

@ -40,7 +40,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b
- name: Initialize CodeQL
uses: github/codeql-action/init@28eead240834b314f7def40f6fcba65d100d99b1

View File

@ -25,7 +25,7 @@ jobs:
CURRENT_REF: "${{ github.ref }}"
steps:
- 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
- name: Set the $COVERITY_SCAN_NOTIFICATION_EMAIL env variable
run: echo "COVERITY_SCAN_NOTIFICATION_EMAIL=$(git log -1 ${{ github.sha }} --pretty=\"%aE\")" >> "$GITHUB_ENV"

View File

@ -23,13 +23,13 @@ jobs:
steps:
- name: Repo checkout
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b
with:
# We need a full repo clone
fetch-depth: 0
- name: Lint Code Base
uses: github/super-linter/slim@3792fe5373cf2f5b22d590fcbbc4533d735c573e
uses: github/super-linter/slim@ae4e373c56efad95924d9cc6b89624fdb2333007
env:
DEFAULT_BRANCH: main
MULTI_STATUS: false

View File

@ -48,7 +48,7 @@ jobs:
release: 9-stream
steps:
- uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
- uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b
- uses: systemd/mkosi@93098e2406e12ea7f06f962d4808952b8a06d345
- name: Install

View File

@ -30,7 +30,7 @@ jobs:
cryptolib: gcrypt
steps:
- name: Repository checkout
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b
- name: Install build dependencies
run: sudo -E .github/workflows/unit_tests.sh SETUP
- name: Build & test (${{ matrix.run_phase }}-${{ matrix.cryptolib }})

View File

@ -2358,6 +2358,19 @@ static int generic_array_bisect(
uint64_t *ret_offset,
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;
bool subtract_one = false;
Object *array = NULL;

View File

@ -493,7 +493,6 @@ static int next_for_match(
int r;
uint64_t np = 0;
Object *n;
assert(j);
assert(m);
@ -569,12 +568,12 @@ static int next_for_match(
assert(np > 0);
r = journal_file_move_to_object(f, OBJECT_ENTRY, np, &n);
if (r < 0)
return r;
if (ret) {
r = journal_file_move_to_object(f, OBJECT_ENTRY, np, ret);
if (r < 0)
return r;
}
if (ret)
*ret = n;
if (offset)
*offset = np;
@ -633,7 +632,6 @@ static int find_location_for_match(
} else if (m->type == MATCH_OR_TERM) {
uint64_t np = 0;
Object *n;
/* Find the earliest match */
@ -652,12 +650,12 @@ static int find_location_for_match(
if (np == 0)
return 0;
r = journal_file_move_to_object(f, OBJECT_ENTRY, np, &n);
if (r < 0)
return r;
if (ret) {
r = journal_file_move_to_object(f, OBJECT_ENTRY, np, ret);
if (r < 0)
return r;
}
if (ret)
*ret = n;
if (offset)
*offset = np;

View File

@ -591,28 +591,6 @@ int network_load(Manager *manager, OrderedHashmap **networks) {
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) {
OrderedHashmap *new_networks = NULL;
Network *n, *old;

View File

@ -34,6 +34,7 @@
#include "set.h"
#include "signal-util.h"
#include "socket-util.h"
#include "stat-util.h"
#include "string-util.h"
#include "strv.h"
#include "syslog-util.h"
@ -556,6 +557,27 @@ int config_parse_many_nulstr(
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. */
int config_parse_many(
const char* const* conf_files,
@ -568,23 +590,128 @@ int config_parse_many(
void *userdata,
Hashmap **ret_stats_by_path) {
_cleanup_strv_free_ char **dropin_dirs = NULL;
_cleanup_strv_free_ char **files = NULL;
const char *suffix;
int r;
suffix = strjoina("/", dropin_dirname);
r = strv_extend_strv_concat(&dropin_dirs, (char**) conf_file_dirs, suffix);
if (r < 0)
return r;
assert(conf_file_dirs);
assert(dropin_dirname);
assert(sections);
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)
return r;
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) {
siphash24_compress_string(c->filename, state);
siphash24_compress(&c->line, sizeof(c->line), state);

View File

@ -114,6 +114,15 @@ int config_parse_many(
void *userdata,
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 {
unsigned line;
bool invalid;

View File

@ -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) {