]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
CLI: show threads all crash fixed
authorMaria Matejka <mq@ucw.cz>
Thu, 12 Dec 2024 14:00:26 +0000 (15:00 +0100)
committerMaria Matejka <mq@ucw.cz>
Thu, 12 Dec 2024 14:00:26 +0000 (15:00 +0100)
When socket dropped before finished, it failed to cleanup.

nest/cli.c
nest/cli.h
nest/rt-show.c
proto/mrt/mrt.c
sysdep/unix/io-loop.c

index 934451b19c1cb8cc17eb736b85f2e86ab21f14fe..3b8e6f468387893027f24ad860cc335e032f7621 100644 (file)
@@ -337,12 +337,18 @@ extern cli *cmd_reconfig_stored_cli;
 void
 cli_free(cli *c)
 {
-  CALL(c->cleanup, c);
+  bool done = c->cleanup ? c->cleanup(c) : true;
 
   if (c == cmd_reconfig_stored_cli)
     cmd_reconfig_stored_cli = NULL;
 
-  rp_free(c->pool);
+  if (done)
+    rp_free(c->pool);
+  else
+  {
+    sk_close(c->sock);
+    c->sock = NULL;
+  }
 }
 
 /**
index 54fc29640a74d8ee1ceb421e0d67b7d5881c79d4..d86ec380160233d6505189df62b294de5c44bf17 100644 (file)
@@ -37,7 +37,9 @@ typedef struct cli {
   struct cli_out *tx_buf, *tx_pos, *tx_write;
   event *event;
   void (*cont)(struct cli *c);
-  void (*cleanup)(struct cli *c);      /* The CLI has closed prematurely */
+  bool (*cleanup)(struct cli *c);      /* The CLI has closed prematurely; if done, return true,
+                                          otherwise return false and call rp_free(c->pool) later yourself.
+                                          The socket is closed anyway, tho. */
   void *rover;                         /* Private to continuation routine */
   struct config *main_config;          /* Main config currently in use */
   int last_reply;
index e4149e66ecb604714cd5d9ca2a1c0869b5425da5..3986da83dbffbad3d033386ec998d1d88123bf60 100644 (file)
@@ -225,7 +225,7 @@ rt_show_net(struct rt_show_data *d, const struct rt_export_feed *feed)
   }
 }
 
-static void
+static bool
 rt_show_cleanup(struct cli *c)
 {
   struct rt_show_data *d = c->rover;
@@ -241,6 +241,9 @@ rt_show_cleanup(struct cli *c)
 
   /* Unreference the config */
   OBSREF_CLEAR(d->running_on_config);
+
+  /* Everything cleaned up */
+  return true;
 }
 
 static void
index cc5ad06a6c35f2af1802b11738411f198ef7744a..015a1e15bdca7b831764a806381bd0ea15090ec1 100644 (file)
@@ -760,11 +760,12 @@ mrt_dump_cont(struct cli *c)
   return mrt_table_dump_step(c->rover);
 }
 
-void
+static bool
 mrt_dump_cleanup(struct cli *c)
 {
   mrt_table_dump_free(c->rover);
   c->rover = NULL;
+  return true;
 }
 
 void
index 6dca5f3c9fa7b6f24fcbb08ca9ba193b17bde2d2..f69189e06187762bf8200335b5bff0afaf159d90 100644 (file)
@@ -1259,10 +1259,11 @@ bird_thread_show_cli_cont(struct cli *c UNUSED)
   /* Explicitly do nothing to prevent CLI from trying to parse another command. */
 }
 
-static int
+static bool
 bird_thread_show_cli_cleanup(struct cli *c UNUSED)
 {
-  return 1; /* Defer the cleanup until the writeout is finished. */
+  /* Defer the cleanup until the writeout is finished. */
+  return false;
 }
 
 static void
@@ -1328,6 +1329,14 @@ cmd_show_threads_done(struct bird_thread_syncer *sync)
   SKIP_BACK_DECLARE(struct bird_thread_show_data, tsd, sync, sync);
   ASSERT_DIE(birdloop_inside(&main_birdloop));
 
+  /* The client lost their patience and dropped the session early. */
+  if (!tsd->cli->sock)
+  {
+    mb_free(tsd);
+    rp_free(tsd->cli->pool);
+    return;
+  }
+
   tsd->cli->cont = NULL;
   tsd->cli->cleanup = NULL;