mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-15 13:27:53 +00:00
Merge pull request #10996 from donaldsharp/watchfrr_systemd_interactions
watchfrr: Send operational state to systemd
This commit is contained in:
commit
af280434ed
@ -54,6 +54,7 @@
|
|||||||
#define DEFAULT_LOGLEVEL LOG_INFO
|
#define DEFAULT_LOGLEVEL LOG_INFO
|
||||||
#define DEFAULT_MIN_RESTART 60
|
#define DEFAULT_MIN_RESTART 60
|
||||||
#define DEFAULT_MAX_RESTART 600
|
#define DEFAULT_MAX_RESTART 600
|
||||||
|
#define DEFAULT_OPERATIONAL_TIMEOUT 60
|
||||||
|
|
||||||
#define DEFAULT_RESTART_CMD WATCHFRR_SH_PATH " restart %s"
|
#define DEFAULT_RESTART_CMD WATCHFRR_SH_PATH " restart %s"
|
||||||
#define DEFAULT_START_CMD WATCHFRR_SH_PATH " start %s"
|
#define DEFAULT_START_CMD WATCHFRR_SH_PATH " start %s"
|
||||||
@ -106,12 +107,14 @@ static struct global_state {
|
|||||||
enum restart_phase phase;
|
enum restart_phase phase;
|
||||||
struct thread *t_phase_hanging;
|
struct thread *t_phase_hanging;
|
||||||
struct thread *t_startup_timeout;
|
struct thread *t_startup_timeout;
|
||||||
|
struct thread *t_operational;
|
||||||
const char *vtydir;
|
const char *vtydir;
|
||||||
long period;
|
long period;
|
||||||
long timeout;
|
long timeout;
|
||||||
long restart_timeout;
|
long restart_timeout;
|
||||||
long min_restart_interval;
|
long min_restart_interval;
|
||||||
long max_restart_interval;
|
long max_restart_interval;
|
||||||
|
long operational_timeout;
|
||||||
struct daemon *daemons;
|
struct daemon *daemons;
|
||||||
const char *restart_command;
|
const char *restart_command;
|
||||||
const char *start_command;
|
const char *start_command;
|
||||||
@ -131,6 +134,7 @@ static struct global_state {
|
|||||||
.loglevel = DEFAULT_LOGLEVEL,
|
.loglevel = DEFAULT_LOGLEVEL,
|
||||||
.min_restart_interval = DEFAULT_MIN_RESTART,
|
.min_restart_interval = DEFAULT_MIN_RESTART,
|
||||||
.max_restart_interval = DEFAULT_MAX_RESTART,
|
.max_restart_interval = DEFAULT_MAX_RESTART,
|
||||||
|
.operational_timeout = DEFAULT_OPERATIONAL_TIMEOUT,
|
||||||
.restart_command = DEFAULT_RESTART_CMD,
|
.restart_command = DEFAULT_RESTART_CMD,
|
||||||
.start_command = DEFAULT_START_CMD,
|
.start_command = DEFAULT_START_CMD,
|
||||||
.stop_command = DEFAULT_STOP_CMD,
|
.stop_command = DEFAULT_STOP_CMD,
|
||||||
@ -177,6 +181,7 @@ struct daemon {
|
|||||||
#define OPTION_MAXRESTART 2001
|
#define OPTION_MAXRESTART 2001
|
||||||
#define OPTION_DRY 2002
|
#define OPTION_DRY 2002
|
||||||
#define OPTION_NETNS 2003
|
#define OPTION_NETNS 2003
|
||||||
|
#define OPTION_MAXOPERATIONAL 2004
|
||||||
|
|
||||||
static const struct option longopts[] = {
|
static const struct option longopts[] = {
|
||||||
{"daemon", no_argument, NULL, 'd'},
|
{"daemon", no_argument, NULL, 'd'},
|
||||||
@ -191,6 +196,7 @@ static const struct option longopts[] = {
|
|||||||
{"dry", no_argument, NULL, OPTION_DRY},
|
{"dry", no_argument, NULL, OPTION_DRY},
|
||||||
{"min-restart-interval", required_argument, NULL, OPTION_MINRESTART},
|
{"min-restart-interval", required_argument, NULL, OPTION_MINRESTART},
|
||||||
{"max-restart-interval", required_argument, NULL, OPTION_MAXRESTART},
|
{"max-restart-interval", required_argument, NULL, OPTION_MAXRESTART},
|
||||||
|
{"operational-timeout", required_argument, NULL, OPTION_MAXOPERATIONAL},
|
||||||
{"pid-file", required_argument, NULL, 'p'},
|
{"pid-file", required_argument, NULL, 'p'},
|
||||||
{"blank-string", required_argument, NULL, 'b'},
|
{"blank-string", required_argument, NULL, 'b'},
|
||||||
#ifdef GNU_LINUX
|
#ifdef GNU_LINUX
|
||||||
@ -265,6 +271,9 @@ Otherwise, the interval is doubled (but capped at the -M value).\n\n",
|
|||||||
--max-restart-interval\n\
|
--max-restart-interval\n\
|
||||||
Set the maximum seconds to wait between invocations of daemon\n\
|
Set the maximum seconds to wait between invocations of daemon\n\
|
||||||
restart commands (default is %d).\n\
|
restart commands (default is %d).\n\
|
||||||
|
--operational-timeout\n\
|
||||||
|
Set the time before systemd is notified that we are considered\n\
|
||||||
|
operational again after a daemon restart (default is %d).\n\
|
||||||
-i, --interval Set the status polling interval in seconds (default is %d)\n\
|
-i, --interval Set the status polling interval in seconds (default is %d)\n\
|
||||||
-t, --timeout Set the unresponsiveness timeout in seconds (default is %d)\n\
|
-t, --timeout Set the unresponsiveness timeout in seconds (default is %d)\n\
|
||||||
-T, --restart-timeout\n\
|
-T, --restart-timeout\n\
|
||||||
@ -296,10 +305,10 @@ Otherwise, the interval is doubled (but capped at the -M value).\n\n",
|
|||||||
-v, --version Print program version\n\
|
-v, --version Print program version\n\
|
||||||
-h, --help Display this help and exit\n",
|
-h, --help Display this help and exit\n",
|
||||||
frr_vtydir, DEFAULT_LOGLEVEL, LOG_EMERG, LOG_DEBUG, LOG_DEBUG,
|
frr_vtydir, DEFAULT_LOGLEVEL, LOG_EMERG, LOG_DEBUG, LOG_DEBUG,
|
||||||
DEFAULT_MIN_RESTART, DEFAULT_MAX_RESTART, DEFAULT_PERIOD,
|
DEFAULT_MIN_RESTART, DEFAULT_MAX_RESTART,
|
||||||
DEFAULT_TIMEOUT, DEFAULT_RESTART_TIMEOUT,
|
DEFAULT_OPERATIONAL_TIMEOUT, DEFAULT_PERIOD, DEFAULT_TIMEOUT,
|
||||||
DEFAULT_RESTART_CMD, DEFAULT_START_CMD, DEFAULT_STOP_CMD,
|
DEFAULT_RESTART_TIMEOUT, DEFAULT_RESTART_CMD, DEFAULT_START_CMD,
|
||||||
frr_vtydir);
|
DEFAULT_STOP_CMD, frr_vtydir);
|
||||||
}
|
}
|
||||||
|
|
||||||
static pid_t run_background(char *shell_cmd)
|
static pid_t run_background(char *shell_cmd)
|
||||||
@ -502,8 +511,6 @@ static int run_job(struct restart_info *restart, const char *cmdtype,
|
|||||||
restart->pid = 0;
|
restart->pid = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
systemd_send_status("FRR Operational");
|
|
||||||
|
|
||||||
/* Calculate the new restart interval. */
|
/* Calculate the new restart interval. */
|
||||||
if (update_interval) {
|
if (update_interval) {
|
||||||
if (delay.tv_sec > 2 * gs.max_restart_interval)
|
if (delay.tv_sec > 2 * gs.max_restart_interval)
|
||||||
@ -584,6 +591,11 @@ static void restart_done(struct daemon *dmn)
|
|||||||
SET_WAKEUP_DOWN(dmn);
|
SET_WAKEUP_DOWN(dmn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void daemon_restarting_operational(struct thread *thread)
|
||||||
|
{
|
||||||
|
systemd_send_status("FRR Operational");
|
||||||
|
}
|
||||||
|
|
||||||
static void daemon_down(struct daemon *dmn, const char *why)
|
static void daemon_down(struct daemon *dmn, const char *why)
|
||||||
{
|
{
|
||||||
if (IS_UP(dmn) || (dmn->state == DAEMON_INIT))
|
if (IS_UP(dmn) || (dmn->state == DAEMON_INIT))
|
||||||
@ -603,6 +615,8 @@ static void daemon_down(struct daemon *dmn, const char *why)
|
|||||||
THREAD_OFF(dmn->t_wakeup);
|
THREAD_OFF(dmn->t_wakeup);
|
||||||
if (try_connect(dmn) < 0)
|
if (try_connect(dmn) < 0)
|
||||||
SET_WAKEUP_DOWN(dmn);
|
SET_WAKEUP_DOWN(dmn);
|
||||||
|
|
||||||
|
systemd_send_status("FRR partially operational");
|
||||||
phase_check();
|
phase_check();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -721,8 +735,15 @@ static void daemon_up(struct daemon *dmn, const char *why)
|
|||||||
gs.numdown--;
|
gs.numdown--;
|
||||||
dmn->connect_tries = 0;
|
dmn->connect_tries = 0;
|
||||||
zlog_notice("%s state -> up : %s", dmn->name, why);
|
zlog_notice("%s state -> up : %s", dmn->name, why);
|
||||||
if (gs.numdown == 0)
|
if (gs.numdown == 0) {
|
||||||
daemon_send_ready(0);
|
daemon_send_ready(0);
|
||||||
|
|
||||||
|
THREAD_OFF(gs.t_operational);
|
||||||
|
|
||||||
|
thread_add_timer(master, daemon_restarting_operational, NULL,
|
||||||
|
gs.operational_timeout, &gs.t_operational);
|
||||||
|
}
|
||||||
|
|
||||||
SET_WAKEUP_ECHO(dmn);
|
SET_WAKEUP_ECHO(dmn);
|
||||||
phase_check();
|
phase_check();
|
||||||
}
|
}
|
||||||
@ -889,6 +910,7 @@ static void phase_check(void)
|
|||||||
case PHASE_WAITING_DOWN:
|
case PHASE_WAITING_DOWN:
|
||||||
if (gs.numdown + IS_UP(gs.special) < gs.numdaemons)
|
if (gs.numdown + IS_UP(gs.special) < gs.numdaemons)
|
||||||
break;
|
break;
|
||||||
|
systemd_send_status("Phased Restart");
|
||||||
zlog_info("Phased restart: all routing daemons now down.");
|
zlog_info("Phased restart: all routing daemons now down.");
|
||||||
run_job(&gs.special->restart, "restart", gs.restart_command, 1,
|
run_job(&gs.special->restart, "restart", gs.restart_command, 1,
|
||||||
1);
|
1);
|
||||||
@ -898,6 +920,7 @@ static void phase_check(void)
|
|||||||
case PHASE_ZEBRA_RESTART_PENDING:
|
case PHASE_ZEBRA_RESTART_PENDING:
|
||||||
if (gs.special->restart.pid)
|
if (gs.special->restart.pid)
|
||||||
break;
|
break;
|
||||||
|
systemd_send_status("Zebra Restarting");
|
||||||
zlog_info("Phased restart: %s restart job completed.",
|
zlog_info("Phased restart: %s restart job completed.",
|
||||||
gs.special->name);
|
gs.special->name);
|
||||||
set_phase(PHASE_WAITING_ZEBRA_UP);
|
set_phase(PHASE_WAITING_ZEBRA_UP);
|
||||||
@ -1395,6 +1418,18 @@ int main(int argc, char **argv)
|
|||||||
frr_help_exit(1);
|
frr_help_exit(1);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
case OPTION_MAXOPERATIONAL: {
|
||||||
|
char garbage[3];
|
||||||
|
|
||||||
|
if ((sscanf(optarg, "%ld%1s", &gs.operational_timeout,
|
||||||
|
garbage) != 1) ||
|
||||||
|
(gs.max_restart_interval < 0)) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Invalid Operational_timeout argument: %s\n",
|
||||||
|
optarg);
|
||||||
|
frr_help_exit(1);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
case OPTION_NETNS:
|
case OPTION_NETNS:
|
||||||
netns_en = true;
|
netns_en = true;
|
||||||
if (optarg && strchr(optarg, '/')) {
|
if (optarg && strchr(optarg, '/')) {
|
||||||
|
Loading…
Reference in New Issue
Block a user