1
0
mirror of https://github.com/systemd/systemd.git synced 2024-10-30 06:25:37 +03:00

shared/copy: add a new flag COPY_ALL_XATTRS

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.
This commit is contained in:
Andrej Lajovic 2021-08-09 01:43:54 +02:00 committed by Lennart Poettering
parent a0c5a3f0c0
commit 23e026de25
9 changed files with 18 additions and 16 deletions

View 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);

View 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)

View 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) {

View 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);

View 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;
}

View 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);
}

View 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,

View 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);

View 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);