mirror of
https://github.com/morgan9e/systemd
synced 2026-04-14 08:25:20 +09:00
Merge pull request #19390 from poettering/repart-copy-fixes
repart: fix CopyFiles= corner case when copying into root dir of newly formatted fs
This commit is contained in:
@@ -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);
|
||||
@@ -2846,10 +2847,23 @@ static int do_copy_files(Partition *p, const char *fs) {
|
||||
UID_INVALID, GID_INVALID,
|
||||
COPY_REFLINK|COPY_MERGE|COPY_REPLACE|COPY_SIGINT|COPY_HARDLINKS);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to copy %s%s to %s: %m", strempty(arg_root), *source, *target);
|
||||
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");
|
||||
@@ -2858,13 +2872,13 @@ static int do_copy_files(Partition *p, const char *fs) {
|
||||
if (pfd < 0)
|
||||
return log_error_errno(pfd, "Failed to open parent directory of target: %m");
|
||||
|
||||
tfd = openat(pfd, basename(*target), O_CREAT|O_EXCL|O_WRONLY|O_CLOEXEC, 0700);
|
||||
tfd = openat(pfd, fn, O_CREAT|O_EXCL|O_WRONLY|O_CLOEXEC, 0700);
|
||||
if (tfd < 0)
|
||||
return log_error_errno(errno, "Failed to create target file '%s': %m", *target);
|
||||
|
||||
r = copy_bytes(sfd, tfd, UINT64_MAX, COPY_REFLINK|COPY_SIGINT);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to copy '%s%s' to '%s': %m", strempty(arg_root), *source, *target);
|
||||
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_access(sfd, tfd);
|
||||
|
||||
Reference in New Issue
Block a user