]> 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, 12 Oct 2008 10:07:48 +0000 (12:07 +0200)
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.

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

index 7268bfaad9f2511397db4e2ae510af1f0b60f85f..72394788c19ae13ec90aed8b314fc20118dbac7e 100644 (file)
@@ -30,6 +30,7 @@ int start_proxies(int verbose);
 void maintain_proxies(struct timeval *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 d34bfbe1c8f73b9dbfd43dfb56bafb5f80e4e2a6..b33800c73777728d662f5c830fcff548ecaca5a8 100644 (file)
@@ -2726,6 +2726,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 6fad76eae7fd48821d0267fffd8c0c2e167128ba..358132995b7b72a65b01b588324b6a41eabf151a 100644 (file)
@@ -351,15 +351,7 @@ void maintain_proxies(struct timeval *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