mirror of
https://github.com/systemd/systemd.git
synced 2025-03-28 02:50:16 +03:00
mkfs-util: Skip non files/directories when calling mcopy
Only files and directories are supported by vfat. When we pass a symlink to mcopy, it will try to dereference them and copy what the symlink points at into the vfat partition instead. Let's avoid this by skipping all unsupported file types when establishing the list of top level targets that mcopy should copy. We also use RECURSE_DIR_SORT everywhere when iterating directories to make things more reproducible.
This commit is contained in:
parent
a0a4c57818
commit
c75cf0164c
@ -129,7 +129,8 @@ static int setup_userns(uid_t uid, gid_t gid) {
|
||||
|
||||
static int do_mcopy(const char *node, const char *root) {
|
||||
_cleanup_strv_free_ char **argv = NULL;
|
||||
_cleanup_closedir_ DIR *rootdir = NULL;
|
||||
_cleanup_close_ int rfd = -1;
|
||||
_cleanup_free_ DirectoryEntries *de = NULL;
|
||||
struct stat st;
|
||||
int r;
|
||||
|
||||
@ -147,15 +148,24 @@ static int do_mcopy(const char *node, const char *root) {
|
||||
/* mcopy copies the top level directory instead of everything in it so we have to pass all
|
||||
* the subdirectories to mcopy instead to end up with the correct directory structure. */
|
||||
|
||||
rootdir = opendir(root);
|
||||
if (!rootdir)
|
||||
return log_error_errno(errno, "Failed to open directory '%s'", root);
|
||||
rfd = open(root, O_RDONLY|O_DIRECTORY|O_CLOEXEC);
|
||||
if (rfd < 0)
|
||||
return log_error_errno(errno, "Failed to open directory '%s': %m", root);
|
||||
|
||||
FOREACH_DIRENT(de, rootdir, return -errno) {
|
||||
char *p = path_join(root, de->d_name);
|
||||
r = readdir_all(rfd, RECURSE_DIR_SORT|RECURSE_DIR_ENSURE_TYPE, &de);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to read '%s' contents: %m", root);
|
||||
|
||||
for (size_t i = 0; i < de->n_entries; i++) {
|
||||
char *p = path_join(root, de->entries[i]->d_name);
|
||||
if (!p)
|
||||
return log_oom();
|
||||
|
||||
if (!IN_SET(de->entries[i]->d_type, DT_REG, DT_DIR)) {
|
||||
log_debug("%s is not a file/directory which are the only file types supported by vfat, ignoring", p);
|
||||
continue;
|
||||
}
|
||||
|
||||
r = strv_consume(&argv, TAKE_PTR(p));
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
@ -165,7 +175,7 @@ static int do_mcopy(const char *node, const char *root) {
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
if (fstat(dirfd(rootdir), &st) < 0)
|
||||
if (fstat(rfd, &st) < 0)
|
||||
return log_error_errno(errno, "Failed to stat '%s': %m", root);
|
||||
|
||||
r = safe_fork("(mcopy)", FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG|FORK_LOG|FORK_WAIT|FORK_STDOUT_TO_STDERR|FORK_NEW_USERNS|FORK_CLOSE_ALL_FDS, NULL);
|
||||
@ -262,7 +272,7 @@ static int make_protofile(const char *root, char **ret) {
|
||||
"0 0\n"
|
||||
"d--755 0 0\n", f);
|
||||
|
||||
r = recurse_dir_at(AT_FDCWD, root, STATX_TYPE|STATX_MODE, UINT_MAX, 0, protofile_print_item, f);
|
||||
r = recurse_dir_at(AT_FDCWD, root, STATX_TYPE|STATX_MODE, UINT_MAX, RECURSE_DIR_SORT, protofile_print_item, f);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to recurse through %s: %m", root);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user