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 173ef76..57fd087 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) {