]> git.kaiwu.me - haproxy.git/commit
BUG/MEDIUM: server: Properly check for streams before deletion
authorOlivier Houchard <ohouchard@haproxy.com>
Mon, 20 Jul 2026 14:05:51 +0000 (16:05 +0200)
committerOlivier Houchard <cognet@ci0.org>
Wed, 22 Jul 2026 12:19:25 +0000 (14:19 +0200)
commitca686e32084d7aed18b01d45f51eb6079c02d9da
tree175e1372454c975c21963538b286f9b1993b44bd
parentfbce63160e09626b958637680d50288059fb7988
BUG/MEDIUM: server: Properly check for streams before deletion

When a server delete command happens, before we actually delete the
server, we check if there are any streams still attached to the server,
and will refuse the deletion if it is so. Unfortunately, the check was
not exhaustive, we would check if there's any stream in the queue, if
there are any connection to the server established, and if served is
non-zero.
But there are at least two cases where a stream will have a reference to
the server, but none of those will be true : the first one is the case
where we tried a connection to the server, and it failed. At this point
we decremented served, but we will still hold a reference to the server
in target until a new server has been assigned. The second one happens
with cookie persistence, in which case target will be set to the server
address way before any connection is attempted, and so way before served
is incremented.
To fix that, introduce a new per-thread-group counter in the server
structure, nb_strm, that counts the streams whose target points to that
server. It is incremented when a stream's target is set to a server, and
decremented when the target changes to another server, to a non-server,
or the stream ends. To make this reliable, all assignments to a stream's
target now go through the new stream_set_target() helper, which keeps
nb_strm up to date and also clears sv_tgcounters when the target is no
longer a server, so we don't keep a dangling reference to the server's
counters (its failure counters have already been accounted for by that
point). To check if there are still any streams attached to the server,
the code just looks at all the per-thread-group counters, and if one of
them is non-zero, there are still streams on that server. This will
always be accurate because the server deletion command runs with thread
isolation.

This should be backported up to 3.0.
include/haproxy/server-t.h
include/haproxy/stream.h
src/backend.c
src/cache.c
src/cli.c
src/http_ana.c
src/http_client.c
src/server.c
src/stream.c