diff --git a/include/proto/proxy.h b/include/proto/proxy.h index 4707e9acf..30a12472e 100644 --- a/include/proto/proxy.h +++ b/include/proto/proxy.h @@ -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); diff --git a/src/cfgparse.c b/src/cfgparse.c index df297b6ab..893557ad1 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -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; } diff --git a/src/proxy.c b/src/proxy.c index 1db7839a7..5fa202bd3 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -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