summaryrefslogtreecommitdiff
path: root/lib/libfrr.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libfrr.c')
-rw-r--r--lib/libfrr.c56
1 files changed, 55 insertions, 1 deletions
diff --git a/lib/libfrr.c b/lib/libfrr.c
index a5c87e6edc..9944fdd1e1 100644
--- a/lib/libfrr.c
+++ b/lib/libfrr.c
@@ -37,6 +37,8 @@
#include "network.h"
DEFINE_HOOK(frr_late_init, (struct thread_master * tm), (tm))
+DEFINE_KOOH(frr_early_fini, (), ())
+DEFINE_KOOH(frr_fini, (), ())
const char frr_sysconfdir[] = SYSCONFDIR;
const char frr_vtydir[] = DAEMON_VTY_DIR;
@@ -50,6 +52,8 @@ char frr_zclientpath[256];
static char pidfile_default[256];
static char vtypath_default[256];
+bool debug_memstats_at_exit = 0;
+
static char comb_optstr[256];
static struct option comb_lo[64];
static struct option *comb_next_lo = &comb_lo[0];
@@ -637,7 +641,10 @@ static void frr_daemon_wait(int fd)
exit(0);
/* child failed one way or another ... */
- if (WIFEXITED(exitstat))
+ if (WIFEXITED(exitstat) && WEXITSTATUS(exitstat) == 0)
+ /* can happen in --terminal case if exit is fast enough */
+ (void)0;
+ else if (WIFEXITED(exitstat))
fprintf(stderr, "%s failed to start, exited %d\n", di->name,
WEXITSTATUS(exitstat));
else if (WIFSIGNALED(exitstat))
@@ -831,3 +838,50 @@ void frr_run(struct thread_master *master)
while (thread_fetch(master, &thread))
thread_call(&thread);
}
+
+void frr_early_fini(void)
+{
+ hook_call(frr_early_fini);
+}
+
+void frr_fini(void)
+{
+ FILE *fp;
+ char filename[128];
+ int have_leftovers;
+
+ hook_call(frr_fini);
+
+ /* memory_init -> nothing needed */
+ vty_terminate();
+ cmd_terminate();
+ zprivs_terminate(di->privs);
+ /* signal_init -> nothing needed */
+ thread_master_free(master);
+ closezlog();
+ /* frrmod_init -> nothing needed / hooks */
+
+ if (!debug_memstats_at_exit)
+ return;
+
+ have_leftovers = log_memstats(stderr, di->name);
+
+ /* in case we decide at runtime that we want exit-memstats for
+ * a daemon, but it has no stderr because it's daemonized
+ * (only do this if we actually have something to print though)
+ */
+ if (!have_leftovers)
+ return;
+
+ snprintf(filename, sizeof(filename),
+ "/tmp/frr-memstats-%s-%llu-%llu",
+ di->name,
+ (unsigned long long)getpid(),
+ (unsigned long long)time(NULL));
+
+ fp = fopen(filename, "w");
+ if (fp) {
+ log_memstats(fp, di->name);
+ fclose(fp);
+ }
+}