summaryrefslogtreecommitdiffstats
path: root/watchfrr
diff options
context:
space:
mode:
authorDavid Lamparter <equinox@opensourcerouting.org>2016-11-13 08:02:23 +0100
committerDavid Lamparter <equinox@opensourcerouting.org>2017-03-07 23:07:20 +0100
commit4f04a76b717fc4881a547f582a02a4d06d356c47 (patch)
tree90951be570b6de3889da7c5358b1fe2f998d4acd /watchfrr
parentMerge pull request #257 from opensourcerouting/nhrpd (diff)
downloadfrr-4f04a76b717fc4881a547f582a02a4d06d356c47.tar.xz
frr-4f04a76b717fc4881a547f582a02a4d06d356c47.zip
*: add frr_init() infrastructure
Start centralising startup & option parsing into the library. FRR_DAEMON_INFO is a bit weird, but it will become useful later (e.g. for killing the ZLOG_* enum, and having the daemon name available) Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Diffstat (limited to 'watchfrr')
-rw-r--r--watchfrr/watchfrr.c150
1 files changed, 71 insertions, 79 deletions
diff --git a/watchfrr/watchfrr.c b/watchfrr/watchfrr.c
index f61dd3858..f6ea77b60 100644
--- a/watchfrr/watchfrr.c
+++ b/watchfrr/watchfrr.c
@@ -26,6 +26,7 @@
#include <lib/version.h>
#include "command.h"
#include "memory_vty.h"
+#include "libfrr.h"
#include <getopt.h>
#include <sys/un.h>
@@ -202,13 +203,10 @@ static int wakeup_send_echo(struct thread *t_wakeup);
static void try_restart(struct daemon *dmn);
static void phase_check(void);
-static int usage(const char *progname, int status)
+static const char *progname;
+static void printhelp(FILE *target)
{
- if (status != 0)
- fprintf(stderr, "Try `%s --help' for more information.\n",
- progname);
- else {
- printf("Usage : %s [OPTION...] <daemon name> ...\n\n\
+ fprintf(target, "Usage : %s [OPTION...] <daemon name> ...\n\n\
Watchdog program to monitor status of frr daemons and try to restart\n\
them if they are down or unresponsive. It determines whether a daemon is\n\
up based on whether it can connect to the daemon's vty unix stream socket.\n\
@@ -254,7 +252,7 @@ a restart is attempted: if the time since the last restart attempt exceeds\n\
twice the -M value, then the restart delay is set to the -m value.\n\
Otherwise, the interval is doubled (but capped at the -M value).\n\n", progname, mode_str[0], progname, mode_str[1], progname, mode_str[2], progname, mode_str[3], progname, mode_str[4], progname, mode_str[2], mode_str[3]);
- printf("Options:\n\
+ fprintf(target, "Options:\n\
-d, --daemon Run in daemon mode. In this mode, error messages are sent\n\
to syslog instead of stdout.\n\
-S, --statedir Set the vty socket directory (default is %s)\n\
@@ -313,9 +311,6 @@ Otherwise, the interval is doubled (but capped at the -M value).\n\n", progname,
passing command-line arguments with embedded spaces.\n\
-v, --version Print program version\n\
-h, --help Display this help and exit\n", VTYDIR, DEFAULT_LOGLEVEL, LOG_EMERG, LOG_DEBUG, LOG_DEBUG, DEFAULT_MIN_RESTART, DEFAULT_MAX_RESTART, DEFAULT_PERIOD, DEFAULT_TIMEOUT, DEFAULT_RESTART_TIMEOUT, DEFAULT_PIDFILE);
- }
-
- return status;
}
static pid_t run_background(char *shell_cmd)
@@ -1011,38 +1006,48 @@ struct zebra_privs_t watchfrr_privs = {
#endif
};
+static struct quagga_signal_t watchfrr_signals[] = {
+ {
+ .signal = SIGINT,
+ .handler = sigint,
+ },
+ {
+ .signal = SIGTERM,
+ .handler = sigint,
+ },
+ {
+ .signal = SIGCHLD,
+ .handler = sigchild,
+ },
+};
+
+FRR_DAEMON_INFO(watchfrr, WATCHFRR,
+ .flags = FRR_NO_PRIVSEP | FRR_NO_TCPVTY,
+
+ .printhelp = printhelp,
+ .copyright = "Copyright 2004 Andrew J. Schorr",
+
+ .signals = watchfrr_signals,
+ .n_signals = array_size(watchfrr_signals),
+
+ .privs = &watchfrr_privs,
+)
+
int main(int argc, char **argv)
{
- const char *progname;
int opt;
int daemon_mode = 0;
const char *pidfile = DEFAULT_PIDFILE;
const char *special = "zebra";
const char *blankstr = NULL;
- static struct quagga_signal_t my_signals[] = {
- {
- .signal = SIGINT,
- .handler = sigint,
- },
- {
- .signal = SIGTERM,
- .handler = sigint,
- },
- {
- .signal = SIGCHLD,
- .handler = sigchild,
- },
- };
- if ((progname = strrchr(argv[0], '/')) != NULL)
- progname++;
- else
- progname = argv[0];
+ frr_preinit(&watchfrr_di, argc, argv);
+ progname = watchfrr_di.progname;
+
+ frr_opt_add("aAb:dek:l:m:M:i:p:r:R:S:s:t:T:z", longopts, "");
gs.restart.name = "all";
- while ((opt =
- getopt_long(argc, argv, "aAb:dek:l:m:M:i:p:r:R:S:s:t:T:zvh",
- longopts, 0)) != EOF) {
+ while ((opt = frr_getopt(argc, argv, NULL)) != EOF) {
switch (opt) {
case 0:
break;
@@ -1051,7 +1056,7 @@ int main(int argc, char **argv)
&& (gs.mode != MODE_SEPARATE_RESTART)) {
fputs("Ambiguous operating mode selected.\n",
stderr);
- return usage(progname, 1);
+ frr_help_exit(1);
}
gs.mode = MODE_PHASED_ZEBRA_RESTART;
break;
@@ -1060,7 +1065,7 @@ int main(int argc, char **argv)
&& (gs.mode != MODE_SEPARATE_RESTART)) {
fputs("Ambiguous operating mode selected.\n",
stderr);
- return usage(progname, 1);
+ frr_help_exit(1);
}
gs.mode = MODE_PHASED_ALL_RESTART;
break;
@@ -1078,7 +1083,7 @@ int main(int argc, char **argv)
fprintf(stderr,
"Invalid kill command, must contain '%%s': %s\n",
optarg);
- return usage(progname, 1);
+ frr_help_exit(1);
}
gs.stop_command = optarg;
break;
@@ -1092,7 +1097,7 @@ int main(int argc, char **argv)
fprintf(stderr,
"Invalid loglevel argument: %s\n",
optarg);
- return usage(progname, 1);
+ frr_help_exit(1);
}
}
break;
@@ -1106,7 +1111,7 @@ int main(int argc, char **argv)
fprintf(stderr,
"Invalid min_restart_interval argument: %s\n",
optarg);
- return usage(progname, 1);
+ frr_help_exit(1);
}
}
break;
@@ -1120,7 +1125,7 @@ int main(int argc, char **argv)
fprintf(stderr,
"Invalid max_restart_interval argument: %s\n",
optarg);
- return usage(progname, 1);
+ frr_help_exit(1);
}
}
break;
@@ -1133,7 +1138,7 @@ int main(int argc, char **argv)
fprintf(stderr,
"Invalid interval argument: %s\n",
optarg);
- return usage(progname, 1);
+ frr_help_exit(1);
}
gs.period = 1000 * period;
}
@@ -1146,13 +1151,13 @@ int main(int argc, char **argv)
(gs.mode == MODE_SEPARATE_RESTART)) {
fputs("Ambiguous operating mode selected.\n",
stderr);
- return usage(progname, 1);
+ frr_help_exit(1);
}
if (!valid_command(optarg)) {
fprintf(stderr,
"Invalid restart command, must contain '%%s': %s\n",
optarg);
- return usage(progname, 1);
+ frr_help_exit(1);
}
gs.restart_command = optarg;
if (gs.mode == MODE_MONITOR)
@@ -1162,13 +1167,13 @@ int main(int argc, char **argv)
if (gs.mode != MODE_MONITOR) {
fputs("Ambiguous operating mode selected.\n",
stderr);
- return usage(progname, 1);
+ frr_help_exit(1);
}
if (strchr(optarg, '%')) {
fprintf(stderr,
"Invalid restart-all arg, must not contain '%%s': %s\n",
optarg);
- return usage(progname, 1);
+ frr_help_exit(1);
}
gs.restart_command = optarg;
gs.mode = MODE_GLOBAL_RESTART;
@@ -1178,7 +1183,7 @@ int main(int argc, char **argv)
fprintf(stderr,
"Invalid start command, must contain '%%s': %s\n",
optarg);
- return usage(progname, 1);
+ frr_help_exit(1);
}
gs.start_command = optarg;
break;
@@ -1194,7 +1199,7 @@ int main(int argc, char **argv)
fprintf(stderr,
"Invalid timeout argument: %s\n",
optarg);
- return usage(progname, 1);
+ frr_help_exit(1);
}
}
break;
@@ -1208,29 +1213,23 @@ int main(int argc, char **argv)
fprintf(stderr,
"Invalid restart timeout argument: %s\n",
optarg);
- return usage(progname, 1);
+ frr_help_exit(1);
}
}
break;
case 'z':
gs.unresponsive_restart = 1;
break;
- case 'v':
- printf("%s version %s\n", progname, FRR_VERSION);
- puts("Copyright 2004 Andrew J. Schorr");
- return 0;
- case 'h':
- return usage(progname, 0);
default:
fputs("Invalid option.\n", stderr);
- return usage(progname, 1);
+ frr_help_exit(1);
}
}
if (gs.unresponsive_restart && (gs.mode == MODE_MONITOR)) {
fputs("Option -z requires a -r or -R restart option.\n",
stderr);
- return usage(progname, 1);
+ frr_help_exit(1);
}
switch (gs.mode) {
case MODE_MONITOR:
@@ -1238,7 +1237,7 @@ int main(int argc, char **argv)
fprintf(stderr,
"No kill/(re)start commands needed for %s mode.\n",
mode_str[gs.mode]);
- return usage(progname, 1);
+ frr_help_exit(1);
}
break;
case MODE_GLOBAL_RESTART:
@@ -1247,7 +1246,7 @@ int main(int argc, char **argv)
fprintf(stderr,
"No start/kill commands needed in [%s] mode.\n",
mode_str[gs.mode]);
- return usage(progname, 1);
+ frr_help_exit(1);
}
break;
case MODE_PHASED_ZEBRA_RESTART:
@@ -1257,7 +1256,7 @@ int main(int argc, char **argv)
fprintf(stderr,
"Need start, kill, and restart commands in [%s] mode.\n",
mode_str[gs.mode]);
- return usage(progname, 1);
+ frr_help_exit(1);
}
break;
}
@@ -1276,17 +1275,25 @@ int main(int argc, char **argv)
gs.restart.interval = gs.min_restart_interval;
- zprivs_init(&watchfrr_privs);
+ master = frr_init();
+
+ zlog_set_level(NULL, ZLOG_DEST_MONITOR, ZLOG_DISABLED);
+ if (daemon_mode) {
+ zlog_set_level(NULL, ZLOG_DEST_SYSLOG, MIN(gs.loglevel, LOG_DEBUG));
+ if (daemon (0, 0) < 0) {
+ fprintf(stderr, "Watchquagga daemon failed: %s",
+ strerror(errno));
+ exit (1);
+ }
+ } else
+ zlog_set_level(NULL, ZLOG_DEST_STDOUT, MIN(gs.loglevel, LOG_DEBUG));
- master = thread_master_create();
cmd_init(-1);
memory_init();
vty_init(master);
watchfrr_vty_init();
- vty_serv_sock(NULL, 0, WATCHFRR_VTYSH_PATH);
- signal_init(master, array_size(my_signals), my_signals);
- srandom(time(NULL));
+ frr_vty_serv(WATCHFRR_VTYSH_PATH);
{
int i;
@@ -1324,31 +1331,16 @@ int main(int argc, char **argv)
}
if (!gs.daemons) {
fputs("Must specify one or more daemons to monitor.\n", stderr);
- return usage(progname, 1);
+ frr_help_exit(1);
}
if (((gs.mode == MODE_PHASED_ZEBRA_RESTART) ||
(gs.mode == MODE_PHASED_ALL_RESTART)) && !gs.special) {
fprintf(stderr,
"In mode [%s], but cannot find master daemon %s\n",
mode_str[gs.mode], special);
- return usage(progname, 1);
+ frr_help_exit(1);
}
- zlog_default = openzlog(progname, ZLOG_WATCHFRR, 0,
- LOG_CONS | LOG_NDELAY | LOG_PID, LOG_DAEMON);
- zlog_set_level(NULL, ZLOG_DEST_MONITOR, ZLOG_DISABLED);
- if (daemon_mode) {
- zlog_set_level(NULL, ZLOG_DEST_SYSLOG,
- MIN(gs.loglevel, LOG_DEBUG));
- if (daemon(0, 0) < 0) {
- fprintf(stderr, "Watchfrr daemon failed: %s",
- strerror(errno));
- exit(1);
- }
- } else
- zlog_set_level(NULL, ZLOG_DEST_STDOUT,
- MIN(gs.loglevel, LOG_DEBUG));
-
/* Make sure we're not already running. */
pid_output(pidfile);