mirror of
https://github.com/systemd/systemd
synced 2026-03-15 17:44:49 +01:00
Compare commits
No commits in common. "cab4b9defdef1f9f9d3c31b262aed408a6616490" and "50caaf267b6ac6a83a0edaffbea232275372dfdb" have entirely different histories.
cab4b9defd
...
50caaf267b
7
NEWS
7
NEWS
@ -33,10 +33,9 @@ CHANGES WITH 260 in spe:
|
|||||||
|
|
||||||
Changes in other components:
|
Changes in other components:
|
||||||
|
|
||||||
* New options SYSTEMD_COLORS=auto-16, SYSTEMD_COLORS=auto-256, and
|
* New options SYSTEMD_COLORS=auto-16 and SYSTEMD_COLORS=auto-256, which
|
||||||
SYSTEMD_COLORS=auto-24bit, which are like SYSTEMD_COLORS=16,
|
are like SYSTEMD_COLORS=16 and SYSTEMD_COLORS=256 respectively when
|
||||||
SYSTEMD_COLORS=256, and SYSTEMD_COLORS=24bit respectively when output
|
output is to a non-dumb TTY, and like SYSTEMD_COLORS=no otherwise.
|
||||||
is to a non-dumb TTY, and like SYSTEMD_COLORS=no otherwise.
|
|
||||||
|
|
||||||
CHANGES WITH 259:
|
CHANGES WITH 259:
|
||||||
|
|
||||||
|
|||||||
@ -268,10 +268,6 @@
|
|||||||
<!-- add Index link at top of page -->
|
<!-- add Index link at top of page -->
|
||||||
<xsl:template name="user.header.content">
|
<xsl:template name="user.header.content">
|
||||||
<style>
|
<style>
|
||||||
:root {
|
|
||||||
color-scheme: light dark;
|
|
||||||
}
|
|
||||||
|
|
||||||
a.headerlink {
|
a.headerlink {
|
||||||
color: #c60f0f;
|
color: #c60f0f;
|
||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
@ -316,13 +312,6 @@
|
|||||||
<xsl:text>"</xsl:text>
|
<xsl:text>"</xsl:text>
|
||||||
</xsl:template>
|
</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 -->
|
<!-- Switch things to UTF-8, ISO-8859-1 is soo yesteryear -->
|
||||||
<xsl:output method="html" encoding="UTF-8" indent="no"/>
|
<xsl:output method="html" encoding="UTF-8" indent="no"/>
|
||||||
|
|
||||||
|
|||||||
@ -24,7 +24,7 @@ ConfFile* conf_file_free(ConfFile *c) {
|
|||||||
if (!c)
|
if (!c)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
free(c->filename);
|
free(c->name);
|
||||||
free(c->result);
|
free(c->result);
|
||||||
free(c->original_path);
|
free(c->original_path);
|
||||||
free(c->resolved_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;
|
return FLAGS_SET(flags, CONF_FILES_WARN) ? LOG_WARNING : LOG_DEBUG;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int prepare_dirs(
|
static int prepare_dirs(const char *root, ConfFilesFlags flags, char * const *dirs, int *ret_rfd, char **ret_root, char ***ret_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_free_ char *root_abs = NULL;
|
||||||
_cleanup_strv_free_ char **dirs_abs = NULL;
|
_cleanup_strv_free_ char **dirs_abs = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(ret_root);
|
|
||||||
assert(ret_rfd);
|
assert(ret_rfd);
|
||||||
|
assert(ret_root);
|
||||||
assert(ret_dirs || strv_isempty(dirs));
|
assert(ret_dirs || strv_isempty(dirs));
|
||||||
|
|
||||||
int log_level = conf_files_log_level(flags);
|
int log_level = conf_files_log_level(flags);
|
||||||
@ -72,7 +65,6 @@ static int prepare_dirs(
|
|||||||
return log_oom_full(log_level);
|
return log_oom_full(log_level);
|
||||||
}
|
}
|
||||||
|
|
||||||
_cleanup_close_ int rfd = XAT_FDROOT;
|
|
||||||
if (root) {
|
if (root) {
|
||||||
/* When a non-trivial root is specified, we will prefix the result later. Hence, it is not
|
/* 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. */
|
* 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);
|
return log_full_errno(log_level, r, "Failed to make '%s' absolute: %m", root);
|
||||||
|
|
||||||
path_simplify(root_abs);
|
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) {
|
} else if (ret_dirs) {
|
||||||
/* When an empty root or "/" is specified, we will open "/" below, hence we need to make
|
/* When an empty root or "/" is specified, we will open "/" below, hence we need to make
|
||||||
* each config directory absolute if relative. */
|
* 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");
|
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_rfd = TAKE_FD(rfd);
|
||||||
|
*ret_root = TAKE_PTR(root_abs);
|
||||||
if (ret_dirs)
|
if (ret_dirs)
|
||||||
*ret_dirs = TAKE_PTR(dirs_abs);
|
*ret_dirs = TAKE_PTR(dirs_abs);
|
||||||
return 0;
|
return 0;
|
||||||
@ -144,8 +135,8 @@ static ChaseFlags conf_files_chase_flags(ConfFilesFlags flags) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int conf_file_chase_and_verify(
|
static int conf_file_chase_and_verify(
|
||||||
const char *root, /* for logging, can be NULL */
|
|
||||||
int rfd,
|
int rfd,
|
||||||
|
const char *root, /* for logging, can be NULL */
|
||||||
const char *original_path, /* for logging */
|
const char *original_path, /* for logging */
|
||||||
const char *path,
|
const char *path,
|
||||||
const char *name,
|
const char *name,
|
||||||
@ -160,7 +151,7 @@ static int conf_file_chase_and_verify(
|
|||||||
struct stat st = {};
|
struct stat st = {};
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(rfd >= 0 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
|
assert(rfd >= 0 || rfd == AT_FDCWD);
|
||||||
assert(original_path);
|
assert(original_path);
|
||||||
assert(path);
|
assert(path);
|
||||||
assert(name);
|
assert(name);
|
||||||
@ -270,25 +261,18 @@ static int conf_file_chase_and_verify(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int conf_file_new_at(
|
int conf_file_new_at(const char *path, int rfd, ConfFilesFlags flags, ConfFile **ret) {
|
||||||
const char *path,
|
|
||||||
const char *root,
|
|
||||||
int rfd,
|
|
||||||
ConfFilesFlags flags,
|
|
||||||
ConfFile **ret) {
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(path);
|
assert(path);
|
||||||
assert(rfd >= 0 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
|
assert(rfd >= 0 || rfd == AT_FDCWD);
|
||||||
assert(ret);
|
assert(ret);
|
||||||
|
|
||||||
int log_level = conf_files_log_level(flags);
|
int log_level = conf_files_log_level(flags);
|
||||||
|
|
||||||
_cleanup_free_ char *_root = NULL;
|
_cleanup_free_ char *root = NULL;
|
||||||
if (DEBUG_LOGGING && !root) {
|
if (rfd >= 0)
|
||||||
(void) fd_get_path(rfd, &_root);
|
(void) fd_get_path(rfd, &root);
|
||||||
root = _root;
|
|
||||||
}
|
|
||||||
|
|
||||||
_cleanup_(conf_file_freep) ConfFile *c = new(ConfFile, 1);
|
_cleanup_(conf_file_freep) ConfFile *c = new(ConfFile, 1);
|
||||||
if (!c)
|
if (!c)
|
||||||
@ -302,7 +286,7 @@ int conf_file_new_at(
|
|||||||
if (!c->original_path)
|
if (!c->original_path)
|
||||||
return log_oom_full(log_level);
|
return log_oom_full(log_level);
|
||||||
|
|
||||||
r = path_extract_filename(path, &c->filename);
|
r = path_extract_filename(path, &c->name);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_full_errno(log_level, r, "Failed to extract filename from '%s': %m", path);
|
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));
|
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)
|
if (!c->result)
|
||||||
return log_oom_full(log_level);
|
return log_oom_full(log_level);
|
||||||
|
|
||||||
r = conf_file_chase_and_verify(
|
r = conf_file_chase_and_verify(
|
||||||
root,
|
|
||||||
rfd,
|
rfd,
|
||||||
|
root,
|
||||||
c->original_path,
|
c->original_path,
|
||||||
c->result,
|
c->result,
|
||||||
c->filename,
|
c->name,
|
||||||
/* masked= */ NULL,
|
/* masked= */ NULL,
|
||||||
flags,
|
flags,
|
||||||
&c->resolved_path,
|
&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_free_ char *root_abs = NULL;
|
||||||
_cleanup_close_ int rfd = -EBADF;
|
_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)
|
if (r < 0)
|
||||||
return r;
|
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;
|
_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)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@ -383,8 +367,8 @@ static int files_add(
|
|||||||
DIR *dir,
|
DIR *dir,
|
||||||
const char *original_dirpath,
|
const char *original_dirpath,
|
||||||
const char *resolved_dirpath,
|
const char *resolved_dirpath,
|
||||||
const char *root, /* for logging, can be NULL */
|
|
||||||
int rfd,
|
int rfd,
|
||||||
|
const char *root, /* for logging, can be NULL */
|
||||||
Hashmap **files,
|
Hashmap **files,
|
||||||
Set **masked,
|
Set **masked,
|
||||||
const char *suffix,
|
const char *suffix,
|
||||||
@ -395,7 +379,7 @@ static int files_add(
|
|||||||
assert(dir);
|
assert(dir);
|
||||||
assert(original_dirpath);
|
assert(original_dirpath);
|
||||||
assert(resolved_dirpath);
|
assert(resolved_dirpath);
|
||||||
assert(rfd >= 0 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
|
assert(rfd >= 0 || rfd == AT_FDCWD);
|
||||||
assert(files);
|
assert(files);
|
||||||
assert(masked);
|
assert(masked);
|
||||||
|
|
||||||
@ -436,8 +420,8 @@ static int files_add(
|
|||||||
_cleanup_close_ int fd = -EBADF;
|
_cleanup_close_ int fd = -EBADF;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
r = conf_file_chase_and_verify(
|
r = conf_file_chase_and_verify(
|
||||||
root,
|
|
||||||
rfd,
|
rfd,
|
||||||
|
root,
|
||||||
original_path,
|
original_path,
|
||||||
p,
|
p,
|
||||||
de->d_name,
|
de->d_name,
|
||||||
@ -456,7 +440,7 @@ static int files_add(
|
|||||||
return log_oom_full(log_level);
|
return log_oom_full(log_level);
|
||||||
|
|
||||||
*c = (ConfFile) {
|
*c = (ConfFile) {
|
||||||
.filename = strdup(de->d_name),
|
.name = strdup(de->d_name),
|
||||||
.result = TAKE_PTR(p),
|
.result = TAKE_PTR(p),
|
||||||
.original_path = TAKE_PTR(original_path),
|
.original_path = TAKE_PTR(original_path),
|
||||||
.resolved_path = TAKE_PTR(resolved_path),
|
.resolved_path = TAKE_PTR(resolved_path),
|
||||||
@ -464,10 +448,10 @@ static int files_add(
|
|||||||
.st = st,
|
.st = st,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!c->filename)
|
if (!c->name)
|
||||||
return log_oom_full(log_level);
|
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) {
|
if (r < 0) {
|
||||||
assert(r == -ENOMEM);
|
assert(r == -ENOMEM);
|
||||||
return log_oom_full(log_level);
|
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. */
|
/* Hence, we need to remove them from the hashmap. */
|
||||||
FOREACH_ARRAY(i, files, n_files)
|
FOREACH_ARRAY(i, files, n_files)
|
||||||
assert_se(hashmap_remove(fh, (*i)->filename) == *i);
|
assert_se(hashmap_remove(fh, (*i)->name) == *i);
|
||||||
|
|
||||||
if (root)
|
if (root)
|
||||||
FOREACH_ARRAY(i, files, n_files) {
|
FOREACH_ARRAY(i, files, n_files) {
|
||||||
@ -538,8 +522,8 @@ static int copy_and_sort_files_from_hashmap(
|
|||||||
const char *add = NULL;
|
const char *add = NULL;
|
||||||
|
|
||||||
if (FLAGS_SET(flags, CONF_FILES_BASENAME))
|
if (FLAGS_SET(flags, CONF_FILES_BASENAME))
|
||||||
add = c->filename;
|
add = c->name;
|
||||||
else if (root && !FLAGS_SET(flags, CONF_FILES_DONT_PREFIX_ROOT)) {
|
else if (root) {
|
||||||
_cleanup_free_ char *p = NULL;
|
_cleanup_free_ char *p = NULL;
|
||||||
|
|
||||||
r = chaseat_prefix_root(c->result, root, &p);
|
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. */
|
/* This consumes the input ConfFile. */
|
||||||
|
|
||||||
ConfFile *existing = hashmap_get(*fh, c->filename);
|
ConfFile *existing = hashmap_get(*fh, c->name);
|
||||||
if (existing) {
|
if (existing) {
|
||||||
log_debug("An entry with higher priority '%s' -> '%s' already exists, ignoring the replacement: %s",
|
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;
|
*ret = NULL;
|
||||||
return 0;
|
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) {
|
if (r < 0) {
|
||||||
assert(r == -ENOMEM);
|
assert(r == -ENOMEM);
|
||||||
return log_oom_full(conf_files_log_level(flags));
|
return log_oom_full(conf_files_log_level(flags));
|
||||||
}
|
}
|
||||||
assert(r > 0);
|
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);
|
*ret = TAKE_PTR(c);
|
||||||
return 0;
|
return 0;
|
||||||
@ -613,8 +597,8 @@ static int insert_replacement(Hashmap **fh, ConfFile *replacement, ConfFilesFlag
|
|||||||
|
|
||||||
static int conf_files_list_impl(
|
static int conf_files_list_impl(
|
||||||
const char *suffix,
|
const char *suffix,
|
||||||
const char *root, /* for logging, can be NULL */
|
|
||||||
int rfd,
|
int rfd,
|
||||||
|
const char *root, /* for logging, can be NULL */
|
||||||
ConfFilesFlags flags,
|
ConfFilesFlags flags,
|
||||||
const char * const *dirs,
|
const char * const *dirs,
|
||||||
const char *replacement,
|
const char *replacement,
|
||||||
@ -627,13 +611,13 @@ static int conf_files_list_impl(
|
|||||||
const ConfFile *inserted = NULL;
|
const ConfFile *inserted = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(rfd >= 0 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
|
assert(rfd >= 0 || rfd == AT_FDCWD);
|
||||||
assert(ret);
|
assert(ret);
|
||||||
|
|
||||||
root = empty_to_root(root);
|
root = empty_to_root(root);
|
||||||
|
|
||||||
if (replacement) {
|
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)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -651,13 +635,13 @@ static int conf_files_list_impl(
|
|||||||
continue;
|
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);
|
r = insert_replacement(&fh, TAKE_PTR(c), flags, &inserted);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
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)
|
if (r == -ENOMEM)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -689,11 +673,11 @@ int conf_files_list_strv(
|
|||||||
|
|
||||||
assert(ret);
|
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)
|
if (r < 0)
|
||||||
return r;
|
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);
|
/* replacement= */ NULL, &fh, /* ret_inserted= */ NULL);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
@ -718,11 +702,11 @@ int conf_files_list_strv_full(
|
|||||||
assert(ret_files);
|
assert(ret_files);
|
||||||
assert(ret_n_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)
|
if (r < 0)
|
||||||
return r;
|
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);
|
/* replacement= */ NULL, &fh, /* ret_inserted= */ NULL);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
@ -741,13 +725,13 @@ int conf_files_list_strv_at(
|
|||||||
_cleanup_free_ char *root = NULL;
|
_cleanup_free_ char *root = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(rfd >= 0 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
|
assert(rfd >= 0 || rfd == AT_FDCWD);
|
||||||
assert(ret);
|
assert(ret);
|
||||||
|
|
||||||
if (DEBUG_LOGGING)
|
if (rfd >= 0)
|
||||||
(void) fd_get_path(rfd, &root); /* for logging */
|
(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)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@ -766,14 +750,14 @@ int conf_files_list_strv_at_full(
|
|||||||
_cleanup_free_ char *root = NULL;
|
_cleanup_free_ char *root = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(rfd >= 0 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
|
assert(rfd >= 0 || rfd == AT_FDCWD);
|
||||||
assert(ret_files);
|
assert(ret_files);
|
||||||
assert(ret_n_files);
|
assert(ret_n_files);
|
||||||
|
|
||||||
if (DEBUG_LOGGING)
|
if (rfd >= 0)
|
||||||
(void) fd_get_path(rfd, &root); /* for logging */
|
(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)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@ -864,11 +848,11 @@ int conf_files_list_with_replacement(
|
|||||||
|
|
||||||
assert(ret_files);
|
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)
|
if (r < 0)
|
||||||
return r;
|
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);
|
replacement, &fh, ret_inserted ? &c : NULL);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
@ -894,7 +878,6 @@ int conf_files_list_dropins(
|
|||||||
char ***ret,
|
char ***ret,
|
||||||
const char *dropin_dirname,
|
const char *dropin_dirname,
|
||||||
const char *root,
|
const char *root,
|
||||||
int root_fd,
|
|
||||||
ConfFilesFlags flags,
|
ConfFilesFlags flags,
|
||||||
const char * const *dirs) {
|
const char * const *dirs) {
|
||||||
|
|
||||||
@ -911,7 +894,7 @@ int conf_files_list_dropins(
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_oom_full(conf_files_log_level(flags));
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -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_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_TRUNCATE_SUFFIX = 1 << 6, /* truncate specified suffix from return filename or path */
|
||||||
CONF_FILES_WARN = 1 << 7, /* warn on some errors */
|
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;
|
} ConfFilesFlags;
|
||||||
|
|
||||||
typedef struct ConfFile {
|
typedef struct ConfFile {
|
||||||
char *filename; /* filename of the discovered file (i.e. without any directory prefix) */
|
char *name; /* name of a file found in config directories */
|
||||||
char *result; /* full path to the file (with the directory prefix fully resolved, but the filename part left as is) */
|
char *result; /* resolved config directory with the original file name found in the directory */
|
||||||
char *original_path; /* full path to the file (original – non-resolved – directory prefix + filename part left as is) */
|
char *original_path; /* original config directory with the original file name found in the directory */
|
||||||
char *resolved_path; /* fully resolved path to the file with both directory prefix and filename fully resolved */
|
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 resolved_path does not exist */
|
int fd; /* O_PATH fd to resolved_path, -EBADF if the resolved_path does not exist */
|
||||||
struct stat st; /* stat of the file. */
|
struct stat st; /* stat of the file. */
|
||||||
} ConfFile;
|
} ConfFile;
|
||||||
|
|
||||||
@ -31,7 +30,7 @@ ConfFile* conf_file_free(ConfFile *c);
|
|||||||
DEFINE_TRIVIAL_CLEANUP_FUNC(ConfFile*, conf_file_free);
|
DEFINE_TRIVIAL_CLEANUP_FUNC(ConfFile*, conf_file_free);
|
||||||
void conf_file_free_many(ConfFile **array, size_t n);
|
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_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);
|
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,
|
char ***ret,
|
||||||
const char *dropin_dirname,
|
const char *dropin_dirname,
|
||||||
const char *root,
|
const char *root,
|
||||||
int root_fd,
|
|
||||||
ConfFilesFlags flags,
|
ConfFilesFlags flags,
|
||||||
const char * const *dirs);
|
const char * const *dirs);
|
||||||
|
|
||||||
|
|||||||
@ -168,7 +168,7 @@ int open_os_release_at(int rfd, char **ret_path, int *ret_fd) {
|
|||||||
const char *e;
|
const char *e;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(rfd >= 0 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
|
assert(rfd >= 0 || rfd == AT_FDCWD);
|
||||||
|
|
||||||
e = secure_getenv("SYSTEMD_OS_RELEASE");
|
e = secure_getenv("SYSTEMD_OS_RELEASE");
|
||||||
if (e)
|
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) {
|
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;
|
_cleanup_free_ char *p = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (!empty_or_root(root)) {
|
rfd = open(empty_to_root(root), O_CLOEXEC | O_DIRECTORY | O_PATH);
|
||||||
rfd = open(root, O_CLOEXEC | O_DIRECTORY | O_PATH);
|
if (rfd < 0)
|
||||||
if (rfd < 0)
|
return -errno;
|
||||||
return -errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = open_os_release_at(rfd, ret_path ? &p : NULL, ret_fd ? &fd : NULL);
|
r = open_os_release_at(rfd, ret_path ? &p : NULL, ret_fd ? &fd : NULL);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@ -225,7 +223,7 @@ int open_extension_release_at(
|
|||||||
const char *p;
|
const char *p;
|
||||||
int r;
|
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));
|
assert(!extension || (image_class >= 0 && image_class < _IMAGE_CLASS_MAX));
|
||||||
|
|
||||||
if (!extension)
|
if (!extension)
|
||||||
@ -332,15 +330,13 @@ int open_extension_release(
|
|||||||
char **ret_path,
|
char **ret_path,
|
||||||
int *ret_fd) {
|
int *ret_fd) {
|
||||||
|
|
||||||
_cleanup_close_ int rfd = XAT_FDROOT, fd = -EBADF;
|
_cleanup_close_ int rfd = -EBADF, fd = -EBADF;
|
||||||
_cleanup_free_ char *p = NULL;
|
_cleanup_free_ char *p = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (!empty_or_root(root)) {
|
rfd = open(empty_to_root(root), O_CLOEXEC | O_DIRECTORY | O_PATH);
|
||||||
rfd = open(root, O_CLOEXEC | O_DIRECTORY | O_PATH);
|
if (rfd < 0)
|
||||||
if (rfd < 0)
|
return -errno;
|
||||||
return -errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = open_extension_release_at(rfd, image_class, extension, relax_extension_release_check,
|
r = open_extension_release_at(rfd, image_class, extension, relax_extension_release_check,
|
||||||
ret_path ? &p : NULL, ret_fd ? &fd : NULL);
|
ret_path ? &p : NULL, ret_fd ? &fd : NULL);
|
||||||
@ -370,7 +366,7 @@ static int parse_extension_release_atv(
|
|||||||
_cleanup_free_ char *p = NULL;
|
_cleanup_free_ char *p = NULL;
|
||||||
int r;
|
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);
|
r = open_extension_release_at(rfd, image_class, extension, relax_extension_release_check, &p, &fd);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@ -389,7 +385,7 @@ int parse_extension_release_at_sentinel(
|
|||||||
va_list ap;
|
va_list ap;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(rfd >= 0 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
|
assert(rfd >= 0 || rfd == AT_FDCWD);
|
||||||
|
|
||||||
va_start(ap, extension);
|
va_start(ap, extension);
|
||||||
r = parse_extension_release_atv(rfd, image_class, extension, relax_extension_release_check, ap);
|
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,
|
const char *extension,
|
||||||
...) {
|
...) {
|
||||||
|
|
||||||
_cleanup_close_ int rfd = XAT_FDROOT;
|
_cleanup_close_ int rfd = -EBADF;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (!empty_or_root(root)) {
|
rfd = open(empty_to_root(root), O_CLOEXEC | O_DIRECTORY | O_PATH);
|
||||||
rfd = open(root, O_CLOEXEC | O_DIRECTORY | O_PATH);
|
if (rfd < 0)
|
||||||
if (rfd < 0)
|
return -errno;
|
||||||
return -errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
va_start(ap, extension);
|
va_start(ap, extension);
|
||||||
r = parse_extension_release_atv(rfd, image_class, extension, relax_extension_release_check, ap);
|
r = parse_extension_release_atv(rfd, image_class, extension, relax_extension_release_check, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -842,10 +842,11 @@ static int parse_config_file(void) {
|
|||||||
(const char* const*) files,
|
(const char* const*) files,
|
||||||
(const char* const*) dirs,
|
(const char* const*) dirs,
|
||||||
"user.conf.d",
|
"user.conf.d",
|
||||||
|
/* root= */ NULL,
|
||||||
"Manager\0",
|
"Manager\0",
|
||||||
config_item_table_lookup, items,
|
config_item_table_lookup, items,
|
||||||
CONFIG_PARSE_WARN,
|
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
|
/* Traditionally "0" was used to turn off the default unit timeouts. Fix this up so that we use
|
||||||
|
|||||||
@ -115,14 +115,8 @@ if [ -f "$TRIES_FILE" ]; then
|
|||||||
if [ -f "$LOADER_ENTRY" ]; then
|
if [ -f "$LOADER_ENTRY" ]; then
|
||||||
[ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && \
|
[ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && \
|
||||||
echo "Removing previous loader entry '$LOADER_ENTRY' without boot counting." >&2
|
echo "Removing previous loader entry '$LOADER_ENTRY' without boot counting." >&2
|
||||||
rm -f "$LOADER_ENTRY"
|
rm -f "$LOADER_ENTRY" "${LOADER_ENTRY%.conf}+"*.conf
|
||||||
fi
|
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"
|
LOADER_ENTRY="${LOADER_ENTRY%.conf}+$TRIES.conf"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@ -70,14 +70,8 @@ if [ -f "$TRIES_FILE" ]; then
|
|||||||
if [ -f "$UKI_DIR/$ENTRY_TOKEN-$KERNEL_VERSION.efi" ]; then
|
if [ -f "$UKI_DIR/$ENTRY_TOKEN-$KERNEL_VERSION.efi" ]; then
|
||||||
[ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && \
|
[ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && \
|
||||||
echo "Removing previous UKI '$UKI_DIR/$ENTRY_TOKEN-$KERNEL_VERSION.efi' without boot counting." >&2
|
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
|
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"
|
UKI_FILE="$UKI_DIR/$ENTRY_TOKEN-$KERNEL_VERSION+$TRIES.efi"
|
||||||
else
|
else
|
||||||
|
|||||||
@ -460,15 +460,13 @@ static int context_load_install_conf(Context *c) {
|
|||||||
|
|
||||||
assert(c);
|
assert(c);
|
||||||
|
|
||||||
r = load_kernel_install_conf_at(
|
r = load_kernel_install_conf(arg_root,
|
||||||
c->conf_root ? NULL : arg_root,
|
c->conf_root,
|
||||||
c->conf_root ? XAT_FDROOT : c->rfd,
|
&machine_id,
|
||||||
c->conf_root,
|
&boot_root,
|
||||||
&machine_id,
|
&layout,
|
||||||
&boot_root,
|
&initrd_generator,
|
||||||
&layout,
|
&uki_generator);
|
||||||
&initrd_generator,
|
|
||||||
&uki_generator);
|
|
||||||
if (r <= 0)
|
if (r <= 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
|||||||
@ -255,10 +255,8 @@ typedef struct sd_bus {
|
|||||||
|
|
||||||
uint64_t creds_mask;
|
uint64_t creds_mask;
|
||||||
|
|
||||||
/* Accumulated fds from multiple recvmsg() calls for a single D-Bus message */
|
|
||||||
int *fds;
|
int *fds;
|
||||||
size_t n_fds;
|
size_t n_fds;
|
||||||
bool got_ctrunc; /* MSG_CTRUNC was seen during any recvmsg() */
|
|
||||||
|
|
||||||
char *exec_path;
|
char *exec_path;
|
||||||
char **exec_argv;
|
char **exec_argv;
|
||||||
|
|||||||
@ -17,7 +17,7 @@
|
|||||||
#include "utf8.h"
|
#include "utf8.h"
|
||||||
|
|
||||||
static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
|
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) {
|
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,
|
size_t length,
|
||||||
int *fds,
|
int *fds,
|
||||||
size_t n_fds,
|
size_t n_fds,
|
||||||
bool got_ctrunc,
|
|
||||||
const char *label,
|
const char *label,
|
||||||
sd_bus_message **ret) {
|
sd_bus_message **ret) {
|
||||||
|
|
||||||
@ -438,7 +437,7 @@ int bus_message_from_malloc(
|
|||||||
m->iovec = m->iovec_fixed;
|
m->iovec = m->iovec_fixed;
|
||||||
m->iovec[0] = IOVEC_MAKE(buffer, length);
|
m->iovec[0] = IOVEC_MAKE(buffer, length);
|
||||||
|
|
||||||
r = message_parse_fields(m, got_ctrunc);
|
r = message_parse_fields(m);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@ -4030,8 +4029,8 @@ static int message_skip_fields(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int message_parse_fields(sd_bus_message *m, bool got_ctrunc) {
|
static int message_parse_fields(sd_bus_message *m) {
|
||||||
uint32_t n_unix_fds_declared = 0;
|
uint32_t unix_fds = 0;
|
||||||
bool unix_fds_set = false;
|
bool unix_fds_set = false;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
@ -4184,7 +4183,7 @@ static int message_parse_fields(sd_bus_message *m, bool got_ctrunc) {
|
|||||||
if (!streq(signature, "u"))
|
if (!streq(signature, "u"))
|
||||||
return -EBADMSG;
|
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)
|
if (r < 0)
|
||||||
return -EBADMSG;
|
return -EBADMSG;
|
||||||
|
|
||||||
@ -4198,26 +4197,8 @@ static int message_parse_fields(sd_bus_message *m, bool got_ctrunc) {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Validate that the number of fds we actually received via SCM_RIGHTS matches (or is compatible
|
if (m->n_fds != unix_fds)
|
||||||
* with) the number declared in the message header.
|
return -EBADMSG;
|
||||||
*
|
|
||||||
* 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);
|
|
||||||
|
|
||||||
switch (m->header->type) {
|
switch (m->header->type) {
|
||||||
|
|
||||||
|
|||||||
@ -177,7 +177,6 @@ int bus_message_from_malloc(
|
|||||||
size_t length,
|
size_t length,
|
||||||
int *fds,
|
int *fds,
|
||||||
size_t n_fds,
|
size_t n_fds,
|
||||||
bool got_ctrunc,
|
|
||||||
const char *label,
|
const char *label,
|
||||||
sd_bus_message **ret);
|
sd_bus_message **ret);
|
||||||
|
|
||||||
|
|||||||
@ -590,25 +590,14 @@ static int bus_process_cmsg(sd_bus *bus, struct msghdr *mh, bool allow_fds) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if we previously received fds with MSG_CTRUNC set. When the kernel truncates the fd array,
|
if (!GREEDY_REALLOC(bus->fds, bus->n_fds + n_fds))
|
||||||
* it drops all fds from the blocked one onwards - we have no way to know how many were lost or which
|
return -ENOMEM;
|
||||||
* 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;
|
|
||||||
|
|
||||||
FOREACH_ARRAY(i, fds, n_fds)
|
FOREACH_ARRAY(i, fds, n_fds)
|
||||||
bus->fds[bus->n_fds++] = fd_move_above_stdio(*i);
|
bus->fds[bus->n_fds++] = fd_move_above_stdio(*i);
|
||||||
|
|
||||||
TAKE_PTR(fds);
|
|
||||||
n_fds = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FLAGS_SET(mh->msg_flags, MSG_CTRUNC))
|
|
||||||
bus->got_ctrunc = true;
|
|
||||||
|
|
||||||
|
TAKE_PTR(fds);
|
||||||
|
n_fds = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -657,7 +646,7 @@ static int bus_socket_read_auth(sd_bus *b) {
|
|||||||
.msg_controllen = sizeof(control),
|
.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) {
|
if (k == -ENOTSOCK) {
|
||||||
b->prefer_readv = true;
|
b->prefer_readv = true;
|
||||||
k = readv(b->input_fd, &iov, 1);
|
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,
|
r = bus_message_from_malloc(bus,
|
||||||
bus->rbuffer, size,
|
bus->rbuffer, size,
|
||||||
bus->fds, bus->n_fds,
|
bus->fds, bus->n_fds,
|
||||||
bus->got_ctrunc,
|
|
||||||
NULL,
|
NULL,
|
||||||
&t);
|
&t);
|
||||||
if (r == -EBADMSG) {
|
if (r == -EBADMSG) {
|
||||||
@ -1385,7 +1373,6 @@ static int bus_socket_make_message(sd_bus *bus, size_t size) {
|
|||||||
|
|
||||||
bus->fds = NULL;
|
bus->fds = NULL;
|
||||||
bus->n_fds = 0;
|
bus->n_fds = 0;
|
||||||
bus->got_ctrunc = false;
|
|
||||||
|
|
||||||
if (t) {
|
if (t) {
|
||||||
t->read_counter = ++bus->read_counter;
|
t->read_counter = ++bus->read_counter;
|
||||||
@ -1436,7 +1423,7 @@ int bus_socket_read_message(sd_bus *bus) {
|
|||||||
.msg_controllen = sizeof(control),
|
.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) {
|
if (k == -ENOTSOCK) {
|
||||||
bus->prefer_readv = true;
|
bus->prefer_readv = true;
|
||||||
k = readv(bus->input_fd, &iov, 1);
|
k = readv(bus->input_fd, &iov, 1);
|
||||||
|
|||||||
@ -23,7 +23,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
|||||||
|
|
||||||
assert_se(buffer = memdup(data, 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)
|
if (r == -EBADMSG)
|
||||||
return 0;
|
return 0;
|
||||||
assert_se(r >= 0);
|
assert_se(r >= 0);
|
||||||
|
|||||||
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <sys/resource.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "sd-bus.h"
|
#include "sd-bus.h"
|
||||||
@ -11,13 +10,10 @@
|
|||||||
#include "bus-error.h"
|
#include "bus-error.h"
|
||||||
#include "bus-internal.h"
|
#include "bus-internal.h"
|
||||||
#include "bus-match.h"
|
#include "bus-match.h"
|
||||||
#include "bus-message.h"
|
|
||||||
#include "errno-util.h"
|
#include "errno-util.h"
|
||||||
#include "fd-util.h"
|
#include "fd-util.h"
|
||||||
#include "format-util.h"
|
#include "format-util.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "memfd-util.h"
|
|
||||||
#include "stat-util.h"
|
|
||||||
#include "string-util.h"
|
#include "string-util.h"
|
||||||
#include "tests.h"
|
#include "tests.h"
|
||||||
#include "time-util.h"
|
#include "time-util.h"
|
||||||
@ -497,128 +493,6 @@ finish:
|
|||||||
return INT_TO_PTR(r);
|
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) {
|
TEST(chat) {
|
||||||
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
|
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
|
||||||
pthread_t c1, c2;
|
pthread_t c1, c2;
|
||||||
|
|||||||
@ -19,16 +19,12 @@ REENABLE_WARNING
|
|||||||
#include "sd-bus.h"
|
#include "sd-bus.h"
|
||||||
|
|
||||||
#include "alloc-util.h"
|
#include "alloc-util.h"
|
||||||
#include "bus-internal.h"
|
|
||||||
#include "bus-label.h"
|
#include "bus-label.h"
|
||||||
#include "bus-message.h"
|
#include "bus-message.h"
|
||||||
#include "bus-util.h"
|
#include "bus-util.h"
|
||||||
#include "escape.h"
|
#include "escape.h"
|
||||||
#include "fd-util.h"
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "memfd-util.h"
|
|
||||||
#include "memstream-util.h"
|
#include "memstream-util.h"
|
||||||
#include "stat-util.h"
|
|
||||||
#include "tests.h"
|
#include "tests.h"
|
||||||
|
|
||||||
static void test_bus_path_encode_unique(void) {
|
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));
|
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) {
|
static void test_bus_label_escape(void) {
|
||||||
test_bus_label_escape_one("foo123bar", "foo123bar");
|
test_bus_label_escape_one("foo123bar", "foo123bar");
|
||||||
test_bus_label_escape_one("foo.bar", "foo_2ebar");
|
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);
|
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);
|
assert_se(r >= 0);
|
||||||
|
|
||||||
sd_bus_message_dump(m, stdout, SD_BUS_MESSAGE_DUMP_WITH_HEADER);
|
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();
|
||||||
test_bus_path_encode_unique();
|
test_bus_path_encode_unique();
|
||||||
test_bus_path_encode_many();
|
test_bus_path_encode_many();
|
||||||
test_bus_fds_truncated();
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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 id128_get_machine_at(int rfd, sd_id128_t *ret) {
|
||||||
int r;
|
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);
|
r = dir_fd_is_root_or_cwd(rfd);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
|||||||
@ -1031,14 +1031,13 @@ int netdev_load_one(Manager *manager, const char *filename, NetDev **ret) {
|
|||||||
|
|
||||||
dropin_dirname = strjoina(file_basename, ".d");
|
dropin_dirname = strjoina(file_basename, ".d");
|
||||||
r = config_parse_many(
|
r = config_parse_many(
|
||||||
STRV_MAKE_CONST(filename),
|
STRV_MAKE_CONST(filename), NETWORK_DIRS, dropin_dirname, /* root= */ NULL,
|
||||||
NETWORK_DIRS,
|
|
||||||
dropin_dirname,
|
|
||||||
NETDEV_COMMON_SECTIONS NETDEV_OTHER_SECTIONS,
|
NETDEV_COMMON_SECTIONS NETDEV_OTHER_SECTIONS,
|
||||||
config_item_perf_lookup,
|
config_item_perf_lookup, network_netdev_gperf_lookup,
|
||||||
network_netdev_gperf_lookup,
|
|
||||||
CONFIG_PARSE_WARN,
|
CONFIG_PARSE_WARN,
|
||||||
netdev_raw);
|
netdev_raw,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r; /* config_parse_many() logs internally. */
|
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)
|
if (NETDEV_VTABLE(netdev)->init)
|
||||||
NETDEV_VTABLE(netdev)->init(netdev);
|
NETDEV_VTABLE(netdev)->init(netdev);
|
||||||
|
|
||||||
r = config_parse_many_full(
|
r = config_parse_many(
|
||||||
STRV_MAKE_CONST(filename),
|
STRV_MAKE_CONST(filename), NETWORK_DIRS, dropin_dirname, /* root= */ NULL,
|
||||||
NETWORK_DIRS,
|
|
||||||
dropin_dirname,
|
|
||||||
/* root= */ NULL,
|
|
||||||
/* root_fd= */ -EBADF,
|
|
||||||
NETDEV_VTABLE(netdev)->sections,
|
NETDEV_VTABLE(netdev)->sections,
|
||||||
config_item_perf_lookup,
|
config_item_perf_lookup, network_netdev_gperf_lookup,
|
||||||
network_netdev_gperf_lookup,
|
|
||||||
CONFIG_PARSE_WARN,
|
CONFIG_PARSE_WARN,
|
||||||
netdev,
|
netdev,
|
||||||
&netdev->stats_by_path,
|
&netdev->stats_by_path,
|
||||||
|
|||||||
@ -17,7 +17,6 @@
|
|||||||
#include "edit-util.h"
|
#include "edit-util.h"
|
||||||
#include "errno-util.h"
|
#include "errno-util.h"
|
||||||
#include "extract-word.h"
|
#include "extract-word.h"
|
||||||
#include "fd-util.h"
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "mkdir-label.h"
|
#include "mkdir-label.h"
|
||||||
#include "netlink-util.h"
|
#include "netlink-util.h"
|
||||||
@ -107,13 +106,7 @@ static int get_config_files_by_name(
|
|||||||
if (!dropin_dirname)
|
if (!dropin_dirname)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
r = conf_files_list_dropins(
|
r = conf_files_list_dropins(ret_dropins, dropin_dirname, /* root= */ NULL, CONF_FILES_WARN, NETWORK_DIRS);
|
||||||
ret_dropins,
|
|
||||||
dropin_dirname,
|
|
||||||
/* root= */ NULL,
|
|
||||||
/* root_fd= */ XAT_FDROOT,
|
|
||||||
CONF_FILES_WARN,
|
|
||||||
NETWORK_DIRS);
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -514,12 +514,8 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
|
|||||||
.ipoib_umcast = -1,
|
.ipoib_umcast = -1,
|
||||||
};
|
};
|
||||||
|
|
||||||
r = config_parse_many_full(
|
r = config_parse_many(
|
||||||
STRV_MAKE_CONST(filename),
|
STRV_MAKE_CONST(filename), NETWORK_DIRS, dropin_dirname, /* root= */ NULL,
|
||||||
NETWORK_DIRS,
|
|
||||||
dropin_dirname,
|
|
||||||
/* root= */ NULL,
|
|
||||||
/* root_fd= */ -EBADF,
|
|
||||||
"Match\0"
|
"Match\0"
|
||||||
"Link\0"
|
"Link\0"
|
||||||
"SR-IOV\0"
|
"SR-IOV\0"
|
||||||
@ -578,8 +574,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
|
|||||||
"StochasticFairnessQueueing\0"
|
"StochasticFairnessQueueing\0"
|
||||||
"TokenBucketFilter\0"
|
"TokenBucketFilter\0"
|
||||||
"TrivialLinkEqualizer\0",
|
"TrivialLinkEqualizer\0",
|
||||||
config_item_perf_lookup,
|
config_item_perf_lookup, network_network_gperf_lookup,
|
||||||
network_network_gperf_lookup,
|
|
||||||
CONFIG_PARSE_WARN,
|
CONFIG_PARSE_WARN,
|
||||||
network,
|
network,
|
||||||
&network->stats_by_path,
|
&network->stats_by_path,
|
||||||
|
|||||||
@ -2871,17 +2871,16 @@ static int partition_read_definition(
|
|||||||
|
|
||||||
dropin_dirname = strjoina(filename, ".d");
|
dropin_dirname = strjoina(filename, ".d");
|
||||||
|
|
||||||
r = config_parse_many_full(
|
r = config_parse_many(
|
||||||
STRV_MAKE_CONST(path),
|
STRV_MAKE_CONST(path),
|
||||||
conf_file_dirs,
|
conf_file_dirs,
|
||||||
dropin_dirname,
|
dropin_dirname,
|
||||||
c->definitions ? NULL : arg_root,
|
c->definitions ? NULL : arg_root,
|
||||||
/* root_fd= */ -EBADF,
|
|
||||||
"Partition\0",
|
"Partition\0",
|
||||||
config_item_table_lookup, table,
|
config_item_table_lookup, table,
|
||||||
CONFIG_PARSE_WARN,
|
CONFIG_PARSE_WARN,
|
||||||
p,
|
p,
|
||||||
/* ret_stats_by_path= */ NULL,
|
NULL,
|
||||||
&p->drop_in_files);
|
&p->drop_in_files);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
@ -3397,7 +3396,7 @@ static int context_read_definitions(Context *context) {
|
|||||||
&files,
|
&files,
|
||||||
".conf",
|
".conf",
|
||||||
context->definitions ? NULL : arg_root,
|
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);
|
dirs);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to enumerate *.conf files: %m");
|
return log_error_errno(r, "Failed to enumerate *.conf files: %m");
|
||||||
|
|||||||
@ -188,11 +188,14 @@ static int dns_delegate_load(Manager *m, const char *path) {
|
|||||||
STRV_MAKE_CONST(path),
|
STRV_MAKE_CONST(path),
|
||||||
DNS_DELEGATE_SEARCH_DIRS,
|
DNS_DELEGATE_SEARCH_DIRS,
|
||||||
dropin_dirname,
|
dropin_dirname,
|
||||||
|
/* root= */ NULL,
|
||||||
"Delegate\0",
|
"Delegate\0",
|
||||||
config_item_perf_lookup,
|
config_item_perf_lookup,
|
||||||
resolved_dns_delegate_gperf_lookup,
|
resolved_dns_delegate_gperf_lookup,
|
||||||
/* flags= */ 0,
|
/* flags= */ 0,
|
||||||
d);
|
d,
|
||||||
|
/* ret_stats_by_path= */ NULL,
|
||||||
|
/* ret_drop_in_files= */ NULL);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
|||||||
@ -125,13 +125,13 @@ static int dnssd_registered_service_load(Manager *manager, const char *path) {
|
|||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
r = config_parse_many(
|
r = config_parse_many(
|
||||||
STRV_MAKE_CONST(path),
|
STRV_MAKE_CONST(path), DNSSD_SERVICE_DIRS, dropin_dirname, /* root= */ NULL,
|
||||||
DNSSD_SERVICE_DIRS,
|
|
||||||
dropin_dirname,
|
|
||||||
"Service\0",
|
"Service\0",
|
||||||
config_item_perf_lookup, resolved_dnssd_gperf_lookup,
|
config_item_perf_lookup, resolved_dnssd_gperf_lookup,
|
||||||
CONFIG_PARSE_WARN,
|
CONFIG_PARSE_WARN,
|
||||||
service);
|
service,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
|||||||
@ -22,7 +22,7 @@ static int entry_token_load_one(int rfd, const char *dir, BootEntryTokenType *ty
|
|||||||
_cleanup_fclose_ FILE *f = NULL;
|
_cleanup_fclose_ FILE *f = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(rfd >= 0 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
|
assert(rfd >= 0 || rfd == AT_FDCWD);
|
||||||
assert(dir);
|
assert(dir);
|
||||||
assert(type);
|
assert(type);
|
||||||
assert(*type == BOOT_ENTRY_TOKEN_AUTO);
|
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) {
|
static int entry_token_load(int rfd, const char *conf_root, BootEntryTokenType *type, char **token) {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(rfd >= 0 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
|
assert(rfd >= 0 || rfd == AT_FDCWD);
|
||||||
assert(type);
|
assert(type);
|
||||||
assert(*type == BOOT_ENTRY_TOKEN_AUTO);
|
assert(*type == BOOT_ENTRY_TOKEN_AUTO);
|
||||||
assert(token);
|
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;
|
_cleanup_free_ char *id = NULL, *image_id = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(rfd >= 0 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
|
assert(rfd >= 0 || rfd == AT_FDCWD);
|
||||||
assert(type);
|
assert(type);
|
||||||
assert(IN_SET(*type, BOOT_ENTRY_TOKEN_AUTO, BOOT_ENTRY_TOKEN_OS_IMAGE_ID, BOOT_ENTRY_TOKEN_OS_ID));
|
assert(IN_SET(*type, BOOT_ENTRY_TOKEN_AUTO, BOOT_ENTRY_TOKEN_OS_IMAGE_ID, BOOT_ENTRY_TOKEN_OS_ID));
|
||||||
assert(token);
|
assert(token);
|
||||||
@ -151,7 +151,7 @@ int boot_entry_token_ensure_at(
|
|||||||
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(rfd >= 0 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
|
assert(rfd >= 0 || rfd == AT_FDCWD);
|
||||||
assert(type);
|
assert(type);
|
||||||
assert(token);
|
assert(token);
|
||||||
|
|
||||||
@ -229,12 +229,11 @@ int boot_entry_token_ensure(
|
|||||||
if (*token)
|
if (*token)
|
||||||
return 0; /* Already set. */
|
return 0; /* Already set. */
|
||||||
|
|
||||||
_cleanup_close_ int rfd = XAT_FDROOT;
|
_cleanup_close_ int rfd = -EBADF;
|
||||||
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)
|
if (rfd < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
}
|
|
||||||
|
|
||||||
return boot_entry_token_ensure_at(rfd, conf_root, machine_id, machine_id_is_random, type, token);
|
return boot_entry_token_ensure_at(rfd, conf_root, machine_id, machine_id_is_random, type, token);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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(
|
static int config_parse_many_files(
|
||||||
const char *root,
|
const char *root,
|
||||||
int root_fd,
|
|
||||||
const char* const* conf_files,
|
const char* const* conf_files,
|
||||||
char **files,
|
char **files,
|
||||||
const char *sections,
|
const char *sections,
|
||||||
@ -503,17 +502,17 @@ static int config_parse_many_files(
|
|||||||
return log_oom_full(level);
|
return log_oom_full(level);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pin and stat() all dropins */
|
|
||||||
STRV_FOREACH(fn, files) {
|
STRV_FOREACH(fn, files) {
|
||||||
_cleanup_fclose_ FILE *f = NULL;
|
_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)
|
if (r == -ENOENT)
|
||||||
continue;
|
continue;
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_full_errno(level, r, "Failed to open %s: %m", *fn);
|
return log_full_errno(level, r, "Failed to open %s: %m", *fn);
|
||||||
|
|
||||||
int fd = fileno(f);
|
int fd = fileno(f);
|
||||||
assert(fd >= 0);
|
|
||||||
|
|
||||||
r = ordered_hashmap_ensure_put(&dropins, &config_file_hash_ops_fclose, *fn, f);
|
r = ordered_hashmap_ensure_put(&dropins, &config_file_hash_ops_fclose, *fn, f);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
@ -538,10 +537,11 @@ static int config_parse_many_files(
|
|||||||
return log_oom_full(level);
|
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) {
|
STRV_FOREACH(fn, conf_files) {
|
||||||
_cleanup_fclose_ FILE *f = NULL;
|
_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)
|
if (r == -ENOENT)
|
||||||
continue;
|
continue;
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@ -572,6 +572,7 @@ static int config_parse_many_files(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Then read all the drop-ins. */
|
/* Then read all the drop-ins. */
|
||||||
|
|
||||||
const char *path_dropin;
|
const char *path_dropin;
|
||||||
FILE *f_dropin;
|
FILE *f_dropin;
|
||||||
ORDERED_HASHMAP_FOREACH_KEY(f_dropin, path_dropin, dropins) {
|
ORDERED_HASHMAP_FOREACH_KEY(f_dropin, path_dropin, dropins) {
|
||||||
@ -593,39 +594,12 @@ static int config_parse_many_files(
|
|||||||
return 0;
|
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. */
|
/* 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_files,
|
||||||
const char* const* conf_file_dirs,
|
const char* const* conf_file_dirs,
|
||||||
const char *dropin_dirname,
|
const char *dropin_dirname,
|
||||||
const char *root,
|
const char *root,
|
||||||
int root_fd,
|
|
||||||
const char *sections,
|
const char *sections,
|
||||||
ConfigItemLookup lookup,
|
ConfigItemLookup lookup,
|
||||||
const void *table,
|
const void *table,
|
||||||
@ -641,33 +615,14 @@ int config_parse_many_full(
|
|||||||
assert(dropin_dirname);
|
assert(dropin_dirname);
|
||||||
assert(table);
|
assert(table);
|
||||||
|
|
||||||
_cleanup_close_ int opened_root_fd = -EBADF;
|
r = conf_files_list_dropins(&files, dropin_dirname, root,
|
||||||
r = normalize_root_fd(root, &root_fd, &opened_root_fd);
|
FLAGS_SET(flags, CONFIG_PARSE_WARN) ? CONF_FILES_WARN : 0,
|
||||||
if (r < 0)
|
conf_file_dirs);
|
||||||
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)
|
if (r < 0)
|
||||||
return log_full_errno(FLAGS_SET(flags, CONFIG_PARSE_WARN) ? LOG_WARNING : LOG_DEBUG, r,
|
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);
|
"Failed to list drop-ins in %s: %m", dropin_dirname);
|
||||||
|
|
||||||
r = config_parse_many_files(
|
r = config_parse_many_files(root, conf_files, files, sections, lookup, table, flags, userdata, ret_stats_by_path);
|
||||||
root,
|
|
||||||
root_fd,
|
|
||||||
conf_files,
|
|
||||||
files,
|
|
||||||
sections,
|
|
||||||
lookup,
|
|
||||||
table,
|
|
||||||
flags,
|
|
||||||
userdata,
|
|
||||||
ret_stats_by_path);
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r; /* config_parse_many_files() logs internally. */
|
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(
|
int config_parse_standard_file_with_dropins_full(
|
||||||
const char *root,
|
const char *root,
|
||||||
int root_fd,
|
|
||||||
const char *main_file, /* A path like "systemd/frobnicator.conf" */
|
const char *main_file, /* A path like "systemd/frobnicator.conf" */
|
||||||
const char *sections,
|
const char *sections,
|
||||||
ConfigItemLookup lookup,
|
ConfigItemLookup lookup,
|
||||||
@ -689,15 +643,12 @@ int config_parse_standard_file_with_dropins_full(
|
|||||||
Hashmap **ret_stats_by_path,
|
Hashmap **ret_stats_by_path,
|
||||||
char ***ret_dropin_files) {
|
char ***ret_dropin_files) {
|
||||||
|
|
||||||
const char* const *conf_file_dirs = (const char* const*) CONF_PATHS_STRV("");
|
const char* const *conf_paths = (const char* const*) CONF_PATHS_STRV("");
|
||||||
_cleanup_strv_free_ char **conf_files = NULL;
|
_cleanup_strv_free_ char **configs = NULL;
|
||||||
int r, level = FLAGS_SET(flags, CONFIG_PARSE_WARN) ? LOG_WARNING : LOG_DEBUG;
|
int r, level = FLAGS_SET(flags, CONFIG_PARSE_WARN) ? LOG_WARNING : LOG_DEBUG;
|
||||||
|
|
||||||
/* Build the list of main config files */
|
/* Build the list of main config files */
|
||||||
r = strv_extend_strv_concat(
|
r = strv_extend_strv_biconcat(&configs, root, conf_paths, main_file);
|
||||||
&conf_files,
|
|
||||||
conf_file_dirs,
|
|
||||||
main_file);
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_oom_full(level);
|
return log_oom_full(level);
|
||||||
|
|
||||||
@ -705,12 +656,11 @@ int config_parse_standard_file_with_dropins_full(
|
|||||||
if (!dropin_dirname)
|
if (!dropin_dirname)
|
||||||
return log_oom_full(level);
|
return log_oom_full(level);
|
||||||
|
|
||||||
return config_parse_many_full(
|
return config_parse_many(
|
||||||
(const char* const*) conf_files,
|
(const char* const*) configs,
|
||||||
conf_file_dirs,
|
conf_paths,
|
||||||
dropin_dirname,
|
dropin_dirname,
|
||||||
root,
|
root,
|
||||||
root_fd,
|
|
||||||
sections,
|
sections,
|
||||||
lookup,
|
lookup,
|
||||||
table,
|
table,
|
||||||
@ -742,13 +692,7 @@ static int dropins_get_stats_by_path(
|
|||||||
if (!strextend(&dropin_dirname, ".d"))
|
if (!strextend(&dropin_dirname, ".d"))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
r = conf_files_list_dropins(
|
r = conf_files_list_dropins(&files, dropin_dirname, /* root= */ NULL, /* flags= */ 0, conf_file_dirs);
|
||||||
&files,
|
|
||||||
dropin_dirname,
|
|
||||||
/* root= */ NULL,
|
|
||||||
/* root_fd= */ XAT_FDROOT,
|
|
||||||
/* flags= */ 0,
|
|
||||||
conf_file_dirs);
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
#include "alloc-util.h"
|
#include "alloc-util.h"
|
||||||
#include "conf-parser-forward.h"
|
#include "conf-parser-forward.h"
|
||||||
#include "fd-util.h"
|
#include "shared-forward.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
/* An abstract parser for simple, line based, shallow configuration files consisting of variable assignments only. */
|
/* An abstract parser for simple, line based, shallow configuration files consisting of variable assignments only. */
|
||||||
@ -66,12 +66,11 @@ int config_parse(
|
|||||||
void *userdata,
|
void *userdata,
|
||||||
struct stat *ret_stat); /* possibly NULL */
|
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_files, /* possibly empty */
|
||||||
const char* const* conf_file_dirs,
|
const char* const* conf_file_dirs,
|
||||||
const char *dropin_dirname,
|
const char *dropin_dirname,
|
||||||
const char *root,
|
const char *root,
|
||||||
int root_fd,
|
|
||||||
const char *sections, /* nulstr */
|
const char *sections, /* nulstr */
|
||||||
ConfigItemLookup lookup,
|
ConfigItemLookup lookup,
|
||||||
const void *table,
|
const void *table,
|
||||||
@ -80,34 +79,8 @@ int config_parse_many_full(
|
|||||||
Hashmap **ret_stats_by_path, /* possibly NULL */
|
Hashmap **ret_stats_by_path, /* possibly NULL */
|
||||||
char ***ret_dropin_files); /* 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(
|
int config_parse_standard_file_with_dropins_full(
|
||||||
const char *root,
|
const char *root,
|
||||||
int root_fd,
|
|
||||||
const char *main_file, /* A path like "systemd/frobnicator.conf" */
|
const char *main_file, /* A path like "systemd/frobnicator.conf" */
|
||||||
const char *sections,
|
const char *sections,
|
||||||
ConfigItemLookup lookup,
|
ConfigItemLookup lookup,
|
||||||
@ -126,7 +99,6 @@ static inline int config_parse_standard_file_with_dropins(
|
|||||||
void *userdata) {
|
void *userdata) {
|
||||||
return config_parse_standard_file_with_dropins_full(
|
return config_parse_standard_file_with_dropins_full(
|
||||||
/* root= */ NULL,
|
/* root= */ NULL,
|
||||||
/* root_fd= */ XAT_FDROOT,
|
|
||||||
main_file,
|
main_file,
|
||||||
sections,
|
sections,
|
||||||
lookup,
|
lookup,
|
||||||
|
|||||||
@ -2,13 +2,11 @@
|
|||||||
|
|
||||||
#include "alloc-util.h"
|
#include "alloc-util.h"
|
||||||
#include "conf-parser.h"
|
#include "conf-parser.h"
|
||||||
#include "fd-util.h"
|
|
||||||
#include "kernel-config.h"
|
#include "kernel-config.h"
|
||||||
#include "path-util.h"
|
#include "path-util.h"
|
||||||
|
|
||||||
int load_kernel_install_conf_at(
|
int load_kernel_install_conf(
|
||||||
const char *root,
|
const char *root,
|
||||||
int root_fd,
|
|
||||||
const char *conf_root,
|
const char *conf_root,
|
||||||
char **ret_machine_id,
|
char **ret_machine_id,
|
||||||
char **ret_boot_root,
|
char **ret_boot_root,
|
||||||
@ -28,19 +26,16 @@ int load_kernel_install_conf_at(
|
|||||||
};
|
};
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(root_fd >= 0 || IN_SET(root_fd, AT_FDCWD, XAT_FDROOT));
|
|
||||||
|
|
||||||
if (conf_root) {
|
if (conf_root) {
|
||||||
_cleanup_free_ char *conf = path_join(conf_root, "install.conf");
|
_cleanup_free_ char *conf = path_join(conf_root, "install.conf");
|
||||||
if (!conf)
|
if (!conf)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
r = config_parse_many_full(
|
r = config_parse_many(
|
||||||
STRV_MAKE_CONST(conf),
|
STRV_MAKE_CONST(conf),
|
||||||
STRV_MAKE_CONST(conf_root),
|
STRV_MAKE_CONST(conf_root),
|
||||||
"install.conf.d",
|
"install.conf.d",
|
||||||
root,
|
/* root= */ NULL, /* $KERNEL_INSTALL_CONF_ROOT and --root are independent */
|
||||||
root_fd,
|
|
||||||
/* sections= */ NULL,
|
/* sections= */ NULL,
|
||||||
config_item_table_lookup, items,
|
config_item_table_lookup, items,
|
||||||
CONFIG_PARSE_WARN,
|
CONFIG_PARSE_WARN,
|
||||||
@ -50,7 +45,6 @@ int load_kernel_install_conf_at(
|
|||||||
} else
|
} else
|
||||||
r = config_parse_standard_file_with_dropins_full(
|
r = config_parse_standard_file_with_dropins_full(
|
||||||
root,
|
root,
|
||||||
root_fd,
|
|
||||||
"kernel/install.conf",
|
"kernel/install.conf",
|
||||||
/* sections= */ NULL,
|
/* sections= */ NULL,
|
||||||
config_item_table_lookup, items,
|
config_item_table_lookup, items,
|
||||||
|
|||||||
@ -1,27 +1,13 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "fd-util.h"
|
|
||||||
#include "shared-forward.h"
|
#include "shared-forward.h"
|
||||||
|
|
||||||
int load_kernel_install_conf_at(
|
int load_kernel_install_conf(
|
||||||
const char *root,
|
const char *root,
|
||||||
int root_fd,
|
|
||||||
const char *conf_root,
|
const char *conf_root,
|
||||||
char **ret_machine_id,
|
char **ret_machine_id,
|
||||||
char **ret_boot_root,
|
char **ret_boot_root,
|
||||||
char **ret_layout,
|
char **ret_layout,
|
||||||
char **ret_initrd_generator,
|
char **ret_initrd_generator,
|
||||||
char **ret_uki_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,7 +191,6 @@ static int parse_config_file(ImageClass image_class) {
|
|||||||
|
|
||||||
r = config_parse_standard_file_with_dropins_full(
|
r = config_parse_standard_file_with_dropins_full(
|
||||||
arg_root,
|
arg_root,
|
||||||
/* root_fd= */ -EBADF,
|
|
||||||
config_file,
|
config_file,
|
||||||
sections,
|
sections,
|
||||||
config_item_table_lookup, items,
|
config_item_table_lookup, items,
|
||||||
|
|||||||
@ -101,12 +101,11 @@ int feature_read_definition(Feature *f, const char *path, const char *const *dir
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to extract filename from path '%s': %m", path);
|
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),
|
STRV_MAKE_CONST(path),
|
||||||
dirs,
|
dirs,
|
||||||
strjoina(filename, ".d"),
|
strjoina(filename, ".d"),
|
||||||
arg_root,
|
arg_root,
|
||||||
/* root_fd= */ -EBADF,
|
|
||||||
"Feature\0",
|
"Feature\0",
|
||||||
config_item_table_lookup, table,
|
config_item_table_lookup, table,
|
||||||
CONFIG_PARSE_WARN,
|
CONFIG_PARSE_WARN,
|
||||||
|
|||||||
@ -543,12 +543,11 @@ int transfer_read_definition(Transfer *t, const char *path, const char **dirs, H
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to extract filename from path '%s': %m", path);
|
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),
|
STRV_MAKE_CONST(path),
|
||||||
dirs,
|
dirs,
|
||||||
strjoina(filename, ".d"),
|
strjoina(filename, ".d"),
|
||||||
arg_root,
|
arg_root,
|
||||||
/* root_fd= */ -EBADF,
|
|
||||||
"Transfer\0"
|
"Transfer\0"
|
||||||
"Source\0"
|
"Source\0"
|
||||||
"Target\0",
|
"Target\0",
|
||||||
|
|||||||
@ -1568,12 +1568,12 @@ static int verb_components(int argc, char **argv, void *userdata) {
|
|||||||
FOREACH_ARRAY(i, directories, n_directories) {
|
FOREACH_ARRAY(i, directories, n_directories) {
|
||||||
ConfFile *e = *i;
|
ConfFile *e = *i;
|
||||||
|
|
||||||
if (streq(e->filename, "sysupdate.d")) {
|
if (streq(e->name, "sysupdate.d")) {
|
||||||
has_default_component = true;
|
has_default_component = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *s = startswith(e->filename, "sysupdate.");
|
const char *s = startswith(e->name, "sysupdate.");
|
||||||
if (!s)
|
if (!s)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|||||||
@ -444,9 +444,7 @@ TEST(config_parse_standard_file_with_dropins_full) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
r = config_parse_standard_file_with_dropins_full(
|
r = config_parse_standard_file_with_dropins_full(
|
||||||
root,
|
root, "kernel/install.conf",
|
||||||
/* root_fd= */ -EBADF,
|
|
||||||
"kernel/install.conf",
|
|
||||||
/* sections= */ NULL,
|
/* sections= */ NULL,
|
||||||
config_item_table_lookup, items,
|
config_item_table_lookup, items,
|
||||||
CONFIG_PARSE_WARN,
|
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);
|
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(
|
r = config_parse_standard_file_with_dropins_full(
|
||||||
root,
|
root, "kernel/install2.conf",
|
||||||
/* root_fd= */ -EBADF,
|
|
||||||
"kernel/install2.conf",
|
|
||||||
/* sections= */ NULL,
|
/* sections= */ NULL,
|
||||||
config_item_table_lookup, items,
|
config_item_table_lookup, items,
|
||||||
CONFIG_PARSE_WARN,
|
CONFIG_PARSE_WARN,
|
||||||
|
|||||||
@ -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);
|
return log_error_errno(r, "Failed to extract file name of '%s': %m", filename);
|
||||||
|
|
||||||
dropin_dirname = strjoina(file_basename, ".d");
|
dropin_dirname = strjoina(file_basename, ".d");
|
||||||
r = config_parse_many_full(
|
r = config_parse_many(
|
||||||
STRV_MAKE_CONST(filename),
|
STRV_MAKE_CONST(filename),
|
||||||
NETWORK_DIRS,
|
NETWORK_DIRS,
|
||||||
dropin_dirname,
|
dropin_dirname,
|
||||||
/* root= */ NULL,
|
/* root= */ NULL,
|
||||||
/* root_fd= */ -EBADF,
|
|
||||||
"Match\0"
|
"Match\0"
|
||||||
"Link\0"
|
"Link\0"
|
||||||
"SR-IOV\0"
|
"SR-IOV\0"
|
||||||
"EnergyEfficientEthernet\0",
|
"EnergyEfficientEthernet\0",
|
||||||
config_item_perf_lookup, link_config_gperf_lookup,
|
config_item_perf_lookup, link_config_gperf_lookup,
|
||||||
CONFIG_PARSE_WARN,
|
CONFIG_PARSE_WARN, config, &stats_by_path,
|
||||||
config,
|
|
||||||
&stats_by_path,
|
|
||||||
&config->dropins);
|
&config->dropins);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r; /* config_parse_many() logs internally. */
|
return r; /* config_parse_many() logs internally. */
|
||||||
|
|||||||
@ -1739,11 +1739,9 @@ static int generate_ssh_keypair(const char *key_path, const char *key_type) {
|
|||||||
log_debug("Executing: %s", joined);
|
log_debug("Executing: %s", joined);
|
||||||
}
|
}
|
||||||
|
|
||||||
r = pidref_safe_fork_full(
|
r = pidref_safe_fork(
|
||||||
ssh_keygen,
|
ssh_keygen,
|
||||||
(int[]) { -EBADF, -EBADF, STDERR_FILENO },
|
FORK_WAIT|FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE|FORK_REARRANGE_STDIO,
|
||||||
/* 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,
|
|
||||||
/* ret= */ NULL);
|
/* ret= */ NULL);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user