]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
shared/copy: add a new flag COPY_ALL_XATTRS
authorAndrej Lajovic <andrej.lajovic@ad-vega.si>
Sun, 8 Aug 2021 23:43:54 +0000 (01:43 +0200)
committerLennart Poettering <lennart@poettering.net>
Wed, 11 Aug 2021 15:48:10 +0000 (17:48 +0200)
When the flag COPY_ALL_XATTRS is set, it causes the complete set of xattrs
to be copied. If the flag is unset, only xattrs from the "user" namespace
are copied.

Fixes #17178.

src/dissect/dissect.c
src/import/export-raw.c
src/import/import-raw.c
src/import/pull-raw.c
src/locale/keymap-util.c
src/partition/repart.c
src/shared/btrfs-util.c
src/shared/copy.c
src/shared/copy.h

index 68c8bedc9b0e2474b84c1a3ec7907b64c2d179ce..4693e7433b47c0236d879701d17446fe2ca3b111 100644 (file)
@@ -679,7 +679,7 @@ static int action_copy(DissectedImage *m, LoopDevice *d) {
                 if (r < 0)
                         return log_error_errno(r, "Failed to copy bytes from %s in mage '%s' to '%s': %m", arg_source, arg_image, arg_target);
 
-                (void) copy_xattr(source_fd, target_fd);
+                (void) copy_xattr(source_fd, target_fd, 0);
                 (void) copy_access(source_fd, target_fd);
                 (void) copy_times(source_fd, target_fd, 0);
 
@@ -748,7 +748,7 @@ static int action_copy(DissectedImage *m, LoopDevice *d) {
                 if (r < 0)
                         return log_error_errno(r, "Failed to copy bytes from '%s' to '%s' in image '%s': %m", arg_source, arg_target, arg_image);
 
-                (void) copy_xattr(source_fd, target_fd);
+                (void) copy_xattr(source_fd, target_fd, 0);
                 (void) copy_access(source_fd, target_fd);
                 (void) copy_times(source_fd, target_fd, 0);
 
index d42c56172fdde8d9a12645bc37c08401f36900a3..6617a9c9b673530c02f42869db224f9a6a241527 100644 (file)
@@ -223,7 +223,7 @@ static int raw_export_process(RawExport *e) {
 finish:
         if (r >= 0) {
                 (void) copy_times(e->input_fd, e->output_fd, COPY_CRTIME);
-                (void) copy_xattr(e->input_fd, e->output_fd);
+                (void) copy_xattr(e->input_fd, e->output_fd, 0);
         }
 
         if (e->on_finished)
index 0e7757b6f0c114e1cf95d79876086510f1d70cc3..649cffb55f1021b4a5a966f5711ba4208832163d 100644 (file)
@@ -206,7 +206,7 @@ static int raw_import_finish(RawImport *i) {
 
         if (S_ISREG(i->st.st_mode)) {
                 (void) copy_times(i->input_fd, i->output_fd, COPY_CRTIME);
-                (void) copy_xattr(i->input_fd, i->output_fd);
+                (void) copy_xattr(i->input_fd, i->output_fd, 0);
         }
 
         if (i->flags & IMPORT_READ_ONLY) {
index ca4f2502101754d5fbb5d616b903b8ff3200b82b..56c99a690e2a3a1e906d771f115424dd8708661f 100644 (file)
@@ -371,7 +371,7 @@ static int raw_pull_make_local_copy(RawPull *i) {
         }
 
         (void) copy_times(i->raw_job->disk_fd, dfd, COPY_CRTIME);
-        (void) copy_xattr(i->raw_job->disk_fd, dfd);
+        (void) copy_xattr(i->raw_job->disk_fd, dfd, 0);
 
         dfd = safe_close(dfd);
 
index d48f0b421688ba31a4e928ec074d72312299f333..32af23d6924187d19add02b32402767237595421 100644 (file)
@@ -845,7 +845,7 @@ int locale_gen_enable_locale(const char *locale) {
                 r = copy_access(fileno(fr), fileno(fw));
                 if (r < 0)
                         return r;
-                r = copy_xattr(fileno(fr), fileno(fw));
+                r = copy_xattr(fileno(fr), fileno(fw), COPY_ALL_XATTRS);
                 if (r < 0)
                         return r;
         }
index c75198e5c97b142b61c852c8459975ddbea26951..6f3b3dbe179f206d06ac58ed683273b13fb2f17f 100644 (file)
@@ -2849,13 +2849,13 @@ static int do_copy_files(Partition *p, const char *fs) {
                                                 sfd, ".",
                                                 pfd, fn,
                                                 UID_INVALID, GID_INVALID,
-                                                COPY_REFLINK|COPY_MERGE|COPY_REPLACE|COPY_SIGINT|COPY_HARDLINKS);
+                                                COPY_REFLINK|COPY_MERGE|COPY_REPLACE|COPY_SIGINT|COPY_HARDLINKS|COPY_ALL_XATTRS);
                         } else
                                 r = copy_tree_at(
                                                 sfd, ".",
                                                 tfd, ".",
                                                 UID_INVALID, GID_INVALID,
-                                                COPY_REFLINK|COPY_MERGE|COPY_REPLACE|COPY_SIGINT|COPY_HARDLINKS);
+                                                COPY_REFLINK|COPY_MERGE|COPY_REPLACE|COPY_SIGINT|COPY_HARDLINKS|COPY_ALL_XATTRS);
                         if (r < 0)
                                 return log_error_errno(r, "Failed to copy '%s' to '%s%s': %m", *source, strempty(arg_root), *target);
                 } else {
@@ -2890,7 +2890,7 @@ static int do_copy_files(Partition *p, const char *fs) {
                         if (r < 0)
                                 return log_error_errno(r, "Failed to copy '%s' to '%s%s': %m", *source, strempty(arg_root), *target);
 
-                        (void) copy_xattr(sfd, tfd);
+                        (void) copy_xattr(sfd, tfd, COPY_ALL_XATTRS);
                         (void) copy_access(sfd, tfd);
                         (void) copy_times(sfd, tfd, 0);
                 }
index 00a6a37ff70925d63aaa583254a20d46f1054a19..b01c72aa9ba5282ceffd58d18afda4da76482097 100644 (file)
@@ -1628,6 +1628,7 @@ int btrfs_subvol_snapshot_fd_full(
                                 COPY_REFLINK|
                                 COPY_SAME_MOUNT|
                                 COPY_HARDLINKS|
+                                COPY_ALL_XATTRS|
                                 (FLAGS_SET(flags, BTRFS_SNAPSHOT_SIGINT) ? COPY_SIGINT : 0)|
                                 (FLAGS_SET(flags, BTRFS_SNAPSHOT_SIGTERM) ? COPY_SIGTERM : 0),
                                 progress_path,
index a01b6df1b22354f86ab9dc49f5d2b4d949702752..f27ce252ee4e5ef0bda547f1772b32e081c3df68 100644 (file)
@@ -652,7 +652,7 @@ static int fd_copy_regular(
                 r = -errno;
 
         (void) futimens(fdt, (struct timespec[]) { st->st_atim, st->st_mtim });
-        (void) copy_xattr(fdf, fdt);
+        (void) copy_xattr(fdf, fdt, copy_flags);
 
         if (copy_flags & COPY_FSYNC) {
                 if (fsync(fdt) < 0) {
@@ -945,7 +945,7 @@ static int fd_copy_directory(
                 if (fchmod(fdt, st->st_mode & 07777) < 0)
                         r = -errno;
 
-                (void) copy_xattr(dirfd(d), fdt);
+                (void) copy_xattr(dirfd(d), fdt, copy_flags);
                 (void) futimens(fdt, (struct timespec[]) { st->st_atim, st->st_mtim });
         }
 
@@ -1139,7 +1139,7 @@ int copy_file_fd_full(
 
         if (S_ISREG(fdt)) {
                 (void) copy_times(fdf, fdt, copy_flags);
-                (void) copy_xattr(fdf, fdt);
+                (void) copy_xattr(fdf, fdt, copy_flags);
         }
 
         if (copy_flags & COPY_FSYNC_FULL) {
@@ -1211,7 +1211,7 @@ int copy_file_full(
                 goto fail;
 
         (void) copy_times(fdf, fdt, copy_flags);
-        (void) copy_xattr(fdf, fdt);
+        (void) copy_xattr(fdf, fdt, copy_flags);
 
         if (chattr_mask != 0)
                 (void) chattr_fd(fdt, chattr_flags, chattr_mask & ~CHATTR_EARLY_FL, NULL);
@@ -1399,7 +1399,7 @@ int copy_rights_with_fallback(int fdf, int fdt, const char *patht) {
         return fchmod_and_chown_with_fallback(fdt, patht, st.st_mode & 07777, st.st_uid, st.st_gid);
 }
 
-int copy_xattr(int fdf, int fdt) {
+int copy_xattr(int fdf, int fdt, CopyFlags copy_flags) {
         _cleanup_free_ char *names = NULL;
         int ret = 0, r;
         const char *p;
@@ -1411,7 +1411,7 @@ int copy_xattr(int fdf, int fdt) {
         NULSTR_FOREACH(p, names) {
                 _cleanup_free_ char *value = NULL;
 
-                if (!startswith(p, "user."))
+                if (!(copy_flags & COPY_ALL_XATTRS) && !startswith(p, "user."))
                         continue;
 
                 r = fgetxattr_malloc(fdf, p, &value);
index f8992843e4594f78a52d548d58e8e0c16cfd10b9..a7b45b4fbf4369135670f125fe7daa7a554945d2 100644 (file)
@@ -23,6 +23,7 @@ typedef enum CopyFlags {
         COPY_FSYNC       = 1 << 10, /* fsync() after we are done */
         COPY_FSYNC_FULL  = 1 << 11, /* fsync_full() after we are done */
         COPY_SYNCFS      = 1 << 12, /* syncfs() the *top-level* dir after we are done */
+        COPY_ALL_XATTRS  = 1 << 13, /* Preserve all xattrs when copying, not just those in the user namespace */
 } CopyFlags;
 
 typedef int (*copy_progress_bytes_t)(uint64_t n_bytes, void *userdata);
@@ -72,4 +73,4 @@ int copy_rights_with_fallback(int fdf, int fdt, const char *patht);
 static inline int copy_rights(int fdf, int fdt) {
         return copy_rights_with_fallback(fdf, fdt, NULL); /* no fallback */
 }
-int copy_xattr(int fdf, int fdt);
+int copy_xattr(int fdf, int fdt, CopyFlags copy_flags);