diff --git a/doc/management.txt b/doc/management.txt index 00ce3909e..0877992b6 100644 --- a/doc/management.txt +++ b/doc/management.txt @@ -2390,7 +2390,11 @@ show servers state [] show sess Dump all known sessions. Avoid doing this on slow connections as this can be huge. This command is restricted and can only be issued on sockets - configured for levels "operator" or "admin". + configured for levels "operator" or "admin". Note that on machines with + quickly recycled connections, it is possible that this output reports less + entries than really exist because it will dump all existing sessions up to + the last one that was created before the command was entered; those which + die in the mean time will not appear. show sess Display a lot of internal information about the specified session identifier. diff --git a/src/stream.c b/src/stream.c index f0618de4d..287f40647 100644 --- a/src/stream.c +++ b/src/stream.c @@ -3137,6 +3137,15 @@ static int cli_parse_show_sess(char **args, char *payload, struct appctx *appctx appctx->ctx.sess.section = 0; /* start with stream status */ appctx->ctx.sess.pos = 0; + /* 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; } @@ -3188,8 +3197,8 @@ static int cli_io_handler_dump_sess(struct appctx *appctx) LIST_INIT(&appctx->ctx.sess.bref.users); } - /* and start from where we stopped */ - while (appctx->ctx.sess.bref.ref != &streams) { + /* and start from where we stopped, never going further than ourselves */ + while (appctx->ctx.sess.bref.ref != si_strm(appctx->owner)->list.n) { char pn[INET6_ADDRSTRLEN]; struct stream *curr_strm;