On Thu, Mar 31, 2022 at 11:56:13AM +0200, Willy Tarreau wrote:
> > I've made some "session shutdown" tests. With simple configuration
> > (attached) it is very easy to reproduce a situation when "shutdown session"
> > works only for the first time.
> 
> Indeed, thanks for this, I can as well reproduce it. With a bit of luck
> I'll figure what's happening, hoping I won't unearth an ugly bug!

Now found and fixed. It's been bogus since we've split the list of streams
to be per-thread in 2.4, patch attached if you need it.

Thanks,
Willy
>From c40c407268190e41d7d0238e3e2b7669147df9f7 Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w...@1wt.eu>
Date: Thu, 31 Mar 2022 14:49:45 +0200
Subject: BUG/MINOR: cli/stream: fix "shutdown session" to iterate over all
 threads

The list of streams was modified in 2.4 to become per-thread with commit
a698eb673 ("MINOR: streams: use one list per stream instead of a global
one"). However the change applied to cli_parse_shutdown_session() is
wrong, as it uses the nullity of the stream pointer to continue on next
threads, but this one is not null once the list_for_each_entry() loop
is finished, it points to the list's head again, so the loop doesn't
check other threads, and no message is printed either to say that the
stream was not found.

Instead we should check if the stream is equal to the requested pointer
since this is the condition to break out of the loop.

Thus must be backported to 2.4. Thanks to Maciej Zdeb for reporting this.
---
 src/stream.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/stream.c b/src/stream.c
index 8acce8075..fd8dada12 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -3750,16 +3750,16 @@ static int cli_parse_shutdown_session(char **args, char 
*payload, struct appctx
        if (!cli_has_level(appctx, ACCESS_LVL_ADMIN))
                return 1;
 
-       if (!*args[2])
-               return cli_err(appctx, "Session pointer expected (use 'show 
sess').\n");
-
        ptr = (void *)strtoul(args[2], NULL, 0);
+       if (!ptr)
+               return cli_err(appctx, "Session pointer expected (use 'show 
sess').\n");
+
        strm = NULL;
 
        thread_isolate();
 
        /* first, look for the requested stream in the stream table */
-       for (thr = 0; !strm && thr < global.nbthread; thr++) {
+       for (thr = 0; strm != ptr && thr < global.nbthread; thr++) {
                list_for_each_entry(strm, &ha_thread_ctx[thr].streams, list) {
                        if (strm == ptr) {
                                stream_shutdown(strm, SF_ERR_KILLED);
@@ -3771,7 +3771,7 @@ static int cli_parse_shutdown_session(char **args, char 
*payload, struct appctx
        thread_release();
 
        /* do we have the stream ? */
-       if (!strm)
+       if (strm != ptr)
                return cli_err(appctx, "No such session (use 'show sess').\n");
 
        return 1;
-- 
2.35.1

Reply via email to