return streq(fstype, "vfat") || (mount_option_supported(fstype, "fmask", "0177") > 0 && mount_option_supported(fstype, "dmask", "0077") > 0);
}
+bool fstype_can_ownership(const char *fstype) {
+ /* File systems which are not known to not support uid/gid ownership.
+ * For some types, this can be a bit murky. So just exclude the ones that for sure
+ * don't support with the current implementations in Linux. */
+
+ return !STR_IN_SET(ASSERT_PTR(fstype),
+ "adfs",
+ "exfat",
+ "fat",
+ "hfs",
+ "hpfs",
+ "msdos",
+ "ntfs",
+ "vfat");
+}
+
bool fstype_can_uid_gid(const char *fstype) {
/* All file systems that have a uid=/gid= mount option that fixates the owners of all files and
* directories, current and future. Note that this does *not* ask the kernel via
return log_oom();
}
+ bool copy_ownership = fstype_can_ownership(p->format);
+
/* 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
return log_error_errno(sfd, "Failed to open source file '%s%s': %m", strempty(arg_copy_source), line->source);
(void) copy_xattr(sfd, NULL, rfd, NULL, COPY_ALL_XATTRS);
- (void) copy_access(sfd, rfd);
+ if (copy_ownership)
+ (void) copy_access(sfd, rfd);
(void) copy_times(sfd, rfd, 0);
break;
}
+ uid_t uid = copy_ownership ? UID_INVALID : getuid();
+ gid_t gid = copy_ownership ? GID_INVALID : getgid();
+
FOREACH_ARRAY(line, copy_files, n_copy_files) {
_cleanup_hashmap_free_ Hashmap *denylist = NULL;
_cleanup_hashmap_free_ Hashmap *subvolumes_by_source_inode = NULL;
r = copy_tree_at(
sfd, ".",
pfd, fn,
- UID_INVALID, GID_INVALID,
+ uid, gid,
line->flags,
denylist, subvolumes_by_source_inode);
} else
r = copy_tree_at(
sfd, ".",
tfd, ".",
- UID_INVALID, GID_INVALID,
+ uid, gid,
line->flags,
denylist, subvolumes_by_source_inode);
if (r < 0)
return log_error_errno(r, "Failed to copy '%s' to '%s%s': %m", line->source, strempty(arg_copy_source), line->target);
(void) copy_xattr(sfd, NULL, tfd, NULL, COPY_ALL_XATTRS);
- (void) copy_access(sfd, tfd);
+ if (copy_ownership)
+ (void) copy_access(sfd, tfd);
(void) copy_times(sfd, tfd, 0);
if (ts != USEC_INFINITY) {