]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
repart: Initialize root directory metadata correctly
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Tue, 14 Feb 2023 10:19:43 +0000 (11:19 +0100)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Tue, 14 Feb 2023 13:30:27 +0000 (14:30 +0100)
Let's make sure we copy the root directory metadata from an
appropriate source directory.

src/partition/repart.c

index 93dfb5fb3e8446766e3056090c24abf9ccbf1ae8..20f571e4cb015001ef9fa014570c5a74eacaa6d3 100644 (file)
@@ -3752,6 +3752,31 @@ static int do_copy_files(Partition *p, const char *root, const Set *denylist) {
         assert(p);
         assert(root);
 
+        /* copy_tree_at() automatically copies the permissions of source directories to target directories if
+         * it created them. However, the root directory is created by us, so we have to manually take care
+         * that it is initialized. We use the first source directory targeting "/" as the metadata source for
+         * the root directory. */
+        STRV_FOREACH_PAIR(source, target, p->copy_files) {
+                _cleanup_close_ int rfd = -EBADF, sfd = -EBADF;
+
+                if (!path_equal(*target, "/"))
+                        continue;
+
+                rfd = open(root, O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
+                if (rfd < 0)
+                        return rfd;
+
+                sfd = chase_symlinks_and_open(*source, arg_root, CHASE_PREFIX_ROOT, O_PATH|O_DIRECTORY|O_CLOEXEC|O_NOCTTY, NULL);
+                if (sfd < 0)
+                        return log_error_errno(sfd, "Failed to open source file '%s%s': %m", strempty(arg_root), *source);
+
+                (void) copy_xattr(sfd, NULL, rfd, NULL, COPY_ALL_XATTRS);
+                (void) copy_access(sfd, rfd);
+                (void) copy_times(sfd, rfd, 0);
+
+                break;
+        }
+
         STRV_FOREACH_PAIR(source, target, p->copy_files) {
                 _cleanup_close_ int sfd = -EBADF, pfd = -EBADF, tfd = -EBADF;