]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Perform gracious shutdown upon receipt of SIGTERM. Finally we can
authorMartin Mares <mj@ucw.cz>
Sat, 13 Feb 1999 20:15:36 +0000 (20:15 +0000)
committerMartin Mares <mj@ucw.cz>
Sat, 13 Feb 1999 20:15:36 +0000 (20:15 +0000)
test the whole protocol shutdown code... :)

nest/bird.h
nest/proto.c
nest/protocol.h
sysdep/unix/io.c
sysdep/unix/main.c
sysdep/unix/unix.h

index 597e2050a2454009e93c384cdfbe042757e98490..b35cd31a6f94c740b2f5cdfc755f9251da242479 100644 (file)
@@ -13,4 +13,6 @@
 #include "lib/birdlib.h"
 #include "lib/ip.h"
 
+extern int shutting_down;              /* The daemon is shutting down */
+
 #endif
index 76422e3173b2c1c73f8f9a8383b5a6f6b595f527..f96d37dc45eba1008a0d6f0676fbd109314b95b5 100644 (file)
@@ -28,6 +28,8 @@ static list inactive_proto_list;
 static list initial_proto_list;
 static list flush_proto_list;
 
+static int proto_shutdown_counter;
+
 static event *proto_flush_event;
 
 static char *p_states[] = { "DOWN", "START", "UP", "STOP" };
@@ -178,7 +180,7 @@ proto_rethink_goal(struct proto *p)
 static void
 proto_set_goal(struct proto *p, unsigned goal)
 {
-  if (p->disabled)
+  if (p->disabled || shutting_down)
     goal = FS_HUNGRY;
   p->core_goal = goal;
   proto_rethink_goal(p);
@@ -194,6 +196,25 @@ protos_start(void)
     proto_set_goal(p, FS_HAPPY);
 }
 
+void
+protos_shutdown(void)
+{
+  struct proto *p, *n;
+
+  debug("Protocol shutdown\n");
+  WALK_LIST_DELSAFE(p, n, inactive_proto_list)
+    if (p->core_state != FS_HUNGRY || p->proto_state != PS_DOWN)
+    {
+      proto_shutdown_counter++;
+      proto_set_goal(p, FS_HUNGRY);
+    }
+  WALK_LIST_DELSAFE(p, n, proto_list)
+    {
+      proto_shutdown_counter++;
+      proto_set_goal(p, FS_HUNGRY);
+    }
+}
+
 void
 protos_dump_all(void)
 {
@@ -235,6 +256,8 @@ static void
 proto_fell_down(struct proto *p)
 {
   DBG("Protocol %s down\n", p->name);
+  if (!--proto_shutdown_counter)
+    protos_shutdown_notify();
   proto_rethink_goal(p);
 }
 
@@ -291,6 +314,7 @@ proto_notify_state(struct proto *p, unsigned ps)
          cs = FS_FLUSHING;
          ev_schedule(proto_flush_event);
        }
+      break;
     default:
     error:
       bug("Invalid state transition for %s from %s/%s to */%s", p->name, c_states[cs], p_states[ops], p_states[ps]);
@@ -313,6 +337,6 @@ proto_flush_all(void *unused)
       p->pool = NULL;
       p->core_state = FS_HUNGRY;
       proto_relink(p);
-      proto_rethink_goal(p);
+      proto_fell_down(p);
     }
 }
index f6facea6bdf8807a6d9011d52a641d1f584c978f..8a27350cae7eb46b0c2ebe28a61d0ab813e627a0 100644 (file)
@@ -46,6 +46,7 @@ void protos_postconfig(struct config *);
 void protos_commit(struct config *);
 void protos_start(void);
 void protos_dump_all(void);
+void protos_shutdown(void);
 
 extern list protocol_list;
 
@@ -188,4 +189,10 @@ void proto_notify_state(struct proto *p, unsigned state);
 
 extern struct proto_config *cf_dev_proto;
 
+/*
+ *     Callback to sysdep code when shutdown is finished
+ */
+
+void protos_shutdown_notify(void);
+
 #endif
index d8713f4c4990f1050f4dc2f8a842201c8567e530..aa4f652a4da42ff8f449bba535bc2538a95691af 100644 (file)
@@ -747,11 +747,19 @@ io_loop(void)
        {
          async_config();
          async_config_flag = 0;
+         continue;
        }
       if (async_dump_flag)
        {
          async_dump();
          async_dump_flag = 0;
+         continue;
+       }
+      if (async_shutdown_flag)
+       {
+         async_shutdown();
+         async_shutdown_flag = 0;
+         continue;
        }
 
       /* And finally enter select() to find active sockets */
index 7b306539cf4bd17f6e931a9a9085af6e44dad033..71bb712aa5aa730cce1b9faa4dfeeeccfe55cceb 100644 (file)
@@ -26,6 +26,8 @@
 #include "unix.h"
 #include "krt.h"
 
+int shutting_down;
+
 /*
  *     Debugging
  */
@@ -82,6 +84,24 @@ async_config(void)
   debug("Asynchronous reconfigurations are not supported in demo version\n");
 }
 
+/*
+ *     Shutdown
+ */
+
+void
+async_shutdown(void)
+{
+  debug("Shutting down...\n");
+  shutting_down = 1;
+  protos_shutdown();
+}
+
+void
+protos_shutdown_notify(void)
+{
+  die("System shutdown completed");
+}
+
 /*
  *     Signals
  */
@@ -100,6 +120,13 @@ handle_sigusr(int sig)
   async_dump_flag = 1;
 }
 
+static void
+handle_sigterm(int sig)
+{
+  debug("Caught SIGTERM...\n");
+  async_shutdown_flag = 1;
+}
+
 static void
 signal_init(void)
 {
@@ -112,6 +139,9 @@ signal_init(void)
   sa.sa_handler = handle_sighup;
   sa.sa_flags = SA_RESTART;
   sigaction(SIGHUP, &sa, NULL);
+  sa.sa_handler = handle_sigterm;
+  sa.sa_flags = SA_RESTART;
+  sigaction(SIGTERM, &sa, NULL);
   signal(SIGPIPE, SIG_IGN);
 }
 
index a79db2ed0000e49eed4ad068e4edb0515950634e..e5271021b82b2b9f34da42d2fe3e4bdab225d27f 100644 (file)
 
 void async_config(void);
 void async_dump(void);
+void async_shutdown(void);
 
 /* io.c */
 
 volatile int async_config_flag;
 volatile int async_dump_flag;
+volatile int async_shutdown_flag;
 
 void io_init(void);
 void io_loop(void);