machine: propagate foreign image clone directory errors

unprivileged_clone() returns success when mountfsd_make_directory() fails.
Consequently, callers can report a successful clone even though the
destination directory was never created.

Return the original error instead of zero so the failed clone is
reported to the caller.

Add a regression test that places a regular file without an image suffix
at the destination path. Such a file is ignored by image discovery but
prevents directory creation. Check that cloning reports failure without
changing the file, then succeeds after the conflicting file is removed.
This commit is contained in:
Totoro
2026-09-05 08:32:02 +02:00
committed by Lennart Poettering
parent 7fa7ff87cd
commit 0c8f57cae2
2 changed files with 19 additions and 1 deletions
+1 -1
View File
@@ -1725,7 +1725,7 @@ static int unprivileged_clone(Image *i, const char *new_path) {
/* flags= */ 0,
&new_fd);
if (r < 0)
return 0;
return r;
/* Mount new image */
_cleanup_close_ int target_fd = -EBADF;
+18
View File
@@ -195,6 +195,24 @@ test -d /var/lib/machines/.hidden1
machinectl clean
test ! -d /var/lib/machines/.hidden1
if can_do_rootless_nspawn; then
mkdir /var/lib/machines/foreign-error-source
chown foreign-0:foreign-0 /var/lib/machines/foreign-error-source
# A regular file without an image suffix is not discovered as an image, but still prevents
# mountfsd from creating the clone directory. The clone operation must report this failure.
echo "existing file" >/var/lib/machines/foreign-error-target
(! machinectl show-image foreign-error-target)
(! machinectl clone foreign-error-source foreign-error-target)
assert_eq "$(</var/lib/machines/foreign-error-target)" "existing file"
rm /var/lib/machines/foreign-error-target
machinectl clone foreign-error-source foreign-error-target
machinectl remove foreign-error-target foreign-error-source
else
echo "Skipping foreign-UID clone error test: rootless nspawn prerequisites not met"
fi
# Prepare a simple raw container
mkdir -p /tmp/mnt
truncate -s 384M /var/tmp/container.raw