Merge pull request #3153 from poettering/async-clone
machined: make "clone" asynchronous, and support copy-based fall-back
This commit is contained in:
+33
-17
@@ -305,6 +305,8 @@ static int fd_copy_directory(
|
||||
fdf = openat(df, from, O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
|
||||
else
|
||||
fdf = fcntl(df, F_DUPFD_CLOEXEC, 3);
|
||||
if (fdf < 0)
|
||||
return -errno;
|
||||
|
||||
d = fdopendir(fdf);
|
||||
if (!d)
|
||||
@@ -325,22 +327,6 @@ static int fd_copy_directory(
|
||||
|
||||
r = 0;
|
||||
|
||||
if (created) {
|
||||
struct timespec ut[2] = {
|
||||
st->st_atim,
|
||||
st->st_mtim
|
||||
};
|
||||
|
||||
if (fchown(fdt, st->st_uid, st->st_gid) < 0)
|
||||
r = -errno;
|
||||
|
||||
if (fchmod(fdt, st->st_mode & 07777) < 0)
|
||||
r = -errno;
|
||||
|
||||
(void) futimens(fdt, ut);
|
||||
(void) copy_xattr(dirfd(d), fdt);
|
||||
}
|
||||
|
||||
FOREACH_DIRENT_ALL(de, d, return -errno) {
|
||||
struct stat buf;
|
||||
int q;
|
||||
@@ -376,6 +362,22 @@ static int fd_copy_directory(
|
||||
r = q;
|
||||
}
|
||||
|
||||
if (created) {
|
||||
struct timespec ut[2] = {
|
||||
st->st_atim,
|
||||
st->st_mtim
|
||||
};
|
||||
|
||||
if (fchown(fdt, st->st_uid, st->st_gid) < 0)
|
||||
r = -errno;
|
||||
|
||||
if (fchmod(fdt, st->st_mode & 07777) < 0)
|
||||
r = -errno;
|
||||
|
||||
(void) copy_xattr(dirfd(d), fdt);
|
||||
(void) futimens(fdt, ut);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -407,7 +409,6 @@ int copy_tree(const char *from, const char *to, bool merge) {
|
||||
}
|
||||
|
||||
int copy_directory_fd(int dirfd, const char *to, bool merge) {
|
||||
|
||||
struct stat st;
|
||||
|
||||
assert(dirfd >= 0);
|
||||
@@ -422,6 +423,21 @@ int copy_directory_fd(int dirfd, const char *to, bool merge) {
|
||||
return fd_copy_directory(dirfd, NULL, &st, AT_FDCWD, to, st.st_dev, merge);
|
||||
}
|
||||
|
||||
int copy_directory(const char *from, const char *to, bool merge) {
|
||||
struct stat st;
|
||||
|
||||
assert(from);
|
||||
assert(to);
|
||||
|
||||
if (lstat(from, &st) < 0)
|
||||
return -errno;
|
||||
|
||||
if (!S_ISDIR(st.st_mode))
|
||||
return -ENOTDIR;
|
||||
|
||||
return fd_copy_directory(AT_FDCWD, from, &st, AT_FDCWD, to, st.st_dev, merge);
|
||||
}
|
||||
|
||||
int copy_file_fd(const char *from, int fdt, bool try_reflink) {
|
||||
_cleanup_close_ int fdf = -1;
|
||||
int r;
|
||||
|
||||
@@ -30,6 +30,7 @@ int copy_file_atomic(const char *from, const char *to, mode_t mode, bool replace
|
||||
int copy_tree(const char *from, const char *to, bool merge);
|
||||
int copy_tree_at(int fdf, const char *from, int fdt, const char *to, bool merge);
|
||||
int copy_directory_fd(int dirfd, const char *to, bool merge);
|
||||
int copy_directory(const char *from, const char *to, bool merge);
|
||||
int copy_bytes(int fdf, int fdt, uint64_t max_bytes, bool try_reflink);
|
||||
int copy_times(int fdf, int fdt);
|
||||
int copy_xattr(int fdf, int fdt);
|
||||
|
||||
@@ -528,14 +528,20 @@ int wait_for_terminate_and_warn(const char *name, pid_t pid, bool check_exit_cod
|
||||
return -EPROTO;
|
||||
}
|
||||
|
||||
void sigkill_wait(pid_t *pid) {
|
||||
void sigkill_wait(pid_t pid) {
|
||||
assert(pid > 1);
|
||||
|
||||
if (kill(pid, SIGKILL) > 0)
|
||||
(void) wait_for_terminate(pid, NULL);
|
||||
}
|
||||
|
||||
void sigkill_waitp(pid_t *pid) {
|
||||
if (!pid)
|
||||
return;
|
||||
if (*pid <= 1)
|
||||
return;
|
||||
|
||||
if (kill(*pid, SIGKILL) > 0)
|
||||
(void) wait_for_terminate(*pid, NULL);
|
||||
sigkill_wait(*pid);
|
||||
}
|
||||
|
||||
int kill_and_sigcont(pid_t pid, int sig) {
|
||||
|
||||
@@ -58,8 +58,8 @@ int get_process_ppid(pid_t pid, pid_t *ppid);
|
||||
int wait_for_terminate(pid_t pid, siginfo_t *status);
|
||||
int wait_for_terminate_and_warn(const char *name, pid_t pid, bool check_exit_code);
|
||||
|
||||
void sigkill_wait(pid_t *pid);
|
||||
#define _cleanup_sigkill_wait_ _cleanup_(sigkill_wait)
|
||||
void sigkill_wait(pid_t pid);
|
||||
void sigkill_waitp(pid_t *pid);
|
||||
|
||||
int kill_and_sigcont(pid_t pid, int sig);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user