1
0
mirror of https://gitlab.labs.nic.cz/labs/bird.git synced 2024-05-11 16:54:54 +00:00

Implements undo command and optional timeout for configuration

Several new configure command variants:

configure undo - undo last reconfiguration
configure timeout - configure with scheduled undo if not confirmed in timeout
configure confirm - confirm last configuration
configure check - just parse and validate config file
This commit is contained in:
Ondrej Zajicek
2012-12-26 12:40:48 +01:00
parent 80a9cadc76
commit a92cf57dd6
16 changed files with 407 additions and 115 deletions

View File

@@ -14,9 +14,9 @@ CF_HDR
CF_DECLS
CF_KEYWORDS(LOG, SYSLOG, ALL, DEBUG, TRACE, INFO, REMOTE, WARNING, ERROR, AUTH, FATAL, BUG, STDERR, SOFT)
CF_KEYWORDS(TIMEFORMAT, ISO, SHORT, LONG, BASE, NAME)
CF_KEYWORDS(TIMEFORMAT, ISO, SHORT, LONG, BASE, NAME, CONFIRM, UNDO, CHECK, TIMEOUT)
%type <i> log_mask log_mask_list log_cat
%type <i> log_mask log_mask_list log_cat cfg_timeout
%type <g> log_file
%type <t> cfg_name
%type <tf> timeformat_which
@@ -104,13 +104,26 @@ timeformat_base:
/* Unix specific commands */
CF_CLI_HELP(CONFIGURE, [soft] [\"<file>\"], [[Reload configuration]])
CF_CLI_HELP(CONFIGURE, ..., [[Reload configuration]])
CF_CLI(CONFIGURE, cfg_name, [\"<file>\"], [[Reload configuration]])
{ cmd_reconfig($2, RECONFIG_HARD); } ;
CF_CLI(CONFIGURE, cfg_name cfg_timeout, [\"<file>\"] [timeout [<sec>]], [[Reload configuration]])
{ cmd_reconfig($2, RECONFIG_HARD, $3); } ;
CF_CLI(CONFIGURE SOFT, cfg_name, [\"<file>\"], [[Reload configuration and ignore changes in filters]])
{ cmd_reconfig($3, RECONFIG_SOFT); } ;
CF_CLI(CONFIGURE SOFT, cfg_name cfg_timeout, [\"<file>\"] [timeout [<sec>]], [[Reload configuration and ignore changes in filters]])
{ cmd_reconfig($3, RECONFIG_SOFT, $4); } ;
/* Hack to get input completion for 'timeout' */
CF_CLI_CMD(CONFIGURE TIMEOUT, [<sec>], [[Reload configuration with undo timeout]])
CF_CLI_CMD(CONFIGURE SOFT TIMEOUT, [<sec>], [[Reload configuration with undo timeout]])
CF_CLI(CONFIGURE CONFIRM,,, [[Confirm last configuration change - deactivate undo timeout]])
{ cmd_reconfig_confirm(); } ;
CF_CLI(CONFIGURE UNDO,,, [[Undo last configuration change]])
{ cmd_reconfig_undo(); } ;
CF_CLI(CONFIGURE CHECK, cfg_name, [\"<file>\"], [[Parse configuration and check its validity]])
{ cmd_check_config($3); } ;
CF_CLI(DOWN,,, [[Shut the daemon down]])
{ cmd_shutdown(); } ;
@@ -120,6 +133,12 @@ cfg_name:
| TEXT
;
cfg_timeout:
/* empty */ { $$ = 0; }
| TIMEOUT { $$ = UNIX_DEFAULT_CONFIGURE_TIMEOUT; }
| TIMEOUT expr { $$ = $2; }
;
CF_CODE
CF_END

View File

@@ -121,7 +121,7 @@ static list near_timers, far_timers;
static bird_clock_t first_far_timer = TIME_INFINITY;
/* now must be different from 0, because 0 is a special value in timer->expires */
bird_clock_t now = 1, now_real;
bird_clock_t now = 1, now_real, boot_time;
static void
update_times_plain(void)
@@ -1530,6 +1530,7 @@ io_init(void)
krt_io_init();
init_times();
update_times();
boot_time = now;
srandom((int) now_real);
}
@@ -1557,7 +1558,7 @@ io_loop(void)
tm_shot();
continue;
}
timo.tv_sec = events ? 0 : tout - now;
timo.tv_sec = events ? 0 : MIN(tout - now, 3);
timo.tv_usec = 0;
if (sock_recalc_fdsets_p)

View File

@@ -900,7 +900,7 @@ krt_notify(struct proto *P, struct rtable *table UNUSED, net *net,
{
struct krt_proto *p = (struct krt_proto *) P;
if (shutting_down)
if (config->shutdown)
return;
if (!(net->n.flags & KRF_INSTALLED))
old = NULL;

View File

@@ -210,7 +210,7 @@ read_config(void)
else
die("Unable to open configuration file %s: %m", config_name);
}
config_commit(conf, RECONFIG_HARD);
config_commit(conf, RECONFIG_HARD, 0);
}
void
@@ -228,19 +228,17 @@ async_config(void)
config_free(conf);
}
else
config_commit(conf, RECONFIG_HARD);
config_commit(conf, RECONFIG_HARD, 0);
}
void
cmd_reconfig(char *name, int type)
static struct config *
cmd_read_config(char *name)
{
struct config *conf;
if (cli_access_restricted())
return;
if (!name)
name = config_name;
cli_msg(-2, "Reading configuration from %s", name);
if (!unix_read_config(&conf, name))
{
@@ -249,26 +247,96 @@ cmd_reconfig(char *name, int type)
else
cli_msg(8002, "%s: %m", name);
config_free(conf);
conf = NULL;
}
else
return conf;
}
void
cmd_check_config(char *name)
{
struct config *conf = cmd_read_config(name);
if (!conf)
return;
cli_msg(20, "Configuration OK");
config_free(conf);
}
static void
cmd_reconfig_msg(int r)
{
switch (r)
{
switch (config_commit(conf, type))
{
case CONF_DONE:
cli_msg(3, "Reconfigured.");
break;
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");
}
case CONF_DONE: cli_msg( 3, "Reconfigured"); break;
case CONF_PROGRESS: cli_msg( 4, "Reconfiguration in progress"); break;
case CONF_QUEUED: cli_msg( 5, "Reconfiguration already in progress, queueing new config"); break;
case CONF_UNQUEUED: cli_msg(17, "Reconfiguration already in progress, removing queued config"); break;
case CONF_CONFIRM: cli_msg(18, "Reconfiguration confirmed"); break;
case CONF_SHUTDOWN: cli_msg( 6, "Reconfiguration ignored, shutting down"); break;
case CONF_NOTHING: cli_msg(19, "Nothing to do"); break;
default: break;
}
}
/* Hack for scheduled undo notification */
cli *cmd_reconfig_stored_cli;
void
cmd_reconfig_undo_notify(void)
{
if (cmd_reconfig_stored_cli)
{
cli *c = cmd_reconfig_stored_cli;
cli_printf(c, CLI_ASYNC_CODE, "Config timeout expired, starting undo");
cli_write_trigger(c);
}
}
void
cmd_reconfig(char *name, int type, int timeout)
{
if (cli_access_restricted())
return;
struct config *conf = cmd_read_config(name);
if (!conf)
return;
int r = config_commit(conf, type, timeout);
if ((r >= 0) && (timeout > 0))
{
cmd_reconfig_stored_cli = this_cli;
cli_msg(-22, "Undo scheduled in %d s", timeout);
}
cmd_reconfig_msg(r);
}
void
cmd_reconfig_confirm(void)
{
if (cli_access_restricted())
return;
int r = config_confirm();
cmd_reconfig_msg(r);
}
void
cmd_reconfig_undo(void)
{
if (cli_access_restricted())
return;
cli_msg(-21, "Undo requested");
int r = config_undo();
cmd_reconfig_msg(r);
}
/*
* Command-Line Interface
*/
@@ -623,6 +691,7 @@ main(int argc, char **argv)
rt_init();
if_init();
roa_init();
config_init();
uid_t use_uid = get_uid(use_user);
gid_t use_gid = get_gid(use_group);

View File

@@ -32,6 +32,7 @@ void tm_dump_all(void);
extern bird_clock_t now; /* Relative, monotonic time in seconds */
extern bird_clock_t now_real; /* Time in seconds since fixed known epoch */
extern bird_clock_t boot_time;
static inline bird_clock_t
tm_remains(timer *t)

View File

@@ -19,9 +19,14 @@ extern char *bird_name;
void async_config(void);
void async_dump(void);
void async_shutdown(void);
void cmd_reconfig(char *name, int type);
void cmd_check_config(char *name);
void cmd_reconfig(char *name, int type, int timeout);
void cmd_reconfig_confirm(void);
void cmd_reconfig_undo(void);
void cmd_shutdown(void);
#define UNIX_DEFAULT_CONFIGURE_TIMEOUT 300
/* io.c */
volatile int async_config_flag;