sysupdate: don't double-prefix definitions with --root=

Definitions enumerated under --root= are already rooted. Passing those
paths to the config parsers with the same root prefixes the root again,
so feature and transfer files are parsed from the wrong path.

Repro: create root/etc/sysupdate.d/rootfeat.feature and
01-root.transfer, then run:
build/systemd-sysupdate --root="$root" --verify=no --offline features rootfeat

Before: parsing failed at line 1 with a bogus Source Type= error.

Fixes #42783.
Follow-up for: e1384cfb09
This commit is contained in:
dongshengyuan
2026-07-26 14:40:05 +09:00
committed by Yu Watanabe
parent 99c6f01321
commit 414777a108
3 changed files with 38 additions and 2 deletions
+3
View File
@@ -102,6 +102,9 @@ static int conf_file_prefix_root(ConfFile *c, const char *root, ConfFilesFlags f
assert(c);
if (FLAGS_SET(flags, CONF_FILES_DONT_PREFIX_ROOT))
return 0;
int log_level = conf_files_log_level(flags);
r = chaseat_prefix_root(c->result, root, &p);
+2 -2
View File
@@ -255,7 +255,7 @@ static int read_features(
r = conf_files_list_strv_full(
".feature",
c->root,
CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED|CONF_FILES_WARN,
CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED|CONF_FILES_WARN|CONF_FILES_DONT_PREFIX_ROOT,
dirs,
&files,
&n_files);
@@ -303,7 +303,7 @@ static int read_transfers(
assert(suffix);
r = conf_files_list_strv_full(suffix, c->root,
CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED|CONF_FILES_WARN,
CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED|CONF_FILES_WARN|CONF_FILES_DONT_PREFIX_ROOT,
dirs, &files, &n_files);
if (r < 0)
return log_error_errno(r, "Failed to enumerate sysupdate.d/*%s definitions: %m", suffix);
+33
View File
@@ -698,6 +698,39 @@ cmp "$WORKDIR/source/tiny-v1.bin" "$WORKDIR/blobs/tiny-v1.bin"
"$SYSUPDATE" features |& grep "No features." >/dev/null
[[ $(varlinkctl call "$VARLINK_SOCKET" io.systemd.SysUpdate.ListFeatures '{"target":{"class":"host"}}' | jq -r '.features') == "[]" ]]
# Test that definitions found through --root= are not prefixed twice.
rm -rf "$WORKDIR/root-definitions"
mkdir -p "$WORKDIR/root-definitions/etc/sysupdate.d" \
"$WORKDIR/root-definitions/etc" \
"$WORKDIR/root-definitions/source" \
"$WORKDIR/root-definitions/target"
printf '%s\n' 'ID=repro' 'VERSION_ID=1' >"$WORKDIR/root-definitions/etc/os-release"
cat >"$WORKDIR/root-definitions/etc/sysupdate.d/rootfeat.feature" <<EOF
[Feature]
Description=Root Feature
EOF
cat >"$WORKDIR/root-definitions/etc/sysupdate.d/01-root.transfer" <<EOF
[Transfer]
[Source]
Type=regular-file
Path=/source
MatchPattern=root-@v.bin
[Target]
Type=regular-file
Path=/target
MatchPattern=root-@v.bin
InstancesMax=2
EOF
"$SYSUPDATE" \
--root="$WORKDIR/root-definitions" \
--verify=no \
--offline \
features rootfeat \
| grep -F "Root Feature" >/dev/null
rm -rf "$WORKDIR/root-definitions"
# Cleanup
rm "$CONFIGDIR/01-tiny-url.transfer"
rm "$WORKDIR/source/tiny-v1.bin"