mirror of
https://github.com/systemd/systemd.git
synced 2024-11-01 09:21:26 +03:00
repart: don't try to extract directory of root dir when copying directories
It's OK to specify the root dir as target directory when copying directories. However, in that case path_extract_filename() is going to fail, because the root dir simply has not filename. Let's address that by moving the call further down into the loop, when we made sure that the target dir doesn't exist yet (the root dir always exists, hence this check is sufficient). Moreover, in the branch for copying regular files, also move the calls down, and generate friendly error messages in case people try to overwrite dirs with regular files (and the root dir is just a special case of a dir). Altogether this makes CopyFiles=/some/place:/ work, i.e. copying some dir on the host into the root dir of the newly created fs. Previously this would fail with an error about the inability to extract a filename from "/", needlessly.
This commit is contained in:
parent
e28190673c
commit
f21a3a82fb
@ -2801,15 +2801,6 @@ static int do_copy_files(Partition *p, const char *fs) {
|
||||
|
||||
STRV_FOREACH_PAIR(source, target, p->copy_files) {
|
||||
_cleanup_close_ int sfd = -1, pfd = -1, tfd = -1;
|
||||
_cleanup_free_ char *dn = NULL, *fn = NULL;
|
||||
|
||||
r = path_extract_directory(*target, &dn);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to extract directory from '%s': %m", *target);
|
||||
|
||||
r = path_extract_filename(*target, &fn);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to extract filename from '%s': %m", *target);
|
||||
|
||||
sfd = chase_symlinks_and_open(*source, arg_root, CHASE_PREFIX_ROOT|CHASE_WARN, O_CLOEXEC|O_NOCTTY, NULL);
|
||||
if (sfd < 0)
|
||||
@ -2823,9 +2814,19 @@ static int do_copy_files(Partition *p, const char *fs) {
|
||||
/* We are looking at a directory */
|
||||
tfd = chase_symlinks_and_open(*target, fs, CHASE_PREFIX_ROOT|CHASE_WARN, O_RDONLY|O_DIRECTORY|O_CLOEXEC, NULL);
|
||||
if (tfd < 0) {
|
||||
_cleanup_free_ char *dn = NULL, *fn = NULL;
|
||||
|
||||
if (tfd != -ENOENT)
|
||||
return log_error_errno(tfd, "Failed to open target directory '%s': %m", *target);
|
||||
|
||||
r = path_extract_filename(*target, &fn);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to extract filename from '%s': %m", *target);
|
||||
|
||||
r = path_extract_directory(*target, &dn);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to extract directory from '%s': %m", *target);
|
||||
|
||||
r = mkdir_p_root(fs, dn, UID_INVALID, GID_INVALID, 0755);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to create parent directory '%s': %m", dn);
|
||||
@ -2848,8 +2849,21 @@ 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);
|
||||
} else {
|
||||
_cleanup_free_ char *dn = NULL, *fn = NULL;
|
||||
|
||||
/* We are looking at a regular file */
|
||||
|
||||
r = path_extract_filename(*target, &fn);
|
||||
if (r == -EADDRNOTAVAIL || r == O_DIRECTORY)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EISDIR),
|
||||
"Target path '%s' refers to a directory, but source path '%s' refers to regular file, can't copy.", *target, *source);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to extract filename from '%s': %m", *target);
|
||||
|
||||
r = path_extract_directory(*target, &dn);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to extract directory from '%s': %m", *target);
|
||||
|
||||
r = mkdir_p_root(fs, dn, UID_INVALID, GID_INVALID, 0755);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to create parent directory: %m");
|
||||
|
Loading…
Reference in New Issue
Block a user