From 7affe9296e81c253fbe554b2d31dcd4cf4fad72a Mon Sep 17 00:00:00 2001 From: Maria Matejka Date: Tue, 10 Sep 2024 11:16:49 +0200 Subject: [PATCH] Flock: Added a proper shutdown routine requestable also from CLI --- flock/ctl.c | 4 +++- flock/flock.c | 41 ++++++++++++++++++++++++++++++++--------- flock/flock.h | 8 ++++++++ flock/hypervisor.c | 32 +++++++++++++++++++++++++++++--- 4 files changed, 72 insertions(+), 13 deletions(-) diff --git a/flock/ctl.c b/flock/ctl.c index d94bae75..ea34a7fe 100644 --- a/flock/ctl.c +++ b/flock/ctl.c @@ -1,5 +1,6 @@ #include "lib/birdlib.h" #include "lib/string.h" +#include "lib/io-loop.h" #include "flock/flock.h" @@ -164,7 +165,8 @@ hcs_parse(struct cbor_parser_context *ctx, const byte *buf, s64 size) if ((ctx->type != 7) || (ctx->value != 22)) CBOR_PARSER_ERROR("Expected null, got %u-%u", ctx->type, ctx->value); - log(L_INFO "Requested shutdown"); + log(L_INFO "Requested shutdown via CLI"); + ev_send_loop(&main_birdloop, &poweroff_event); ctx->major_state = 1; break; diff --git a/flock/flock.c b/flock/flock.c index 6ad8c445..daf8dc8c 100644 --- a/flock/flock.c +++ b/flock/flock.c @@ -1,7 +1,7 @@ #include "flock/flock.h" +#include "lib/obstacle.h" #include "lib/string.h" - #include "lib/timer.h" #include "sysdep/unix/unix.h" #include "sysdep/unix/io-loop.h" @@ -23,12 +23,10 @@ struct flock_config flock_config; /** - * Signal handling - * - * We wanna behave as the init process inside the newly create PID namespace - * which means that the signals have different meanings than for other processes, - * For more information, see pid_namespaces(7). + * Shutdown routines */ +event_list shutdown_event_list; +struct shutdown_placeholder shutdown_placeholder; static void reboot_event_hook(void *data UNUSED) @@ -39,12 +37,29 @@ reboot_event_hook(void *data UNUSED) static void poweroff_event_hook(void *data UNUSED) { - log(L_INFO "Shutdown requested. TODO: properly clean up"); + log(L_INFO "Shutdown requested."); + ev_run_list(&shutdown_event_list); +} + +event reboot_event = { .hook = reboot_event_hook }, + poweroff_event = { .hook = poweroff_event_hook }; + +callback shutdown_done_callback; + +static void +shutdown_done(callback *c UNUSED) +{ + log(L_INFO "Shutdown finished."); exit(0); } -static event reboot_event = { .hook = reboot_event_hook }, - poweroff_event = { .hook = poweroff_event_hook }; +/** + * Signal handling + * + * We wanna behave as the init process inside the newly create PID namespace + * which means that the signals have different meanings than for other processes, + * For more information, see pid_namespaces(7). + */ static void hypervisor_reboot_sighandler(int signo UNUSED) @@ -109,6 +124,14 @@ main(int argc, char **argv, char **argh UNUSED) ev_init_list(&global_event_list, &main_birdloop, "Global event list"); ev_init_list(&global_work_list, &main_birdloop, "Global work list"); ev_init_list(&main_birdloop.event_list, &main_birdloop, "Global fast event list"); + + /* Shutdown hooks */ + ev_init_list(&shutdown_event_list, &main_birdloop, "Shutdown event list"); + callback_init(&shutdown_done_callback, shutdown_done, &main_birdloop); + obstacle_target_init( + &shutdown_placeholder.obstacles, + &shutdown_done_callback, &root_pool, "Shutdown"); + boot_time = current_time(); log_switch(1, NULL, NULL); diff --git a/flock/flock.h b/flock/flock.h index 4a7956fa..2f83c558 100644 --- a/flock/flock.h +++ b/flock/flock.h @@ -3,6 +3,8 @@ #ifndef INCLUDE_FLOCK_H #define INCLUDE_FLOCK_H #include "lib/birdlib.h" +#include "lib/event.h" +#include "lib/obstacle.h" #include "lib/resource.h" void hypervisor_exposed_fork(void); @@ -22,4 +24,10 @@ void hcs_parser_cleanup(struct cbor_parser_context *ctx); const char *hcs_error(struct cbor_parser_context *ctx); bool hcs_complete(struct cbor_parser_context *ctx); +extern event reboot_event, poweroff_event; +extern event_list shutdown_event_list; + +extern struct shutdown_placeholder { + struct obstacle_target obstacles; +} shutdown_placeholder; #endif diff --git a/flock/hypervisor.c b/flock/hypervisor.c index 2b52396d..a6e87b7d 100644 --- a/flock/hypervisor.c +++ b/flock/hypervisor.c @@ -12,7 +12,10 @@ * Main control socket **/ -pool *hypervisor_control_socket_pool; +static struct birdloop *hcs_loop; +static pool *hcs_pool; + +OBSREF(struct shutdown_placeholder) hcs_shutdown_placeholder; static int hcs_rx(sock *s, uint size) @@ -71,13 +74,30 @@ hcs_connect_err(sock *s UNUSED, int err) log(L_INFO "Failed to accept CLI connection: %s", strerror(err)); } +static void +hcs_stopped(void *data) +{ + ASSERT_DIE(data == hcs_loop); + hcs_pool = NULL; + hcs_loop = NULL; + OBSREF_CLEAR(hcs_shutdown_placeholder); + + unlink(flock_config.control_socket_path); +} + +static void +hcs_shutdown(void *_data UNUSED) +{ + birdloop_stop(hcs_loop, hcs_stopped, hcs_loop); +} + void hypervisor_control_socket(void) { - struct birdloop *loop = birdloop_new(&root_pool, DOMAIN_ORDER(control), 0, "Control socket"); + struct birdloop *loop = hcs_loop = birdloop_new(&root_pool, DOMAIN_ORDER(control), 0, "Control socket"); birdloop_enter(loop); - pool *p = hypervisor_control_socket_pool = rp_new(birdloop_pool(loop), birdloop_domain(loop), "Control socket pool"); + pool *p = hcs_pool = rp_new(birdloop_pool(loop), birdloop_domain(loop), "Control socket pool"); sock *s = sk_new(p); s->type = SK_UNIX_PASSIVE; s->rx_hook = hcs_connect; @@ -88,9 +108,15 @@ hypervisor_control_socket(void) if (sk_open_unix(s, loop, flock_config.control_socket_path) < 0) die("Can't create control socket %s: %m", flock_config.control_socket_path); + ev_send(&shutdown_event_list, ev_new_init(p, hcs_shutdown, NULL)); + birdloop_leave(loop); + + OBSREF_SET(hcs_shutdown_placeholder, &shutdown_placeholder); } + + /** * Exposed process' communication structure **/