]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Flock: Added a proper shutdown routine requestable also from CLI
authorMaria Matejka <mq@ucw.cz>
Tue, 10 Sep 2024 09:16:49 +0000 (11:16 +0200)
committerMaria Matejka <mq@ucw.cz>
Sun, 23 Feb 2025 18:07:35 +0000 (19:07 +0100)
flock/ctl.c
flock/flock.c
flock/flock.h
flock/hypervisor.c

index d94bae755644d40b6bafbafd50623f79a7647ade..ea34a7fe2a80e26a8a7bf1a0b8b3faab641c0237 100644 (file)
@@ -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;
 
index 6ad8c445961984a99db71ed6b764e069bec305bf..daf8dc8c5e282f2bb20142982d1dfd2827839a6c 100644 (file)
@@ -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"
 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);
index 4a7956fa5cd862b6d706afd5e625717e4db68ba1..2f83c5583017403be8c784459748a633fb13ae30 100644 (file)
@@ -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
index 2b52396db7c821fabaebbef621814cfc6e68ae2e..a6e87b7dafb3169d5a704af13bd1ba85c0d8a3f8 100644 (file)
  * 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
  **/