preparations for installer PR (#40446)
As suggested by @keszybz the generic preparatory work split out of #38764
This commit is contained in:
+69
-52
@@ -24,7 +24,7 @@ ConfFile* conf_file_free(ConfFile *c) {
|
||||
if (!c)
|
||||
return NULL;
|
||||
|
||||
free(c->name);
|
||||
free(c->filename);
|
||||
free(c->result);
|
||||
free(c->original_path);
|
||||
free(c->resolved_path);
|
||||
@@ -44,13 +44,20 @@ static int conf_files_log_level(ConfFilesFlags flags) {
|
||||
return FLAGS_SET(flags, CONF_FILES_WARN) ? LOG_WARNING : LOG_DEBUG;
|
||||
}
|
||||
|
||||
static int prepare_dirs(const char *root, ConfFilesFlags flags, char * const *dirs, int *ret_rfd, char **ret_root, char ***ret_dirs) {
|
||||
static int prepare_dirs(
|
||||
const char *root,
|
||||
ConfFilesFlags flags,
|
||||
char * const *dirs,
|
||||
char **ret_root,
|
||||
int *ret_rfd,
|
||||
char ***ret_dirs) {
|
||||
|
||||
_cleanup_free_ char *root_abs = NULL;
|
||||
_cleanup_strv_free_ char **dirs_abs = NULL;
|
||||
int r;
|
||||
|
||||
assert(ret_rfd);
|
||||
assert(ret_root);
|
||||
assert(ret_rfd);
|
||||
assert(ret_dirs || strv_isempty(dirs));
|
||||
|
||||
int log_level = conf_files_log_level(flags);
|
||||
@@ -65,6 +72,7 @@ static int prepare_dirs(const char *root, ConfFilesFlags flags, char * const *di
|
||||
return log_oom_full(log_level);
|
||||
}
|
||||
|
||||
_cleanup_close_ int rfd = XAT_FDROOT;
|
||||
if (root) {
|
||||
/* When a non-trivial root is specified, we will prefix the result later. Hence, it is not
|
||||
* necessary to modify each config directories here. but needs to normalize the root directory. */
|
||||
@@ -73,6 +81,11 @@ static int prepare_dirs(const char *root, ConfFilesFlags flags, char * const *di
|
||||
return log_full_errno(log_level, r, "Failed to make '%s' absolute: %m", root);
|
||||
|
||||
path_simplify(root_abs);
|
||||
|
||||
rfd = open(root, O_CLOEXEC|O_DIRECTORY|O_PATH);
|
||||
if (rfd < 0)
|
||||
return log_full_errno(log_level, errno, "Failed to open '%s': %m", root_abs);
|
||||
|
||||
} else if (ret_dirs) {
|
||||
/* When an empty root or "/" is specified, we will open "/" below, hence we need to make
|
||||
* each config directory absolute if relative. */
|
||||
@@ -81,12 +94,8 @@ static int prepare_dirs(const char *root, ConfFilesFlags flags, char * const *di
|
||||
return log_full_errno(log_level, r, "Failed to make directories absolute: %m");
|
||||
}
|
||||
|
||||
_cleanup_close_ int rfd = open(empty_to_root(root_abs), O_CLOEXEC|O_DIRECTORY|O_PATH);
|
||||
if (rfd < 0)
|
||||
return log_full_errno(log_level, errno, "Failed to open '%s': %m", empty_to_root(root_abs));
|
||||
|
||||
*ret_rfd = TAKE_FD(rfd);
|
||||
*ret_root = TAKE_PTR(root_abs);
|
||||
*ret_rfd = TAKE_FD(rfd);
|
||||
if (ret_dirs)
|
||||
*ret_dirs = TAKE_PTR(dirs_abs);
|
||||
return 0;
|
||||
@@ -135,8 +144,8 @@ static ChaseFlags conf_files_chase_flags(ConfFilesFlags flags) {
|
||||
}
|
||||
|
||||
static int conf_file_chase_and_verify(
|
||||
int rfd,
|
||||
const char *root, /* for logging, can be NULL */
|
||||
int rfd,
|
||||
const char *original_path, /* for logging */
|
||||
const char *path,
|
||||
const char *name,
|
||||
@@ -151,7 +160,7 @@ static int conf_file_chase_and_verify(
|
||||
struct stat st = {};
|
||||
int r;
|
||||
|
||||
assert(rfd >= 0 || rfd == AT_FDCWD);
|
||||
assert(rfd >= 0 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
|
||||
assert(original_path);
|
||||
assert(path);
|
||||
assert(name);
|
||||
@@ -261,18 +270,25 @@ static int conf_file_chase_and_verify(
|
||||
return 0;
|
||||
}
|
||||
|
||||
int conf_file_new_at(const char *path, int rfd, ConfFilesFlags flags, ConfFile **ret) {
|
||||
int conf_file_new_at(
|
||||
const char *path,
|
||||
const char *root,
|
||||
int rfd,
|
||||
ConfFilesFlags flags,
|
||||
ConfFile **ret) {
|
||||
int r;
|
||||
|
||||
assert(path);
|
||||
assert(rfd >= 0 || rfd == AT_FDCWD);
|
||||
assert(rfd >= 0 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
|
||||
assert(ret);
|
||||
|
||||
int log_level = conf_files_log_level(flags);
|
||||
|
||||
_cleanup_free_ char *root = NULL;
|
||||
if (rfd >= 0)
|
||||
(void) fd_get_path(rfd, &root);
|
||||
_cleanup_free_ char *_root = NULL;
|
||||
if (DEBUG_LOGGING && !root) {
|
||||
(void) fd_get_path(rfd, &_root);
|
||||
root = _root;
|
||||
}
|
||||
|
||||
_cleanup_(conf_file_freep) ConfFile *c = new(ConfFile, 1);
|
||||
if (!c)
|
||||
@@ -286,7 +302,7 @@ int conf_file_new_at(const char *path, int rfd, ConfFilesFlags flags, ConfFile *
|
||||
if (!c->original_path)
|
||||
return log_oom_full(log_level);
|
||||
|
||||
r = path_extract_filename(path, &c->name);
|
||||
r = path_extract_filename(path, &c->filename);
|
||||
if (r < 0)
|
||||
return log_full_errno(log_level, r, "Failed to extract filename from '%s': %m", path);
|
||||
|
||||
@@ -302,16 +318,16 @@ int conf_file_new_at(const char *path, int rfd, ConfFilesFlags flags, ConfFile *
|
||||
return log_full_errno(log_level, r, "Failed to chase '%s%s': %m", empty_to_root(root), skip_leading_slash(dirpath));
|
||||
}
|
||||
|
||||
c->result = path_join(resolved_dirpath, c->name);
|
||||
c->result = path_join(resolved_dirpath, c->filename);
|
||||
if (!c->result)
|
||||
return log_oom_full(log_level);
|
||||
|
||||
r = conf_file_chase_and_verify(
|
||||
rfd,
|
||||
root,
|
||||
rfd,
|
||||
c->original_path,
|
||||
c->result,
|
||||
c->name,
|
||||
c->filename,
|
||||
/* masked= */ NULL,
|
||||
flags,
|
||||
&c->resolved_path,
|
||||
@@ -332,7 +348,7 @@ int conf_file_new(const char *path, const char *root, ConfFilesFlags flags, Conf
|
||||
|
||||
_cleanup_free_ char *root_abs = NULL;
|
||||
_cleanup_close_ int rfd = -EBADF;
|
||||
r = prepare_dirs(root, flags, /* dirs= */ NULL, &rfd, &root_abs, /* ret_dirs= */ NULL);
|
||||
r = prepare_dirs(root, flags, /* dirs= */ NULL, &root_abs, &rfd, /* ret_dirs= */ NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -346,7 +362,7 @@ int conf_file_new(const char *path, const char *root, ConfFilesFlags flags, Conf
|
||||
}
|
||||
|
||||
_cleanup_(conf_file_freep) ConfFile *c = NULL;
|
||||
r = conf_file_new_at(path, rfd, flags, &c);
|
||||
r = conf_file_new_at(path, root_abs, rfd, flags, &c);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -367,8 +383,8 @@ static int files_add(
|
||||
DIR *dir,
|
||||
const char *original_dirpath,
|
||||
const char *resolved_dirpath,
|
||||
int rfd,
|
||||
const char *root, /* for logging, can be NULL */
|
||||
int rfd,
|
||||
Hashmap **files,
|
||||
Set **masked,
|
||||
const char *suffix,
|
||||
@@ -379,7 +395,7 @@ static int files_add(
|
||||
assert(dir);
|
||||
assert(original_dirpath);
|
||||
assert(resolved_dirpath);
|
||||
assert(rfd >= 0 || rfd == AT_FDCWD);
|
||||
assert(rfd >= 0 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
|
||||
assert(files);
|
||||
assert(masked);
|
||||
|
||||
@@ -420,8 +436,8 @@ static int files_add(
|
||||
_cleanup_close_ int fd = -EBADF;
|
||||
struct stat st;
|
||||
r = conf_file_chase_and_verify(
|
||||
rfd,
|
||||
root,
|
||||
rfd,
|
||||
original_path,
|
||||
p,
|
||||
de->d_name,
|
||||
@@ -440,7 +456,7 @@ static int files_add(
|
||||
return log_oom_full(log_level);
|
||||
|
||||
*c = (ConfFile) {
|
||||
.name = strdup(de->d_name),
|
||||
.filename = strdup(de->d_name),
|
||||
.result = TAKE_PTR(p),
|
||||
.original_path = TAKE_PTR(original_path),
|
||||
.resolved_path = TAKE_PTR(resolved_path),
|
||||
@@ -448,10 +464,10 @@ static int files_add(
|
||||
.st = st,
|
||||
};
|
||||
|
||||
if (!c->name)
|
||||
if (!c->filename)
|
||||
return log_oom_full(log_level);
|
||||
|
||||
r = hashmap_ensure_put(files, &conf_file_hash_ops, c->name, c);
|
||||
r = hashmap_ensure_put(files, &conf_file_hash_ops, c->filename, c);
|
||||
if (r < 0) {
|
||||
assert(r == -ENOMEM);
|
||||
return log_oom_full(log_level);
|
||||
@@ -481,7 +497,7 @@ static int dump_files(Hashmap *fh, const char *root, ConfFilesFlags flags, ConfF
|
||||
|
||||
/* Hence, we need to remove them from the hashmap. */
|
||||
FOREACH_ARRAY(i, files, n_files)
|
||||
assert_se(hashmap_remove(fh, (*i)->name) == *i);
|
||||
assert_se(hashmap_remove(fh, (*i)->filename) == *i);
|
||||
|
||||
if (root)
|
||||
FOREACH_ARRAY(i, files, n_files) {
|
||||
@@ -522,8 +538,8 @@ static int copy_and_sort_files_from_hashmap(
|
||||
const char *add = NULL;
|
||||
|
||||
if (FLAGS_SET(flags, CONF_FILES_BASENAME))
|
||||
add = c->name;
|
||||
else if (root) {
|
||||
add = c->filename;
|
||||
else if (root && !FLAGS_SET(flags, CONF_FILES_DONT_PREFIX_ROOT)) {
|
||||
_cleanup_free_ char *p = NULL;
|
||||
|
||||
r = chaseat_prefix_root(c->result, root, &p);
|
||||
@@ -574,22 +590,22 @@ static int insert_replacement(Hashmap **fh, ConfFile *replacement, ConfFilesFlag
|
||||
|
||||
/* This consumes the input ConfFile. */
|
||||
|
||||
ConfFile *existing = hashmap_get(*fh, c->name);
|
||||
ConfFile *existing = hashmap_get(*fh, c->filename);
|
||||
if (existing) {
|
||||
log_debug("An entry with higher priority '%s' -> '%s' already exists, ignoring the replacement: %s",
|
||||
existing->name, existing->result, c->original_path);
|
||||
existing->filename, existing->result, c->original_path);
|
||||
*ret = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = hashmap_ensure_put(fh, &conf_file_hash_ops, c->name, c);
|
||||
r = hashmap_ensure_put(fh, &conf_file_hash_ops, c->filename, c);
|
||||
if (r < 0) {
|
||||
assert(r == -ENOMEM);
|
||||
return log_oom_full(conf_files_log_level(flags));
|
||||
}
|
||||
assert(r > 0);
|
||||
|
||||
log_debug("Inserted replacement: '%s' -> '%s'", c->name, c->result);
|
||||
log_debug("Inserted replacement: '%s' -> '%s'", c->filename, c->result);
|
||||
|
||||
*ret = TAKE_PTR(c);
|
||||
return 0;
|
||||
@@ -597,8 +613,8 @@ static int insert_replacement(Hashmap **fh, ConfFile *replacement, ConfFilesFlag
|
||||
|
||||
static int conf_files_list_impl(
|
||||
const char *suffix,
|
||||
int rfd,
|
||||
const char *root, /* for logging, can be NULL */
|
||||
int rfd,
|
||||
ConfFilesFlags flags,
|
||||
const char * const *dirs,
|
||||
const char *replacement,
|
||||
@@ -611,13 +627,13 @@ static int conf_files_list_impl(
|
||||
const ConfFile *inserted = NULL;
|
||||
int r;
|
||||
|
||||
assert(rfd >= 0 || rfd == AT_FDCWD);
|
||||
assert(rfd >= 0 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
|
||||
assert(ret);
|
||||
|
||||
root = empty_to_root(root);
|
||||
|
||||
if (replacement) {
|
||||
r = conf_file_new_at(replacement, rfd, flags & CONF_FILES_WARN, &c);
|
||||
r = conf_file_new_at(replacement, root, rfd, flags & CONF_FILES_WARN, &c);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
@@ -635,13 +651,13 @@ static int conf_files_list_impl(
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c && streq_ptr(path_startswith(c->result, path), c->name)) {
|
||||
if (c && streq_ptr(path_startswith(c->result, path), c->filename)) {
|
||||
r = insert_replacement(&fh, TAKE_PTR(c), flags, &inserted);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = files_add(dir, *p, path, rfd, root, &fh, &masked, suffix, flags);
|
||||
r = files_add(dir, *p, path, root, rfd, &fh, &masked, suffix, flags);
|
||||
if (r == -ENOMEM)
|
||||
return r;
|
||||
}
|
||||
@@ -673,11 +689,11 @@ int conf_files_list_strv(
|
||||
|
||||
assert(ret);
|
||||
|
||||
r = prepare_dirs(root, flags, (char**) dirs, &rfd, &root_abs, &dirs_abs);
|
||||
r = prepare_dirs(root, flags, (char**) dirs, &root_abs, &rfd, &dirs_abs);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = conf_files_list_impl(suffix, rfd, root_abs, flags, (const char * const *) dirs_abs,
|
||||
r = conf_files_list_impl(suffix, root_abs, rfd, flags, (const char * const *) dirs_abs,
|
||||
/* replacement= */ NULL, &fh, /* ret_inserted= */ NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -702,11 +718,11 @@ int conf_files_list_strv_full(
|
||||
assert(ret_files);
|
||||
assert(ret_n_files);
|
||||
|
||||
r = prepare_dirs(root, flags, (char**) dirs, &rfd, &root_abs, &dirs_abs);
|
||||
r = prepare_dirs(root, flags, (char**) dirs, &root_abs, &rfd, &dirs_abs);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = conf_files_list_impl(suffix, rfd, root_abs, flags, (const char * const *) dirs_abs,
|
||||
r = conf_files_list_impl(suffix, root_abs, rfd, flags, (const char * const *) dirs_abs,
|
||||
/* replacement= */ NULL, &fh, /* ret_inserted= */ NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -725,13 +741,13 @@ int conf_files_list_strv_at(
|
||||
_cleanup_free_ char *root = NULL;
|
||||
int r;
|
||||
|
||||
assert(rfd >= 0 || rfd == AT_FDCWD);
|
||||
assert(rfd >= 0 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
|
||||
assert(ret);
|
||||
|
||||
if (rfd >= 0)
|
||||
if (DEBUG_LOGGING)
|
||||
(void) fd_get_path(rfd, &root); /* for logging */
|
||||
|
||||
r = conf_files_list_impl(suffix, rfd, root, flags, dirs, /* replacement= */ NULL, &fh, /* ret_inserted= */ NULL);
|
||||
r = conf_files_list_impl(suffix, root, rfd, flags, dirs, /* replacement= */ NULL, &fh, /* ret_inserted= */ NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -750,14 +766,14 @@ int conf_files_list_strv_at_full(
|
||||
_cleanup_free_ char *root = NULL;
|
||||
int r;
|
||||
|
||||
assert(rfd >= 0 || rfd == AT_FDCWD);
|
||||
assert(rfd >= 0 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
|
||||
assert(ret_files);
|
||||
assert(ret_n_files);
|
||||
|
||||
if (rfd >= 0)
|
||||
if (DEBUG_LOGGING)
|
||||
(void) fd_get_path(rfd, &root); /* for logging */
|
||||
|
||||
r = conf_files_list_impl(suffix, rfd, root, flags, dirs, /* replacement= */ NULL, &fh, /* ret_inserted= */ NULL);
|
||||
r = conf_files_list_impl(suffix, root, rfd, flags, dirs, /* replacement= */ NULL, &fh, /* ret_inserted= */ NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -848,11 +864,11 @@ int conf_files_list_with_replacement(
|
||||
|
||||
assert(ret_files);
|
||||
|
||||
r = prepare_dirs(root, flags, config_dirs, &rfd, &root_abs, &dirs_abs);
|
||||
r = prepare_dirs(root, flags, config_dirs, &root_abs, &rfd, &dirs_abs);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = conf_files_list_impl(".conf", rfd, root_abs, flags, (const char * const *) dirs_abs,
|
||||
r = conf_files_list_impl(".conf", root_abs, rfd, flags, (const char * const *) dirs_abs,
|
||||
replacement, &fh, ret_inserted ? &c : NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -878,6 +894,7 @@ int conf_files_list_dropins(
|
||||
char ***ret,
|
||||
const char *dropin_dirname,
|
||||
const char *root,
|
||||
int root_fd,
|
||||
ConfFilesFlags flags,
|
||||
const char * const *dirs) {
|
||||
|
||||
@@ -894,7 +911,7 @@ int conf_files_list_dropins(
|
||||
if (r < 0)
|
||||
return log_oom_full(conf_files_log_level(flags));
|
||||
|
||||
return conf_files_list_strv(ret, ".conf", root, flags, (const char* const*) dropin_dirs);
|
||||
return conf_files_list_strv_at(ret, ".conf", root_fd, flags, (const char* const*) dropin_dirs);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,14 +15,15 @@ typedef enum ConfFilesFlags {
|
||||
CONF_FILES_FILTER_MASKED = CONF_FILES_FILTER_MASKED_BY_SYMLINK | CONF_FILES_FILTER_MASKED_BY_EMPTY,
|
||||
CONF_FILES_TRUNCATE_SUFFIX = 1 << 6, /* truncate specified suffix from return filename or path */
|
||||
CONF_FILES_WARN = 1 << 7, /* warn on some errors */
|
||||
CONF_FILES_DONT_PREFIX_ROOT = 1 << 8, /* don't prefix the specified root path to the resulting paths */
|
||||
} ConfFilesFlags;
|
||||
|
||||
typedef struct ConfFile {
|
||||
char *name; /* name of a file found in config directories */
|
||||
char *result; /* resolved config directory with the original file name found in the directory */
|
||||
char *original_path; /* original config directory with the original file name found in the directory */
|
||||
char *resolved_path; /* fully resolved path, where the filename part of the path may be different from the original name */
|
||||
int fd; /* O_PATH fd to resolved_path, -EBADF if the resolved_path does not exist */
|
||||
char *filename; /* filename of the discovered file (i.e. without any directory prefix) */
|
||||
char *result; /* full path to the file (with the directory prefix fully resolved, but the filename part left as is) */
|
||||
char *original_path; /* full path to the file (original – non-resolved – directory prefix + filename part left as is) */
|
||||
char *resolved_path; /* fully resolved path to the file with both directory prefix and filename fully resolved */
|
||||
int fd; /* O_PATH fd to resolved_path, -EBADF if resolved_path does not exist */
|
||||
struct stat st; /* stat of the file. */
|
||||
} ConfFile;
|
||||
|
||||
@@ -30,7 +31,7 @@ ConfFile* conf_file_free(ConfFile *c);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(ConfFile*, conf_file_free);
|
||||
void conf_file_free_many(ConfFile **array, size_t n);
|
||||
|
||||
int conf_file_new_at(const char *path, int rfd, ConfFilesFlags flags, ConfFile **ret);
|
||||
int conf_file_new_at(const char *path, const char *root, int rfd, ConfFilesFlags flags, ConfFile **ret);
|
||||
int conf_file_new(const char *path, const char *root, ConfFilesFlags flags, ConfFile **ret);
|
||||
|
||||
int conf_files_list(char ***ret, const char *suffix, const char *root, ConfFilesFlags flags, const char *dir);
|
||||
@@ -57,6 +58,7 @@ int conf_files_list_dropins(
|
||||
char ***ret,
|
||||
const char *dropin_dirname,
|
||||
const char *root,
|
||||
int root_fd,
|
||||
ConfFilesFlags flags,
|
||||
const char * const *dirs);
|
||||
|
||||
|
||||
+23
-16
@@ -168,7 +168,7 @@ int open_os_release_at(int rfd, char **ret_path, int *ret_fd) {
|
||||
const char *e;
|
||||
int r;
|
||||
|
||||
assert(rfd >= 0 || rfd == AT_FDCWD);
|
||||
assert(rfd >= 0 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
|
||||
|
||||
e = secure_getenv("SYSTEMD_OS_RELEASE");
|
||||
if (e)
|
||||
@@ -184,13 +184,15 @@ int open_os_release_at(int rfd, char **ret_path, int *ret_fd) {
|
||||
}
|
||||
|
||||
int open_os_release(const char *root, char **ret_path, int *ret_fd) {
|
||||
_cleanup_close_ int rfd = -EBADF, fd = -EBADF;
|
||||
_cleanup_close_ int rfd = XAT_FDROOT, fd = -EBADF;
|
||||
_cleanup_free_ char *p = NULL;
|
||||
int r;
|
||||
|
||||
rfd = open(empty_to_root(root), O_CLOEXEC | O_DIRECTORY | O_PATH);
|
||||
if (rfd < 0)
|
||||
return -errno;
|
||||
if (!empty_or_root(root)) {
|
||||
rfd = open(root, O_CLOEXEC | O_DIRECTORY | O_PATH);
|
||||
if (rfd < 0)
|
||||
return -errno;
|
||||
}
|
||||
|
||||
r = open_os_release_at(rfd, ret_path ? &p : NULL, ret_fd ? &fd : NULL);
|
||||
if (r < 0)
|
||||
@@ -223,7 +225,7 @@ int open_extension_release_at(
|
||||
const char *p;
|
||||
int r;
|
||||
|
||||
assert(rfd >= 0 || rfd == AT_FDCWD);
|
||||
assert(rfd >= 0 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
|
||||
assert(!extension || (image_class >= 0 && image_class < _IMAGE_CLASS_MAX));
|
||||
|
||||
if (!extension)
|
||||
@@ -330,13 +332,15 @@ int open_extension_release(
|
||||
char **ret_path,
|
||||
int *ret_fd) {
|
||||
|
||||
_cleanup_close_ int rfd = -EBADF, fd = -EBADF;
|
||||
_cleanup_close_ int rfd = XAT_FDROOT, fd = -EBADF;
|
||||
_cleanup_free_ char *p = NULL;
|
||||
int r;
|
||||
|
||||
rfd = open(empty_to_root(root), O_CLOEXEC | O_DIRECTORY | O_PATH);
|
||||
if (rfd < 0)
|
||||
return -errno;
|
||||
if (!empty_or_root(root)) {
|
||||
rfd = open(root, O_CLOEXEC | O_DIRECTORY | O_PATH);
|
||||
if (rfd < 0)
|
||||
return -errno;
|
||||
}
|
||||
|
||||
r = open_extension_release_at(rfd, image_class, extension, relax_extension_release_check,
|
||||
ret_path ? &p : NULL, ret_fd ? &fd : NULL);
|
||||
@@ -366,7 +370,7 @@ static int parse_extension_release_atv(
|
||||
_cleanup_free_ char *p = NULL;
|
||||
int r;
|
||||
|
||||
assert(rfd >= 0 || rfd == AT_FDCWD);
|
||||
assert(rfd >= 0 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
|
||||
|
||||
r = open_extension_release_at(rfd, image_class, extension, relax_extension_release_check, &p, &fd);
|
||||
if (r < 0)
|
||||
@@ -385,7 +389,7 @@ int parse_extension_release_at_sentinel(
|
||||
va_list ap;
|
||||
int r;
|
||||
|
||||
assert(rfd >= 0 || rfd == AT_FDCWD);
|
||||
assert(rfd >= 0 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
|
||||
|
||||
va_start(ap, extension);
|
||||
r = parse_extension_release_atv(rfd, image_class, extension, relax_extension_release_check, ap);
|
||||
@@ -400,17 +404,20 @@ int parse_extension_release_sentinel(
|
||||
const char *extension,
|
||||
...) {
|
||||
|
||||
_cleanup_close_ int rfd = -EBADF;
|
||||
_cleanup_close_ int rfd = XAT_FDROOT;
|
||||
va_list ap;
|
||||
int r;
|
||||
|
||||
rfd = open(empty_to_root(root), O_CLOEXEC | O_DIRECTORY | O_PATH);
|
||||
if (rfd < 0)
|
||||
return -errno;
|
||||
if (!empty_or_root(root)) {
|
||||
rfd = open(root, O_CLOEXEC | O_DIRECTORY | O_PATH);
|
||||
if (rfd < 0)
|
||||
return -errno;
|
||||
}
|
||||
|
||||
va_start(ap, extension);
|
||||
r = parse_extension_release_atv(rfd, image_class, extension, relax_extension_release_check, ap);
|
||||
va_end(ap);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
+1
-2
@@ -842,11 +842,10 @@ static int parse_config_file(void) {
|
||||
(const char* const*) files,
|
||||
(const char* const*) dirs,
|
||||
"user.conf.d",
|
||||
/* root= */ NULL,
|
||||
"Manager\0",
|
||||
config_item_table_lookup, items,
|
||||
CONFIG_PARSE_WARN,
|
||||
NULL, NULL, NULL);
|
||||
/* userdata= */ NULL);
|
||||
}
|
||||
|
||||
/* Traditionally "0" was used to turn off the default unit timeouts. Fix this up so that we use
|
||||
|
||||
@@ -460,13 +460,15 @@ static int context_load_install_conf(Context *c) {
|
||||
|
||||
assert(c);
|
||||
|
||||
r = load_kernel_install_conf(arg_root,
|
||||
c->conf_root,
|
||||
&machine_id,
|
||||
&boot_root,
|
||||
&layout,
|
||||
&initrd_generator,
|
||||
&uki_generator);
|
||||
r = load_kernel_install_conf_at(
|
||||
c->conf_root ? NULL : arg_root,
|
||||
c->conf_root ? XAT_FDROOT : c->rfd,
|
||||
c->conf_root,
|
||||
&machine_id,
|
||||
&boot_root,
|
||||
&layout,
|
||||
&initrd_generator,
|
||||
&uki_generator);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
|
||||
@@ -138,7 +138,7 @@ _public_ int sd_id128_get_machine(sd_id128_t *ret) {
|
||||
int id128_get_machine_at(int rfd, sd_id128_t *ret) {
|
||||
int r;
|
||||
|
||||
assert(rfd >= 0 || rfd == AT_FDCWD);
|
||||
assert(rfd >= 0 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
|
||||
|
||||
r = dir_fd_is_root_or_cwd(rfd);
|
||||
if (r < 0)
|
||||
|
||||
@@ -1031,13 +1031,14 @@ int netdev_load_one(Manager *manager, const char *filename, NetDev **ret) {
|
||||
|
||||
dropin_dirname = strjoina(file_basename, ".d");
|
||||
r = config_parse_many(
|
||||
STRV_MAKE_CONST(filename), NETWORK_DIRS, dropin_dirname, /* root= */ NULL,
|
||||
STRV_MAKE_CONST(filename),
|
||||
NETWORK_DIRS,
|
||||
dropin_dirname,
|
||||
NETDEV_COMMON_SECTIONS NETDEV_OTHER_SECTIONS,
|
||||
config_item_perf_lookup, network_netdev_gperf_lookup,
|
||||
config_item_perf_lookup,
|
||||
network_netdev_gperf_lookup,
|
||||
CONFIG_PARSE_WARN,
|
||||
netdev_raw,
|
||||
NULL,
|
||||
NULL);
|
||||
netdev_raw);
|
||||
if (r < 0)
|
||||
return r; /* config_parse_many() logs internally. */
|
||||
|
||||
@@ -1064,10 +1065,15 @@ int netdev_load_one(Manager *manager, const char *filename, NetDev **ret) {
|
||||
if (NETDEV_VTABLE(netdev)->init)
|
||||
NETDEV_VTABLE(netdev)->init(netdev);
|
||||
|
||||
r = config_parse_many(
|
||||
STRV_MAKE_CONST(filename), NETWORK_DIRS, dropin_dirname, /* root= */ NULL,
|
||||
r = config_parse_many_full(
|
||||
STRV_MAKE_CONST(filename),
|
||||
NETWORK_DIRS,
|
||||
dropin_dirname,
|
||||
/* root= */ NULL,
|
||||
/* root_fd= */ -EBADF,
|
||||
NETDEV_VTABLE(netdev)->sections,
|
||||
config_item_perf_lookup, network_netdev_gperf_lookup,
|
||||
config_item_perf_lookup,
|
||||
network_netdev_gperf_lookup,
|
||||
CONFIG_PARSE_WARN,
|
||||
netdev,
|
||||
&netdev->stats_by_path,
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "edit-util.h"
|
||||
#include "errno-util.h"
|
||||
#include "extract-word.h"
|
||||
#include "fd-util.h"
|
||||
#include "log.h"
|
||||
#include "mkdir-label.h"
|
||||
#include "netlink-util.h"
|
||||
@@ -106,7 +107,13 @@ static int get_config_files_by_name(
|
||||
if (!dropin_dirname)
|
||||
return -ENOMEM;
|
||||
|
||||
r = conf_files_list_dropins(ret_dropins, dropin_dirname, /* root= */ NULL, CONF_FILES_WARN, NETWORK_DIRS);
|
||||
r = conf_files_list_dropins(
|
||||
ret_dropins,
|
||||
dropin_dirname,
|
||||
/* root= */ NULL,
|
||||
/* root_fd= */ XAT_FDROOT,
|
||||
CONF_FILES_WARN,
|
||||
NETWORK_DIRS);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -514,8 +514,12 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
|
||||
.ipoib_umcast = -1,
|
||||
};
|
||||
|
||||
r = config_parse_many(
|
||||
STRV_MAKE_CONST(filename), NETWORK_DIRS, dropin_dirname, /* root= */ NULL,
|
||||
r = config_parse_many_full(
|
||||
STRV_MAKE_CONST(filename),
|
||||
NETWORK_DIRS,
|
||||
dropin_dirname,
|
||||
/* root= */ NULL,
|
||||
/* root_fd= */ -EBADF,
|
||||
"Match\0"
|
||||
"Link\0"
|
||||
"SR-IOV\0"
|
||||
@@ -574,7 +578,8 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
|
||||
"StochasticFairnessQueueing\0"
|
||||
"TokenBucketFilter\0"
|
||||
"TrivialLinkEqualizer\0",
|
||||
config_item_perf_lookup, network_network_gperf_lookup,
|
||||
config_item_perf_lookup,
|
||||
network_network_gperf_lookup,
|
||||
CONFIG_PARSE_WARN,
|
||||
network,
|
||||
&network->stats_by_path,
|
||||
|
||||
+4
-3
@@ -2871,16 +2871,17 @@ static int partition_read_definition(
|
||||
|
||||
dropin_dirname = strjoina(filename, ".d");
|
||||
|
||||
r = config_parse_many(
|
||||
r = config_parse_many_full(
|
||||
STRV_MAKE_CONST(path),
|
||||
conf_file_dirs,
|
||||
dropin_dirname,
|
||||
c->definitions ? NULL : arg_root,
|
||||
/* root_fd= */ -EBADF,
|
||||
"Partition\0",
|
||||
config_item_table_lookup, table,
|
||||
CONFIG_PARSE_WARN,
|
||||
p,
|
||||
NULL,
|
||||
/* ret_stats_by_path= */ NULL,
|
||||
&p->drop_in_files);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -3396,7 +3397,7 @@ static int context_read_definitions(Context *context) {
|
||||
&files,
|
||||
".conf",
|
||||
context->definitions ? NULL : arg_root,
|
||||
CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED|CONF_FILES_WARN,
|
||||
CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED|CONF_FILES_WARN|CONF_FILES_DONT_PREFIX_ROOT,
|
||||
dirs);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to enumerate *.conf files: %m");
|
||||
|
||||
@@ -188,14 +188,11 @@ static int dns_delegate_load(Manager *m, const char *path) {
|
||||
STRV_MAKE_CONST(path),
|
||||
DNS_DELEGATE_SEARCH_DIRS,
|
||||
dropin_dirname,
|
||||
/* root= */ NULL,
|
||||
"Delegate\0",
|
||||
config_item_perf_lookup,
|
||||
resolved_dns_delegate_gperf_lookup,
|
||||
/* flags= */ 0,
|
||||
d,
|
||||
/* ret_stats_by_path= */ NULL,
|
||||
/* ret_drop_in_files= */ NULL);
|
||||
d);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
@@ -125,13 +125,13 @@ static int dnssd_registered_service_load(Manager *manager, const char *path) {
|
||||
return log_oom();
|
||||
|
||||
r = config_parse_many(
|
||||
STRV_MAKE_CONST(path), DNSSD_SERVICE_DIRS, dropin_dirname, /* root= */ NULL,
|
||||
STRV_MAKE_CONST(path),
|
||||
DNSSD_SERVICE_DIRS,
|
||||
dropin_dirname,
|
||||
"Service\0",
|
||||
config_item_perf_lookup, resolved_dnssd_gperf_lookup,
|
||||
CONFIG_PARSE_WARN,
|
||||
service,
|
||||
NULL,
|
||||
NULL);
|
||||
service);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
+10
-9
@@ -22,7 +22,7 @@ static int entry_token_load_one(int rfd, const char *dir, BootEntryTokenType *ty
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
int r;
|
||||
|
||||
assert(rfd >= 0 || rfd == AT_FDCWD);
|
||||
assert(rfd >= 0 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
|
||||
assert(dir);
|
||||
assert(type);
|
||||
assert(*type == BOOT_ENTRY_TOKEN_AUTO);
|
||||
@@ -58,7 +58,7 @@ static int entry_token_load_one(int rfd, const char *dir, BootEntryTokenType *ty
|
||||
static int entry_token_load(int rfd, const char *conf_root, BootEntryTokenType *type, char **token) {
|
||||
int r;
|
||||
|
||||
assert(rfd >= 0 || rfd == AT_FDCWD);
|
||||
assert(rfd >= 0 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
|
||||
assert(type);
|
||||
assert(*type == BOOT_ENTRY_TOKEN_AUTO);
|
||||
assert(token);
|
||||
@@ -98,7 +98,7 @@ static int entry_token_from_os_release(int rfd, BootEntryTokenType *type, char *
|
||||
_cleanup_free_ char *id = NULL, *image_id = NULL;
|
||||
int r;
|
||||
|
||||
assert(rfd >= 0 || rfd == AT_FDCWD);
|
||||
assert(rfd >= 0 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
|
||||
assert(type);
|
||||
assert(IN_SET(*type, BOOT_ENTRY_TOKEN_AUTO, BOOT_ENTRY_TOKEN_OS_IMAGE_ID, BOOT_ENTRY_TOKEN_OS_ID));
|
||||
assert(token);
|
||||
@@ -151,7 +151,7 @@ int boot_entry_token_ensure_at(
|
||||
|
||||
int r;
|
||||
|
||||
assert(rfd >= 0 || rfd == AT_FDCWD);
|
||||
assert(rfd >= 0 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
|
||||
assert(type);
|
||||
assert(token);
|
||||
|
||||
@@ -229,11 +229,12 @@ int boot_entry_token_ensure(
|
||||
if (*token)
|
||||
return 0; /* Already set. */
|
||||
|
||||
_cleanup_close_ int rfd = -EBADF;
|
||||
|
||||
rfd = open(empty_to_root(root), O_CLOEXEC | O_DIRECTORY | O_PATH);
|
||||
if (rfd < 0)
|
||||
return -errno;
|
||||
_cleanup_close_ int rfd = XAT_FDROOT;
|
||||
if (!empty_or_root(root)) {
|
||||
rfd = open(root, O_CLOEXEC | O_DIRECTORY | O_PATH);
|
||||
if (rfd < 0)
|
||||
return -errno;
|
||||
}
|
||||
|
||||
return boot_entry_token_ensure_at(rfd, conf_root, machine_id, machine_id_is_random, type, token);
|
||||
}
|
||||
|
||||
+75
-19
@@ -481,6 +481,7 @@ int hashmap_put_stats_by_path(Hashmap **stats_by_path, const char *path, const s
|
||||
|
||||
static int config_parse_many_files(
|
||||
const char *root,
|
||||
int root_fd,
|
||||
const char* const* conf_files,
|
||||
char **files,
|
||||
const char *sections,
|
||||
@@ -502,17 +503,17 @@ static int config_parse_many_files(
|
||||
return log_oom_full(level);
|
||||
}
|
||||
|
||||
/* Pin and stat() all dropins */
|
||||
STRV_FOREACH(fn, files) {
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
_cleanup_free_ char *fname = NULL;
|
||||
|
||||
r = chase_and_fopen_unlocked(*fn, root, CHASE_AT_RESOLVE_IN_ROOT, "re", &fname, &f);
|
||||
r = chase_and_fopenat_unlocked(root_fd, *fn, CHASE_AT_RESOLVE_IN_ROOT|CHASE_MUST_BE_REGULAR, "re", /* ret_path= */ NULL, &f);
|
||||
if (r == -ENOENT)
|
||||
continue;
|
||||
if (r < 0)
|
||||
return log_full_errno(level, r, "Failed to open %s: %m", *fn);
|
||||
|
||||
int fd = fileno(f);
|
||||
assert(fd >= 0);
|
||||
|
||||
r = ordered_hashmap_ensure_put(&dropins, &config_file_hash_ops_fclose, *fn, f);
|
||||
if (r < 0) {
|
||||
@@ -537,11 +538,10 @@ static int config_parse_many_files(
|
||||
return log_oom_full(level);
|
||||
}
|
||||
|
||||
/* First read the first found main config file. */
|
||||
/* First process the first found main config file. */
|
||||
STRV_FOREACH(fn, conf_files) {
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
|
||||
r = chase_and_fopen_unlocked(*fn, root, CHASE_AT_RESOLVE_IN_ROOT, "re", NULL, &f);
|
||||
r = chase_and_fopenat_unlocked(root_fd, *fn, CHASE_AT_RESOLVE_IN_ROOT|CHASE_MUST_BE_REGULAR, "re", /* ret_path= */ NULL, &f);
|
||||
if (r == -ENOENT)
|
||||
continue;
|
||||
if (r < 0)
|
||||
@@ -572,7 +572,6 @@ static int config_parse_many_files(
|
||||
}
|
||||
|
||||
/* Then read all the drop-ins. */
|
||||
|
||||
const char *path_dropin;
|
||||
FILE *f_dropin;
|
||||
ORDERED_HASHMAP_FOREACH_KEY(f_dropin, path_dropin, dropins) {
|
||||
@@ -594,12 +593,39 @@ static int config_parse_many_files(
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int normalize_root_fd(const char *root, int *root_fd, int *ret_opened_fd) {
|
||||
assert(root_fd);
|
||||
assert(ret_opened_fd);
|
||||
|
||||
/* Normalizes a root dir specification: if root_fd is already valid, keep it. Otherwise, we open the
|
||||
* specified dir */
|
||||
|
||||
if (*root_fd >= 0 || IN_SET(*root_fd, AT_FDCWD, XAT_FDROOT)) {
|
||||
*ret_opened_fd = -EBADF;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (empty_or_root(root)) {
|
||||
*root_fd = XAT_FDROOT;
|
||||
*ret_opened_fd = -EBADF;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fd = open(root, O_CLOEXEC|O_PATH|O_DIRECTORY);
|
||||
if (fd < 0)
|
||||
return log_error_errno(errno, "Failed to open root directory '%s': %m", root);
|
||||
|
||||
*ret_opened_fd = *root_fd = fd;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Parse each config file in the directories specified as strv. */
|
||||
int config_parse_many(
|
||||
int config_parse_many_full(
|
||||
const char* const* conf_files,
|
||||
const char* const* conf_file_dirs,
|
||||
const char *dropin_dirname,
|
||||
const char *root,
|
||||
int root_fd,
|
||||
const char *sections,
|
||||
ConfigItemLookup lookup,
|
||||
const void *table,
|
||||
@@ -615,14 +641,33 @@ int config_parse_many(
|
||||
assert(dropin_dirname);
|
||||
assert(table);
|
||||
|
||||
r = conf_files_list_dropins(&files, dropin_dirname, root,
|
||||
FLAGS_SET(flags, CONFIG_PARSE_WARN) ? CONF_FILES_WARN : 0,
|
||||
conf_file_dirs);
|
||||
_cleanup_close_ int opened_root_fd = -EBADF;
|
||||
r = normalize_root_fd(root, &root_fd, &opened_root_fd);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = conf_files_list_dropins(
|
||||
&files,
|
||||
dropin_dirname,
|
||||
root,
|
||||
root_fd,
|
||||
FLAGS_SET(flags, CONFIG_PARSE_WARN) ? CONF_FILES_WARN : 0,
|
||||
conf_file_dirs);
|
||||
if (r < 0)
|
||||
return log_full_errno(FLAGS_SET(flags, CONFIG_PARSE_WARN) ? LOG_WARNING : LOG_DEBUG, r,
|
||||
"Failed to list drop-ins in %s: %m", dropin_dirname);
|
||||
|
||||
r = config_parse_many_files(root, conf_files, files, sections, lookup, table, flags, userdata, ret_stats_by_path);
|
||||
r = config_parse_many_files(
|
||||
root,
|
||||
root_fd,
|
||||
conf_files,
|
||||
files,
|
||||
sections,
|
||||
lookup,
|
||||
table,
|
||||
flags,
|
||||
userdata,
|
||||
ret_stats_by_path);
|
||||
if (r < 0)
|
||||
return r; /* config_parse_many_files() logs internally. */
|
||||
|
||||
@@ -634,6 +679,7 @@ int config_parse_many(
|
||||
|
||||
int config_parse_standard_file_with_dropins_full(
|
||||
const char *root,
|
||||
int root_fd,
|
||||
const char *main_file, /* A path like "systemd/frobnicator.conf" */
|
||||
const char *sections,
|
||||
ConfigItemLookup lookup,
|
||||
@@ -643,12 +689,15 @@ int config_parse_standard_file_with_dropins_full(
|
||||
Hashmap **ret_stats_by_path,
|
||||
char ***ret_dropin_files) {
|
||||
|
||||
const char* const *conf_paths = (const char* const*) CONF_PATHS_STRV("");
|
||||
_cleanup_strv_free_ char **configs = NULL;
|
||||
const char* const *conf_file_dirs = (const char* const*) CONF_PATHS_STRV("");
|
||||
_cleanup_strv_free_ char **conf_files = NULL;
|
||||
int r, level = FLAGS_SET(flags, CONFIG_PARSE_WARN) ? LOG_WARNING : LOG_DEBUG;
|
||||
|
||||
/* Build the list of main config files */
|
||||
r = strv_extend_strv_biconcat(&configs, root, conf_paths, main_file);
|
||||
r = strv_extend_strv_concat(
|
||||
&conf_files,
|
||||
conf_file_dirs,
|
||||
main_file);
|
||||
if (r < 0)
|
||||
return log_oom_full(level);
|
||||
|
||||
@@ -656,11 +705,12 @@ int config_parse_standard_file_with_dropins_full(
|
||||
if (!dropin_dirname)
|
||||
return log_oom_full(level);
|
||||
|
||||
return config_parse_many(
|
||||
(const char* const*) configs,
|
||||
conf_paths,
|
||||
return config_parse_many_full(
|
||||
(const char* const*) conf_files,
|
||||
conf_file_dirs,
|
||||
dropin_dirname,
|
||||
root,
|
||||
root_fd,
|
||||
sections,
|
||||
lookup,
|
||||
table,
|
||||
@@ -692,7 +742,13 @@ static int dropins_get_stats_by_path(
|
||||
if (!strextend(&dropin_dirname, ".d"))
|
||||
return -ENOMEM;
|
||||
|
||||
r = conf_files_list_dropins(&files, dropin_dirname, /* root= */ NULL, /* flags= */ 0, conf_file_dirs);
|
||||
r = conf_files_list_dropins(
|
||||
&files,
|
||||
dropin_dirname,
|
||||
/* root= */ NULL,
|
||||
/* root_fd= */ XAT_FDROOT,
|
||||
/* flags= */ 0,
|
||||
conf_file_dirs);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "conf-parser-forward.h"
|
||||
#include "shared-forward.h"
|
||||
#include "fd-util.h"
|
||||
#include "log.h"
|
||||
|
||||
/* An abstract parser for simple, line based, shallow configuration files consisting of variable assignments only. */
|
||||
@@ -66,11 +66,12 @@ int config_parse(
|
||||
void *userdata,
|
||||
struct stat *ret_stat); /* possibly NULL */
|
||||
|
||||
int config_parse_many(
|
||||
int config_parse_many_full(
|
||||
const char* const* conf_files, /* possibly empty */
|
||||
const char* const* conf_file_dirs,
|
||||
const char *dropin_dirname,
|
||||
const char *root,
|
||||
int root_fd,
|
||||
const char *sections, /* nulstr */
|
||||
ConfigItemLookup lookup,
|
||||
const void *table,
|
||||
@@ -79,8 +80,34 @@ int config_parse_many(
|
||||
Hashmap **ret_stats_by_path, /* possibly NULL */
|
||||
char ***ret_dropin_files); /* possibly NULL */
|
||||
|
||||
static inline int config_parse_many(
|
||||
const char* const* conf_files, /* possibly empty */
|
||||
const char* const* conf_file_dirs,
|
||||
const char *dropin_dirname,
|
||||
const char *sections, /* nulstr */
|
||||
ConfigItemLookup lookup,
|
||||
const void *table,
|
||||
ConfigParseFlags flags,
|
||||
void *userdata) {
|
||||
|
||||
return config_parse_many_full(
|
||||
conf_files,
|
||||
conf_file_dirs,
|
||||
dropin_dirname,
|
||||
/* root= */ NULL,
|
||||
/* root_fd= */ XAT_FDROOT,
|
||||
sections,
|
||||
lookup,
|
||||
table,
|
||||
flags,
|
||||
userdata,
|
||||
/* ret_stats_by_path= */ NULL,
|
||||
/* ret_drop_in_files= */ NULL);
|
||||
}
|
||||
|
||||
int config_parse_standard_file_with_dropins_full(
|
||||
const char *root,
|
||||
int root_fd,
|
||||
const char *main_file, /* A path like "systemd/frobnicator.conf" */
|
||||
const char *sections,
|
||||
ConfigItemLookup lookup,
|
||||
@@ -99,6 +126,7 @@ static inline int config_parse_standard_file_with_dropins(
|
||||
void *userdata) {
|
||||
return config_parse_standard_file_with_dropins_full(
|
||||
/* root= */ NULL,
|
||||
/* root_fd= */ XAT_FDROOT,
|
||||
main_file,
|
||||
sections,
|
||||
lookup,
|
||||
|
||||
@@ -2,11 +2,13 @@
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "conf-parser.h"
|
||||
#include "fd-util.h"
|
||||
#include "kernel-config.h"
|
||||
#include "path-util.h"
|
||||
|
||||
int load_kernel_install_conf(
|
||||
int load_kernel_install_conf_at(
|
||||
const char *root,
|
||||
int root_fd,
|
||||
const char *conf_root,
|
||||
char **ret_machine_id,
|
||||
char **ret_boot_root,
|
||||
@@ -26,16 +28,19 @@ int load_kernel_install_conf(
|
||||
};
|
||||
int r;
|
||||
|
||||
assert(root_fd >= 0 || IN_SET(root_fd, AT_FDCWD, XAT_FDROOT));
|
||||
|
||||
if (conf_root) {
|
||||
_cleanup_free_ char *conf = path_join(conf_root, "install.conf");
|
||||
if (!conf)
|
||||
return log_oom();
|
||||
|
||||
r = config_parse_many(
|
||||
r = config_parse_many_full(
|
||||
STRV_MAKE_CONST(conf),
|
||||
STRV_MAKE_CONST(conf_root),
|
||||
"install.conf.d",
|
||||
/* root= */ NULL, /* $KERNEL_INSTALL_CONF_ROOT and --root are independent */
|
||||
root,
|
||||
root_fd,
|
||||
/* sections= */ NULL,
|
||||
config_item_table_lookup, items,
|
||||
CONFIG_PARSE_WARN,
|
||||
@@ -45,6 +50,7 @@ int load_kernel_install_conf(
|
||||
} else
|
||||
r = config_parse_standard_file_with_dropins_full(
|
||||
root,
|
||||
root_fd,
|
||||
"kernel/install.conf",
|
||||
/* sections= */ NULL,
|
||||
config_item_table_lookup, items,
|
||||
|
||||
@@ -1,13 +1,27 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include "fd-util.h"
|
||||
#include "shared-forward.h"
|
||||
|
||||
int load_kernel_install_conf(
|
||||
int load_kernel_install_conf_at(
|
||||
const char *root,
|
||||
int root_fd,
|
||||
const char *conf_root,
|
||||
char **ret_machine_id,
|
||||
char **ret_boot_root,
|
||||
char **ret_layout,
|
||||
char **ret_initrd_generator,
|
||||
char **ret_uki_generator);
|
||||
|
||||
static inline int load_kernel_install_conf(
|
||||
const char *root,
|
||||
const char *conf_root,
|
||||
char **ret_machine_id,
|
||||
char **ret_boot_root,
|
||||
char **ret_layout,
|
||||
char **ret_initrd_generator,
|
||||
char **ret_uki_generator) {
|
||||
|
||||
return load_kernel_install_conf_at(root, XAT_FDROOT, conf_root, ret_machine_id, ret_boot_root, ret_layout, ret_initrd_generator, ret_uki_generator);
|
||||
}
|
||||
|
||||
@@ -191,6 +191,7 @@ static int parse_config_file(ImageClass image_class) {
|
||||
|
||||
r = config_parse_standard_file_with_dropins_full(
|
||||
arg_root,
|
||||
/* root_fd= */ -EBADF,
|
||||
config_file,
|
||||
sections,
|
||||
config_item_table_lookup, items,
|
||||
|
||||
@@ -101,11 +101,12 @@ int feature_read_definition(Feature *f, const char *path, const char *const *dir
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to extract filename from path '%s': %m", path);
|
||||
|
||||
r = config_parse_many(
|
||||
r = config_parse_many_full(
|
||||
STRV_MAKE_CONST(path),
|
||||
dirs,
|
||||
strjoina(filename, ".d"),
|
||||
arg_root,
|
||||
/* root_fd= */ -EBADF,
|
||||
"Feature\0",
|
||||
config_item_table_lookup, table,
|
||||
CONFIG_PARSE_WARN,
|
||||
|
||||
@@ -543,11 +543,12 @@ int transfer_read_definition(Transfer *t, const char *path, const char **dirs, H
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to extract filename from path '%s': %m", path);
|
||||
|
||||
r = config_parse_many(
|
||||
r = config_parse_many_full(
|
||||
STRV_MAKE_CONST(path),
|
||||
dirs,
|
||||
strjoina(filename, ".d"),
|
||||
arg_root,
|
||||
/* root_fd= */ -EBADF,
|
||||
"Transfer\0"
|
||||
"Source\0"
|
||||
"Target\0",
|
||||
|
||||
@@ -1568,12 +1568,12 @@ static int verb_components(int argc, char **argv, void *userdata) {
|
||||
FOREACH_ARRAY(i, directories, n_directories) {
|
||||
ConfFile *e = *i;
|
||||
|
||||
if (streq(e->name, "sysupdate.d")) {
|
||||
if (streq(e->filename, "sysupdate.d")) {
|
||||
has_default_component = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
const char *s = startswith(e->name, "sysupdate.");
|
||||
const char *s = startswith(e->filename, "sysupdate.");
|
||||
if (!s)
|
||||
continue;
|
||||
|
||||
|
||||
@@ -444,7 +444,9 @@ TEST(config_parse_standard_file_with_dropins_full) {
|
||||
};
|
||||
|
||||
r = config_parse_standard_file_with_dropins_full(
|
||||
root, "kernel/install.conf",
|
||||
root,
|
||||
/* root_fd= */ -EBADF,
|
||||
"kernel/install.conf",
|
||||
/* sections= */ NULL,
|
||||
config_item_table_lookup, items,
|
||||
CONFIG_PARSE_WARN,
|
||||
@@ -483,7 +485,9 @@ TEST(config_parse_standard_file_with_dropins_full) {
|
||||
assert_se(symlinkat("/etc/kernel/install.conf.d/drop4.conf", rfd, "etc/kernel/install2.conf.d/drop4.conf") == 0);
|
||||
|
||||
r = config_parse_standard_file_with_dropins_full(
|
||||
root, "kernel/install2.conf",
|
||||
root,
|
||||
/* root_fd= */ -EBADF,
|
||||
"kernel/install2.conf",
|
||||
/* sections= */ NULL,
|
||||
config_item_table_lookup, items,
|
||||
CONFIG_PARSE_WARN,
|
||||
|
||||
@@ -280,17 +280,20 @@ int link_load_one(LinkConfigContext *ctx, const char *filename) {
|
||||
return log_error_errno(r, "Failed to extract file name of '%s': %m", filename);
|
||||
|
||||
dropin_dirname = strjoina(file_basename, ".d");
|
||||
r = config_parse_many(
|
||||
r = config_parse_many_full(
|
||||
STRV_MAKE_CONST(filename),
|
||||
NETWORK_DIRS,
|
||||
dropin_dirname,
|
||||
/* root= */ NULL,
|
||||
/* root_fd= */ -EBADF,
|
||||
"Match\0"
|
||||
"Link\0"
|
||||
"SR-IOV\0"
|
||||
"EnergyEfficientEthernet\0",
|
||||
config_item_perf_lookup, link_config_gperf_lookup,
|
||||
CONFIG_PARSE_WARN, config, &stats_by_path,
|
||||
CONFIG_PARSE_WARN,
|
||||
config,
|
||||
&stats_by_path,
|
||||
&config->dropins);
|
||||
if (r < 0)
|
||||
return r; /* config_parse_many() logs internally. */
|
||||
|
||||
Reference in New Issue
Block a user