diff --git a/SOURCES/bz1678480-add-child_wait_time.patch b/SOURCES/bz1678480-add-child_wait_time.patch new file mode 100644 index 0000000..11e4db7 --- /dev/null +++ b/SOURCES/bz1678480-add-child_wait_time.patch @@ -0,0 +1,158 @@ +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 + diff --git a/SOURCES/bz1678480-fix-checker-coding-style.patch b/SOURCES/bz1678480-fix-checker-coding-style.patch new file mode 100644 index 0000000..6b12508 --- /dev/null +++ b/SOURCES/bz1678480-fix-checker-coding-style.patch @@ -0,0 +1,350 @@ +From 99ad17d4906f478c51b58ab8f288edbca0bab906 Mon Sep 17 00:00:00 2001 +From: YAMAMOTO Masaya +Date: Fri, 14 Jul 2017 14:34:28 +0900 +Subject: [PATCH 6/8] Fix to match coding style + +--- + keepalived/check/check_api.c | 22 ++++++++++------------ + keepalived/check/check_dns.c | 20 +++++++++----------- + keepalived/check/check_http.c | 26 ++++++++++++-------------- + keepalived/check/check_misc.c | 18 ++++++++---------- + keepalived/check/check_smtp.c | 26 ++++++++++++-------------- + keepalived/check/check_tcp.c | 18 ++++++++---------- + keepalived/include/check_api.h | 6 +++--- + 7 files changed, 62 insertions(+), 74 deletions(-) + +diff --git a/keepalived/check/check_api.c b/keepalived/check/check_api.c +index a722fc84..1d915414 100644 +--- a/keepalived/check/check_api.c ++++ b/keepalived/check/check_api.c +@@ -81,7 +81,7 @@ dump_conn_opts(void *data) + void + queue_checker(void (*free_func) (void *), void (*dump_func) (void *) + , int (*launch) (thread_t *) +- , int (*compare) (void *, void *) ++ , bool (*compare) (void *, void *) + , void *data + , conn_opts_t *co) + { +@@ -120,28 +120,26 @@ queue_checker(void (*free_func) (void *), void (*dump_func) (void *) + } + } + +-int ++bool + compare_conn_opts(conn_opts_t *a, conn_opts_t *b) + { + if (a == b) +- return 0; ++ return true; + + if (!a || !b) +- goto err; ++ return false; + if (!sockstorage_equal(&a->dst, &b->dst)) +- goto err; ++ return false; + if (!sockstorage_equal(&a->bindto, &b->bindto)) +- goto err; +- //if (a->connection_to != b->connection_to) +- // goto err; ++ return false; ++ if (a->connection_to != b->connection_to) ++ return false; + #ifdef _WITH_SO_MARK_ + if (a->fwmark != b->fwmark) +- goto err; ++ return false; + #endif + +- return 0; +-err: +- return -1; ++ return true; + } + + static void +diff --git a/keepalived/check/check_dns.c b/keepalived/check/check_dns.c +index 84a5f56d..603742a4 100644 +--- a/keepalived/check/check_dns.c ++++ b/keepalived/check/check_dns.c +@@ -388,24 +388,22 @@ dns_dump(void *data) + log_message(LOG_INFO, " Name = %s", dns_check->name); + } + +-static int +-dns_compare(void *a, void *b) ++static bool ++dns_check_compare(void *a, void *b) + { + dns_check_t *old = CHECKER_DATA(a); + dns_check_t *new = CHECKER_DATA(b); + +- if (compare_conn_opts(CHECKER_CO(a), CHECKER_CO(b)) != 0) +- goto err; ++ if (!compare_conn_opts(CHECKER_CO(a), CHECKER_CO(b))) ++ return false; + if (old->retry != new->retry) +- goto err; ++ return false; + if (strcmp(old->type, new->type) != 0) +- goto err; ++ return false; + if (strcmp(old->name, new->name) != 0) +- goto err; ++ return false; + +- return 0; +-err: +- return -1; ++ return true; + } + + static void +@@ -417,7 +415,7 @@ dns_check_handler(__attribute__((unused)) vector_t * strvec) + dns_check->type = DNS_DEFAULT_TYPE; + dns_check->name = DNS_DEFAULT_NAME; + queue_checker(dns_free, dns_dump, dns_connect_thread, +- dns_compare, dns_check, CHECKER_NEW_CO()); ++ dns_check_compare, dns_check, CHECKER_NEW_CO()); + } + + static void +diff --git a/keepalived/check/check_http.c b/keepalived/check/check_http.c +index c2089a3b..1ad395cf 100644 +--- a/keepalived/check/check_http.c ++++ b/keepalived/check/check_http.c +@@ -123,36 +123,34 @@ alloc_http_get(char *proto) + return http_get_chk; + } + +-static int +-compare_http_get_check(void *a, void *b) ++static bool ++http_get_check_compare(void *a, void *b) + { + http_checker_t *old = CHECKER_DATA(a); + http_checker_t *new = CHECKER_DATA(b); + size_t n; + url_t *u1, *u2; + +- if (compare_conn_opts(CHECKER_CO(a), CHECKER_CO(b)) != 0) +- goto err; ++ if (!compare_conn_opts(CHECKER_CO(a), CHECKER_CO(b))) ++ return false; + if (old->nb_get_retry != new->nb_get_retry) +- goto err; ++ return false; + if (old->delay_before_retry != new->delay_before_retry) +- goto err; ++ return false; + if (LIST_SIZE(old->url) != LIST_SIZE(new->url)) +- goto err; ++ return false; + for (n = 0; n < LIST_SIZE(new->url); n++) { + u1 = (url_t *)list_element(old->url, n); + u2 = (url_t *)list_element(new->url, n); + if (strcmp(u1->path, u2->path) != 0) +- goto err; ++ return false; + if (strcmp(u1->digest, u2->digest) != 0) +- goto err; ++ return false; + if (u1->status_code != u2->status_code) +- goto err; ++ return false; + } + +- return 0; +-err: +- return -1; ++ return true; + } + + static void +@@ -164,7 +162,7 @@ http_get_handler(vector_t *strvec) + /* queue new checker */ + http_get_chk = alloc_http_get(str); + queue_checker(free_http_get_check, dump_http_get_check, +- http_connect_thread, compare_http_get_check, ++ http_connect_thread, http_get_check_compare, + http_get_chk, CHECKER_NEW_CO()); + } + +diff --git a/keepalived/check/check_misc.c b/keepalived/check/check_misc.c +index 311a1127..f1f66955 100644 +--- a/keepalived/check/check_misc.c ++++ b/keepalived/check/check_misc.c +@@ -72,24 +72,22 @@ dump_misc_check(void *data) + log_message(LOG_INFO, " insecure = %s", misck_checker->insecure ? "Yes" : "No"); + } + +-static int +-compare_misc_check(void *a, void *b) ++static bool ++misc_check_compare(void *a, void *b) + { + misc_checker_t *old = CHECKER_DATA(a); + misc_checker_t *new = CHECKER_DATA(b); + + if (strcmp(old->path, new->path) != 0) +- goto err; ++ return false; + if (old->timeout != new->timeout) +- goto err; ++ return false; + if (old->dynamic != new->dynamic) +- goto err; ++ return false; + if (old->uid != new->uid || new->gid != new->gid) +- goto err; ++ return false; + +- return 0; +-err: +- return -1; ++ return true; + } + + static void +@@ -169,7 +167,7 @@ log_message(LOG_INFO, "Setting uid.gid"); + } + + /* queue new checker */ +- queue_checker(free_misc_check, dump_misc_check, misc_check_thread, compare_misc_check, misck_checker, NULL); ++ queue_checker(free_misc_check, dump_misc_check, misc_check_thread, misc_check_compare, misck_checker, NULL); + misck_checker = NULL; + log_message(LOG_INFO, "Leaving misc_end_handler"); + } +diff --git a/keepalived/check/check_smtp.c b/keepalived/check/check_smtp.c +index e19511cc..44d15e01 100644 +--- a/keepalived/check/check_smtp.c ++++ b/keepalived/check/check_smtp.c +@@ -82,8 +82,8 @@ dump_smtp_check(void *data) + dump_list(smtp_checker->host); + } + +-static int +-compare_smtp_check(void *a, void *b) ++static bool ++smtp_check_compare(void *a, void *b) + { + smtp_checker_t *old = CHECKER_DATA(a); + smtp_checker_t *new = CHECKER_DATA(b); +@@ -91,26 +91,24 @@ compare_smtp_check(void *a, void *b) + smtp_host_t *h1, *h2; + + if (strcmp(old->helo_name, new->helo_name) != 0) +- goto err; ++ return false; + if (old->retry != new->retry) +- goto err; ++ return false; + if (old->db_retry != new->db_retry) +- goto err; +- if (compare_conn_opts(CHECKER_CO(a), CHECKER_CO(b)) != 0) +- goto err; ++ return false; ++ if (!compare_conn_opts(CHECKER_CO(a), CHECKER_CO(b))) ++ return false; + if (LIST_SIZE(old->host) != LIST_SIZE(new->host)) +- goto err; ++ return false; + for (n = 0; n < LIST_SIZE(new->host); n++) { + h1 = (smtp_host_t *)list_element(old->host, n); + h2 = (smtp_host_t *)list_element(new->host, n); +- if (compare_conn_opts(h1, h2) != 0) { +- goto err; ++ if (!compare_conn_opts(h1, h2)) { ++ return false; + } + } + +- return 0; +-err: +- return -1; ++ return true; + } + + /* Allocates a default host structure */ +@@ -167,7 +165,7 @@ smtp_check_handler(__attribute__((unused)) vector_t *strvec) + * void *data, conn_opts_t *) + */ + queue_checker(free_smtp_check, dump_smtp_check, smtp_connect_thread, +- compare_smtp_check, smtp_checker, smtp_checker->default_co); ++ smtp_check_compare, smtp_checker, smtp_checker->default_co); + + /* + * Last, allocate the list that will hold all the per host +diff --git a/keepalived/check/check_tcp.c b/keepalived/check/check_tcp.c +index 026a0e3c..1858f5fc 100644 +--- a/keepalived/check/check_tcp.c ++++ b/keepalived/check/check_tcp.c +@@ -62,22 +62,20 @@ dump_tcp_check(void *data) + } + } + +-static int +-compare_tcp_check(void *a, void *b) ++static bool ++tcp_check_compare(void *a, void *b) + { + tcp_check_t *old = CHECKER_DATA(a); + tcp_check_t *new = CHECKER_DATA(b); + +- if (compare_conn_opts(CHECKER_CO(a), CHECKER_CO(b)) != 0) +- goto err; ++ if (!compare_conn_opts(CHECKER_CO(a), CHECKER_CO(b))) ++ return false; + if (old->n_retry != new->n_retry) +- goto err; ++ return false; + if (old->delay_before_retry != new->delay_before_retry) +- goto err; ++ return false; + +- return 0; +-err: +- return -1; ++ return true; + } + + static void +@@ -91,7 +89,7 @@ tcp_check_handler(__attribute__((unused)) vector_t *strvec) + + /* queue new checker */ + queue_checker(free_tcp_check, dump_tcp_check, tcp_connect_thread, +- compare_tcp_check, tcp_check, CHECKER_NEW_CO()); ++ tcp_check_compare, tcp_check, CHECKER_NEW_CO()); + } + + static void +diff --git a/keepalived/include/check_api.h b/keepalived/include/check_api.h +index 4a10a36b..c7bc297d 100644 +--- a/keepalived/include/check_api.h ++++ b/keepalived/include/check_api.h +@@ -36,7 +36,7 @@ typedef struct _checker { + void (*free_func) (void *); + void (*dump_func) (void *); + int (*launch) (struct _thread *); +- int (*compare) (void *, void *); ++ bool (*compare) (void *, void *); + virtual_server_t *vs; /* pointer to the checker thread virtualserver */ + real_server_t *rs; /* pointer to the checker thread realserver */ + void *data; +@@ -71,10 +71,10 @@ extern void init_checkers_queue(void); + extern void dump_conn_opts(void *); + extern void queue_checker(void (*free_func) (void *), void (*dump_func) (void *) + , int (*launch) (thread_t *) +- , int (*compare) (void *, void *) ++ , bool (*compare) (void *, void *) + , void * + , conn_opts_t *); +-extern int compare_conn_opts(conn_opts_t *, conn_opts_t *); ++extern bool compare_conn_opts(conn_opts_t *, conn_opts_t *); + extern void dump_checkers_queue(void); + extern void free_checkers_queue(void); + extern void register_checkers_thread(void); +-- +2.20.1 + diff --git a/SOURCES/bz1678480-fix-wrong-migrate-checker-id.patch b/SOURCES/bz1678480-fix-wrong-migrate-checker-id.patch new file mode 100644 index 0000000..eb171fe --- /dev/null +++ b/SOURCES/bz1678480-fix-wrong-migrate-checker-id.patch @@ -0,0 +1,25 @@ +From cd8b3f6b79d8cd5e89a05825144277785933b687 Mon Sep 17 00:00:00 2001 +From: YAMAMOTO Masaya +Date: Tue, 11 Jul 2017 15:47:12 +0900 +Subject: [PATCH 4/8] Fix worng migrate of checker-id + +--- + keepalived/check/ipwrapper.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/keepalived/check/ipwrapper.c b/keepalived/check/ipwrapper.c +index 49262e25..09d86f08 100644 +--- a/keepalived/check/ipwrapper.c ++++ b/keepalived/check/ipwrapper.c +@@ -651,7 +651,7 @@ migrate_failed_checkers(real_server_t *old_rs, real_server_t *new_rs) + if (old_c->compare == new_c->compare && new_c->compare(old_c, new_c) == 0) { + if (svr_checker_up(old_c->id, old_rs) == 0) { + id = (checker_id_t *) MALLOC(sizeof(checker_id_t)); +- *id = old_c->id; ++ *id = new_c->id; + list_add(new_rs->failed_checkers, id); + } + break; +-- +2.20.1 + diff --git a/SOURCES/bz1678480-implment-checker-comparison.patch b/SOURCES/bz1678480-implment-checker-comparison.patch new file mode 100644 index 0000000..b542750 --- /dev/null +++ b/SOURCES/bz1678480-implment-checker-comparison.patch @@ -0,0 +1,420 @@ +From fce93460597d27a86798c57ec410f63e4bd33be9 Mon Sep 17 00:00:00 2001 +From: YAMAMOTO Masaya +Date: Fri, 7 Jul 2017 19:27:16 +0900 +Subject: [PATCH 3/8] Implement comparison of checkers + +--- + keepalived/check/check_api.c | 29 ++++++++++++++++++++++++- + keepalived/check/check_daemon.c | 7 +++++- + keepalived/check/check_dns.c | 24 +++++++++++++++++++-- + keepalived/check/check_http.c | 35 +++++++++++++++++++++++++++++- + keepalived/check/check_misc.c | 22 ++++++++++++++++++- + keepalived/check/check_smtp.c | 33 +++++++++++++++++++++++++++- + keepalived/check/check_tcp.c | 22 +++++++++++++++++-- + keepalived/check/ipwrapper.c | 38 +++++++++++++++++++++++++-------- + keepalived/include/check_api.h | 5 +++++ + 9 files changed, 197 insertions(+), 18 deletions(-) + +diff --git a/keepalived/check/check_api.c b/keepalived/check/check_api.c +index b7081fd0..a722fc84 100644 +--- a/keepalived/check/check_api.c ++++ b/keepalived/check/check_api.c +@@ -42,8 +42,9 @@ + #include "check_dns.h" + + /* Global vars */ +-static checker_id_t ncheckers = 0; ++checker_id_t ncheckers = 0; + list checkers_queue; ++list old_checkers_queue; + + /* free checker data */ + static void +@@ -80,6 +81,7 @@ dump_conn_opts(void *data) + void + queue_checker(void (*free_func) (void *), void (*dump_func) (void *) + , int (*launch) (thread_t *) ++ , int (*compare) (void *, void *) + , void *data + , conn_opts_t *co) + { +@@ -96,6 +98,7 @@ queue_checker(void (*free_func) (void *), void (*dump_func) (void *) + checker->free_func = free_func; + checker->dump_func = dump_func; + checker->launch = launch; ++ checker->compare = compare; + checker->vs = vs; + checker->rs = rs; + checker->data = data; +@@ -117,6 +120,30 @@ queue_checker(void (*free_func) (void *), void (*dump_func) (void *) + } + } + ++int ++compare_conn_opts(conn_opts_t *a, conn_opts_t *b) ++{ ++ if (a == b) ++ return 0; ++ ++ if (!a || !b) ++ goto err; ++ if (!sockstorage_equal(&a->dst, &b->dst)) ++ goto err; ++ if (!sockstorage_equal(&a->bindto, &b->bindto)) ++ goto err; ++ //if (a->connection_to != b->connection_to) ++ // goto err; ++#ifdef _WITH_SO_MARK_ ++ if (a->fwmark != b->fwmark) ++ goto err; ++#endif ++ ++ return 0; ++err: ++ return -1; ++} ++ + static void + checker_set_dst_port(struct sockaddr_storage *dst, uint16_t port) + { +diff --git a/keepalived/check/check_daemon.c b/keepalived/check/check_daemon.c +index a3ff8cab..462360e6 100644 +--- a/keepalived/check/check_daemon.c ++++ b/keepalived/check/check_daemon.c +@@ -233,7 +233,11 @@ reload_check_thread(__attribute__((unused)) thread_t * thread) + thread_cleanup_master(master); + free_global_data(global_data); + +- free_checkers_queue(); ++ /* Save previous checker data */ ++ old_checkers_queue = checkers_queue; ++ checkers_queue = NULL; ++ ncheckers = 0; ++ + free_ssl(); + ipvs_stop(); + +@@ -246,6 +250,7 @@ reload_check_thread(__attribute__((unused)) thread_t * thread) + + /* free backup data */ + free_check_data(old_check_data); ++ free_list(&old_checkers_queue); + UNSET_RELOAD; + + return 0; +diff --git a/keepalived/check/check_dns.c b/keepalived/check/check_dns.c +index 96328027..84a5f56d 100644 +--- a/keepalived/check/check_dns.c ++++ b/keepalived/check/check_dns.c +@@ -388,6 +388,26 @@ dns_dump(void *data) + log_message(LOG_INFO, " Name = %s", dns_check->name); + } + ++static int ++dns_compare(void *a, void *b) ++{ ++ dns_check_t *old = CHECKER_DATA(a); ++ dns_check_t *new = CHECKER_DATA(b); ++ ++ if (compare_conn_opts(CHECKER_CO(a), CHECKER_CO(b)) != 0) ++ goto err; ++ if (old->retry != new->retry) ++ goto err; ++ if (strcmp(old->type, new->type) != 0) ++ goto err; ++ if (strcmp(old->name, new->name) != 0) ++ goto err; ++ ++ return 0; ++err: ++ return -1; ++} ++ + static void + dns_check_handler(__attribute__((unused)) vector_t * strvec) + { +@@ -396,8 +416,8 @@ dns_check_handler(__attribute__((unused)) vector_t * strvec) + dns_check->attempts = 0; + dns_check->type = DNS_DEFAULT_TYPE; + dns_check->name = DNS_DEFAULT_NAME; +- queue_checker(dns_free, dns_dump, dns_connect_thread, dns_check, +- CHECKER_NEW_CO()); ++ queue_checker(dns_free, dns_dump, dns_connect_thread, ++ dns_compare, dns_check, CHECKER_NEW_CO()); + } + + static void +diff --git a/keepalived/check/check_http.c b/keepalived/check/check_http.c +index 05e29b23..c2089a3b 100644 +--- a/keepalived/check/check_http.c ++++ b/keepalived/check/check_http.c +@@ -123,6 +123,38 @@ alloc_http_get(char *proto) + return http_get_chk; + } + ++static int ++compare_http_get_check(void *a, void *b) ++{ ++ http_checker_t *old = CHECKER_DATA(a); ++ http_checker_t *new = CHECKER_DATA(b); ++ size_t n; ++ url_t *u1, *u2; ++ ++ if (compare_conn_opts(CHECKER_CO(a), CHECKER_CO(b)) != 0) ++ goto err; ++ if (old->nb_get_retry != new->nb_get_retry) ++ goto err; ++ if (old->delay_before_retry != new->delay_before_retry) ++ goto err; ++ if (LIST_SIZE(old->url) != LIST_SIZE(new->url)) ++ goto err; ++ for (n = 0; n < LIST_SIZE(new->url); n++) { ++ u1 = (url_t *)list_element(old->url, n); ++ u2 = (url_t *)list_element(new->url, n); ++ if (strcmp(u1->path, u2->path) != 0) ++ goto err; ++ if (strcmp(u1->digest, u2->digest) != 0) ++ goto err; ++ if (u1->status_code != u2->status_code) ++ goto err; ++ } ++ ++ return 0; ++err: ++ return -1; ++} ++ + static void + http_get_handler(vector_t *strvec) + { +@@ -132,7 +164,8 @@ http_get_handler(vector_t *strvec) + /* queue new checker */ + http_get_chk = alloc_http_get(str); + queue_checker(free_http_get_check, dump_http_get_check, +- http_connect_thread, http_get_chk, CHECKER_NEW_CO()); ++ http_connect_thread, compare_http_get_check, ++ http_get_chk, CHECKER_NEW_CO()); + } + + static void +diff --git a/keepalived/check/check_misc.c b/keepalived/check/check_misc.c +index 10ac1e23..311a1127 100644 +--- a/keepalived/check/check_misc.c ++++ b/keepalived/check/check_misc.c +@@ -72,6 +72,26 @@ dump_misc_check(void *data) + log_message(LOG_INFO, " insecure = %s", misck_checker->insecure ? "Yes" : "No"); + } + ++static int ++compare_misc_check(void *a, void *b) ++{ ++ misc_checker_t *old = CHECKER_DATA(a); ++ misc_checker_t *new = CHECKER_DATA(b); ++ ++ if (strcmp(old->path, new->path) != 0) ++ goto err; ++ if (old->timeout != new->timeout) ++ goto err; ++ if (old->dynamic != new->dynamic) ++ goto err; ++ if (old->uid != new->uid || new->gid != new->gid) ++ goto err; ++ ++ return 0; ++err: ++ return -1; ++} ++ + static void + misc_check_handler(__attribute__((unused)) vector_t *strvec) + { +@@ -149,7 +169,7 @@ log_message(LOG_INFO, "Setting uid.gid"); + } + + /* queue new checker */ +- queue_checker(free_misc_check, dump_misc_check, misc_check_thread, misck_checker, NULL); ++ queue_checker(free_misc_check, dump_misc_check, misc_check_thread, compare_misc_check, misck_checker, NULL); + misck_checker = NULL; + log_message(LOG_INFO, "Leaving misc_end_handler"); + } +diff --git a/keepalived/check/check_smtp.c b/keepalived/check/check_smtp.c +index 901b77f5..e19511cc 100644 +--- a/keepalived/check/check_smtp.c ++++ b/keepalived/check/check_smtp.c +@@ -82,6 +82,37 @@ dump_smtp_check(void *data) + dump_list(smtp_checker->host); + } + ++static int ++compare_smtp_check(void *a, void *b) ++{ ++ smtp_checker_t *old = CHECKER_DATA(a); ++ smtp_checker_t *new = CHECKER_DATA(b); ++ size_t n; ++ smtp_host_t *h1, *h2; ++ ++ if (strcmp(old->helo_name, new->helo_name) != 0) ++ goto err; ++ if (old->retry != new->retry) ++ goto err; ++ if (old->db_retry != new->db_retry) ++ goto err; ++ if (compare_conn_opts(CHECKER_CO(a), CHECKER_CO(b)) != 0) ++ goto err; ++ if (LIST_SIZE(old->host) != LIST_SIZE(new->host)) ++ goto err; ++ for (n = 0; n < LIST_SIZE(new->host); n++) { ++ h1 = (smtp_host_t *)list_element(old->host, n); ++ h2 = (smtp_host_t *)list_element(new->host, n); ++ if (compare_conn_opts(h1, h2) != 0) { ++ goto err; ++ } ++ } ++ ++ return 0; ++err: ++ return -1; ++} ++ + /* Allocates a default host structure */ + static smtp_host_t * + smtp_alloc_host(void) +@@ -136,7 +167,7 @@ smtp_check_handler(__attribute__((unused)) vector_t *strvec) + * void *data, conn_opts_t *) + */ + queue_checker(free_smtp_check, dump_smtp_check, smtp_connect_thread, +- smtp_checker, smtp_checker->default_co); ++ compare_smtp_check, smtp_checker, smtp_checker->default_co); + + /* + * Last, allocate the list that will hold all the per host +diff --git a/keepalived/check/check_tcp.c b/keepalived/check/check_tcp.c +index 078ba705..026a0e3c 100644 +--- a/keepalived/check/check_tcp.c ++++ b/keepalived/check/check_tcp.c +@@ -62,6 +62,24 @@ dump_tcp_check(void *data) + } + } + ++static int ++compare_tcp_check(void *a, void *b) ++{ ++ tcp_check_t *old = CHECKER_DATA(a); ++ tcp_check_t *new = CHECKER_DATA(b); ++ ++ if (compare_conn_opts(CHECKER_CO(a), CHECKER_CO(b)) != 0) ++ goto err; ++ if (old->n_retry != new->n_retry) ++ goto err; ++ if (old->delay_before_retry != new->delay_before_retry) ++ goto err; ++ ++ return 0; ++err: ++ return -1; ++} ++ + static void + tcp_check_handler(__attribute__((unused)) vector_t *strvec) + { +@@ -72,8 +90,8 @@ tcp_check_handler(__attribute__((unused)) vector_t *strvec) + tcp_check->delay_before_retry = 1 * TIMER_HZ; + + /* queue new checker */ +- queue_checker(free_tcp_check, dump_tcp_check, tcp_connect_thread +- ,tcp_check, CHECKER_NEW_CO()); ++ queue_checker(free_tcp_check, dump_tcp_check, tcp_connect_thread, ++ compare_tcp_check, tcp_check, CHECKER_NEW_CO()); + } + + static void +diff --git a/keepalived/check/ipwrapper.c b/keepalived/check/ipwrapper.c +index 6acf18ba..49262e25 100644 +--- a/keepalived/check/ipwrapper.c ++++ b/keepalived/check/ipwrapper.c +@@ -626,20 +626,40 @@ rs_exist(real_server_t * old_rs, list l) + static void + migrate_failed_checkers(real_server_t *old_rs, real_server_t *new_rs) + { +- element e; +- checker_t *checker; ++ list l; ++ element e, e1; ++ checker_t *old_c, *new_c; + checker_id_t *id; + +- /* Notes: It's a provisional implementation */ +- (void)old_rs; ++ l = alloc_list(NULL, NULL); ++ for (e = LIST_HEAD(old_checkers_queue); e; ELEMENT_NEXT(e)) { ++ old_c = ELEMENT_DATA(e); ++ if (old_c->rs == old_rs) { ++ list_add(l, old_c); ++ } ++ } ++ ++ if (LIST_ISEMPTY(l)) ++ goto end; ++ + for (e = LIST_HEAD(checkers_queue); e; ELEMENT_NEXT(e)) { +- checker = ELEMENT_DATA(e); +- if (checker->rs == new_rs) { +- id = (checker_id_t *) MALLOC(sizeof(checker_id_t)); +- *id = checker->id; +- list_add(new_rs->failed_checkers, id); ++ new_c = ELEMENT_DATA(e); ++ if (new_c->rs != new_rs || !new_c->compare) ++ continue; ++ for (e1 = LIST_HEAD(l); e1; ELEMENT_NEXT(e1)) { ++ old_c = ELEMENT_DATA(e1); ++ if (old_c->compare == new_c->compare && new_c->compare(old_c, new_c) == 0) { ++ if (svr_checker_up(old_c->id, old_rs) == 0) { ++ id = (checker_id_t *) MALLOC(sizeof(checker_id_t)); ++ *id = old_c->id; ++ list_add(new_rs->failed_checkers, id); ++ } ++ break; ++ } + } + } ++end: ++ free_list(&l); + } + + /* Clear the diff rs of the old vs */ +diff --git a/keepalived/include/check_api.h b/keepalived/include/check_api.h +index 359c794a..4a10a36b 100644 +--- a/keepalived/include/check_api.h ++++ b/keepalived/include/check_api.h +@@ -36,6 +36,7 @@ typedef struct _checker { + void (*free_func) (void *); + void (*dump_func) (void *); + int (*launch) (struct _thread *); ++ int (*compare) (void *, void *); + virtual_server_t *vs; /* pointer to the checker thread virtualserver */ + real_server_t *rs; /* pointer to the checker thread realserver */ + void *data; +@@ -46,7 +47,9 @@ typedef struct _checker { + } checker_t; + + /* Checkers queue */ ++extern checker_id_t ncheckers; + extern list checkers_queue; ++extern list old_checkers_queue; + + /* utility macro */ + #define CHECKER_ARG(X) ((X)->data) +@@ -68,8 +71,10 @@ extern void init_checkers_queue(void); + extern void dump_conn_opts(void *); + extern void queue_checker(void (*free_func) (void *), void (*dump_func) (void *) + , int (*launch) (thread_t *) ++ , int (*compare) (void *, void *) + , void * + , conn_opts_t *); ++extern int compare_conn_opts(conn_opts_t *, conn_opts_t *); + extern void dump_checkers_queue(void); + extern void free_checkers_queue(void); + extern void register_checkers_thread(void); +-- +2.20.1 + diff --git a/SOURCES/bz1678480-include-check_api-in-ipwrapper.patch b/SOURCES/bz1678480-include-check_api-in-ipwrapper.patch new file mode 100644 index 0000000..6d97ff0 --- /dev/null +++ b/SOURCES/bz1678480-include-check_api-in-ipwrapper.patch @@ -0,0 +1,24 @@ +From 44ad4db4a45c7f152c074dacab48e051b42fde53 Mon Sep 17 00:00:00 2001 +From: Ryan O'Hara +Date: Wed, 3 Apr 2019 07:28:56 -0500 +Subject: [PATCH] Include check_api in ipwrapper + +--- + keepalived/check/ipwrapper.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/keepalived/check/ipwrapper.c b/keepalived/check/ipwrapper.c +index c9dce2b7..17f0157d 100644 +--- a/keepalived/check/ipwrapper.c ++++ b/keepalived/check/ipwrapper.c +@@ -24,6 +24,7 @@ + + #include "ipwrapper.h" + #include "ipvswrapper.h" ++#include "check_api.h" + #include "logger.h" + #include "memory.h" + #include "utils.h" +-- +2.20.1 + diff --git a/SOURCES/bz1678480-migrate-failed-checkers-reload.patch b/SOURCES/bz1678480-migrate-failed-checkers-reload.patch new file mode 100644 index 0000000..9b10fdd --- /dev/null +++ b/SOURCES/bz1678480-migrate-failed-checkers-reload.patch @@ -0,0 +1,89 @@ +From 6c5646bec26fe86214a34a877b84da83f9d9cfb4 Mon Sep 17 00:00:00 2001 +From: YAMAMOTO Masaya +Date: Tue, 4 Jul 2017 15:08:36 +0900 +Subject: [PATCH 2/8] Migrate failed checkers at reload (provisional + implementation) + +--- + keepalived/check/ipwrapper.c | 36 +++++++++++++++++++++++++----------- + 1 file changed, 25 insertions(+), 11 deletions(-) + +diff --git a/keepalived/check/ipwrapper.c b/keepalived/check/ipwrapper.c +index ecf12713..6acf18ba 100644 +--- a/keepalived/check/ipwrapper.c ++++ b/keepalived/check/ipwrapper.c +@@ -623,9 +623,28 @@ rs_exist(real_server_t * old_rs, list l) + return NULL; + } + ++static void ++migrate_failed_checkers(real_server_t *old_rs, real_server_t *new_rs) ++{ ++ element e; ++ checker_t *checker; ++ checker_id_t *id; ++ ++ /* Notes: It's a provisional implementation */ ++ (void)old_rs; ++ for (e = LIST_HEAD(checkers_queue); e; ELEMENT_NEXT(e)) { ++ checker = ELEMENT_DATA(e); ++ if (checker->rs == new_rs) { ++ id = (checker_id_t *) MALLOC(sizeof(checker_id_t)); ++ *id = checker->id; ++ list_add(new_rs->failed_checkers, id); ++ } ++ } ++} ++ + /* Clear the diff rs of the old vs */ + static void +-clear_diff_rs(virtual_server_t * old_vs, list new_rs_list) ++clear_diff_rs(virtual_server_t *old_vs, virtual_server_t *new_vs) + { + element e; + list l = old_vs->rs; +@@ -639,7 +658,7 @@ clear_diff_rs(virtual_server_t * old_vs, list new_rs_list) + list rs_to_remove = alloc_list (NULL, NULL); + for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) { + rs = ELEMENT_DATA(e); +- new_rs = rs_exist(rs, new_rs_list); ++ new_rs = rs_exist(rs, new_vs->rs); + if (!new_rs) { + /* Reset inhibit flag to delete inhibit entries */ + log_message(LOG_INFO, "service %s no longer exist" +@@ -662,20 +681,15 @@ clear_diff_rs(virtual_server_t * old_vs, list new_rs_list) + free_list_elements(new_rs->failed_checkers); + } else { + /* +- * if not alive, we must copy the failed checker list ++ * if not alive, we must migrate the failed checker list + * If we do not, the new RS is in a state where it’s reported + * as down with no check failed. As a result, the server will never + * be put up back when it’s alive again in check_tcp.c#83 because + * of the check that put a rs up only if it was not previously up + * based on the failed_checkers list + */ +- element hc_e; +- list hc_l = rs->failed_checkers; +- list new_hc_l = new_rs->failed_checkers; +- for (hc_e = LIST_HEAD(hc_l); hc_e; ELEMENT_NEXT(hc_e)) { +- list_add(new_hc_l, ELEMENT_DATA(hc_e)); +- ELEMENT_DATA(hc_e) = NULL; +- } ++ if (!new_vs->alpha) ++ migrate_failed_checkers(rs, new_rs); + } + } + } +@@ -748,7 +762,7 @@ clear_diff_services(void) + /* omega = false must not prevent the notifiers from being called, + because the VS still exists in new configuration */ + vs->omega = true; +- clear_diff_rs(vs, new_vs->rs); ++ clear_diff_rs(vs, new_vs); + clear_diff_s_srv(vs, new_vs->s_svr); + } + } +-- +2.20.1 + diff --git a/SOURCES/bz1678480-remove-unnecessary-parameter-compare.patch b/SOURCES/bz1678480-remove-unnecessary-parameter-compare.patch new file mode 100644 index 0000000..5f3f18b --- /dev/null +++ b/SOURCES/bz1678480-remove-unnecessary-parameter-compare.patch @@ -0,0 +1,91 @@ +From a6a44b6a8f8a6af9d1cef3efaae9331e24257572 Mon Sep 17 00:00:00 2001 +From: YAMAMOTO Masaya +Date: Fri, 14 Jul 2017 14:47:00 +0900 +Subject: [PATCH 7/8] Remove unnecessary parameter compare + +--- + keepalived/check/check_dns.c | 2 -- + keepalived/check/check_http.c | 4 ---- + keepalived/check/check_misc.c | 6 ------ + keepalived/check/check_smtp.c | 4 ---- + keepalived/check/check_tcp.c | 4 ---- + 5 files changed, 20 deletions(-) + +diff --git a/keepalived/check/check_dns.c b/keepalived/check/check_dns.c +index 603742a4..671062bf 100644 +--- a/keepalived/check/check_dns.c ++++ b/keepalived/check/check_dns.c +@@ -396,8 +396,6 @@ dns_check_compare(void *a, void *b) + + if (!compare_conn_opts(CHECKER_CO(a), CHECKER_CO(b))) + return false; +- if (old->retry != new->retry) +- return false; + if (strcmp(old->type, new->type) != 0) + return false; + if (strcmp(old->name, new->name) != 0) +diff --git a/keepalived/check/check_http.c b/keepalived/check/check_http.c +index 1ad395cf..2802d6f5 100644 +--- a/keepalived/check/check_http.c ++++ b/keepalived/check/check_http.c +@@ -133,10 +133,6 @@ http_get_check_compare(void *a, void *b) + + if (!compare_conn_opts(CHECKER_CO(a), CHECKER_CO(b))) + return false; +- if (old->nb_get_retry != new->nb_get_retry) +- return false; +- if (old->delay_before_retry != new->delay_before_retry) +- return false; + if (LIST_SIZE(old->url) != LIST_SIZE(new->url)) + return false; + for (n = 0; n < LIST_SIZE(new->url); n++) { +diff --git a/keepalived/check/check_misc.c b/keepalived/check/check_misc.c +index f1f66955..0cc649b6 100644 +--- a/keepalived/check/check_misc.c ++++ b/keepalived/check/check_misc.c +@@ -80,12 +80,6 @@ misc_check_compare(void *a, void *b) + + if (strcmp(old->path, new->path) != 0) + return false; +- if (old->timeout != new->timeout) +- return false; +- if (old->dynamic != new->dynamic) +- return false; +- if (old->uid != new->uid || new->gid != new->gid) +- return false; + + return true; + } +diff --git a/keepalived/check/check_smtp.c b/keepalived/check/check_smtp.c +index 44d15e01..c135258f 100644 +--- a/keepalived/check/check_smtp.c ++++ b/keepalived/check/check_smtp.c +@@ -92,10 +92,6 @@ smtp_check_compare(void *a, void *b) + + if (strcmp(old->helo_name, new->helo_name) != 0) + return false; +- if (old->retry != new->retry) +- return false; +- if (old->db_retry != new->db_retry) +- return false; + if (!compare_conn_opts(CHECKER_CO(a), CHECKER_CO(b))) + return false; + if (LIST_SIZE(old->host) != LIST_SIZE(new->host)) +diff --git a/keepalived/check/check_tcp.c b/keepalived/check/check_tcp.c +index 1858f5fc..7afed022 100644 +--- a/keepalived/check/check_tcp.c ++++ b/keepalived/check/check_tcp.c +@@ -70,10 +70,6 @@ tcp_check_compare(void *a, void *b) + + if (!compare_conn_opts(CHECKER_CO(a), CHECKER_CO(b))) + return false; +- if (old->n_retry != new->n_retry) +- return false; +- if (old->delay_before_retry != new->delay_before_retry) +- return false; + + return true; + } +-- +2.20.1 + diff --git a/SOURCES/bz1678480-resolve-compiler-warning.patch b/SOURCES/bz1678480-resolve-compiler-warning.patch new file mode 100644 index 0000000..7d451eb --- /dev/null +++ b/SOURCES/bz1678480-resolve-compiler-warning.patch @@ -0,0 +1,27 @@ +From 1dce490fdf829a0decb544a6147c4c5cc4cecf51 Mon Sep 17 00:00:00 2001 +From: Quentin Armitage +Date: Fri, 14 Jul 2017 16:45:02 +0100 +Subject: [PATCH 8/8] Resolve compiler warning introduced by commit 8361b11 + +Signed-off-by: Quentin Armitage +--- + keepalived/check/check_tcp.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/keepalived/check/check_tcp.c b/keepalived/check/check_tcp.c +index 7afed022..69615544 100644 +--- a/keepalived/check/check_tcp.c ++++ b/keepalived/check/check_tcp.c +@@ -65,9 +65,6 @@ dump_tcp_check(void *data) + static bool + tcp_check_compare(void *a, void *b) + { +- tcp_check_t *old = CHECKER_DATA(a); +- tcp_check_t *new = CHECKER_DATA(b); +- + if (!compare_conn_opts(CHECKER_CO(a), CHECKER_CO(b))) + return false; + +-- +2.20.1 + diff --git a/SOURCES/bz1678480-set-active-if-failed-checkers-empty.patch b/SOURCES/bz1678480-set-active-if-failed-checkers-empty.patch new file mode 100644 index 0000000..3acd745 --- /dev/null +++ b/SOURCES/bz1678480-set-active-if-failed-checkers-empty.patch @@ -0,0 +1,26 @@ +From ebd51b5f4a26619a4dd0393a7e97e4ca1a122700 Mon Sep 17 00:00:00 2001 +From: YAMAMOTO Masaya +Date: Tue, 11 Jul 2017 17:55:50 +0900 +Subject: [PATCH 5/8] Set active if new failed_checkers is empty + +--- + keepalived/check/ipwrapper.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/keepalived/check/ipwrapper.c b/keepalived/check/ipwrapper.c +index 09d86f08..c9dce2b7 100644 +--- a/keepalived/check/ipwrapper.c ++++ b/keepalived/check/ipwrapper.c +@@ -658,6 +658,9 @@ migrate_failed_checkers(real_server_t *old_rs, real_server_t *new_rs) + } + } + } ++ ++ if (LIST_ISEMPTY(new_rs->failed_checkers)) ++ SET_ALIVE(new_rs); + end: + free_list(&l); + } +-- +2.20.1 + diff --git a/SOURCES/bz1715308-fix-checkers-comparison-on-reload.patch b/SOURCES/bz1715308-fix-checkers-comparison-on-reload.patch new file mode 100644 index 0000000..30233b9 --- /dev/null +++ b/SOURCES/bz1715308-fix-checkers-comparison-on-reload.patch @@ -0,0 +1,46 @@ +From 8e42d6970457336bd92d327c628e38129f221f8a Mon Sep 17 00:00:00 2001 +From: Quentin Armitage +Date: Mon, 17 Jul 2017 11:43:28 +0100 +Subject: [PATCH] Correct comparison for checker compare in + migrate_failed_checkers + +Commit 2ff6b3f changed the sense of the comparisons of checkers, +but didn't make the corresponding change to checking the result. + +Signed-off-by: Quentin Armitage +--- + keepalived/check/check_api.c | 4 ++-- + keepalived/check/ipwrapper.c | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/keepalived/check/check_api.c b/keepalived/check/check_api.c +index 1d915414..82b0f2df 100644 +--- a/keepalived/check/check_api.c ++++ b/keepalived/check/check_api.c +@@ -266,8 +266,8 @@ register_checkers_thread(void) + + for (e = LIST_HEAD(checkers_queue); e; ELEMENT_NEXT(e)) { + checker = ELEMENT_DATA(e); +- log_message(LOG_INFO, "%sctivating healthchecker for service %s" +- , checker->enabled ? "A" : "Dea", FMT_VS(checker->vs)); ++ log_message(LOG_INFO, "%sctivating healthchecker for service %s" ++ , checker->enabled ? "A" : "Dea", FMT_VS(checker->vs)); + if (checker->launch) + { + /* wait for a random timeout to begin checker thread. +diff --git a/keepalived/check/ipwrapper.c b/keepalived/check/ipwrapper.c +index 17f0157d..ad8c3154 100644 +--- a/keepalived/check/ipwrapper.c ++++ b/keepalived/check/ipwrapper.c +@@ -649,7 +649,7 @@ migrate_failed_checkers(real_server_t *old_rs, real_server_t *new_rs) + continue; + for (e1 = LIST_HEAD(l); e1; ELEMENT_NEXT(e1)) { + old_c = ELEMENT_DATA(e1); +- if (old_c->compare == new_c->compare && new_c->compare(old_c, new_c) == 0) { ++ if (old_c->compare == new_c->compare && new_c->compare(old_c, new_c)) { + if (svr_checker_up(old_c->id, old_rs) == 0) { + id = (checker_id_t *) MALLOC(sizeof(checker_id_t)); + *id = new_c->id; +-- +2.21.0 + diff --git a/SOURCES/bz1715308-make-checker-variables-non-global.patch b/SOURCES/bz1715308-make-checker-variables-non-global.patch new file mode 100644 index 0000000..b60e725 --- /dev/null +++ b/SOURCES/bz1715308-make-checker-variables-non-global.patch @@ -0,0 +1,173 @@ +From 6f18ff4f0a06015691b25cb91bf4c6dccec5cc89 Mon Sep 17 00:00:00 2001 +From: Quentin Armitage +Date: Sun, 16 Jul 2017 10:00:20 +0100 +Subject: [PATCH] Make a couple of checker variables non global + +Signed-off-by: Quentin Armitage +--- + keepalived/check/check_api.c | 4 ++-- + keepalived/check/check_daemon.c | 11 ++++++----- + keepalived/check/ipwrapper.c | 10 +++++----- + keepalived/include/check_api.h | 2 -- + keepalived/include/ipwrapper.h | 2 +- + 5 files changed, 14 insertions(+), 15 deletions(-) + +diff --git a/keepalived/check/check_api.c b/keepalived/check/check_api.c +index 82b0f2df..016850f0 100644 +--- a/keepalived/check/check_api.c ++++ b/keepalived/check/check_api.c +@@ -42,9 +42,8 @@ + #include "check_dns.h" + + /* Global vars */ +-checker_id_t ncheckers = 0; ++static checker_id_t ncheckers; + list checkers_queue; +-list old_checkers_queue; + + /* free checker data */ + static void +@@ -243,6 +242,7 @@ void + init_checkers_queue(void) + { + checkers_queue = alloc_list(free_checker, dump_checker); ++ ncheckers = 0; + } + + /* release the checkers_queue */ +diff --git a/keepalived/check/check_daemon.c b/keepalived/check/check_daemon.c +index 462360e6..85f8bdbd 100644 +--- a/keepalived/check/check_daemon.c ++++ b/keepalived/check/check_daemon.c +@@ -108,7 +108,7 @@ stop_check(int status) + + /* Daemon init sequence */ + static void +-start_check(void) ++start_check(list old_checkers_queue) + { + /* Initialize sub-system */ + if (ipvs_start() != IPVS_SUCCESS) { +@@ -171,7 +171,7 @@ start_check(void) + + /* Processing differential configuration parsing */ + if (reload) +- clear_diff_services(); ++ clear_diff_services(old_checkers_queue); + + /* Initialize IPVS topology */ + if (!init_services()) +@@ -219,6 +219,8 @@ check_signal_init(void) + static int + reload_check_thread(__attribute__((unused)) thread_t * thread) + { ++ list old_checkers_queue; ++ + /* set the reloading flag */ + SET_RELOAD; + +@@ -236,7 +238,6 @@ reload_check_thread(__attribute__((unused)) thread_t * thread) + /* Save previous checker data */ + old_checkers_queue = checkers_queue; + checkers_queue = NULL; +- ncheckers = 0; + + free_ssl(); + ipvs_stop(); +@@ -246,7 +247,7 @@ reload_check_thread(__attribute__((unused)) thread_t * thread) + check_data = NULL; + + /* Reload the conf */ +- start_check(); ++ start_check(old_checkers_queue); + + /* free backup data */ + free_check_data(old_check_data); +@@ -355,7 +356,7 @@ start_check_child(void) + check_signal_init(); + + /* Start Healthcheck daemon */ +- start_check(); ++ start_check(NULL); + + /* Launch the scheduling I/O multiplexer */ + launch_scheduler(); +diff --git a/keepalived/check/ipwrapper.c b/keepalived/check/ipwrapper.c +index ad8c3154..34bb59f8 100644 +--- a/keepalived/check/ipwrapper.c ++++ b/keepalived/check/ipwrapper.c +@@ -625,7 +625,7 @@ rs_exist(real_server_t * old_rs, list l) + } + + static void +-migrate_failed_checkers(real_server_t *old_rs, real_server_t *new_rs) ++migrate_failed_checkers(real_server_t *old_rs, real_server_t *new_rs, list old_checkers_queue) + { + list l; + element e, e1; +@@ -668,7 +668,7 @@ end: + + /* Clear the diff rs of the old vs */ + static void +-clear_diff_rs(virtual_server_t *old_vs, virtual_server_t *new_vs) ++clear_diff_rs(virtual_server_t *old_vs, virtual_server_t *new_vs, list old_checkers_queue) + { + element e; + list l = old_vs->rs; +@@ -713,7 +713,7 @@ clear_diff_rs(virtual_server_t *old_vs, virtual_server_t *new_vs) + * based on the failed_checkers list + */ + if (!new_vs->alpha) +- migrate_failed_checkers(rs, new_rs); ++ migrate_failed_checkers(rs, new_rs, old_checkers_queue); + } + } + } +@@ -746,7 +746,7 @@ clear_diff_s_srv(virtual_server_t *old_vs, real_server_t *new_rs) + /* When reloading configuration, remove negative diff entries + * and copy status of existing entries to the new ones */ + void +-clear_diff_services(void) ++clear_diff_services(list old_checkers_queue) + { + element e; + list l = old_check_data->vs; +@@ -786,7 +786,7 @@ clear_diff_services(void) + /* omega = false must not prevent the notifiers from being called, + because the VS still exists in new configuration */ + vs->omega = true; +- clear_diff_rs(vs, new_vs); ++ clear_diff_rs(vs, new_vs, old_checkers_queue); + clear_diff_s_srv(vs, new_vs->s_svr); + } + } +diff --git a/keepalived/include/check_api.h b/keepalived/include/check_api.h +index c7bc297d..c43eca14 100644 +--- a/keepalived/include/check_api.h ++++ b/keepalived/include/check_api.h +@@ -47,9 +47,7 @@ typedef struct _checker { + } checker_t; + + /* Checkers queue */ +-extern checker_id_t ncheckers; + extern list checkers_queue; +-extern list old_checkers_queue; + + /* utility macro */ + #define CHECKER_ARG(X) ((X)->data) +diff --git a/keepalived/include/ipwrapper.h b/keepalived/include/ipwrapper.h +index 11cdbbc6..0a6c48ba 100644 +--- a/keepalived/include/ipwrapper.h ++++ b/keepalived/include/ipwrapper.h +@@ -55,7 +55,7 @@ extern int svr_checker_up(checker_id_t, real_server_t *); + extern void update_svr_checker_state(bool, checker_id_t, virtual_server_t *, real_server_t *); + extern bool init_services(void); + extern void clear_services(void); +-extern void clear_diff_services(void); ++extern void clear_diff_services(list); + extern void link_vsg_to_vs(void); + + #endif +-- +2.21.0 + diff --git a/SPECS/keepalived.spec b/SPECS/keepalived.spec index 83fd422..aa55882 100644 --- a/SPECS/keepalived.spec +++ b/SPECS/keepalived.spec @@ -9,7 +9,7 @@ Name: keepalived Summary: Load balancer and high availability service Version: 1.3.5 -Release: 8%{?dist} +Release: 8%{?dist}.5 License: GPLv2+ URL: http://www.keepalived.org/ Group: System Environment/Daemons @@ -25,6 +25,17 @@ Patch4: bz1508435-no-segfault-ip_vs-load.patch Patch5: bz1508435-remove-ipset-handling.patch Patch6: bz1477587-exclude-mismatch-vips.patch Patch7: bz1652694-fix-buffer-overflow-http-status.patch +patch10: bz1678480-add-child_wait_time.patch +patch11: bz1678480-migrate-failed-checkers-reload.patch +patch12: bz1678480-implment-checker-comparison.patch +patch13: bz1678480-fix-wrong-migrate-checker-id.patch +patch14: bz1678480-set-active-if-failed-checkers-empty.patch +patch15: bz1678480-fix-checker-coding-style.patch +patch16: bz1678480-remove-unnecessary-parameter-compare.patch +patch17: bz1678480-resolve-compiler-warning.patch +patch18: bz1678480-include-check_api-in-ipwrapper.patch +patch19: bz1715308-make-checker-variables-non-global.patch +patch20: bz1715308-fix-checkers-comparison-on-reload.patch Requires: ipset-libs Requires(post): systemd @@ -63,6 +74,17 @@ Keepalived also implements the Virtual Router Redundancy Protocol %patch5 -p1 %patch6 -p1 %patch7 -p1 +%patch10 -p1 +%patch11 -p1 +%patch12 -p1 +%patch13 -p1 +%patch14 -p1 +%patch15 -p1 +%patch16 -p1 +%patch17 -p1 +%patch18 -p1 +%patch19 -p1 +%patch20 -p1 %build %configure \ @@ -119,7 +141,22 @@ Keepalived also implements the Virtual Router Redundancy Protocol %{_mandir}/man8/keepalived.8* %changelog -* Thu Dec 31 2018 Ryan O'Hara - 1.3.5-8 +* Mon Jun 03 2019 Ryan O'Hara - 1.3.5-8.5 +- Rework previous checker comparison patch (#1716588) + +* Mon Jun 03 2019 Ryan O'Hara - 1.3.5-8.4 +- Make checker variables non global (#1716588) + +* Mon Jun 03 2019 Ryan O'Hara - 1.3.5-8.3 +- Fix comparison of checkers on reload (#1716588) + +* Wed Apr 03 2019 Ryan O'Hara - 1.3.5-8.2 +- Fix build errors (#1678480) + +* Tue Apr 02 2019 Ryan O'Hara - 1.3.5-8.1 +- Fix problems with health checks & real servers after reload/restart (#1695653) + +* Thu Dec 13 2018 Ryan O'Hara - 1.3.5-8 - Fixed patch that was incorrectly removed (#1652694) * Mon Dec 10 2018 Ryan O'Hara - 1.3.5-7