From d3292ee776448de67241bf7efc8f9bb23f166752 Mon Sep 17 00:00:00 2001 From: Quentin Armitage Date: Fri, 2 Feb 2018 10:12:06 +0000 Subject: [PATCH 1/8] Add child_wait_time to allow longer shutdown time of child processes With very large configurations it can be necessary to allow longer than the default 5 seconds for child processes to cleanup and terminate. Signed-off-by: Quentin Armitage --- doc/keepalived.conf.SYNOPSIS | 5 ++++- doc/man/man5/keepalived.conf.5 | 3 +++ keepalived/core/global_parser.c | 19 +++++++++++++++++++ keepalived/core/main.c | 12 +++++++----- keepalived/include/main.h | 3 +++ lib/parser.c | 2 ++ 6 files changed, 38 insertions(+), 6 deletions(-) diff --git a/doc/keepalived.conf.SYNOPSIS b/doc/keepalived.conf.SYNOPSIS index 90eb83d4..3d042b1c 100644 --- a/doc/keepalived.conf.SYNOPSIS +++ b/doc/keepalived.conf.SYNOPSIS @@ -176,7 +176,10 @@ use_pid_dir # Create pid files in /var/run/keepalived linkbeat_use_polling # Use media link failure detection polling fashion - 1.2. Static addresses +child_wait_time SECS # Time for main process to allow for child processes to exit on termination + # in seconds (default 5). This can be needed for very large configurations. + + 1.2. Static addresses The configuration block looks like : diff --git a/doc/man/man5/keepalived.conf.5 b/doc/man/man5/keepalived.conf.5 index 1dabdec7..d0d04727 100644 --- a/doc/man/man5/keepalived.conf.5 +++ b/doc/man/man5/keepalived.conf.5 @@ -219,6 +219,9 @@ and linkbeat_use_polling # Poll to detect media link failure otherwise attempt to use ETHTOOL or MII interface + child_wait_time SECS # Time for main process to allow for child processes to exit on termination + # in seconds (default 5). This can be needed for very large configurations. + .SH Static routes/addresses/rules .PP Keepalived can configure static addresses, routes, and rules. These addresses are diff --git a/keepalived/core/global_parser.c b/keepalived/core/global_parser.c index a59fbc0b..e8ed6333 100644 --- a/keepalived/core/global_parser.c +++ b/keepalived/core/global_parser.c @@ -719,6 +719,24 @@ script_security_handler(__attribute__((unused)) vector_t *strvec) global_data->script_security = true; } +static void +child_wait_handler(vector_t *strvec) +{ + char *endptr; + unsigned long secs; + + if (!strvec) + return; + + secs = strtoul(strvec_slot(strvec,1), &endptr, 10); + if (*endptr) { + log_message(LOG_INFO, "Invalid child_wait_time %s", FMT_STR_VSLOT(strvec, 1)); + return; + } + + child_wait_time = secs; +} + void init_global_keywords(bool global_active) { @@ -730,6 +748,7 @@ init_global_keywords(bool global_active) #endif install_keyword_root("use_pid_dir", &use_pid_dir_handler, !global_active); install_keyword_root("instance", &instance_handler, !global_active); + install_keyword_root("child_wait_time", &child_wait_handler, !global_active); install_keyword_root("global_defs", NULL, global_active); install_keyword("router_id", &routerid_handler); install_keyword("notification_email_from", &emailfrom_handler); diff --git a/keepalived/core/main.c b/keepalived/core/main.c index 95bb76a9..51f83a07 100644 --- a/keepalived/core/main.c +++ b/keepalived/core/main.c @@ -93,6 +93,8 @@ bool namespace_with_ipsets; /* Override for using namespaces and ipsets with static char *override_namespace; /* If namespace specified on command line */ #endif +unsigned child_wait_time = CHILD_WAIT_SECS; /* Time to wait for children to exit */ + /* Log facility table */ static struct { int facility; @@ -359,7 +361,7 @@ sigend(__attribute__((unused)) void *v, __attribute__((unused)) int sig) int wait_count = 0; sigset_t old_set, child_wait; struct timespec timeout = { - .tv_sec = CHILD_WAIT_SECS, + .tv_sec = child_wait_time, .tv_nsec = 0 }; struct timeval start_time, now; @@ -416,17 +418,17 @@ sigend(__attribute__((unused)) void *v, __attribute__((unused)) int sig) gettimeofday(&now, NULL); if (now.tv_usec < start_time.tv_usec) { timeout.tv_nsec = (start_time.tv_usec - now.tv_usec) * 1000; - timeout.tv_sec = CHILD_WAIT_SECS - (now.tv_sec - start_time.tv_sec); + timeout.tv_sec = child_wait_time - (now.tv_sec - start_time.tv_sec); } else if (now.tv_usec == start_time.tv_usec) { timeout.tv_nsec = 0; - timeout.tv_sec = CHILD_WAIT_SECS - (now.tv_sec - start_time.tv_sec); + timeout.tv_sec = child_wait_time - (now.tv_sec - start_time.tv_sec); } else { timeout.tv_nsec = (1000000L + start_time.tv_usec - now.tv_usec) * 1000; - timeout.tv_sec = CHILD_WAIT_SECS - (now.tv_sec - start_time.tv_sec + 1); + timeout.tv_sec = child_wait_time - (now.tv_sec - start_time.tv_sec + 1); } timeout.tv_nsec = (start_time.tv_usec - now.tv_usec) * 1000; - timeout.tv_sec = CHILD_WAIT_SECS - (now.tv_sec - start_time.tv_sec); + timeout.tv_sec = child_wait_time - (now.tv_sec - start_time.tv_sec); if (timeout.tv_nsec < 0) { timeout.tv_nsec += 1000000000L; timeout.tv_sec--; diff --git a/keepalived/include/main.h b/keepalived/include/main.h index eebde77e..b03a7efd 100644 --- a/keepalived/include/main.h +++ b/keepalived/include/main.h @@ -82,4 +82,7 @@ extern void free_parent_mallocs_exit(void); extern char *make_syslog_ident(const char*); extern int keepalived_main(int, char**); /* The "real" main function */ + +extern unsigned child_wait_time; + #endif diff --git a/lib/parser.c b/lib/parser.c index a5c3465b..2e1beac8 100644 --- a/lib/parser.c +++ b/lib/parser.c @@ -120,6 +120,8 @@ install_sublevel_end(void) void install_keyword_root(const char *string, void (*handler) (vector_t *), bool active) { + /* If the root keyword is inactive, the handler will still be called, + * but with a NULL strvec */ keyword_alloc(keywords, string, handler, active); } -- 2.20.1