#include "lib/birdlib.h"
#include "lib/string.h"
+#include "lib/io-loop.h"
#include "flock/flock.h"
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;
#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"
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)
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)
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);
#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);
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
* 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)
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;
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
**/