]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: queue: prevent a backup server from draining the proxy's connections
authorWilly Tarreau <w@1wt.eu>
Tue, 7 Aug 2018 08:44:58 +0000 (10:44 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 7 Aug 2018 08:52:01 +0000 (10:52 +0200)
When switching back from a backup to an active server, the backup server
currently continues to drain the proxy's connections, which is a problem
because it's not expected to be able to pick them.

This patch ensures that a backup server will only pick backend connections
if there is no active server and it is the selected backup server or all
backup servers are supposed to be used.

This issue seems to have existed forever, so this fix should be backported
to all stable versions.

src/queue.c

index 173ef76f64d0d61a386bf355148671e4b05e20b5..57fd087bfe10084a6c7d8cda50b3f8a1ed28abf6 100644 (file)
@@ -209,7 +209,10 @@ static int pendconn_process_next_strm(struct server *srv, struct proxy *px)
        if (srv->nbpend)
                p = LIST_ELEM(srv->pendconns.n, struct pendconn *, list);
 
-       if (srv_currently_usable(rsrv) && px->nbpend) {
+       if (srv_currently_usable(rsrv) && px->nbpend &&
+           (!(srv->flags & SRV_F_BACKUP) ||
+            (!px->srv_act &&
+             (srv == px->lbprm.fbck || (px->options & PR_O_USE_ALL_BK))))) {
                struct pendconn *pp;
 
                pp = LIST_ELEM(px->pendconns.n, struct pendconn *, list);
@@ -360,6 +363,15 @@ int pendconn_grab_from_px(struct server *s)
        if (!srv_currently_usable(s))
                return 0;
 
+       /* if this is a backup server and there are active servers or at
+        * least another backup server was elected, then this one must
+        * not dequeue requests from the proxy.
+        */
+       if ((s->flags & SRV_F_BACKUP) &&
+           (s->proxy->srv_act ||
+            ((s != s->proxy->lbprm.fbck) && !(s->proxy->options & PR_O_USE_ALL_BK))))
+               return 0;
+
        HA_SPIN_LOCK(PROXY_LOCK, &s->proxy->lock);
        maxconn = srv_dynamic_maxconn(s);
        list_for_each_entry_safe(p, pback, &s->proxy->pendconns, list) {