Perform gracious shutdown upon receipt of SIGTERM. Finally we can
test the whole protocol shutdown code... :)
This commit is contained in:
parent
7f3d1a0850
commit
f4aabcee62
6 changed files with 75 additions and 2 deletions
|
@ -13,4 +13,6 @@
|
||||||
#include "lib/birdlib.h"
|
#include "lib/birdlib.h"
|
||||||
#include "lib/ip.h"
|
#include "lib/ip.h"
|
||||||
|
|
||||||
|
extern int shutting_down; /* The daemon is shutting down */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
28
nest/proto.c
28
nest/proto.c
|
@ -28,6 +28,8 @@ static list inactive_proto_list;
|
||||||
static list initial_proto_list;
|
static list initial_proto_list;
|
||||||
static list flush_proto_list;
|
static list flush_proto_list;
|
||||||
|
|
||||||
|
static int proto_shutdown_counter;
|
||||||
|
|
||||||
static event *proto_flush_event;
|
static event *proto_flush_event;
|
||||||
|
|
||||||
static char *p_states[] = { "DOWN", "START", "UP", "STOP" };
|
static char *p_states[] = { "DOWN", "START", "UP", "STOP" };
|
||||||
|
@ -178,7 +180,7 @@ proto_rethink_goal(struct proto *p)
|
||||||
static void
|
static void
|
||||||
proto_set_goal(struct proto *p, unsigned goal)
|
proto_set_goal(struct proto *p, unsigned goal)
|
||||||
{
|
{
|
||||||
if (p->disabled)
|
if (p->disabled || shutting_down)
|
||||||
goal = FS_HUNGRY;
|
goal = FS_HUNGRY;
|
||||||
p->core_goal = goal;
|
p->core_goal = goal;
|
||||||
proto_rethink_goal(p);
|
proto_rethink_goal(p);
|
||||||
|
@ -194,6 +196,25 @@ protos_start(void)
|
||||||
proto_set_goal(p, FS_HAPPY);
|
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
|
void
|
||||||
protos_dump_all(void)
|
protos_dump_all(void)
|
||||||
{
|
{
|
||||||
|
@ -235,6 +256,8 @@ static void
|
||||||
proto_fell_down(struct proto *p)
|
proto_fell_down(struct proto *p)
|
||||||
{
|
{
|
||||||
DBG("Protocol %s down\n", p->name);
|
DBG("Protocol %s down\n", p->name);
|
||||||
|
if (!--proto_shutdown_counter)
|
||||||
|
protos_shutdown_notify();
|
||||||
proto_rethink_goal(p);
|
proto_rethink_goal(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,6 +314,7 @@ proto_notify_state(struct proto *p, unsigned ps)
|
||||||
cs = FS_FLUSHING;
|
cs = FS_FLUSHING;
|
||||||
ev_schedule(proto_flush_event);
|
ev_schedule(proto_flush_event);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
error:
|
error:
|
||||||
bug("Invalid state transition for %s from %s/%s to */%s", p->name, c_states[cs], p_states[ops], p_states[ps]);
|
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->pool = NULL;
|
||||||
p->core_state = FS_HUNGRY;
|
p->core_state = FS_HUNGRY;
|
||||||
proto_relink(p);
|
proto_relink(p);
|
||||||
proto_rethink_goal(p);
|
proto_fell_down(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,7 @@ void protos_postconfig(struct config *);
|
||||||
void protos_commit(struct config *);
|
void protos_commit(struct config *);
|
||||||
void protos_start(void);
|
void protos_start(void);
|
||||||
void protos_dump_all(void);
|
void protos_dump_all(void);
|
||||||
|
void protos_shutdown(void);
|
||||||
|
|
||||||
extern list protocol_list;
|
extern list protocol_list;
|
||||||
|
|
||||||
|
@ -188,4 +189,10 @@ void proto_notify_state(struct proto *p, unsigned state);
|
||||||
|
|
||||||
extern struct proto_config *cf_dev_proto;
|
extern struct proto_config *cf_dev_proto;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Callback to sysdep code when shutdown is finished
|
||||||
|
*/
|
||||||
|
|
||||||
|
void protos_shutdown_notify(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -747,11 +747,19 @@ io_loop(void)
|
||||||
{
|
{
|
||||||
async_config();
|
async_config();
|
||||||
async_config_flag = 0;
|
async_config_flag = 0;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
if (async_dump_flag)
|
if (async_dump_flag)
|
||||||
{
|
{
|
||||||
async_dump();
|
async_dump();
|
||||||
async_dump_flag = 0;
|
async_dump_flag = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (async_shutdown_flag)
|
||||||
|
{
|
||||||
|
async_shutdown();
|
||||||
|
async_shutdown_flag = 0;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* And finally enter select() to find active sockets */
|
/* And finally enter select() to find active sockets */
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
#include "unix.h"
|
#include "unix.h"
|
||||||
#include "krt.h"
|
#include "krt.h"
|
||||||
|
|
||||||
|
int shutting_down;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Debugging
|
* Debugging
|
||||||
*/
|
*/
|
||||||
|
@ -82,6 +84,24 @@ async_config(void)
|
||||||
debug("Asynchronous reconfigurations are not supported in demo version\n");
|
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
|
* Signals
|
||||||
*/
|
*/
|
||||||
|
@ -100,6 +120,13 @@ handle_sigusr(int sig)
|
||||||
async_dump_flag = 1;
|
async_dump_flag = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_sigterm(int sig)
|
||||||
|
{
|
||||||
|
debug("Caught SIGTERM...\n");
|
||||||
|
async_shutdown_flag = 1;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
signal_init(void)
|
signal_init(void)
|
||||||
{
|
{
|
||||||
|
@ -112,6 +139,9 @@ signal_init(void)
|
||||||
sa.sa_handler = handle_sighup;
|
sa.sa_handler = handle_sighup;
|
||||||
sa.sa_flags = SA_RESTART;
|
sa.sa_flags = SA_RESTART;
|
||||||
sigaction(SIGHUP, &sa, NULL);
|
sigaction(SIGHUP, &sa, NULL);
|
||||||
|
sa.sa_handler = handle_sigterm;
|
||||||
|
sa.sa_flags = SA_RESTART;
|
||||||
|
sigaction(SIGTERM, &sa, NULL);
|
||||||
signal(SIGPIPE, SIG_IGN);
|
signal(SIGPIPE, SIG_IGN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,11 +13,13 @@
|
||||||
|
|
||||||
void async_config(void);
|
void async_config(void);
|
||||||
void async_dump(void);
|
void async_dump(void);
|
||||||
|
void async_shutdown(void);
|
||||||
|
|
||||||
/* io.c */
|
/* io.c */
|
||||||
|
|
||||||
volatile int async_config_flag;
|
volatile int async_config_flag;
|
||||||
volatile int async_dump_flag;
|
volatile int async_dump_flag;
|
||||||
|
volatile int async_shutdown_flag;
|
||||||
|
|
||||||
void io_init(void);
|
void io_init(void);
|
||||||
void io_loop(void);
|
void io_loop(void);
|
||||||
|
|
Loading…
Reference in a new issue