machined: also make image removal operation asynchronous

If we remove a directory image (i.e. not a btrfs snapshot) then things might
get quite expensive, hence run this asynchronous in a forked off process, too.
This commit is contained in:
Lennart Poettering 2016-04-29 20:17:55 +02:00
parent 9a50e3caab
commit 5d2036b5f3
1 changed files with 33 additions and 4 deletions

View File

@ -35,13 +35,18 @@ int bus_image_method_remove(
void *userdata,
sd_bus_error *error) {
_cleanup_close_pair_ int errno_pipe_fd[2] = { -1, -1 };
Image *image = userdata;
Manager *m = image->userdata;
pid_t child;
int r;
assert(message);
assert(image);
if (m->n_operations >= OPERATIONS_MAX)
return sd_bus_error_setf(error, SD_BUS_ERROR_LIMITS_EXCEEDED, "Too many ongoing operations.");
r = bus_verify_polkit_async(
message,
CAP_SYS_ADMIN,
@ -56,11 +61,35 @@ int bus_image_method_remove(
if (r == 0)
return 1; /* Will call us back */
r = image_remove(image);
if (r < 0)
return r;
if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0)
return sd_bus_error_set_errnof(error, errno, "Failed to create pipe: %m");
return sd_bus_reply_method_return(message, NULL);
child = fork();
if (child < 0)
return sd_bus_error_set_errnof(error, errno, "Failed to fork(): %m");
if (child == 0) {
errno_pipe_fd[0] = safe_close(errno_pipe_fd[0]);
r = image_remove(image);
if (r < 0) {
(void) write(errno_pipe_fd[1], &r, sizeof(r));
_exit(EXIT_FAILURE);
}
_exit(EXIT_SUCCESS);
}
errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
r = operation_new(m, child, message, errno_pipe_fd[0]);
if (r < 0) {
(void) sigkill_wait(child);
return r;
}
errno_pipe_fd[0] = -1;
return 1;
}
int bus_image_method_rename(