summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilly Tarreau <w@1wt.eu>2020-09-24 16:03:29 +0200
committerWilly Tarreau <w@1wt.eu>2020-10-07 18:45:03 +0200
commitc39840ced736fcfd0d46df665d3a5468c665e55f (patch)
tree6a3195205e27f0b6ee80f83ab5deb81e7efbd553
parentfcbdae37e2fbfe9d51596ad49c6d12e1670a2b9d (diff)
downloadhaproxy-c39840ced736fcfd0d46df665d3a5468c665e55f.tar.gz
MEDIUM: listener/proxy: make the listeners notify about proxy pause/resume
Till now, we used to call pause_proxy()/resume_proxy() to enable/disable processing on a proxy, which is used during soft reloads. But since we want to drive this process from the listeners themselves, we have to instead proceed the other way around so that when we enable/disable a listener, it checks if it changed anything for the proxy and notifies about updates at this level. The detection is made using li_ready=0 for pause(), and li_paused=0 for resume(). Note that we must not include any test for li_bound because this state is seen by processes which share the listener with another one and which must not act on it since the other process will do it. As such the socket behind the FD will automatically be paused and resume without its local state changing, but this is the limit of a multi-process system with shared listeners.
-rw-r--r--src/listener.c16
-rw-r--r--src/proxy.c6
2 files changed, 15 insertions, 7 deletions
diff --git a/src/listener.c b/src/listener.c
index 1518e228a..5e9dcde57 100644
--- a/src/listener.c
+++ b/src/listener.c
@@ -335,6 +335,7 @@ static void disable_listener(struct listener *listener)
*/
int pause_listener(struct listener *l)
{
+ struct proxy *px = l->bind_conf->frontend;
int ret = 1;
HA_SPIN_LOCK(LISTENER_LOCK, &l->lock);
@@ -364,6 +365,11 @@ int pause_listener(struct listener *l)
fd_stop_recv(l->rx.fd);
listener_set_state(l, LI_PAUSED);
+
+ if (px && !px->li_ready) {
+ ha_warning("Paused %s %s.\n", proxy_cap_str(px->cap), px->id);
+ send_log(px, LOG_WARNING, "Paused %s %s.\n", proxy_cap_str(px->cap), px->id);
+ }
end:
HA_SPIN_UNLOCK(LISTENER_LOCK, &l->lock);
return ret;
@@ -381,6 +387,8 @@ int pause_listener(struct listener *l)
*/
int resume_listener(struct listener *l)
{
+ struct proxy *px = l->bind_conf->frontend;
+ int was_paused = px && px->li_paused;
int ret = 1;
HA_SPIN_LOCK(LISTENER_LOCK, &l->lock);
@@ -428,11 +436,17 @@ int resume_listener(struct listener *l)
if (l->maxconn && l->nbconn >= l->maxconn) {
listener_set_state(l, LI_FULL);
- goto end;
+ goto done;
}
fd_want_recv(l->rx.fd);
listener_set_state(l, LI_READY);
+
+ done:
+ if (was_paused && !px->li_paused) {
+ ha_warning("Resumed %s %s.\n", proxy_cap_str(px->cap), px->id);
+ send_log(px, LOG_WARNING, "Resumed %s %s.\n", proxy_cap_str(px->cap), px->id);
+ }
end:
HA_SPIN_UNLOCK(LISTENER_LOCK, &l->lock);
return ret;
diff --git a/src/proxy.c b/src/proxy.c
index 1e889f7a2..7d256c666 100644
--- a/src/proxy.c
+++ b/src/proxy.c
@@ -1275,9 +1275,6 @@ int pause_proxy(struct proxy *p)
if (!(p->cap & PR_CAP_FE) || p->disabled || !p->li_ready)
return 1;
- ha_warning("Pausing %s %s.\n", proxy_cap_str(p->cap), p->id);
- send_log(p, LOG_WARNING, "Pausing %s %s.\n", proxy_cap_str(p->cap), p->id);
-
list_for_each_entry(l, &p->conf.listeners, by_fe)
pause_listener(l);
@@ -1342,9 +1339,6 @@ int resume_proxy(struct proxy *p)
if (p->disabled || !p->li_paused)
return 1;
- ha_warning("Enabling %s %s.\n", proxy_cap_str(p->cap), p->id);
- send_log(p, LOG_WARNING, "Enabling %s %s.\n", proxy_cap_str(p->cap), p->id);
-
fail = 0;
list_for_each_entry(l, &p->conf.listeners, by_fe) {
if (!resume_listener(l)) {