]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[BUG] ensure that listeners from disabled proxies are correctly unbound.
authorWilly Tarreau <w@1wt.eu>
Sun, 12 Oct 2008 10:07:48 +0000 (12:07 +0200)
committerWilly Tarreau <w@1wt.eu>
Sun, 7 Dec 2008 22:33:25 +0000 (23:33 +0100)
There is a problem when an instance is marked "disabled". Its ports are
still bound but will not be unbound upon termination. This causes processes
to accumulate during soft restarts, and might even cause failures to restart
new ones due to the inability to bind to the same port.

The ideal solution would be to bind all ports at the end of the configuration
parsing. An acceptable workaround is to unbind all listeners of disabled
proxies. This is what the current patch does.
(cherry picked from commit a944218e9c1d5ff1aca34609146389dc680335b7)
(cherry picked from commit 8cfebbb82b87345bade831920177077e7d25840a)

include/proto/proxy.h
src/cfgparse.c
src/proxy.c

index 4707e9acfe2f572550e58a8bb10a07433a2db45f..30a12472e80b58e97d3b230d8a6a0e888cc4bf5f 100644 (file)
@@ -31,6 +31,7 @@ int start_proxies(int verbose);
 void maintain_proxies(int *next);
 void soft_stop(void);
 void pause_proxy(struct proxy *p);
+void stop_proxy(struct proxy *p);
 void pause_proxies(void);
 void listen_proxies(void);
 
index df297b6ab469df51eb3de37f1914a6ba5c63fe49..893557ad17fa5ba4c2771177bc5680cdebcf4047 100644 (file)
@@ -2867,6 +2867,8 @@ int readcfgfile(const char *file)
                struct listener *listener;
 
                if (curproxy->state == PR_STSTOPPED) {
+                       /* ensure we don't keep listeners uselessly bound */
+                       stop_proxy(curproxy);
                        curproxy = curproxy->next;
                        continue;
                }
index 1db7839a71ec7ccc4f8088e7293f8b1e70b9a537..5fa202bd3cb31a11c3b2774add67c766332f43ae 100644 (file)
@@ -351,15 +351,7 @@ void maintain_proxies(int *next)
                                if (t == 0) {
                                        Warning("Proxy %s stopped.\n", p->id);
                                        send_log(p, LOG_WARNING, "Proxy %s stopped.\n", p->id);
-
-                                       for (l = p->listen; l != NULL; l = l->next) {
-                                               unbind_listener(l);
-                                               if (l->state >= LI_ASSIGNED) {
-                                                       delete_listener(l);
-                                                       listeners--;
-                                               }
-                                       }
-                                       p->state = PR_STSTOPPED;
+                                       stop_proxy(p);
                                        /* try to free more memory */
                                        pool_gc2();
                                }
@@ -421,6 +413,28 @@ void pause_proxy(struct proxy *p)
        }
 }
 
+
+/*
+ * This function completely stops a proxy and releases its listeners. It has
+ * to be called when going down in order to release the ports so that another
+ * process may bind to them. It must also be called on disabled proxies at the
+ * end of start-up. When all listeners are closed, the proxy is set to the
+ * PR_STSTOPPED state.
+ */
+void stop_proxy(struct proxy *p)
+{
+       struct listener *l;
+
+       for (l = p->listen; l != NULL; l = l->next) {
+               unbind_listener(l);
+               if (l->state >= LI_ASSIGNED) {
+                       delete_listener(l);
+                       listeners--;
+               }
+       }
+       p->state = PR_STSTOPPED;
+}
+
 /*
  * This function temporarily disables listening so that another new instance
  * can start listening. It is designed to be called upon reception of a