1
0
mirror of https://github.com/systemd/systemd synced 2026-03-15 09:34:47 +01:00

Compare commits

..

No commits in common. "cab4b9defdef1f9f9d3c31b262aed408a6616490" and "50caaf267b6ac6a83a0edaffbea232275372dfdb" have entirely different histories.

35 changed files with 173 additions and 636 deletions

7
NEWS
View File

@ -33,10 +33,9 @@ CHANGES WITH 260 in spe:
Changes in other components:
* New options SYSTEMD_COLORS=auto-16, SYSTEMD_COLORS=auto-256, and
SYSTEMD_COLORS=auto-24bit, which are like SYSTEMD_COLORS=16,
SYSTEMD_COLORS=256, and SYSTEMD_COLORS=24bit respectively when output
is to a non-dumb TTY, and like SYSTEMD_COLORS=no otherwise.
* New options SYSTEMD_COLORS=auto-16 and SYSTEMD_COLORS=auto-256, which
are like SYSTEMD_COLORS=16 and SYSTEMD_COLORS=256 respectively when
output is to a non-dumb TTY, and like SYSTEMD_COLORS=no otherwise.
CHANGES WITH 259:

View File

@ -268,10 +268,6 @@
<!-- add Index link at top of page -->
<xsl:template name="user.header.content">
<style>
:root {
color-scheme: light dark;
}
a.headerlink {
color: #c60f0f;
font-size: 0.8em;
@ -316,13 +312,6 @@
<xsl:text>"</xsl:text>
</xsl:template>
<!-- copied from docbook to remove the static color declarations -->
<xsl:template name="body.attributes">
<xsl:if test="starts-with($writing.mode, 'rl')">
<xsl:attribute name="dir">rtl</xsl:attribute>
</xsl:if>
</xsl:template>
<!-- Switch things to UTF-8, ISO-8859-1 is soo yesteryear -->
<xsl:output method="html" encoding="UTF-8" indent="no"/>

View File

@ -24,7 +24,7 @@ ConfFile* conf_file_free(ConfFile *c) {
if (!c)
return NULL;
free(c->filename);
free(c->name);
free(c->result);
free(c->original_path);
free(c->resolved_path);
@ -44,20 +44,13 @@ 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,
char **ret_root,
int *ret_rfd,
char ***ret_dirs) {
static int prepare_dirs(const char *root, ConfFilesFlags flags, char * const *dirs, int *ret_rfd, char **ret_root, char ***ret_dirs) {
_cleanup_free_ char *root_abs = NULL;
_cleanup_strv_free_ char **dirs_abs = NULL;
int r;
assert(ret_root);
assert(ret_rfd);
assert(ret_root);
assert(ret_dirs || strv_isempty(dirs));
int log_level = conf_files_log_level(flags);
@ -72,7 +65,6 @@ static int prepare_dirs(
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. */
@ -81,11 +73,6 @@ static int prepare_dirs(
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. */
@ -94,8 +81,12 @@ static int prepare_dirs(
return log_full_errno(log_level, r, "Failed to make directories absolute: %m");
}
*ret_root = TAKE_PTR(root_abs);
_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);
if (ret_dirs)
*ret_dirs = TAKE_PTR(dirs_abs);
return 0;
@ -144,8 +135,8 @@ static ChaseFlags conf_files_chase_flags(ConfFilesFlags flags) {
}
static int conf_file_chase_and_verify(
const char *root, /* for logging, can be NULL */
int rfd,
const char *root, /* for logging, can be NULL */
const char *original_path, /* for logging */
const char *path,
const char *name,
@ -160,7 +151,7 @@ static int conf_file_chase_and_verify(
struct stat st = {};
int r;
assert(rfd >= 0 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
assert(rfd >= 0 || rfd == AT_FDCWD);
assert(original_path);
assert(path);
assert(name);
@ -270,25 +261,18 @@ static int conf_file_chase_and_verify(
return 0;
}
int conf_file_new_at(
const char *path,
const char *root,
int rfd,
ConfFilesFlags flags,
ConfFile **ret) {
int conf_file_new_at(const char *path, int rfd, ConfFilesFlags flags, ConfFile **ret) {
int r;
assert(path);
assert(rfd >= 0 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
assert(rfd >= 0 || rfd == AT_FDCWD);
assert(ret);
int log_level = conf_files_log_level(flags);
_cleanup_free_ char *_root = NULL;
if (DEBUG_LOGGING && !root) {
(void) fd_get_path(rfd, &_root);
root = _root;
}
_cleanup_free_ char *root = NULL;
if (rfd >= 0)
(void) fd_get_path(rfd, &root);
_cleanup_(conf_file_freep) ConfFile *c = new(ConfFile, 1);
if (!c)
@ -302,7 +286,7 @@ int conf_file_new_at(
if (!c->original_path)
return log_oom_full(log_level);
r = path_extract_filename(path, &c->filename);
r = path_extract_filename(path, &c->name);
if (r < 0)
return log_full_errno(log_level, r, "Failed to extract filename from '%s': %m", path);
@ -318,16 +302,16 @@ int conf_file_new_at(
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->filename);
c->result = path_join(resolved_dirpath, c->name);
if (!c->result)
return log_oom_full(log_level);
r = conf_file_chase_and_verify(
root,
rfd,
root,
c->original_path,
c->result,
c->filename,
c->name,
/* masked= */ NULL,
flags,
&c->resolved_path,
@ -348,7 +332,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, &root_abs, &rfd, /* ret_dirs= */ NULL);
r = prepare_dirs(root, flags, /* dirs= */ NULL, &rfd, &root_abs, /* ret_dirs= */ NULL);
if (r < 0)
return r;
@ -362,7 +346,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, root_abs, rfd, flags, &c);
r = conf_file_new_at(path, rfd, flags, &c);
if (r < 0)
return r;
@ -383,8 +367,8 @@ static int files_add(
DIR *dir,
const char *original_dirpath,
const char *resolved_dirpath,
const char *root, /* for logging, can be NULL */
int rfd,
const char *root, /* for logging, can be NULL */
Hashmap **files,
Set **masked,
const char *suffix,
@ -395,7 +379,7 @@ static int files_add(
assert(dir);
assert(original_dirpath);
assert(resolved_dirpath);
assert(rfd >= 0 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
assert(rfd >= 0 || rfd == AT_FDCWD);
assert(files);
assert(masked);
@ -436,8 +420,8 @@ static int files_add(
_cleanup_close_ int fd = -EBADF;
struct stat st;
r = conf_file_chase_and_verify(
root,
rfd,
root,
original_path,
p,
de->d_name,
@ -456,7 +440,7 @@ static int files_add(
return log_oom_full(log_level);
*c = (ConfFile) {
.filename = strdup(de->d_name),
.name = strdup(de->d_name),
.result = TAKE_PTR(p),
.original_path = TAKE_PTR(original_path),
.resolved_path = TAKE_PTR(resolved_path),
@ -464,10 +448,10 @@ static int files_add(
.st = st,
};
if (!c->filename)
if (!c->name)
return log_oom_full(log_level);
r = hashmap_ensure_put(files, &conf_file_hash_ops, c->filename, c);
r = hashmap_ensure_put(files, &conf_file_hash_ops, c->name, c);
if (r < 0) {
assert(r == -ENOMEM);
return log_oom_full(log_level);
@ -497,7 +481,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)->filename) == *i);
assert_se(hashmap_remove(fh, (*i)->name) == *i);
if (root)
FOREACH_ARRAY(i, files, n_files) {
@ -538,8 +522,8 @@ static int copy_and_sort_files_from_hashmap(
const char *add = NULL;
if (FLAGS_SET(flags, CONF_FILES_BASENAME))
add = c->filename;
else if (root && !FLAGS_SET(flags, CONF_FILES_DONT_PREFIX_ROOT)) {
add = c->name;
else if (root) {
_cleanup_free_ char *p = NULL;
r = chaseat_prefix_root(c->result, root, &p);
@ -590,22 +574,22 @@ static int insert_replacement(Hashmap **fh, ConfFile *replacement, ConfFilesFlag
/* This consumes the input ConfFile. */
ConfFile *existing = hashmap_get(*fh, c->filename);
ConfFile *existing = hashmap_get(*fh, c->name);
if (existing) {
log_debug("An entry with higher priority '%s' -> '%s' already exists, ignoring the replacement: %s",
existing->filename, existing->result, c->original_path);
existing->name, existing->result, c->original_path);
*ret = NULL;
return 0;
}
r = hashmap_ensure_put(fh, &conf_file_hash_ops, c->filename, c);
r = hashmap_ensure_put(fh, &conf_file_hash_ops, c->name, 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->filename, c->result);
log_debug("Inserted replacement: '%s' -> '%s'", c->name, c->result);
*ret = TAKE_PTR(c);
return 0;
@ -613,8 +597,8 @@ static int insert_replacement(Hashmap **fh, ConfFile *replacement, ConfFilesFlag
static int conf_files_list_impl(
const char *suffix,
const char *root, /* for logging, can be NULL */
int rfd,
const char *root, /* for logging, can be NULL */
ConfFilesFlags flags,
const char * const *dirs,
const char *replacement,
@ -627,13 +611,13 @@ static int conf_files_list_impl(
const ConfFile *inserted = NULL;
int r;
assert(rfd >= 0 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
assert(rfd >= 0 || rfd == AT_FDCWD);
assert(ret);
root = empty_to_root(root);
if (replacement) {
r = conf_file_new_at(replacement, root, rfd, flags & CONF_FILES_WARN, &c);
r = conf_file_new_at(replacement, rfd, flags & CONF_FILES_WARN, &c);
if (r < 0)
return r;
}
@ -651,13 +635,13 @@ static int conf_files_list_impl(
continue;
}
if (c && streq_ptr(path_startswith(c->result, path), c->filename)) {
if (c && streq_ptr(path_startswith(c->result, path), c->name)) {
r = insert_replacement(&fh, TAKE_PTR(c), flags, &inserted);
if (r < 0)
return r;
}
r = files_add(dir, *p, path, root, rfd, &fh, &masked, suffix, flags);
r = files_add(dir, *p, path, rfd, root, &fh, &masked, suffix, flags);
if (r == -ENOMEM)
return r;
}
@ -689,11 +673,11 @@ int conf_files_list_strv(
assert(ret);
r = prepare_dirs(root, flags, (char**) dirs, &root_abs, &rfd, &dirs_abs);
r = prepare_dirs(root, flags, (char**) dirs, &rfd, &root_abs, &dirs_abs);
if (r < 0)
return r;
r = conf_files_list_impl(suffix, root_abs, rfd, flags, (const char * const *) dirs_abs,
r = conf_files_list_impl(suffix, rfd, root_abs, flags, (const char * const *) dirs_abs,
/* replacement= */ NULL, &fh, /* ret_inserted= */ NULL);
if (r < 0)
return r;
@ -718,11 +702,11 @@ int conf_files_list_strv_full(
assert(ret_files);
assert(ret_n_files);
r = prepare_dirs(root, flags, (char**) dirs, &root_abs, &rfd, &dirs_abs);
r = prepare_dirs(root, flags, (char**) dirs, &rfd, &root_abs, &dirs_abs);
if (r < 0)
return r;
r = conf_files_list_impl(suffix, root_abs, rfd, flags, (const char * const *) dirs_abs,
r = conf_files_list_impl(suffix, rfd, root_abs, flags, (const char * const *) dirs_abs,
/* replacement= */ NULL, &fh, /* ret_inserted= */ NULL);
if (r < 0)
return r;
@ -741,13 +725,13 @@ int conf_files_list_strv_at(
_cleanup_free_ char *root = NULL;
int r;
assert(rfd >= 0 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
assert(rfd >= 0 || rfd == AT_FDCWD);
assert(ret);
if (DEBUG_LOGGING)
if (rfd >= 0)
(void) fd_get_path(rfd, &root); /* for logging */
r = conf_files_list_impl(suffix, root, rfd, flags, dirs, /* replacement= */ NULL, &fh, /* ret_inserted= */ NULL);
r = conf_files_list_impl(suffix, rfd, root, flags, dirs, /* replacement= */ NULL, &fh, /* ret_inserted= */ NULL);
if (r < 0)
return r;
@ -766,14 +750,14 @@ int conf_files_list_strv_at_full(
_cleanup_free_ char *root = NULL;
int r;
assert(rfd >= 0 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
assert(rfd >= 0 || rfd == AT_FDCWD);
assert(ret_files);
assert(ret_n_files);
if (DEBUG_LOGGING)
if (rfd >= 0)
(void) fd_get_path(rfd, &root); /* for logging */
r = conf_files_list_impl(suffix, root, rfd, flags, dirs, /* replacement= */ NULL, &fh, /* ret_inserted= */ NULL);
r = conf_files_list_impl(suffix, rfd, root, flags, dirs, /* replacement= */ NULL, &fh, /* ret_inserted= */ NULL);
if (r < 0)
return r;
@ -864,11 +848,11 @@ int conf_files_list_with_replacement(
assert(ret_files);
r = prepare_dirs(root, flags, config_dirs, &root_abs, &rfd, &dirs_abs);
r = prepare_dirs(root, flags, config_dirs, &rfd, &root_abs, &dirs_abs);
if (r < 0)
return r;
r = conf_files_list_impl(".conf", root_abs, rfd, flags, (const char * const *) dirs_abs,
r = conf_files_list_impl(".conf", rfd, root_abs, flags, (const char * const *) dirs_abs,
replacement, &fh, ret_inserted ? &c : NULL);
if (r < 0)
return r;
@ -894,7 +878,6 @@ int conf_files_list_dropins(
char ***ret,
const char *dropin_dirname,
const char *root,
int root_fd,
ConfFilesFlags flags,
const char * const *dirs) {
@ -911,7 +894,7 @@ int conf_files_list_dropins(
if (r < 0)
return log_oom_full(conf_files_log_level(flags));
return conf_files_list_strv_at(ret, ".conf", root_fd, flags, (const char* const*) dropin_dirs);
return conf_files_list_strv(ret, ".conf", root, flags, (const char* const*) dropin_dirs);
}
/**

View File

@ -15,15 +15,14 @@ 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 *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 */
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 */
struct stat st; /* stat of the file. */
} ConfFile;
@ -31,7 +30,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, const char *root, int rfd, ConfFilesFlags flags, ConfFile **ret);
int conf_file_new_at(const char *path, 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);
@ -58,7 +57,6 @@ int conf_files_list_dropins(
char ***ret,
const char *dropin_dirname,
const char *root,
int root_fd,
ConfFilesFlags flags,
const char * const *dirs);

View File

@ -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 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
assert(rfd >= 0 || rfd == AT_FDCWD);
e = secure_getenv("SYSTEMD_OS_RELEASE");
if (e)
@ -184,15 +184,13 @@ 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 = XAT_FDROOT, fd = -EBADF;
_cleanup_close_ int rfd = -EBADF, fd = -EBADF;
_cleanup_free_ char *p = NULL;
int r;
if (!empty_or_root(root)) {
rfd = open(root, O_CLOEXEC | O_DIRECTORY | O_PATH);
rfd = open(empty_to_root(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)
@ -225,7 +223,7 @@ int open_extension_release_at(
const char *p;
int r;
assert(rfd >= 0 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
assert(rfd >= 0 || rfd == AT_FDCWD);
assert(!extension || (image_class >= 0 && image_class < _IMAGE_CLASS_MAX));
if (!extension)
@ -332,15 +330,13 @@ int open_extension_release(
char **ret_path,
int *ret_fd) {
_cleanup_close_ int rfd = XAT_FDROOT, fd = -EBADF;
_cleanup_close_ int rfd = -EBADF, fd = -EBADF;
_cleanup_free_ char *p = NULL;
int r;
if (!empty_or_root(root)) {
rfd = open(root, O_CLOEXEC | O_DIRECTORY | O_PATH);
rfd = open(empty_to_root(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);
@ -370,7 +366,7 @@ static int parse_extension_release_atv(
_cleanup_free_ char *p = NULL;
int r;
assert(rfd >= 0 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
assert(rfd >= 0 || rfd == AT_FDCWD);
r = open_extension_release_at(rfd, image_class, extension, relax_extension_release_check, &p, &fd);
if (r < 0)
@ -389,7 +385,7 @@ int parse_extension_release_at_sentinel(
va_list ap;
int r;
assert(rfd >= 0 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
assert(rfd >= 0 || rfd == AT_FDCWD);
va_start(ap, extension);
r = parse_extension_release_atv(rfd, image_class, extension, relax_extension_release_check, ap);
@ -404,20 +400,17 @@ int parse_extension_release_sentinel(
const char *extension,
...) {
_cleanup_close_ int rfd = XAT_FDROOT;
_cleanup_close_ int rfd = -EBADF;
va_list ap;
int r;
if (!empty_or_root(root)) {
rfd = open(root, O_CLOEXEC | O_DIRECTORY | O_PATH);
rfd = open(empty_to_root(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;
}

View File

@ -842,10 +842,11 @@ 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,
/* userdata= */ NULL);
NULL, NULL, NULL);
}
/* Traditionally "0" was used to turn off the default unit timeouts. Fix this up so that we use

View File

@ -115,14 +115,8 @@ if [ -f "$TRIES_FILE" ]; then
if [ -f "$LOADER_ENTRY" ]; then
[ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && \
echo "Removing previous loader entry '$LOADER_ENTRY' without boot counting." >&2
rm -f "$LOADER_ENTRY"
rm -f "$LOADER_ENTRY" "${LOADER_ENTRY%.conf}+"*.conf
fi
for loaderentry in "${LOADER_ENTRY%.conf}+"*.conf; do
[ "$loaderentry" = "${LOADER_ENTRY%.conf}+*.conf" ] && break
[ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && \
echo "Removing previous loader entry '$loaderentry' that has not yet booted successfully." >&2
rm -f "$loaderentry"
done
LOADER_ENTRY="${LOADER_ENTRY%.conf}+$TRIES.conf"
fi

View File

@ -70,14 +70,8 @@ if [ -f "$TRIES_FILE" ]; then
if [ -f "$UKI_DIR/$ENTRY_TOKEN-$KERNEL_VERSION.efi" ]; then
[ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && \
echo "Removing previous UKI '$UKI_DIR/$ENTRY_TOKEN-$KERNEL_VERSION.efi' without boot counting." >&2
rm -f "$UKI_DIR/$ENTRY_TOKEN-$KERNEL_VERSION.efi"
rm -f "$UKI_DIR/$ENTRY_TOKEN-$KERNEL_VERSION.efi" "$UKI_DIR/$ENTRY_TOKEN-$KERNEL_VERSION+"*.efi
fi
for uki in "$UKI_DIR/$ENTRY_TOKEN-$KERNEL_VERSION+"*.efi; do
[ "$uki" = "$UKI_DIR/$ENTRY_TOKEN-$KERNEL_VERSION+*.efi" ] && break
[ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && \
echo "Removing previous UKI '$uki' that has not yet booted successfully." >&2
rm -f "$uki"
done
UKI_FILE="$UKI_DIR/$ENTRY_TOKEN-$KERNEL_VERSION+$TRIES.efi"
else

View File

@ -460,9 +460,7 @@ static int context_load_install_conf(Context *c) {
assert(c);
r = load_kernel_install_conf_at(
c->conf_root ? NULL : arg_root,
c->conf_root ? XAT_FDROOT : c->rfd,
r = load_kernel_install_conf(arg_root,
c->conf_root,
&machine_id,
&boot_root,

View File

@ -255,10 +255,8 @@ typedef struct sd_bus {
uint64_t creds_mask;
/* Accumulated fds from multiple recvmsg() calls for a single D-Bus message */
int *fds;
size_t n_fds;
bool got_ctrunc; /* MSG_CTRUNC was seen during any recvmsg() */
char *exec_path;
char **exec_argv;

View File

@ -17,7 +17,7 @@
#include "utf8.h"
static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
static int message_parse_fields(sd_bus_message *m, bool got_ctrunc);
static int message_parse_fields(sd_bus_message *m);
static void* adjust_pointer(const void *p, void *old_base, size_t sz, void *new_base) {
@ -408,7 +408,6 @@ int bus_message_from_malloc(
size_t length,
int *fds,
size_t n_fds,
bool got_ctrunc,
const char *label,
sd_bus_message **ret) {
@ -438,7 +437,7 @@ int bus_message_from_malloc(
m->iovec = m->iovec_fixed;
m->iovec[0] = IOVEC_MAKE(buffer, length);
r = message_parse_fields(m, got_ctrunc);
r = message_parse_fields(m);
if (r < 0)
return r;
@ -4030,8 +4029,8 @@ static int message_skip_fields(
}
}
static int message_parse_fields(sd_bus_message *m, bool got_ctrunc) {
uint32_t n_unix_fds_declared = 0;
static int message_parse_fields(sd_bus_message *m) {
uint32_t unix_fds = 0;
bool unix_fds_set = false;
int r;
@ -4184,7 +4183,7 @@ static int message_parse_fields(sd_bus_message *m, bool got_ctrunc) {
if (!streq(signature, "u"))
return -EBADMSG;
r = message_peek_field_uint32(m, &ri, item_size, &n_unix_fds_declared);
r = message_peek_field_uint32(m, &ri, item_size, &unix_fds);
if (r < 0)
return -EBADMSG;
@ -4198,26 +4197,8 @@ static int message_parse_fields(sd_bus_message *m, bool got_ctrunc) {
return r;
}
/* Validate that the number of fds we actually received via SCM_RIGHTS matches (or is compatible
* with) the number declared in the message header.
*
* Normally these must match exactly. However, when MSG_CTRUNC was set during recvmsg(), the kernel
* might have truncated the fd array (e.g., due to LSM denials blocking fd passing). In that case,
* we also accept fewer fds than declared. Any attempt to actually use a truncated fd will fail later
* when sd_bus_message_read_basic() finds the fd index out of range. Too many fds is always wrong. */
if (m->n_fds > n_unix_fds_declared)
return log_error_errno(SYNTHETIC_ERRNO(EBADMSG),
"Received a bus message with too many fds: %" PRIu32 " received vs. %" PRIu32 " declared",
m->n_fds, n_unix_fds_declared);
if (m->n_fds < n_unix_fds_declared && !got_ctrunc)
return log_error_errno(SYNTHETIC_ERRNO(EBADMSG),
"Received a bus message with too few fds: %" PRIu32 " received vs. %" PRIu32 " declared",
m->n_fds, n_unix_fds_declared);
if (got_ctrunc)
log_error("Received a bus message with MSG_CTRUNC set with %" PRIu32 " fds received vs %" PRIu32 " declared",
m->n_fds, n_unix_fds_declared);
if (m->n_fds != unix_fds)
return -EBADMSG;
switch (m->header->type) {

View File

@ -177,7 +177,6 @@ int bus_message_from_malloc(
size_t length,
int *fds,
size_t n_fds,
bool got_ctrunc,
const char *label,
sd_bus_message **ret);

View File

@ -590,12 +590,6 @@ static int bus_process_cmsg(sd_bus *bus, struct msghdr *mh, bool allow_fds) {
return 0;
}
/* Check if we previously received fds with MSG_CTRUNC set. When the kernel truncates the fd array,
* it drops all fds from the blocked one onwards - we have no way to know how many were lost or which
* indexes are affected. Any fds we receive now would be appended at the wrong indexes, corrupting
* the message's fd table. We must silently drop them to avoid a worse mess. Reading the message will
* still fail later when the user tries to access a truncated fd. */
if (!bus->got_ctrunc) {
if (!GREEDY_REALLOC(bus->fds, bus->n_fds + n_fds))
return -ENOMEM;
@ -604,11 +598,6 @@ static int bus_process_cmsg(sd_bus *bus, struct msghdr *mh, bool allow_fds) {
TAKE_PTR(fds);
n_fds = 0;
}
if (FLAGS_SET(mh->msg_flags, MSG_CTRUNC))
bus->got_ctrunc = true;
return 0;
}
@ -657,7 +646,7 @@ static int bus_socket_read_auth(sd_bus *b) {
.msg_controllen = sizeof(control),
};
k = RET_NERRNO(recvmsg(b->input_fd, &mh, MSG_DONTWAIT|MSG_CMSG_CLOEXEC));
k = recvmsg_safe(b->input_fd, &mh, MSG_DONTWAIT|MSG_CMSG_CLOEXEC);
if (k == -ENOTSOCK) {
b->prefer_readv = true;
k = readv(b->input_fd, &iov, 1);
@ -1368,7 +1357,6 @@ static int bus_socket_make_message(sd_bus *bus, size_t size) {
r = bus_message_from_malloc(bus,
bus->rbuffer, size,
bus->fds, bus->n_fds,
bus->got_ctrunc,
NULL,
&t);
if (r == -EBADMSG) {
@ -1385,7 +1373,6 @@ static int bus_socket_make_message(sd_bus *bus, size_t size) {
bus->fds = NULL;
bus->n_fds = 0;
bus->got_ctrunc = false;
if (t) {
t->read_counter = ++bus->read_counter;
@ -1436,7 +1423,7 @@ int bus_socket_read_message(sd_bus *bus) {
.msg_controllen = sizeof(control),
};
k = RET_NERRNO(recvmsg(bus->input_fd, &mh, MSG_DONTWAIT|MSG_CMSG_CLOEXEC));
k = recvmsg_safe(bus->input_fd, &mh, MSG_DONTWAIT|MSG_CMSG_CLOEXEC);
if (k == -ENOTSOCK) {
bus->prefer_readv = true;
k = readv(bus->input_fd, &iov, 1);

View File

@ -23,7 +23,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
assert_se(buffer = memdup(data, size));
r = bus_message_from_malloc(bus, buffer, size, NULL, 0, /* got_ctrunc= */ false, NULL, &m);
r = bus_message_from_malloc(bus, buffer, size, NULL, 0, NULL, &m);
if (r == -EBADMSG)
return 0;
assert_se(r >= 0);

View File

@ -2,7 +2,6 @@
#include <fcntl.h>
#include <pthread.h>
#include <sys/resource.h>
#include <unistd.h>
#include "sd-bus.h"
@ -11,13 +10,10 @@
#include "bus-error.h"
#include "bus-internal.h"
#include "bus-match.h"
#include "bus-message.h"
#include "errno-util.h"
#include "fd-util.h"
#include "format-util.h"
#include "log.h"
#include "memfd-util.h"
#include "stat-util.h"
#include "string-util.h"
#include "tests.h"
#include "time-util.h"
@ -497,128 +493,6 @@ finish:
return INT_TO_PTR(r);
}
static ino_t get_inode(int fd) {
struct stat st;
assert_se(fstat(fd, &st) >= 0);
return st.st_ino;
}
static int get_one_message(sd_bus *bus, sd_bus_message **m) {
int r;
assert (m);
while (!*m) {
r = sd_bus_wait(bus, UINT64_MAX);
if (r < 0)
return log_error_errno(r, "Failed to wait: %m");
r = sd_bus_process(bus, m);
if (r < 0)
return log_error_errno(r, "Failed to process requests: %m");
}
return 0;
}
TEST(ctrunc) {
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
_cleanup_(sd_bus_message_unrefp) sd_bus_message *recvd = NULL, *sent = NULL;
struct rlimit orig_rl, new_rl;
const char *unique;
const int n_fds_to_send = 64;
ino_t memfd_st_ino[n_fds_to_send];
int r;
/* Connect to the session bus and eat the NamedAcquired message */
r = sd_bus_open_user(&bus);
if (r < 0)
return (void) log_error_errno(r, "Cannot connect to bus: %m");
ASSERT_OK(get_one_message(bus, &recvd));
recvd = sd_bus_message_unref(recvd);
if (!sd_bus_can_send(bus, 'h'))
return (void) log_error("Bus does not support fd passing: %m");
/* We will create a message with 64 fds in it and set a fd limit of 128 and try to receive it. We'll
* hold on to that message after we send it and then attempt to receive it back. Since various other
* fds will be open, with both copies of the message, we'll definitely hit the limit of 128.
*/
ASSERT_OK(sd_bus_get_unique_name(bus, &unique));
ASSERT_OK(sd_bus_message_new_method_call(bus, &sent, unique, "/", "org.freedesktop.systemd.test", "SendFds"));
ASSERT_OK(sd_bus_message_open_container(sent, SD_BUS_TYPE_ARRAY, "h"));
/* Create a series of memfds, appending each to the message */
for (int i = 0; i < n_fds_to_send; i++) {
_cleanup_close_ int memfd = memfd_create_wrapper("ctrunc-test", 0);
ASSERT_OK(memfd);
memfd_st_ino[i] = get_inode(memfd);
ASSERT_OK(sd_bus_message_append(sent, "h", memfd));
}
ASSERT_OK(sd_bus_message_close_container(sent));
/* Send the message - keep 'sent' alive to hold the duplicated fd references */
ASSERT_OK(sd_bus_send(bus, sent, NULL));
/* Now turn down the fd limit, receive the message, and turn it back up again */
ASSERT_OK_ERRNO(getrlimit(RLIMIT_NOFILE, &orig_rl));
new_rl.rlim_cur = n_fds_to_send * 2;
new_rl.rlim_max = orig_rl.rlim_max;
ASSERT_OK_ERRNO(setrlimit(RLIMIT_NOFILE, &new_rl));
/* The very first message should be the one we expect */
ASSERT_OK(get_one_message(bus, &recvd));
ASSERT_TRUE(sd_bus_message_is_method_call(recvd, "org.freedesktop.systemd.test", "SendFds"));
/* This needs to succeed or the following tests are going to be unhappy... */
ASSERT_EQ(setrlimit(RLIMIT_NOFILE, &orig_rl), 0);
/* Try to read all the fds. We expect at least one to fail with -EBADMSG due to
* truncation, and all subsequent reads must also fail with -EBADMSG. */
int i;
ASSERT_OK(sd_bus_message_enter_container(recvd, SD_BUS_TYPE_ARRAY, "h"));
for (i = 0; i < n_fds_to_send; i++) {
int fd; /* weakly owned: the fd belongs to the message */
r = sd_bus_message_read_basic(recvd, 'h', &fd);
if (r == -EBADMSG)
/* Good! We were expecting this! */
break;
ASSERT_OK(r);
ASSERT_EQ(get_inode(fd), memfd_st_ino[i]);
}
/* Make sure we successfully sent at least one fd but not all of them */
ASSERT_GT(i, 0);
ASSERT_LT(i, n_fds_to_send);
log_info("fds truncated at %i", i);
/* At this point we're stuck. We can call sd_bus_message_read_basic() as often as we want, but we
* won't be able to make progress and won't be able to close the array or read anything else in the
* message.
*/
for (i = 0; i < 2 * n_fds_to_send; i++) {
int fd; /* weakly owned: the fd belongs to the message */
ASSERT_ERROR(sd_bus_message_read_basic(recvd, 'h', &fd), EBADMSG);
}
ASSERT_ERROR(sd_bus_message_exit_container(recvd), EBUSY);
recvd = sd_bus_message_unref(recvd);
/* Send the message again without the fd limits to make sure the connection still works */
ASSERT_OK(sd_bus_send(bus, sent, NULL));
ASSERT_OK(get_one_message(bus, &recvd));
ASSERT_TRUE(sd_bus_message_is_method_call(recvd, "org.freedesktop.systemd.test", "SendFds"));
/* Read all the fds. */
ASSERT_EQ(sd_bus_message_enter_container(recvd, SD_BUS_TYPE_ARRAY, "h"), 1);
for (i = 0; i < n_fds_to_send; i++) {
int fd; /* weakly owned: the fd belongs to the message */
ASSERT_OK(sd_bus_message_read_basic(recvd, 'h', &fd));
ASSERT_EQ(get_inode(fd), memfd_st_ino[i]);
}
ASSERT_OK(sd_bus_message_exit_container(recvd));
log_info("MSG_CTRUNC test passed");
}
TEST(chat) {
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
pthread_t c1, c2;

View File

@ -19,16 +19,12 @@ REENABLE_WARNING
#include "sd-bus.h"
#include "alloc-util.h"
#include "bus-internal.h"
#include "bus-label.h"
#include "bus-message.h"
#include "bus-util.h"
#include "escape.h"
#include "fd-util.h"
#include "log.h"
#include "memfd-util.h"
#include "memstream-util.h"
#include "stat-util.h"
#include "tests.h"
static void test_bus_path_encode_unique(void) {
@ -103,119 +99,6 @@ static void test_bus_label_escape_one(const char *a, const char *b) {
assert_se(streq(a, y));
}
static ino_t get_inode(int fd) {
struct stat st;
assert_se(fstat(fd, &st) >= 0);
return st.st_ino;
}
static void test_bus_fds_truncated(void) {
_cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
_cleanup_close_ int memfd0 = -EBADF, memfd1 = -EBADF;
_cleanup_free_ void *blob = NULL;
_cleanup_free_ int *fds = NULL;
ino_t ino0, ino1;
size_t blob_size;
int fd;
/* Create two memfds and record their inodes for later verification */
memfd0 = ASSERT_OK(memfd_create_wrapper("test-fd-0", 0));
ino0 = get_inode(memfd0);
memfd1 = ASSERT_OK(memfd_create_wrapper("test-fd-1", 0));
ino1 = get_inode(memfd1);
/* Create a bus for message operations (no actual connection needed) */
ASSERT_OK(sd_bus_new(&bus));
bus->state = BUS_RUNNING; /* Fake state to allow message creation */
bus->can_fds = true; /* Allow fd passing */
/* Build a message containing two fds */
ASSERT_OK(sd_bus_message_new_method_call(bus, &m, "foo.bar", "/", "foo.bar", "Ping"));
ASSERT_OK(sd_bus_message_append(m, "hh", memfd0, memfd1));
ASSERT_OK(sd_bus_message_seal(m, 1, 0));
/* Serialize the message to a blob */
ASSERT_OK(bus_message_get_blob(m, &blob, &blob_size));
m = sd_bus_message_unref(m);
/* Duplicate the fds since bus_message_from_malloc() takes ownership */
fds = ASSERT_NOT_NULL(new(int, 2));
fds[0] = ASSERT_OK_ERRNO(fcntl(memfd0, F_DUPFD_CLOEXEC, 3));
fds[1] = ASSERT_OK_ERRNO(fcntl(memfd1, F_DUPFD_CLOEXEC, 3));
/* Test 1: Parse with correct fd count, no truncation - should succeed */
log_info("Test 1: Exact fd count match, got_ctrunc=false");
void *blob_copy = ASSERT_NOT_NULL(memdup(blob, blob_size));
ASSERT_OK(bus_message_from_malloc(bus, blob_copy, blob_size, fds, 2, /* got_ctrunc= */ false, NULL, &m));
/* Verify we can read both fds and they have the expected inodes */
ASSERT_OK(sd_bus_message_read_basic(m, 'h', &fd));
ASSERT_EQ(get_inode(fd), ino0);
ASSERT_OK(sd_bus_message_read_basic(m, 'h', &fd));
ASSERT_EQ(get_inode(fd), ino1);
m = sd_bus_message_unref(m);
fds = NULL; /* ownership transferred */
/* Test 2: Parse with fewer fds than declared, no truncation flag - should fail */
log_info("Test 2: Fewer fds than declared, got_ctrunc=false");
fds = ASSERT_NOT_NULL(new(int, 1));
fds[0] = ASSERT_OK_ERRNO(fcntl(memfd0, F_DUPFD_CLOEXEC, 3));
blob_copy = ASSERT_NOT_NULL(memdup(blob, blob_size));
ASSERT_ERROR(bus_message_from_malloc(bus, blob_copy, blob_size, fds, 1, /* got_ctrunc= */ false, NULL, &m), EBADMSG);
free(blob_copy);
close(fds[0]);
fds = mfree(fds);
/* Test 3: Parse with fewer fds than declared, with truncation flag - parsing should succeed */
log_info("Test 3: Fewer fds than declared, got_ctrunc=true");
fds = ASSERT_NOT_NULL(new(int, 1));
fds[0] = ASSERT_OK_ERRNO(fcntl(memfd0, F_DUPFD_CLOEXEC, 3));
blob_copy = ASSERT_NOT_NULL(memdup(blob, blob_size));
ASSERT_OK(bus_message_from_malloc(bus, blob_copy, blob_size, fds, 1, /* got_ctrunc= */ true, NULL, &m));
/* First fd should be readable and have correct inode */
ASSERT_OK(sd_bus_message_read_basic(m, 'h', &fd));
ASSERT_EQ(get_inode(fd), ino0);
/* Second fd was truncated - reading it should fail */
ASSERT_ERROR(sd_bus_message_read_basic(m, 'h', &fd), EBADMSG);
m = sd_bus_message_unref(m);
fds = NULL; /* ownership transferred */
/* Test 4: Parse with more fds than declared, with truncation flag - should fail */
log_info("Test 4: More fds than declared, got_ctrunc=true");
fds = ASSERT_NOT_NULL(new(int, 3));
fds[0] = ASSERT_OK_ERRNO(fcntl(memfd0, F_DUPFD_CLOEXEC, 3));
fds[1] = ASSERT_OK_ERRNO(fcntl(memfd1, F_DUPFD_CLOEXEC, 3));
fds[2] = ASSERT_OK_ERRNO(fcntl(memfd0, F_DUPFD_CLOEXEC, 3));
blob_copy = ASSERT_NOT_NULL(memdup(blob, blob_size));
ASSERT_ERROR(bus_message_from_malloc(bus, blob_copy, blob_size, fds, 3, /* got_ctrunc= */ true, NULL, &m), EBADMSG);
free(blob_copy);
close(fds[0]);
close(fds[1]);
close(fds[2]);
fds = mfree(fds);
/* Test 5: Parse with zero fds when two were declared, with truncation flag - should succeed */
log_info("Test 5: Zero fds when some declared, got_ctrunc=true");
blob_copy = ASSERT_NOT_NULL(memdup(blob, blob_size));
ASSERT_OK(bus_message_from_malloc(bus, blob_copy, blob_size, NULL, 0, /* got_ctrunc= */ true, NULL, &m));
/* Both fd reads should fail since all were truncated */
ASSERT_ERROR(sd_bus_message_read_basic(m, 'h', &fd), EBADMSG);
m = sd_bus_message_unref(m);
log_info("All fd truncation tests passed");
}
static void test_bus_label_escape(void) {
test_bus_label_escape_one("foo123bar", "foo123bar");
test_bus_label_escape_one("foo.bar", "foo_2ebar");
@ -360,7 +243,7 @@ int main(int argc, char *argv[]) {
m = sd_bus_message_unref(m);
r = bus_message_from_malloc(bus, buffer, sz, NULL, 0, /* got_ctrunc= */ false, NULL, &m);
r = bus_message_from_malloc(bus, buffer, sz, NULL, 0, NULL, &m);
assert_se(r >= 0);
sd_bus_message_dump(m, stdout, SD_BUS_MESSAGE_DUMP_WITH_HEADER);
@ -532,7 +415,6 @@ int main(int argc, char *argv[]) {
test_bus_path_encode();
test_bus_path_encode_unique();
test_bus_path_encode_many();
test_bus_fds_truncated();
return 0;
}

View File

@ -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 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
assert(rfd >= 0 || rfd == AT_FDCWD);
r = dir_fd_is_root_or_cwd(rfd);
if (r < 0)

View File

@ -1031,14 +1031,13 @@ 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,
STRV_MAKE_CONST(filename), NETWORK_DIRS, dropin_dirname, /* root= */ NULL,
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);
netdev_raw,
NULL,
NULL);
if (r < 0)
return r; /* config_parse_many() logs internally. */
@ -1065,15 +1064,10 @@ 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_full(
STRV_MAKE_CONST(filename),
NETWORK_DIRS,
dropin_dirname,
/* root= */ NULL,
/* root_fd= */ -EBADF,
r = config_parse_many(
STRV_MAKE_CONST(filename), NETWORK_DIRS, dropin_dirname, /* root= */ NULL,
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,

View File

@ -17,7 +17,6 @@
#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"
@ -107,13 +106,7 @@ static int get_config_files_by_name(
if (!dropin_dirname)
return -ENOMEM;
r = conf_files_list_dropins(
ret_dropins,
dropin_dirname,
/* root= */ NULL,
/* root_fd= */ XAT_FDROOT,
CONF_FILES_WARN,
NETWORK_DIRS);
r = conf_files_list_dropins(ret_dropins, dropin_dirname, /* root= */ NULL, CONF_FILES_WARN, NETWORK_DIRS);
if (r < 0)
return r;
}

View File

@ -514,12 +514,8 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
.ipoib_umcast = -1,
};
r = config_parse_many_full(
STRV_MAKE_CONST(filename),
NETWORK_DIRS,
dropin_dirname,
/* root= */ NULL,
/* root_fd= */ -EBADF,
r = config_parse_many(
STRV_MAKE_CONST(filename), NETWORK_DIRS, dropin_dirname, /* root= */ NULL,
"Match\0"
"Link\0"
"SR-IOV\0"
@ -578,8 +574,7 @@ 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,

View File

@ -2871,17 +2871,16 @@ static int partition_read_definition(
dropin_dirname = strjoina(filename, ".d");
r = config_parse_many_full(
r = config_parse_many(
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,
/* ret_stats_by_path= */ NULL,
NULL,
&p->drop_in_files);
if (r < 0)
return r;
@ -3397,7 +3396,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_DONT_PREFIX_ROOT,
CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED|CONF_FILES_WARN,
dirs);
if (r < 0)
return log_error_errno(r, "Failed to enumerate *.conf files: %m");

View File

@ -188,11 +188,14 @@ 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);
d,
/* ret_stats_by_path= */ NULL,
/* ret_drop_in_files= */ NULL);
if (r < 0)
return r;

View File

@ -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,
STRV_MAKE_CONST(path), DNSSD_SERVICE_DIRS, dropin_dirname, /* root= */ NULL,
"Service\0",
config_item_perf_lookup, resolved_dnssd_gperf_lookup,
CONFIG_PARSE_WARN,
service);
service,
NULL,
NULL);
if (r < 0)
return r;

View File

@ -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 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
assert(rfd >= 0 || rfd == AT_FDCWD);
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 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
assert(rfd >= 0 || rfd == AT_FDCWD);
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 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
assert(rfd >= 0 || rfd == AT_FDCWD);
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 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
assert(rfd >= 0 || rfd == AT_FDCWD);
assert(type);
assert(token);
@ -229,12 +229,11 @@ int boot_entry_token_ensure(
if (*token)
return 0; /* Already set. */
_cleanup_close_ int rfd = XAT_FDROOT;
if (!empty_or_root(root)) {
rfd = open(root, O_CLOEXEC | O_DIRECTORY | O_PATH);
_cleanup_close_ int rfd = -EBADF;
rfd = open(empty_to_root(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);
}

View File

@ -481,7 +481,6 @@ 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,
@ -503,17 +502,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;
r = chase_and_fopenat_unlocked(root_fd, *fn, CHASE_AT_RESOLVE_IN_ROOT|CHASE_MUST_BE_REGULAR, "re", /* ret_path= */ NULL, &f);
_cleanup_free_ char *fname = NULL;
r = chase_and_fopen_unlocked(*fn, root, CHASE_AT_RESOLVE_IN_ROOT, "re", &fname, &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) {
@ -538,10 +537,11 @@ static int config_parse_many_files(
return log_oom_full(level);
}
/* First process the first found main config file. */
/* First read the first found main config file. */
STRV_FOREACH(fn, conf_files) {
_cleanup_fclose_ FILE *f = NULL;
r = chase_and_fopenat_unlocked(root_fd, *fn, CHASE_AT_RESOLVE_IN_ROOT|CHASE_MUST_BE_REGULAR, "re", /* ret_path= */ NULL, &f);
r = chase_and_fopen_unlocked(*fn, root, CHASE_AT_RESOLVE_IN_ROOT, "re", NULL, &f);
if (r == -ENOENT)
continue;
if (r < 0)
@ -572,6 +572,7 @@ 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) {
@ -593,39 +594,12 @@ 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_full(
int config_parse_many(
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,
@ -641,33 +615,14 @@ int config_parse_many_full(
assert(dropin_dirname);
assert(table);
_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,
r = conf_files_list_dropins(&files, dropin_dirname, root,
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,
root_fd,
conf_files,
files,
sections,
lookup,
table,
flags,
userdata,
ret_stats_by_path);
r = config_parse_many_files(root, conf_files, files, sections, lookup, table, flags, userdata, ret_stats_by_path);
if (r < 0)
return r; /* config_parse_many_files() logs internally. */
@ -679,7 +634,6 @@ int config_parse_many_full(
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,
@ -689,15 +643,12 @@ int config_parse_standard_file_with_dropins_full(
Hashmap **ret_stats_by_path,
char ***ret_dropin_files) {
const char* const *conf_file_dirs = (const char* const*) CONF_PATHS_STRV("");
_cleanup_strv_free_ char **conf_files = NULL;
const char* const *conf_paths = (const char* const*) CONF_PATHS_STRV("");
_cleanup_strv_free_ char **configs = 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_concat(
&conf_files,
conf_file_dirs,
main_file);
r = strv_extend_strv_biconcat(&configs, root, conf_paths, main_file);
if (r < 0)
return log_oom_full(level);
@ -705,12 +656,11 @@ int config_parse_standard_file_with_dropins_full(
if (!dropin_dirname)
return log_oom_full(level);
return config_parse_many_full(
(const char* const*) conf_files,
conf_file_dirs,
return config_parse_many(
(const char* const*) configs,
conf_paths,
dropin_dirname,
root,
root_fd,
sections,
lookup,
table,
@ -742,13 +692,7 @@ static int dropins_get_stats_by_path(
if (!strextend(&dropin_dirname, ".d"))
return -ENOMEM;
r = conf_files_list_dropins(
&files,
dropin_dirname,
/* root= */ NULL,
/* root_fd= */ XAT_FDROOT,
/* flags= */ 0,
conf_file_dirs);
r = conf_files_list_dropins(&files, dropin_dirname, /* root= */ NULL, /* flags= */ 0, conf_file_dirs);
if (r < 0)
return r;

View File

@ -5,7 +5,7 @@
#include "alloc-util.h"
#include "conf-parser-forward.h"
#include "fd-util.h"
#include "shared-forward.h"
#include "log.h"
/* An abstract parser for simple, line based, shallow configuration files consisting of variable assignments only. */
@ -66,12 +66,11 @@ int config_parse(
void *userdata,
struct stat *ret_stat); /* possibly NULL */
int config_parse_many_full(
int config_parse_many(
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,
@ -80,34 +79,8 @@ int config_parse_many_full(
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,
@ -126,7 +99,6 @@ 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,

View File

@ -2,13 +2,11 @@
#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_at(
int load_kernel_install_conf(
const char *root,
int root_fd,
const char *conf_root,
char **ret_machine_id,
char **ret_boot_root,
@ -28,19 +26,16 @@ int load_kernel_install_conf_at(
};
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_full(
r = config_parse_many(
STRV_MAKE_CONST(conf),
STRV_MAKE_CONST(conf_root),
"install.conf.d",
root,
root_fd,
/* root= */ NULL, /* $KERNEL_INSTALL_CONF_ROOT and --root are independent */
/* sections= */ NULL,
config_item_table_lookup, items,
CONFIG_PARSE_WARN,
@ -50,7 +45,6 @@ int load_kernel_install_conf_at(
} else
r = config_parse_standard_file_with_dropins_full(
root,
root_fd,
"kernel/install.conf",
/* sections= */ NULL,
config_item_table_lookup, items,

View File

@ -1,27 +1,13 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include "fd-util.h"
#include "shared-forward.h"
int load_kernel_install_conf_at(
int load_kernel_install_conf(
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);
}

View File

@ -191,7 +191,6 @@ 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,

View File

@ -101,12 +101,11 @@ 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_full(
r = config_parse_many(
STRV_MAKE_CONST(path),
dirs,
strjoina(filename, ".d"),
arg_root,
/* root_fd= */ -EBADF,
"Feature\0",
config_item_table_lookup, table,
CONFIG_PARSE_WARN,

View File

@ -543,12 +543,11 @@ 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_full(
r = config_parse_many(
STRV_MAKE_CONST(path),
dirs,
strjoina(filename, ".d"),
arg_root,
/* root_fd= */ -EBADF,
"Transfer\0"
"Source\0"
"Target\0",

View File

@ -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->filename, "sysupdate.d")) {
if (streq(e->name, "sysupdate.d")) {
has_default_component = true;
continue;
}
const char *s = startswith(e->filename, "sysupdate.");
const char *s = startswith(e->name, "sysupdate.");
if (!s)
continue;

View File

@ -444,9 +444,7 @@ TEST(config_parse_standard_file_with_dropins_full) {
};
r = config_parse_standard_file_with_dropins_full(
root,
/* root_fd= */ -EBADF,
"kernel/install.conf",
root, "kernel/install.conf",
/* sections= */ NULL,
config_item_table_lookup, items,
CONFIG_PARSE_WARN,
@ -485,9 +483,7 @@ 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,
/* root_fd= */ -EBADF,
"kernel/install2.conf",
root, "kernel/install2.conf",
/* sections= */ NULL,
config_item_table_lookup, items,
CONFIG_PARSE_WARN,

View File

@ -280,20 +280,17 @@ 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_full(
r = config_parse_many(
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. */

View File

@ -1739,11 +1739,9 @@ static int generate_ssh_keypair(const char *key_path, const char *key_type) {
log_debug("Executing: %s", joined);
}
r = pidref_safe_fork_full(
r = pidref_safe_fork(
ssh_keygen,
(int[]) { -EBADF, -EBADF, STDERR_FILENO },
/* except_fds= */ NULL, /* n_except_fds= */ 0,
FORK_WAIT|FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE|FORK_REARRANGE_STDIO|FORK_REOPEN_LOG,
FORK_WAIT|FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE|FORK_REARRANGE_STDIO,
/* ret= */ NULL);
if (r < 0)
return r;