@@ -0,0 +1,185 @@
+From e2edaa6b637227c70ec6dc0f0d00de4d5fe5b620 Mon Sep 17 00:00:00 2001
+From: Vincent Bernat <bernat@luffy.cx>
+Date: Mon, 06 Jun 2011 07:01:54 +0000
+Subject: checker: keep retry in case of early TCP failures in checks
+
+Patch from Brad Schick. Original mail:
+
+Two patched attached. It turns out that 1.1.20 and 1.2.2 each had some
+partial implementations of my proposed improvements already, but they
+are inconsistent. And I believe in the case of 1.2.2, the existing
+implementation leaks socket handles.
+
+These patches cleanup 1.1.20 and 1.2.2 respectively and make both of
+them continue to retry after socket creation and bind failures. I also
+added INFO level logging rather than DGB only since this is very
+helpful information when things aren't working as expected.
+
+I also fixed another random mis-use of the DBG macro that I noticed in
+both 1.1.20 and 1.2.2. Patches attached.
+---
+diff --git a/keepalived/check/check_http.c b/keepalived/check/check_http.c
+index 0d1a12c..3d2e46b 100644
+--- a/keepalived/check/check_http.c
++++ b/keepalived/check/check_http.c
+@@ -793,7 +793,7 @@ http_check_thread(thread_t * thread)
+ thread->u.fd,
+ http_get_check->connection_to);
+ } else {
+- DBG(LOG_INFO, "Connection trouble to: [%s]:%d."
++ DBG("Connection trouble to: [%s]:%d."
+ , inet_sockaddrtos(&http_get_check->dst)
+ , ntohs(inet_sockaddrport(&http_get_check->dst)));
+ #ifdef _DEBUG_
+@@ -871,19 +871,23 @@ http_connect_thread(thread_t * thread)
+
+ /* Create the socket */
+ if ((fd = socket(http_get_check->dst.ss_family, SOCK_STREAM, IPPROTO_TCP)) == -1) {
+- DBG("WEB connection fail to create socket.");
++ log_message(LOG_INFO, "WEB connection fail to create socket. Rescheduling.");
++ thread_add_timer(thread->master, http_connect_thread, checker,
++ checker->vs->delay_loop);
++
+ return 0;
+ }
+
+ status = tcp_bind_connect(fd, &http_get_check->dst, &http_get_check->bindto);
+- if (status == connect_error) {
++
++ /* handle tcp connection status & register check worker thread */
++ if(tcp_connection_state(fd, status, thread, http_check_thread,
++ http_get_check->connection_to)) {
++ close(fd);
++ log_message(LOG_INFO, "WEB socket bind failed. Rescheduling");
+ thread_add_timer(thread->master, http_connect_thread, checker,
+- checker->vs->delay_loop);
+- return 0;
++ checker->vs->delay_loop);
+ }
+
+- /* handle tcp connection status & register check worker thread */
+- tcp_connection_state(fd, status, thread, http_check_thread,
+- http_get_check->connection_to);
+ return 0;
+ }
+diff --git a/keepalived/check/check_smtp.c b/keepalived/check/check_smtp.c
+index 79a8f5b..bf62a8c 100644
+--- a/keepalived/check/check_smtp.c
++++ b/keepalived/check/check_smtp.c
+@@ -811,20 +811,21 @@ smtp_connect_thread(thread_t *thread)
+
+ /* Create the socket, failling here should be an oddity */
+ if ((sd = socket(smtp_host->dst.ss_family, SOCK_STREAM, IPPROTO_TCP)) == -1) {
+- DBG("SMTP_CHECK connection failed to create socket.");
++ log_message(LOG_INFO, "SMTP_CHECK connection failed to create socket. Rescheduling.");
+ thread_add_timer(thread->master, smtp_connect_thread, checker,
+ checker->vs->delay_loop);
+ return 0;
+ }
+
+ status = tcp_bind_connect(sd, &smtp_host->dst, &smtp_host->bindto);
+- if (status == connect_error) {
+- thread_add_timer(thread->master, smtp_connect_thread, checker,
+- checker->vs->delay_loop);
+- return 0;
+- }
+
+ /* handle tcp connection status & register callback the next setp in the process */
+- tcp_connection_state(sd, status, thread, smtp_check_thread, smtp_checker->timeout);
++ if(tcp_connection_state(sd, status, thread, smtp_check_thread, smtp_checker->timeout)) {
++ close(sd);
++ log_message(LOG_INFO, "SMTP_CHECK socket bind failed. Rescheduling.");
++ thread_add_timer(thread->master, smtp_connect_thread, checker,
++ checker->vs->delay_loop);
++ }
++
+ return 0;
+ }
+diff --git a/keepalived/check/check_tcp.c b/keepalived/check/check_tcp.c
+index e0fb077..9f2b3e8 100644
+--- a/keepalived/check/check_tcp.c
++++ b/keepalived/check/check_tcp.c
+@@ -169,19 +169,23 @@ tcp_connect_thread(thread_t * thread)
+ }
+
+ if ((fd = socket(tcp_check->dst.ss_family, SOCK_STREAM, IPPROTO_TCP)) == -1) {
+- DBG("TCP connect fail to create socket.");
++ log_message(LOG_INFO, "TCP connect fail to create socket. Rescheduling.");
++ thread_add_timer(thread->master, tcp_connect_thread, checker,
++ checker->vs->delay_loop);
++
+ return 0;
+ }
+
+ status = tcp_bind_connect(fd, &tcp_check->dst, &tcp_check->bindto);
+- if (status == connect_error) {
+- thread_add_timer(thread->master, tcp_connect_thread, checker,
+- checker->vs->delay_loop);
+- return 0;
+- }
+
+ /* handle tcp connection status & register check worker thread */
+- tcp_connection_state(fd, status, thread, tcp_check_thread,
+- tcp_check->connection_to);
++ if(tcp_connection_state(fd, status, thread, tcp_check_thread,
++ tcp_check->connection_to)) {
++ close(fd);
++ log_message(LOG_INFO, "TCP socket bind failed. Rescheduling.");
++ thread_add_timer(thread->master, tcp_connect_thread, checker,
++ checker->vs->delay_loop);
++ }
++
+ return 0;
+ }
+diff --git a/keepalived/core/layer4.c b/keepalived/core/layer4.c
+index ce2035e..5725500 100644
+--- a/keepalived/core/layer4.c
++++ b/keepalived/core/layer4.c
+@@ -119,7 +119,7 @@ tcp_socket_state(int fd, thread_t * thread, int (*func) (thread_t *))
+ return connect_success;
+ }
+
+-void
++int
+ tcp_connection_state(int fd, enum connect_result status, thread_t * thread,
+ int (*func) (thread_t *), long timeout)
+ {
+@@ -128,20 +128,16 @@ tcp_connection_state(int fd, enum connect_result status, thread_t * thread,
+ checker = THREAD_ARG(thread);
+
+ switch (status) {
+- case connect_error:
+- close(fd);
+- break;
+-
+ case connect_success:
+ thread_add_write(thread->master, func, checker, fd, timeout);
+- break;
++ return 0;
+
+ /* Checking non-blocking connect, we wait until socket is writable */
+ case connect_in_progress:
+ thread_add_write(thread->master, func, checker, fd, timeout);
+- break;
++ return 0;
+
+ default:
+- break;
++ return 1;
+ }
+ }
+diff --git a/keepalived/include/layer4.h b/keepalived/include/layer4.h
+index 857927b..ad2fc57 100644
+--- a/keepalived/include/layer4.h
++++ b/keepalived/include/layer4.h
+@@ -52,7 +52,7 @@ extern enum connect_result
+ extern enum connect_result
+ tcp_socket_state(int, thread_t *, int (*func) (thread_t *));
+
+-extern void
++extern int
+ tcp_connection_state(int, enum connect_result
+ , thread_t *, int (*func) (thread_t *)
+ , long);
+--
+cgit v0.8.3.4
|
@@ -0,0 +1,26 @@
+From 0b770193b214d527982ee5dcf73b4538d3bc8cb5 Mon Sep 17 00:00:00 2001
+From: Vincent Bernat <bernat@luffy.cx>
+Date: Wed, 01 Sep 2010 13:36:21 +0000
+Subject: Do not set reload flag in the main process.
+
+The main process does not use the reload flag. When setting the reload
+flag in the main process and a child dies, the new child will have the
+reload flag for a short time. There seems to be some race condition
+here. This "fix" seems to circumvent this race condition.
+---
+diff --git a/keepalived/core/main.c b/keepalived/core/main.c
+index ef472f8..5b6ec7a 100644
+--- a/keepalived/core/main.c
++++ b/keepalived/core/main.c
+@@ -87,9 +87,6 @@ start_keepalived(void)
+ void
+ sighup(void *v, int sig)
+ {
+- /* Set the reloading flag */
+- SET_RELOAD;
+-
+ /* Signal child process */
+ if (vrrp_child > 0)
+ kill(vrrp_child, SIGHUP);
+--
+cgit v0.8.3.4
|