repart: when copying files into vfat or similar, do not set ownership
$ mkdir /var/tmp/files $ touch /var/tmp/files/a $ mkdir /var/tmp/conf $ cat >>/var/tmp/conf/esp.conf [Partition] Type=esp Format=vfat CopyFiles=/var/tmp/files:/ $ truncate /var/tmp/disk -s 300M $ sudo systemd-repart --dry-run=no --empty=require --definitions=/var/tmp/conf /var/tmp/disk ... Populating vfat filesystem. Failed to copy '...' to '/run/systemd/mount-root/': Operation not permitted (sd-copy) failed with exit status 1. The issue is that if there's a file owned by non-root and we try to copy it into a newly-created DOS partition, fchown fails: fchown(11</run/systemd/mount-root/...>, 1000, 1000) = -1 EPERM (Operation not permitted) We want to ignore file ownership in such cases, so pass our own UID/GID to copy_tree_at(), which turns the fchown into a noop and let's the operation pass through. Fixes #38863.
This commit is contained in:
@@ -485,6 +485,22 @@ bool fstype_can_fmask_dmask(const char *fstype) {
|
||||
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
|
||||
|
||||
@@ -66,6 +66,7 @@ bool fstype_is_api_vfs(const char *fstype);
|
||||
bool fstype_is_blockdev_backed(const char *fstype);
|
||||
bool fstype_is_ro(const char *fsype);
|
||||
bool fstype_can_discard(const char *fstype);
|
||||
bool fstype_can_ownership(const char *fstype);
|
||||
bool fstype_can_uid_gid(const char *fstype);
|
||||
bool fstype_can_fmask_dmask(const char *fstype);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user