Skip to content

Commit 6be02d1

Browse files
committed
BUG/MAJOR: leastconn: do not loop forever when facing saturated servers
Since commit 9fe72bb ("MAJOR: leastconn; Revamp the way servers are ordered."), there's no way to escape the loop visiting the mt_list heads in fwlc_get_next_server if all servers in the list are saturated, resulting in a watchdog panic. It can be reproduced with this config and injecting with more than 2 concurrent conns: balance leastconn server s1 127.0.0.1:8000 maxconn 1 server s2 127.0.0.1:8000 maxconn 1 Here we count the number of saturated servers that were encountered, and escape the loop once the number of remaining servers exceeds the number of saturated ones. No backport is needed since this arrived in 3.2.
1 parent ccc6501 commit 6be02d1

File tree

1 file changed

+4
-1
lines changed

1 file changed

+4
-1
lines changed

src/lb_fwlc.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -762,13 +762,14 @@ struct server *fwlc_get_next_server(struct proxy *p, struct server *srvtoavoid)
762762
while (node) {
763763
struct fwlc_tree_elt *tree_elt;
764764
struct server *s;
765+
int unusable = 0;
765766
int orig_nb;
766767
int i = 0;
767768

768769
tree_elt = eb32_entry(node, struct fwlc_tree_elt, lb_node);
769770
orig_nb = statistical_prng_range(FWLC_LISTS_NB);
770771

771-
while (_HA_ATOMIC_LOAD(&tree_elt->elements) > 0) {
772+
while (_HA_ATOMIC_LOAD(&tree_elt->elements) > unusable) {
772773
struct mt_list mt_list;
773774
mt_list.next = _HA_ATOMIC_LOAD(&tree_elt->srv_list[(i + orig_nb) % FWLC_LISTS_NB].next);
774775

@@ -802,6 +803,8 @@ struct server *fwlc_get_next_server(struct proxy *p, struct server *srvtoavoid)
802803
}
803804
avoided = s;
804805
}
806+
else
807+
unusable++;
805808
i++;
806809
} else if (mt_list.next == &tree_elt->srv_list[(i + orig_nb) % FWLC_LISTS_NB]) {
807810
i++;

0 commit comments

Comments
 (0)