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

View file

@ -35,13 +35,18 @@ int bus_image_method_remove(
void *userdata, void *userdata,
sd_bus_error *error) { sd_bus_error *error) {
_cleanup_close_pair_ int errno_pipe_fd[2] = { -1, -1 };
Image *image = userdata; Image *image = userdata;
Manager *m = image->userdata; Manager *m = image->userdata;
pid_t child;
int r; int r;
assert(message); assert(message);
assert(image); 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( r = bus_verify_polkit_async(
message, message,
CAP_SYS_ADMIN, CAP_SYS_ADMIN,
@ -56,11 +61,35 @@ int bus_image_method_remove(
if (r == 0) if (r == 0)
return 1; /* Will call us back */ return 1; /* Will call us back */
r = image_remove(image); if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0)
if (r < 0) return sd_bus_error_set_errnof(error, errno, "Failed to create pipe: %m");
return r;
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( int bus_image_method_rename(