]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: listener/proxy: make the listeners notify about proxy pause/resume
authorWilly Tarreau <w@1wt.eu>
Thu, 24 Sep 2020 14:03:29 +0000 (16:03 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 9 Oct 2020 09:27:30 +0000 (11:27 +0200)
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.

src/listener.c
src/proxy.c

index 6327949a1554ebd5751150500332f52bb4154b1e..85158e443846dc624872d9a60c5986df22b39a71 100644 (file)
@@ -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;
index 1e889f7a21704ff78edadeca0591e489c20d656d..7d256c6668313589605d9c7880f048dc144843c3 100644 (file)
@@ -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)) {