Merge pull request #26829 from DaanDeMeyer/copy-at
copy: Add more at() helpers
This commit is contained in:
@@ -2753,7 +2753,7 @@ static int offline_security_checks(
|
||||
profile = profile_path;
|
||||
}
|
||||
|
||||
r = copy_file(profile, dropin, 0, 0644, 0, 0, 0);
|
||||
r = copy_file(profile, dropin, 0, 0644, 0);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to copy: %m");
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ static int process_aliases(char *argv[], char *tempdir, char ***ret) {
|
||||
if (!dst)
|
||||
return -ENOMEM;
|
||||
|
||||
r = copy_file(src, dst, 0, 0644, 0, 0, COPY_REFLINK);
|
||||
r = copy_file(src, dst, 0, 0644, COPY_REFLINK);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
@@ -325,7 +325,7 @@ static int process_locale(void) {
|
||||
if (arg_copy_locale && arg_root) {
|
||||
|
||||
(void) mkdir_parents(etc_localeconf, 0755);
|
||||
r = copy_file("/etc/locale.conf", etc_localeconf, 0, 0644, 0, 0, COPY_REFLINK);
|
||||
r = copy_file("/etc/locale.conf", etc_localeconf, 0, 0644, COPY_REFLINK);
|
||||
if (r != -ENOENT) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to copy %s: %m", etc_localeconf);
|
||||
@@ -405,7 +405,7 @@ static int process_keymap(void) {
|
||||
if (arg_copy_keymap && arg_root) {
|
||||
|
||||
(void) mkdir_parents(etc_vconsoleconf, 0755);
|
||||
r = copy_file("/etc/vconsole.conf", etc_vconsoleconf, 0, 0644, 0, 0, COPY_REFLINK);
|
||||
r = copy_file("/etc/vconsole.conf", etc_vconsoleconf, 0, 0644, COPY_REFLINK);
|
||||
if (r != -ENOENT) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to copy %s: %m", etc_vconsoleconf);
|
||||
|
||||
@@ -327,7 +327,6 @@ static int raw_pull_copy_auxiliary_file(
|
||||
*path,
|
||||
local,
|
||||
0644,
|
||||
0, 0,
|
||||
COPY_REFLINK |
|
||||
(FLAGS_SET(i->flags, PULL_FORCE) ? COPY_REPLACE : 0) |
|
||||
(FLAGS_SET(i->flags, PULL_SYNC) ? COPY_FSYNC_FULL : 0));
|
||||
|
||||
@@ -275,7 +275,6 @@ static int tar_pull_make_local_copy(TarPull *i) {
|
||||
i->settings_path,
|
||||
local_settings,
|
||||
0664,
|
||||
0, 0,
|
||||
COPY_REFLINK |
|
||||
(FLAGS_SET(i->flags, PULL_FORCE) ? COPY_REPLACE : 0) |
|
||||
(FLAGS_SET(i->flags, PULL_SYNC) ? COPY_FSYNC_FULL : 0));
|
||||
|
||||
@@ -222,10 +222,11 @@ static void managed_journal_file_set_offline_internal(ManagedJournalFile *f) {
|
||||
|
||||
log_debug_errno(r, "Failed to re-enable copy-on-write for %s: %m, rewriting file", f->file->path);
|
||||
|
||||
r = copy_file_atomic(FORMAT_PROC_FD_PATH(f->file->fd), f->file->path, f->file->mode,
|
||||
0,
|
||||
FS_NOCOW_FL,
|
||||
COPY_REPLACE | COPY_FSYNC | COPY_HOLES | COPY_ALL_XATTRS);
|
||||
r = copy_file_atomic_full(FORMAT_PROC_FD_PATH(f->file->fd), f->file->path, f->file->mode,
|
||||
0,
|
||||
FS_NOCOW_FL,
|
||||
COPY_REPLACE | COPY_FSYNC | COPY_HOLES | COPY_ALL_XATTRS,
|
||||
NULL, NULL);
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Failed to rewrite %s: %m", f->file->path);
|
||||
continue;
|
||||
|
||||
+7
-4
@@ -2034,7 +2034,7 @@ static int setup_timezone(const char *dest) {
|
||||
|
||||
case TIMEZONE_COPY:
|
||||
/* If mounting failed, try to copy */
|
||||
r = copy_file_atomic("/etc/localtime", where, 0644, 0, 0, COPY_REFLINK|COPY_REPLACE);
|
||||
r = copy_file_atomic("/etc/localtime", where, 0644, COPY_REFLINK|COPY_REPLACE);
|
||||
if (r < 0) {
|
||||
log_full_errno(IN_SET(r, -EROFS, -EACCES, -EPERM) ? LOG_DEBUG : LOG_WARNING, r,
|
||||
"Failed to copy /etc/localtime to %s, ignoring: %m", where);
|
||||
@@ -2168,9 +2168,9 @@ static int setup_resolv_conf(const char *dest) {
|
||||
}
|
||||
|
||||
if (IN_SET(m, RESOLV_CONF_REPLACE_HOST, RESOLV_CONF_REPLACE_STATIC, RESOLV_CONF_REPLACE_UPLINK, RESOLV_CONF_REPLACE_STUB))
|
||||
r = copy_file_atomic(what, where, 0644, 0, 0, COPY_REFLINK|COPY_REPLACE);
|
||||
r = copy_file_atomic(what, where, 0644, COPY_REFLINK|COPY_REPLACE);
|
||||
else
|
||||
r = copy_file(what, where, O_TRUNC|O_NOFOLLOW, 0644, 0, 0, COPY_REFLINK);
|
||||
r = copy_file(what, where, O_TRUNC|O_NOFOLLOW, 0644, COPY_REFLINK);
|
||||
if (r < 0) {
|
||||
/* If the file already exists as symlink, let's suppress the warning, under the assumption that
|
||||
* resolved or something similar runs inside and the symlink points there.
|
||||
@@ -5697,7 +5697,10 @@ static int run(int argc, char *argv[]) {
|
||||
|
||||
{
|
||||
BLOCK_SIGNALS(SIGINT);
|
||||
r = copy_file(arg_image, np, O_EXCL, arg_read_only ? 0400 : 0600, FS_NOCOW_FL, FS_NOCOW_FL, COPY_REFLINK|COPY_CRTIME|COPY_SIGINT);
|
||||
r = copy_file_full(arg_image, np, O_EXCL, arg_read_only ? 0400 : 0600,
|
||||
FS_NOCOW_FL, FS_NOCOW_FL,
|
||||
COPY_REFLINK|COPY_CRTIME|COPY_SIGINT,
|
||||
NULL, NULL);
|
||||
}
|
||||
if (r == -EINTR) {
|
||||
log_error_errno(r, "Interrupted while copying image file to %s, removed again.", np);
|
||||
|
||||
@@ -1072,7 +1072,7 @@ static int install_profile_dropin(
|
||||
|
||||
if (flags & PORTABLE_PREFER_COPY) {
|
||||
|
||||
r = copy_file_atomic(from, dropin, 0644, 0, 0, COPY_REFLINK);
|
||||
r = copy_file_atomic(from, dropin, 0644, COPY_REFLINK);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to copy %s %s %s: %m", from, special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), dropin);
|
||||
|
||||
|
||||
+1
-1
@@ -152,7 +152,7 @@ static int move_file(PStoreEntry *pe, const char *subdir1, const char *subdir2)
|
||||
r = mkdir_parents(ofd_path, 0755);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to create directory %s: %m", ofd_path);
|
||||
r = copy_file_atomic(ifd_path, ofd_path, 0600, 0, 0, COPY_REPLACE);
|
||||
r = copy_file_atomic(ifd_path, ofd_path, 0600, COPY_REPLACE);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to copy_file_atomic: %s to %s", ifd_path, ofd_path);
|
||||
}
|
||||
|
||||
+13
-9
@@ -1293,7 +1293,8 @@ int copy_directory_full(
|
||||
return 0;
|
||||
}
|
||||
|
||||
int copy_file_fd_full(
|
||||
int copy_file_fd_at_full(
|
||||
int dir_fdf,
|
||||
const char *from,
|
||||
int fdt,
|
||||
CopyFlags copy_flags,
|
||||
@@ -1304,10 +1305,11 @@ int copy_file_fd_full(
|
||||
struct stat st;
|
||||
int r;
|
||||
|
||||
assert(dir_fdf >= 0 || dir_fdf == AT_FDCWD);
|
||||
assert(from);
|
||||
assert(fdt >= 0);
|
||||
|
||||
fdf = open(from, O_RDONLY|O_CLOEXEC|O_NOCTTY);
|
||||
fdf = openat(dir_fdf, from, O_RDONLY|O_CLOEXEC|O_NOCTTY);
|
||||
if (fdf < 0)
|
||||
return -errno;
|
||||
|
||||
@@ -1435,8 +1437,10 @@ fail:
|
||||
return r;
|
||||
}
|
||||
|
||||
int copy_file_atomic_full(
|
||||
int copy_file_atomic_at_full(
|
||||
int dir_fdf,
|
||||
const char *from,
|
||||
int dir_fdt,
|
||||
const char *to,
|
||||
mode_t mode,
|
||||
unsigned chattr_flags,
|
||||
@@ -1453,11 +1457,11 @@ int copy_file_atomic_full(
|
||||
assert(to);
|
||||
|
||||
if (copy_flags & COPY_MAC_CREATE) {
|
||||
r = mac_selinux_create_file_prepare(to, S_IFREG);
|
||||
r = mac_selinux_create_file_prepare_at(dir_fdt, to, S_IFREG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
fdt = open_tmpfile_linkable(to, O_WRONLY|O_CLOEXEC, &t);
|
||||
fdt = open_tmpfile_linkable_at(dir_fdt, to, O_WRONLY|O_CLOEXEC, &t);
|
||||
if (copy_flags & COPY_MAC_CREATE)
|
||||
mac_selinux_create_file_clear();
|
||||
if (fdt < 0)
|
||||
@@ -1466,7 +1470,7 @@ int copy_file_atomic_full(
|
||||
if (chattr_mask != 0)
|
||||
(void) chattr_fd(fdt, chattr_flags, chattr_mask & CHATTR_EARLY_FL, NULL);
|
||||
|
||||
r = copy_file_fd_full(from, fdt, copy_flags, progress_bytes, userdata);
|
||||
r = copy_file_fd_at_full(dir_fdf, from, fdt, copy_flags, progress_bytes, userdata);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -1479,7 +1483,7 @@ int copy_file_atomic_full(
|
||||
return -errno;
|
||||
}
|
||||
|
||||
r = link_tmpfile(fdt, t, to, copy_flags & COPY_REPLACE);
|
||||
r = link_tmpfile_at(fdt, dir_fdt, t, to, copy_flags & COPY_REPLACE);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -1494,7 +1498,7 @@ int copy_file_atomic_full(
|
||||
|
||||
if (copy_flags & COPY_FSYNC_FULL) {
|
||||
/* Sync the parent directory */
|
||||
r = fsync_parent_at(AT_FDCWD, to);
|
||||
r = fsync_parent_at(dir_fdt, to);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
}
|
||||
@@ -1502,7 +1506,7 @@ int copy_file_atomic_full(
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
(void) unlink(to);
|
||||
(void) unlinkat(dir_fdt, to, 0);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
+21
-9
@@ -41,25 +41,37 @@ typedef enum DenyType {
|
||||
typedef int (*copy_progress_bytes_t)(uint64_t n_bytes, void *userdata);
|
||||
typedef int (*copy_progress_path_t)(const char *path, const struct stat *st, void *userdata);
|
||||
|
||||
int copy_file_fd_full(const char *from, int to, CopyFlags copy_flags, copy_progress_bytes_t progress, void *userdata);
|
||||
int copy_file_fd_at_full(int dir_fdf, const char *from, int to, CopyFlags copy_flags, copy_progress_bytes_t progress, void *userdata);
|
||||
static inline int copy_file_fd_at(int dir_fdf, const char *from, int to, CopyFlags copy_flags, copy_progress_bytes_t progress, void *userdata) {
|
||||
return copy_file_fd_at_full(dir_fdf, from, to, copy_flags, progress, userdata);
|
||||
}
|
||||
static inline int copy_file_fd_full(const char *from, int to, CopyFlags copy_flags) {
|
||||
return copy_file_fd_at_full(AT_FDCWD, from, to, copy_flags, NULL, NULL);
|
||||
}
|
||||
static inline int copy_file_fd(const char *from, int to, CopyFlags copy_flags) {
|
||||
return copy_file_fd_full(from, to, copy_flags, NULL, NULL);
|
||||
return copy_file_fd_at(AT_FDCWD, from, to, copy_flags, NULL, NULL);
|
||||
}
|
||||
|
||||
int copy_file_at_full(int dir_fdf, const char *from, int dir_fdt, const char *to, int open_flags, mode_t mode, unsigned chattr_flags, unsigned chattr_mask, CopyFlags copy_flags, copy_progress_bytes_t progress, void *userdata);
|
||||
static inline int copy_file_at(int dir_fdf, const char *from, int dir_fdt, const char *to, int open_flags, mode_t mode, unsigned chattr_flags, unsigned chattr_mask, CopyFlags copy_flags) {
|
||||
return copy_file_at_full(dir_fdf, from, dir_fdt, to, open_flags, mode, chattr_flags, chattr_mask, copy_flags, NULL, NULL);
|
||||
static inline int copy_file_at(int dir_fdf, const char *from, int dir_fdt, const char *to, int open_flags, mode_t mode, CopyFlags copy_flags) {
|
||||
return copy_file_at_full(dir_fdf, from, dir_fdt, to, open_flags, mode, 0, 0, copy_flags, NULL, NULL);
|
||||
}
|
||||
static inline int copy_file_full(const char *from, const char *to, int open_flags, mode_t mode, unsigned chattr_flags, unsigned chattr_mask, CopyFlags copy_flags, copy_progress_bytes_t progress, void *userdata) {
|
||||
return copy_file_at_full(AT_FDCWD, from, AT_FDCWD, to, open_flags, mode, chattr_flags, chattr_mask, copy_flags, progress, userdata);
|
||||
}
|
||||
static inline int copy_file(const char *from, const char *to, int open_flags, mode_t mode, unsigned chattr_flags, unsigned chattr_mask, CopyFlags copy_flags) {
|
||||
return copy_file_at(AT_FDCWD, from, AT_FDCWD, to, open_flags, mode, chattr_flags, chattr_mask, copy_flags);
|
||||
static inline int copy_file(const char *from, const char *to, int open_flags, mode_t mode, CopyFlags copy_flags) {
|
||||
return copy_file_at(AT_FDCWD, from, AT_FDCWD, to, open_flags, mode, copy_flags);
|
||||
}
|
||||
|
||||
int copy_file_atomic_full(const char *from, const char *to, mode_t mode, unsigned chattr_flags, unsigned chattr_mask, CopyFlags copy_flags, copy_progress_bytes_t progress, void *userdata);
|
||||
static inline int copy_file_atomic(const char *from, const char *to, mode_t mode, unsigned chattr_flags, unsigned chattr_mask, CopyFlags copy_flags) {
|
||||
return copy_file_atomic_full(from, to, mode, chattr_flags, chattr_mask, copy_flags, NULL, NULL);
|
||||
int copy_file_atomic_at_full(int dir_fdf, const char *from, int dir_fdt, const char *to, mode_t mode, unsigned chattr_flags, unsigned chattr_mask, CopyFlags copy_flags, copy_progress_bytes_t progress, void *userdata);
|
||||
static inline int copy_file_atomic_at(int dir_fdf, const char *from, int dir_fdt, const char *to, mode_t mode, CopyFlags copy_flags) {
|
||||
return copy_file_atomic_at_full(dir_fdf, from, dir_fdt, to, mode, 0, 0, copy_flags, NULL, NULL);
|
||||
}
|
||||
static inline int copy_file_atomic_full(const char *from, const char *to, mode_t mode, unsigned chattr_flags, unsigned chattr_mask, CopyFlags copy_flags, copy_progress_bytes_t progress, void *userdata) {
|
||||
return copy_file_atomic_at_full(AT_FDCWD, from, AT_FDCWD, to, mode, 0, 0, copy_flags, NULL, NULL);
|
||||
}
|
||||
static inline int copy_file_atomic(const char *from, const char *to, mode_t mode, CopyFlags copy_flags) {
|
||||
return copy_file_atomic_full(from, to, mode, 0, 0, copy_flags, NULL, NULL);
|
||||
}
|
||||
|
||||
int copy_tree_at_full(int fdf, const char *from, int fdt, const char *to, uid_t override_uid, gid_t override_gid, CopyFlags copy_flags, Hashmap *denylist, copy_progress_path_t progress_path, copy_progress_bytes_t progress_bytes, void *userdata);
|
||||
|
||||
@@ -850,7 +850,7 @@ static int clone_auxiliary_file(const char *path, const char *new_name, const ch
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return copy_file_atomic(path, rs, 0664, 0, 0, COPY_REFLINK);
|
||||
return copy_file_atomic(path, rs, 0664, COPY_REFLINK);
|
||||
}
|
||||
|
||||
int image_clone(Image *i, const char *new_name, bool read_only) {
|
||||
@@ -911,7 +911,8 @@ int image_clone(Image *i, const char *new_name, bool read_only) {
|
||||
case IMAGE_RAW:
|
||||
new_path = strjoina("/var/lib/machines/", new_name, ".raw");
|
||||
|
||||
r = copy_file_atomic(i->path, new_path, read_only ? 0444 : 0644, FS_NOCOW_FL, FS_NOCOW_FL, COPY_REFLINK|COPY_CRTIME);
|
||||
r = copy_file_atomic_full(i->path, new_path, read_only ? 0444 : 0644, FS_NOCOW_FL, FS_NOCOW_FL,
|
||||
COPY_REFLINK|COPY_CRTIME, NULL, NULL);
|
||||
break;
|
||||
|
||||
case IMAGE_BLOCK:
|
||||
|
||||
@@ -138,7 +138,7 @@ static int create_edit_temp_file(EditFile *e) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = copy_file(e->original_path, temp, 0, 0644, 0, 0, COPY_REFLINK);
|
||||
r = copy_file(e->original_path, temp, 0, 0644, COPY_REFLINK);
|
||||
if (r == -ENOENT) {
|
||||
r = touch(temp);
|
||||
mac_selinux_create_file_clear();
|
||||
|
||||
@@ -39,7 +39,7 @@ TEST(copy_file) {
|
||||
|
||||
assert_se(write_string_file(fn, "foo bar bar bar foo", WRITE_STRING_FILE_CREATE) == 0);
|
||||
|
||||
assert_se(copy_file(fn, fn_copy, 0, 0644, 0, 0, COPY_REFLINK) == 0);
|
||||
assert_se(copy_file(fn, fn_copy, 0, 0644, COPY_REFLINK) == 0);
|
||||
|
||||
assert_se(read_full_file(fn_copy, &buf, &sz) == 0);
|
||||
assert_se(streq(buf, "foo bar bar bar foo\n"));
|
||||
@@ -366,13 +366,13 @@ TEST(copy_atomic) {
|
||||
|
||||
q = strjoina(p, "/fstab");
|
||||
|
||||
r = copy_file_atomic("/etc/fstab", q, 0644, 0, 0, COPY_REFLINK);
|
||||
r = copy_file_atomic("/etc/fstab", q, 0644, COPY_REFLINK);
|
||||
if (r == -ENOENT || ERRNO_IS_PRIVILEGE(r))
|
||||
return;
|
||||
|
||||
assert_se(copy_file_atomic("/etc/fstab", q, 0644, 0, 0, COPY_REFLINK) == -EEXIST);
|
||||
assert_se(copy_file_atomic("/etc/fstab", q, 0644, COPY_REFLINK) == -EEXIST);
|
||||
|
||||
assert_se(copy_file_atomic("/etc/fstab", q, 0644, 0, 0, COPY_REPLACE) >= 0);
|
||||
assert_se(copy_file_atomic("/etc/fstab", q, 0644, COPY_REPLACE) >= 0);
|
||||
}
|
||||
|
||||
TEST(copy_proc) {
|
||||
@@ -383,7 +383,7 @@ TEST(copy_proc) {
|
||||
|
||||
assert_se(mkdtemp_malloc(NULL, &p) >= 0);
|
||||
assert_se(f = path_join(p, "version"));
|
||||
assert_se(copy_file("/proc/version", f, 0, MODE_INVALID, 0, 0, 0) >= 0);
|
||||
assert_se(copy_file("/proc/version", f, 0, MODE_INVALID, 0) >= 0);
|
||||
|
||||
assert_se(read_one_line_file("/proc/version", &a) >= 0);
|
||||
assert_se(read_one_line_file(f, &b) >= 0);
|
||||
|
||||
@@ -283,7 +283,7 @@ static void test_exec_workingdirectory(Manager *m) {
|
||||
static void test_exec_execsearchpath(Manager *m) {
|
||||
assert_se(mkdir_p("/tmp/test-exec_execsearchpath", 0755) >= 0);
|
||||
|
||||
assert_se(copy_file("/bin/ls", "/tmp/test-exec_execsearchpath/ls_temp", 0, 0777, 0, 0, COPY_REPLACE) >= 0);
|
||||
assert_se(copy_file("/bin/ls", "/tmp/test-exec_execsearchpath/ls_temp", 0, 0777, COPY_REPLACE) >= 0);
|
||||
|
||||
test(m, "exec-execsearchpath.service", 0, CLD_EXITED);
|
||||
|
||||
|
||||
@@ -997,7 +997,7 @@ TEST(conservative_rename) {
|
||||
assert_se(access(q, F_OK) < 0 && errno == ENOENT);
|
||||
|
||||
/* Check that a manual copy is detected */
|
||||
assert_se(copy_file(p, q, 0, MODE_INVALID, 0, 0, COPY_REFLINK) >= 0);
|
||||
assert_se(copy_file(p, q, 0, MODE_INVALID, COPY_REFLINK) >= 0);
|
||||
assert_se(conservative_renameat(AT_FDCWD, q, AT_FDCWD, p) == 0);
|
||||
assert_se(access(q, F_OK) < 0 && errno == ENOENT);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user