dissect: Use COPY_MERGE

When copying a directory from or to an image, let's always merge
with existing directories instead of failing with "File Exists".

Fixes https://github.com/systemd/mkosi/issues/3342.
This commit is contained in:
Daan De Meyer
2025-01-10 15:53:59 +01:00
parent 6e5fb09d1c
commit 6309efbf31
2 changed files with 7 additions and 7 deletions

View File

@@ -282,8 +282,8 @@
standard output. If the source path in the image file system refers to a regular file it is copied to
the destination path. In this case, access mode, extended attributes and timestamps are copied as
well, but file ownership is not. If the source path in the image refers to a directory, it is copied
to the destination path, recursively with all containing files and directories. In this case, the file
ownership is copied too.</para>
to the destination path, recursively with all containing files and directories, merging into existing
directories and updating already existing files. In this case, the file ownership is copied too.</para>
<xi:include href="version-info.xml" xpointer="v247"/></listitem>
</varlistentry>
@@ -300,8 +300,8 @@
source path in the host file system refers to a regular file, it is copied to the destination path.
In this case, access mode, extended attributes and timestamps are copied as well, but file ownership
is not. If the source path in the host file system refers to a directory it is copied to the
destination path, recursively with all containing files and directories. In this case, the file
ownership is copied too.</para>
destination path, recursively with all containing files and directories, merging into existing
directories and updating already existing files.. In this case, the file ownership is copied too.</para>
<para>As with <option>--mount</option> file system checks are implicitly run before the copy
operation begins.</para>

View File

@@ -1546,7 +1546,7 @@ static int action_list_or_mtree_or_copy_or_make_archive(DissectedImage *m, LoopD
}
/* Try to copy as directory? */
r = copy_directory_at(source_fd, NULL, AT_FDCWD, arg_target, COPY_REFLINK|COPY_MERGE_EMPTY|COPY_SIGINT|COPY_HARDLINKS);
r = copy_directory_at(source_fd, NULL, AT_FDCWD, arg_target, COPY_REFLINK|COPY_MERGE|COPY_REPLACE|COPY_SIGINT|COPY_HARDLINKS);
if (r >= 0)
return 0;
if (r != -ENOTDIR)
@@ -1625,9 +1625,9 @@ static int action_list_or_mtree_or_copy_or_make_archive(DissectedImage *m, LoopD
if (errno != ENOENT)
return log_error_errno(errno, "Failed to open destination '%s': %m", arg_target);
r = copy_tree_at(source_fd, ".", dfd, bn, UID_INVALID, GID_INVALID, COPY_REFLINK|COPY_REPLACE|COPY_SIGINT|COPY_HARDLINKS, NULL, NULL);
r = copy_tree_at(source_fd, ".", dfd, bn, UID_INVALID, GID_INVALID, COPY_REFLINK|COPY_MERGE|COPY_REPLACE|COPY_SIGINT|COPY_HARDLINKS, NULL, NULL);
} else
r = copy_tree_at(source_fd, ".", target_fd, ".", UID_INVALID, GID_INVALID, COPY_REFLINK|COPY_REPLACE|COPY_SIGINT|COPY_HARDLINKS, NULL, NULL);
r = copy_tree_at(source_fd, ".", target_fd, ".", UID_INVALID, GID_INVALID, COPY_REFLINK|COPY_MERGE|COPY_REPLACE|COPY_SIGINT|COPY_HARDLINKS, NULL, NULL);
if (r < 0)
return log_error_errno(r, "Failed to copy '%s' to '%s' in image '%s': %m", arg_source, arg_target, arg_image);