]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
dissect: Use COPY_MERGE
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Fri, 10 Jan 2025 14:53:59 +0000 (15:53 +0100)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Tue, 14 Jan 2025 10:13:25 +0000 (11:13 +0100)
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.

man/systemd-dissect.xml
src/dissect/dissect.c

index 2718feccb75da12ea1d73656ddd88f286a70c44b..7c9369e387e36ea1fd712ba9f08c1a88db1e1f85 100644 (file)
         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>
         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>
index 3ca1e17be4b6c8fd7ff7cfe7d2aa07693366bbd4..33e651c6c16374e1129ab43415ef3eb893293075 100644 (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);