Merge pull request #13091 from poettering/nspawn-copy

nspawn: allow nspawn's copy operation to be abortable via C-c
This commit is contained in:
Lennart Poettering
2019-07-17 14:10:06 +02:00
committed by GitHub
5 changed files with 80 additions and 29 deletions
+1 -1
View File
@@ -1624,7 +1624,7 @@ int btrfs_subvol_snapshot_fd_full(
} else if (r < 0)
return r;
r = copy_directory_fd_full(old_fd, new_path, COPY_MERGE|COPY_REFLINK|COPY_SAME_MOUNT, progress_path, progress_bytes, userdata);
r = copy_directory_fd_full(old_fd, new_path, COPY_MERGE|COPY_REFLINK|COPY_SAME_MOUNT|(FLAGS_SET(flags, BTRFS_SNAPSHOT_SIGINT) ? COPY_SIGINT : 0), progress_path, progress_bytes, userdata);
if (r < 0)
goto fallback_fail;
+1
View File
@@ -34,6 +34,7 @@ typedef enum BtrfsSnapshotFlags {
BTRFS_SNAPSHOT_QUOTA = 1 << 3,
BTRFS_SNAPSHOT_FALLBACK_DIRECTORY = 1 << 4, /* If the destination doesn't support subvolumes, reflink/copy instead */
BTRFS_SNAPSHOT_FALLBACK_IMMUTABLE = 1 << 5, /* When we can't create a subvolume, use the FS_IMMUTABLE attribute for indicating read-only */
BTRFS_SNAPSHOT_SIGINT = 1 << 6, /* Check for SIGINT regularly, and return EINTR if seen */
} BtrfsSnapshotFlags;
typedef enum BtrfsRemoveFlags {
+34 -1
View File
@@ -86,6 +86,22 @@ static int fd_is_nonblock_pipe(int fd) {
return FLAGS_SET(flags, O_NONBLOCK) ? FD_IS_NONBLOCKING_PIPE : FD_IS_BLOCKING_PIPE;
}
static int sigint_pending(void) {
sigset_t ss;
assert_se(sigemptyset(&ss) >= 0);
assert_se(sigaddset(&ss, SIGINT) >= 0);
if (sigtimedwait(&ss, NULL, &(struct timespec) { 0, 0 }) < 0) {
if (errno == EAGAIN)
return false;
return -errno;
}
return true;
}
int copy_bytes_full(
int fdf, int fdt,
uint64_t max_bytes,
@@ -174,6 +190,14 @@ int copy_bytes_full(
if (max_bytes <= 0)
return 1; /* return > 0 if we hit the max_bytes limit */
if (FLAGS_SET(copy_flags, COPY_SIGINT)) {
r = sigint_pending();
if (r < 0)
return r;
if (r > 0)
return -EINTR;
}
if (max_bytes != UINT64_MAX && m > max_bytes)
m = max_bytes;
@@ -559,6 +583,14 @@ static int fd_copy_directory(
if (dot_or_dot_dot(de->d_name))
continue;
if (FLAGS_SET(copy_flags, COPY_SIGINT)) {
r = sigint_pending();
if (r < 0)
return r;
if (r > 0)
return -EINTR;
}
if (fstatat(dirfd(d), de->d_name, &buf, AT_SYMLINK_NOFOLLOW) < 0) {
r = -errno;
continue;
@@ -618,9 +650,10 @@ static int fd_copy_directory(
else
q = -EOPNOTSUPP;
if (q == -EINTR) /* Propagate SIGINT up instantly */
return q;
if (q == -EEXIST && (copy_flags & COPY_MERGE))
q = 0;
if (q < 0)
r = q;
}
+1
View File
@@ -15,6 +15,7 @@ typedef enum CopyFlags {
COPY_SAME_MOUNT = 1 << 3, /* Don't descend recursively into other file systems, across mount point boundaries */
COPY_MERGE_EMPTY = 1 << 4, /* Merge an existing, empty directory with our new tree to copy */
COPY_CRTIME = 1 << 5, /* Generate a user.crtime_usec xattr off the source crtime if there is one, on copying */
COPY_SIGINT = 1 << 6, /* Check for SIGINT regularly and return EINTR if seen (caller needs to block SIGINT) */
} CopyFlags;
typedef int (*copy_progress_bytes_t)(uint64_t n_bytes, void *userdata);