]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Converted shutdown to a kind of reconfiguration, it's no more handled
authorMartin Mares <mj@ucw.cz>
Sun, 16 Jan 2000 17:40:26 +0000 (17:40 +0000)
committerMartin Mares <mj@ucw.cz>
Sun, 16 Jan 2000 17:40:26 +0000 (17:40 +0000)
as a exception in protocol state machines. Introduced a `shutdown'
CLI command. Killed few reconfiguration bugs.

TODO
conf/conf.c
conf/conf.h
doc/reply_codes
nest/bird.h
nest/proto.c
nest/protocol.h
nest/rt-table.c
sysdep/unix/config.Y
sysdep/unix/main.c

diff --git a/TODO b/TODO
index c2a6fc880f6c9fbed6598a5a61c131d97fa855a5..e932761a0c4f07605d7cd8e8d3e019752126699c 100644 (file)
--- a/TODO
+++ b/TODO
@@ -30,8 +30,6 @@ Core
 - config: useless rules when protocols disabled
 - config: remove protocol startup priority hacks?
 - config: better datetime format
-- config: treat shutdown as reconfiguration to null config? (what about config of logging etc. ?)
-- config: fix auto_router_id
 
 - krt: rescan interfaces when route addition fails?
 - krt: does PERSIST mode have any sense if kernel syncer is shut down as last?
index 1c5401bc44a20a4e23694a5f1db22f12fb13ff27..c3f5234472bcf0254bd9a89d2e26a0d3a85218a0 100644 (file)
@@ -25,6 +25,7 @@ static jmp_buf conf_jmpbuf;
 
 struct config *config, *new_config, *old_config, *future_config;
 static event *config_event;
+int shutting_down;
 
 struct config *
 config_alloc(byte *name)
@@ -100,11 +101,13 @@ config_del_obstacle(struct config *c)
 }
 
 static int
-global_commit(struct config *c, struct config *old)
+global_commit(struct config *new, struct config *old)
 {
   if (!old)
     return 0;
-  if (c->router_id != old->router_id)
+  if (!new->router_id)
+    new->router_id = old->router_id;
+  if (new->router_id != old->router_id)
     return 1;
   return 0;
 }
@@ -116,7 +119,7 @@ config_do_commit(struct config *c)
 
   DBG("do_commit\n");
   old_config = config;
-  config = c;
+  config = new_config = c;
   if (old_config)
     old_config->obstacle_count++;
   DBG("sysdep_commit\n");
@@ -144,6 +147,8 @@ config_done(void *unused)
   DBG("config_done\n");
   for(;;)
     {
+      if (config->shutdown)
+       sysdep_shutdown_done();
       log(L_INFO "Reconfigured");
       if (old_config)
        {
@@ -171,6 +176,12 @@ config_commit(struct config *c)
     }
   if (old_config)                      /* Reconfiguration already in progress */
     {
+      if (shutting_down)
+       {
+         log(L_INFO "New configuration discarded due to shutdown");
+         config_free(c);
+         return CONF_SHUTDOWN;
+       }
       if (future_config)
        {
          log(L_INFO "Queueing new configuration, ignoring the one already queued");
@@ -194,6 +205,23 @@ config_commit(struct config *c)
   return CONF_PROGRESS;
 }
 
+void
+order_shutdown(void)
+{
+  struct config *c;
+
+  if (shutting_down)
+    return;
+  log(L_INFO "Shutting down");
+  c = lp_alloc(config->mem, sizeof(struct config));
+  memcpy(c, config, sizeof(struct config));
+  init_list(&c->protos);
+  init_list(&c->tables);
+  c->shutdown = 1;
+  config_commit(c);
+  shutting_down = 1;
+}
+
 void
 cf_error(char *msg, ...)
 {
index 7d13ae9ce4a923543a42c1dd126eb7f420329e73..9fe133ee417a85f29e31258553d74ab34a47549c 100644 (file)
@@ -27,6 +27,7 @@ struct config {
   struct symbol **sym_hash;            /* Lexer: symbol hash table */
   struct symbol **sym_fallback;                /* Lexer: fallback symbol hash table */
   int obstacle_count;                  /* Number of items blocking freeing of this config */
+  int shutdown;                                /* This is a pseudo-config for daemon shutdown */
 };
 
 /* Please don't use these variables in protocols. Use proto_config->global instead. */
@@ -35,6 +36,8 @@ extern struct config *new_config;     /* Configuration being parsed */
 extern struct config *old_config;      /* Old configuration when reconfiguration is in progress */
 extern struct config *future_config;   /* New config held here if recon requested during recon */
 
+extern int shutting_down;
+
 struct config *config_alloc(byte *name);
 int config_parse(struct config *);
 int cli_parse(struct config *);
@@ -43,10 +46,12 @@ int config_commit(struct config *);
 void cf_error(char *msg, ...) NORET;
 void config_add_obstacle(struct config *);
 void config_del_obstacle(struct config *);
+void order_shutdown(void);
 
 #define CONF_DONE 0
 #define CONF_PROGRESS 1
 #define CONF_QUEUED 2
+#define CONF_SHUTDOWN 3
 
 /* Pools */
 
@@ -98,5 +103,6 @@ int cf_parse(void);
 
 void sysdep_preconfig(struct config *);
 int sysdep_commit(struct config *, struct config *);
+void sysdep_shutdown_done(void);
 
 #endif
index 9b74c5b15bb18a912c7ca3b92344725269ae6b19..93c3d515a8de4c6ab1a3e6087eeb349f5de1b12e 100644 (file)
@@ -11,6 +11,11 @@ Reply codes of BIRD command-line interface
 0000   OK
 0001   Welcome
 0002   Reading configuration
+0003   Reconfigured
+0004   Reconfiguration in progress
+0005   Reconfiguration already in progress, queueing
+0006   Reconfiguration ignored, shutting down
+0007   Shutdown ordered
 
 1000   BIRD version
 1001   Interface list
index b35cd31a6f94c740b2f5cdfc755f9251da242479..3c7d749b596ad782473a3bf0856ca3037f8ed0af 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *     BIRD Internet Routing Daemon -- Basic Declarations
  *
- *     (c) 1998--1999 Martin Mares <mj@ucw.cz>
+ *     (c) 1998--2000 Martin Mares <mj@ucw.cz>
  *
  *     Can be freely distributed and used under the terms of the GNU GPL.
  */
@@ -13,6 +13,4 @@
 #include "lib/birdlib.h"
 #include "lib/ip.h"
 
-extern int shutting_down;              /* The daemon is shutting down */
-
 #endif
index ecf0d906ee1dcc8fa359fe8c94e79bbfc6ea2246..36829bfda8680ab5ccdaaa633fe4989e6d71d524 100644 (file)
@@ -30,8 +30,6 @@ 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" };
@@ -221,7 +219,7 @@ protos_commit(struct config *new, struct config *old, int force_reconfig)
        {
          struct proto *p = oc->proto;
          struct symbol *sym = cf_find_symbol(oc->name);
-         if (sym && sym->class == SYM_PROTO)
+         if (sym && sym->class == SYM_PROTO && !new->shutdown)
            {
              /* Found match, let's check if we can smoothly switch to new configuration */
              nc = sym->def;
@@ -236,7 +234,7 @@ protos_commit(struct config *new, struct config *old, int force_reconfig)
                {
                  /* Generic attributes match, try converting them and then ask the protocol */
                  p->debug = nc->debug;
-                 if (p->proto->reconfigure(p, nc))
+                 if (p->proto->reconfigure && p->proto->reconfigure(p, nc))
                    {
                      DBG("\t%s: same\n", oc->name);
                      p->cf = nc;
@@ -247,6 +245,7 @@ protos_commit(struct config *new, struct config *old, int force_reconfig)
              /* Unsuccessful, force reconfig */
              DBG("\t%s: power cycling\n", oc->name);
              p->cf_new = nc;
+             nc->proto = p;
            }
          else
            {
@@ -290,7 +289,7 @@ proto_rethink_goal(struct proto *p)
     }
 
   /* Determine what state we want to reach */
-  if (p->disabled || shutting_down || p->reconfiguring)
+  if (p->disabled || p->reconfiguring)
     p->core_goal = FS_HUNGRY;
   else
     p->core_goal = FS_HAPPY;
@@ -320,25 +319,6 @@ proto_rethink_goal(struct proto *p)
     }
 }
 
-void
-protos_shutdown(void)
-{
-  struct proto *p, *n;
-
-  debug("Protocol shutdown\n");
-  WALK_LIST_BACKWARDS_DELSAFE(p, n, inactive_proto_list)
-    if (p->core_state != FS_HUNGRY || p->proto_state != PS_DOWN)
-    {
-      proto_shutdown_counter++;
-      proto_rethink_goal(p);
-    }
-  WALK_LIST_BACKWARDS_DELSAFE(p, n, proto_list)
-    {
-      proto_shutdown_counter++;
-      proto_rethink_goal(p);
-    }
-}
-
 void
 protos_dump_all(void)
 {
@@ -389,8 +369,6 @@ proto_fell_down(struct proto *p)
 {
   DBG("Protocol %s down\n", p->name);
   rt_unlock_table(p->table);
-  if (!--proto_shutdown_counter)
-    protos_shutdown_notify();
   proto_rethink_goal(p);
 }
 
index 72f88b6b6f7b869cfd57af8b618e03c33957cc3c..7c14f97283657bc09ec65d068128315ca31540c9 100644 (file)
@@ -56,7 +56,6 @@ void protos_preconfig(struct config *);
 void protos_postconfig(struct config *);
 void protos_commit(struct config *new, struct config *old, int force_restart);
 void protos_dump_all(void);
-void protos_shutdown(void);
 
 extern list protocol_list;
 
@@ -251,10 +250,4 @@ struct announce_hook {
 
 struct announce_hook *proto_add_announce_hook(struct proto *, struct rtable *);
 
-/*
- *     Callback to sysdep code when shutdown is finished
- */
-
-void protos_shutdown_notify(void);
-
 #endif
index b0d1e2911ab081efcc2b5add66fb31b1ea6948c1..dcde0af865935b961d6f9cfa9cc01a7adc83de60 100644 (file)
@@ -513,7 +513,7 @@ rt_commit(struct config *new, struct config *old)
          if (!ot->deleted)
            {
              struct symbol *sym = cf_find_symbol(o->name);
-             if (sym && sym->class == SYM_TABLE)
+             if (sym && sym->class == SYM_TABLE && !new->shutdown)
                {
                  DBG("\t%s: same\n", o->name);
                  r = sym->def;
@@ -522,7 +522,7 @@ rt_commit(struct config *new, struct config *old)
                }
              else
                {
-                 DBG("\t%s: deleted", o->name);
+                 DBG("\t%s: deleted\n", o->name);
                  ot->deleted = old;
                  config_add_obstacle(old);
                  rt_lock_table(ot);
index 299cc41d94d28e511d1ba27ba2f853bcd92a3db8..cd553f8e2734425d7930700c1971975da178eefb 100644 (file)
@@ -67,6 +67,9 @@ log_cat:
 CF_CLI(CONFIGURE, cfg_name, [<file>], [[Reload configuration]])
 { cmd_reconfig($2); } ;
 
+CF_CLI(SHUTDOWN,,, [[Shut the daemon down]])
+{ cli_msg(7, "Shutdown ordered"); order_shutdown(); } ;
+
 cfg_name:
    /* empty */ { $$ = NULL; }
  | TEXT
index 97b9dc608a172d2a05cdcd91be975bbb5034836a..5019a3d50876c609478e51fd11a31f09cd2a5f15 100644 (file)
@@ -29,8 +29,6 @@
 #include "unix.h"
 #include "krt.h"
 
-int shutting_down;
-
 /*
  *     Debugging
  */
@@ -153,6 +151,9 @@ cmd_reconfig(char *name)
        case CONF_PROGRESS:
          cli_msg(4, "Reconfiguration in progress.");
          break;
+       case CONF_SHUTDOWN:
+         cli_msg(6, "Reconfiguration ignored, shutting down.");
+         break;
        default:
          cli_msg(5, "Reconfiguration already in progress, queueing new config");
        }
@@ -275,12 +276,11 @@ void
 async_shutdown(void)
 {
   debug("Shutting down...\n");
-  shutting_down = 1;
-  protos_shutdown();
+  order_shutdown();
 }
 
 void
-protos_shutdown_notify(void)
+sysdep_shutdown_done(void)
 {
   unlink(PATH_CONTROL_SOCKET);
   die("System shutdown completed");