]> git.kaiwu.me - haproxy.git/commit
BUG/MEDIUM: counters: preserve shared.tg pointer on 'clear counters all'
authorAlexander Stephan <alexander.stephan@sap.com>
Fri, 3 Jul 2026 08:35:47 +0000 (08:35 +0000)
committerWilly Tarreau <w@1wt.eu>
Thu, 30 Jul 2026 17:00:47 +0000 (19:00 +0200)
commit219b80d79e9519ff3de34c25233c2b2264df8f6d
treee09bfa34cd14f5939ef483aebe644bab759d0fb3
parentceb896ab307153e51531bbee8d8a85d7734bca5e
BUG/MEDIUM: counters: preserve shared.tg pointer on 'clear counters all'

proxy_stats_clear_counters() did a blanket memset() on the be_counters /
fe_counters / listener counter structs when clearing all counters. This
zeroed the embedded shared.tg pointer array, which every hot path
dereferences with no NULL check (for example
_HA_ATOMIC_INC(&srv->counters.shared.tg[tgid-1]->cum_lbconn) in
process_srv_queue()). After 'clear counters all' the next request on
that server would segfault.

The memset pattern predates the switch to per-thread-group shared
counters (commit 5495c8844 "MEDIUM: counters: Dynamically allocate
per-thread group counters") and wasn't updated when shared.tg gained
pointer-array semantics. Additionally, memset'ing only the outer struct
never actually reset the accumulated counters in the pointed-at
per-tgroup structs, so 'clear counters all' silently failed to match
its documented "same effect as restarting" behaviour for cumulative
counters (bytes, sessions, requests, ...).

Introduce two helpers in src/counters.c:

  void counters_fe_reset(struct fe_counters *counters);
  void counters_be_reset(struct be_counters *counters);

Both iterate shared.tg[0 .. nbtgroups-1] and zero the *contents* of each
per-tgroup struct via memset, then zero the local (non-shared) fields of
the outer struct. The shared.tg pointer array, each shared.tg[it]
pointer, and shared.flags (COUNTERS_SHARED_F_LOCAL is set at boot and
reflects allocation ownership, not counter state) are preserved.

Refactor proxy_stats_clear_counters() to call these helpers instead of
the inline memset. This fixes both the segfault after 'clear counters
all' and the silent no-op on cumulative counters, and provides a shared
primitive for a subsequent 'clear counters server <b>/<s>' command.

In SHM stats-file mode, zeroing the per-tgroup structs affects every
process attached to the same object; this matches the intended
"reset everywhere" semantic of clear counters and is unchanged from
the outer-memset intent.

This bug should be backported wherever the per-thread-group shared
counter refactor is present.
include/haproxy/counters-t.h
include/haproxy/counters.h
reg-tests/stats/clear_counters_all_survives.vtc [new file with mode: 0644]
src/counters.c
src/stats-proxy.c