Now with list in CC, sry! -----Original Message----- From: Stephan, Alexander Sent: Thursday, February 19, 2026 2:22 PM To: 'William Lallemand' <[email protected]> Cc: Willy Tarreau <[email protected]> Subject: RE: BUG/MINOR: mworker/cli: avoid duplicates in 'show proc'
Hi William and Willy,
First, thanks for the backports! However, I noticed an issue with the backport
on stable branches <= 3.0 where the entries get re-emitted after 198 processes.
The final proc_list ordering differs between the versions:
<= 3.0: In haproxy.c main(), the new worker is appended to proc_list first
(before mworker_env_to_proc_list() is called), so deserialized old workers end
up after the current worker.
This would mean old (LEAVING) workers appear in the list in descending reload
order (newest old worker first).
>= 3.1 (current master): mworker_env_to_proc_list() runs early in init
>(haproxy.c:3311), appending all deserialized entries first.
Then mworker_prepare_master() (haproxy.c:3350) appends the new worker last. Old
workers are therefore in ascending reload order (oldest first).
The original pagination fix (commit 594408c) used child->reloads >=
ctx->next_reload to skip already-printed entries on resume.
This comparison is direction-dependent — it only works correctly when the list
is in one specific order.
On branches where the order is reversed (i.e. <= 3.0, so effectively 2.9, 3.0,
since the other patch was only backported to this version), it loops back to
the beginning after ~198 processes.
A version-specific fix, applicable to 2.9 and 3.0 would be trivial (flip >= to
<), created from 3.0.16 in this case:
diff --git a/src/mworker.c b/src/mworker.c index 355e015..fb830fc 100644
--- a/src/mworker.c
+++ b/src/mworker.c
@@ -638,8 +638,8 @@ static int cli_io_handler_show_proc(struct appctx *appctx)
if (up <= 0) /* must never be negative because of clock
drift */
up = 0;
- /* If we're resuming, skip entries that were already
printed (reload >= ctx->next_reload) */
- if (ctx->next_reload && child->reloads >=
ctx->next_reload)
+ /* If we're resuming, skip entries that were already
printed (reload < ctx->next_reload) */
+ if (ctx->next_reload && child->reloads <
ctx->next_reload)
continue;
if (!(child->options & PROC_O_TYPE_WORKER))
--
2.43.7
But as we've seen, this approach is fragile and will depend on the specific
HAProxy version.
From what I understood, the backported commits should be apply to all target
versions as is.
So, instead of a directional comparison, the new approach:
I renamed ctx->next_reload to ctx->resume_reload and changed its semantics: it
now stores the reload count of the last successfully flushed row, not the
failed one.
On flush failure, the value is left unchanged, so the failed row is replayed on
the next call.
On resume, walk the list and skip entries until we find the one whose
child->reloads == skip, then resume from the next entry.
This works identically whether the list is ascending or descending.
For correctness, we also need to handle the deletion of the marker entry (e.g.,
a worker process exits and SIGCHLD removes it from proc_list between handler
calls).
Here, track the previous LEAVING entry's reload count during the skip phase. If
two consecutive LEAVING entries straddle the skip value (one has reloads >
skip, the other has reloads < skip, or vice versa), the deleted entry's former
position has been crossed, so skipping stops and the current entry is emitted.
This makes the pagination completely direction-agnostic — it doesn't matter
whether old workers are in ascending or descending order in proc_list.
IMO, it should be backported to all stable branches. On branches where
proc_list happens to be in descending order (2.9, 3.0), the fix works the same
way since the skip logic no longer depends on list direction.
What do you think of this? In general, I would find a stable ascending order in
>= 3.1 that is consistent to 3.0 ideal. This would also prevent tools that use
the output from breaking.
But I am not sure about the implications of changing this again.
As usual, I attach my patch to make sure my email client doesn't mess with it.
Best regards,
Alexander
-----Original Message-----
From: William Lallemand <[email protected]>
Sent: Wednesday, January 28, 2026 3:42 PM
To: Stephan, Alexander <[email protected]>
Cc: [email protected]
Subject: Re: BUG/MINOR: mworker/cli: avoid duplicates in 'show proc'
Hello Alexander,
On Mon, Jan 26, 2026 at 04:16:56PM +0000, Stephan, Alexander wrote:
> Subject: RE: BUG/MINOR: mworker/cli: avoid duplicates in 'show proc'
> Hi William,
>
> I have been investigating the backport situation a bit and I wanted to
> quickly share some findings that might be useful.
>
I backported the patches to version 3.2, but as you already observed, there's a
lot of changes before this version. The "program" section still exists in these
versions and the code was not written for it.
I backported a few patches to do the backport as far as 3.0 but I don't think
it's worth it going further given the impact of the problem. We probably don't
want to mess with a feature which works for 99% of usecases in an older branch.
> So, I noticed a difference regarding the process list before version 3.0,
> which would need to be accounted for.
> "show proc" still uses the default parser here, which leaves
> appctx->svcctx uninitialized:
> https://gith/
> ub.com%2Fhaproxy%2Fhaproxy%2Fblob%2Ff76e73511addd075f556449b0ebf33c9f7
> a5184b%2Fsrc%2Fmworker.c%23L803C100-L803C117&data=05%7C02%7Calexander.
> stephan%40sap.com%7C44fb7a032eec4a725fec08de5e7b6d62%7C42f7676cf455423
> c82f6dc2d99791af7%7C0%7C0%7C639052081403606857%7CUnknown%7CTWFpbGZsb3d
> 8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiT
> WFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=P%2B%2Foi%2BYVifCU82eQOCUcC
> VoPQ5SGh0d8wd74M%2BeBBvI%3D&reserved=0
> Therefore, additional context would be needed like in the patch below where
> also the custom parser method needs to be copied from master.
>
> Furthermore, from what I can see the process list works a bit
> differently when it comes to reloads, using a min counter:
> https://gith/
> ub.com%2Fhaproxy%2Fhaproxy%2Fblob%2Ff76e73511addd075f556449b0ebf33c9f7
> a5184b%2Fsrc%2Fmworker.c%23L174&data=05%7C02%7Calexander.stephan%40sap
> .com%7C44fb7a032eec4a725fec08de5e7b6d62%7C42f7676cf455423c82f6dc2d9979
> 1af7%7C0%7C0%7C639052081403631160%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1h
> cGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIj
> oyfQ%3D%3D%7C0%7C%7C%7C&sdata=xitlobHSOmFfjcC6uNTAvExXTMuptzybtemtOcqi
> vD4%3D&reserved=0 With the 1:1 logic from master, I again run into
> duplicates and messed up ordering in the the "show proc" output.
>
> I had success fixing this by adjusting the iteration, replacing
> ctx->next_reload = child->reloads with ctx->next_reload =
> child->reloads + 1; and replace
>
> if (ctx->next_reload && child->reloads >= ctx->next_reload)
> continue;
> with
>
> if (ctx->next_reload && child->reloads < ctx->next_reload)
> continue;
>
> in the old worker part. I appended the resulting patch which directly applies
> to 3.0-dev13 (just as an example, not fully ready for a commit yet).
>
> With this, it works very well for me for the backport targets 2.8 and 3.0
> (deferred from the issue https://github.com/haproxy/haproxy/issues/3204).
>
> I hope this helps, I am also curious whether you agree with my approach here.
>
> Thanks in advance, and best regards,
Thank you for the investigating the problem. Regarding your patch, we try to
backport the patches instead of writing new ones in previous branches. So for
the 3.0 branch I backported these ones:
e41829dda6 BUG/MINOR: mworker/cli: fix show proc pagination using reload counter
9cae4b8f28 BUG/MINOR: mworker/cli: 'show proc' is limited by buffer size
48d20c79e7 MINOR: mworker/cli: 'show proc debug' for old workers 5b851f94af
MINOR: mworker/cli: remove comment line for program when useless 948a4c372b
MINOR: mworker/cli: add 'debug' to 'show proc'
d55d3c6225 CLEANUP: mworker/cli: remove useless variable
These are minor changes that are not that intrusive for a backport, backporting
without them would change too much the original patches, so I took them in 3.0.
Regards,
--
William Lallemand
0001-BUG-MINOR-mworker-cli-fix-show-proc-pagination-losin.patch
Description: 0001-BUG-MINOR-mworker-cli-fix-show-proc-pagination-losin.patch

