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.
(cherry picked from commit 5d533e2bad668f10e5b00c24b7593847149a6be2)
Signed-off-by: Willy Tarreau <w@1wt.eu>
diff --git a/src/stream.c b/src/stream.c
index 61cb5ec..b2ed69a 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -3156,16 +3156,6 @@
* 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;
}
@@ -3217,13 +3207,17 @@
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;