From: Willy Tarreau Date: Wed, 24 Feb 2021 10:53:17 +0000 (+0100) Subject: MINOR: cli/streams: make "show sess" dump all streams till the new epoch X-Git-Tag: v2.4-dev10~67 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5d533e2bad668f10e5b00c24b7593847149a6be2;p=thirdparty%2Fhaproxy.git MINOR: cli/streams: make "show sess" dump all streams till the new epoch Instead of placing the current stream at the end of the stream list when issuing a "show sess" on the CLI as was done in 2.2 with commit c6e7a1b8e ("MINOR: cli: make "show sess" stop at the last known session"), now we compare the listed stream's epoch with the dumping stream's and stop on more recent ones. This way we're certain to always only dump known streams at the moment we issue the dump command without having to modify the list. In theory we could miss some streams if more than 2^31 "show sess" requests are issued while an old stream remains present, but that's 68 years at 1 "show sess" per second and it's unlikely we'll keep a process, let alone a stream, that long. It could be verified that the count of dumped streams still matches the one before this change. --- diff --git a/src/stream.c b/src/stream.c index 0b86488a53..d04581a335 100644 --- a/src/stream.c +++ b/src/stream.c @@ -3192,16 +3192,6 @@ static int cli_parse_show_sess(char **args, char *payload, struct appctx *appctx * it so that we know which streams were already there before us. */ si_strm(appctx->owner)->stream_epoch = _HA_ATOMIC_XADD(&stream_epoch, 1); - - /* we need to put an end marker into the streams list. We're just moving - * ourselves there, so that once we found ourselves we know we've reached - * the end. Without this we can run forever if new streams arrive faster - * than we can dump them. - */ - HA_SPIN_LOCK(STRMS_LOCK, &streams_lock); - LIST_DEL(&si_strm(appctx->owner)->list); - LIST_ADDQ(&streams, &si_strm(appctx->owner)->list); - HA_SPIN_UNLOCK(STRMS_LOCK, &streams_lock); return 0; } @@ -3253,13 +3243,17 @@ static int cli_io_handler_dump_sess(struct appctx *appctx) LIST_INIT(&appctx->ctx.sess.bref.users); } - /* and start from where we stopped, never going further than ourselves */ - while (appctx->ctx.sess.bref.ref != si_strm(appctx->owner)->list.n) { + /* and start from where we stopped */ + while (appctx->ctx.sess.bref.ref != &streams) { char pn[INET6_ADDRSTRLEN]; struct stream *curr_strm; curr_strm = LIST_ELEM(appctx->ctx.sess.bref.ref, struct stream *, list); + /* check if we've found a stream created after issuing the "show sess" */ + if ((int)(curr_strm->stream_epoch - si_strm(appctx->owner)->stream_epoch) > 0) + break; + if (appctx->ctx.sess.target) { if (appctx->ctx.sess.target != (void *)-1 && appctx->ctx.sess.target != curr_strm) goto next_sess;