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/ip.h"
|
||||
|
||||
extern int shutting_down; /* The daemon is shutting down */
|
||||
|
||||
#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 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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -13,11 +13,13 @@
|
|||
|
||||
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);
|
||||
|
|
Loading…
Reference in a new issue