From: Willy Tarreau Date: Wed, 24 Feb 2021 10:29:51 +0000 (+0100) Subject: MINOR: stream: add an "epoch" to figure which streams appeared when X-Git-Tag: v2.4-dev10~68 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b981318c11ce8c1969b931b01d51be38dbbaa4a7;p=thirdparty%2Fhaproxy.git MINOR: stream: add an "epoch" to figure which streams appeared when The "show sess" CLI command currently lists all streams and needs to stop at a given position to avoid dumping forever. Since 2.2 with commit c6e7a1b8e ("MINOR: cli: make "show sess" stop at the last known session"), a hack consists in unlinking the stream running the applet and linking it again at the current end of the list, in order to serve as a delimiter. But this forces the stream list to be global, which affects scalability. This patch introduces an epoch, which is a global 32-bit counter that is incremented by the "show sess" command, and which is copied by newly created streams. This way any stream can know whether any other one is newer or older than itself. For now it's only stored and not exploited. --- diff --git a/include/haproxy/stream-t.h b/include/haproxy/stream-t.h index 1e0ab1ecd7..429d99244c 100644 --- a/include/haproxy/stream-t.h +++ b/include/haproxy/stream-t.h @@ -181,6 +181,8 @@ struct stream { struct list *current_rule_list; /* this is used to store the current executed rule list. */ void *current_rule; /* this is used to store the current rule to be resumed. */ int rules_exp; /* expiration date for current rules execution */ + + unsigned int stream_epoch; /* copy of stream_epoch when the stream was created */ struct hlua *hlua; /* lua runtime context */ /* Context */ diff --git a/src/stream.c b/src/stream.c index 1dfbd361ac..0b86488a53 100644 --- a/src/stream.c +++ b/src/stream.c @@ -64,6 +64,8 @@ DECLARE_POOL(pool_head_stream, "stream", sizeof(struct stream)); DECLARE_POOL(pool_head_uniqueid, "uniqueid", UNIQUEID_LEN); +/* incremented by each "show sess" to fix a delimiter between streams */ +unsigned stream_epoch = 0; struct list streams = LIST_HEAD_INIT(streams); __decl_spinlock(streams_lock); @@ -414,6 +416,7 @@ struct stream *stream_new(struct session *sess, enum obj_type *origin, struct bu s->si[0].flags = SI_FL_NONE; s->si[1].flags = SI_FL_ISBACK; + s->stream_epoch = _HA_ATOMIC_LOAD(&stream_epoch); s->uniq_id = _HA_ATOMIC_XADD(&global.req_count, 1); /* OK, we're keeping the stream, so let's properly initialize the stream */ @@ -2885,9 +2888,9 @@ static int stats_dump_full_strm_to_buffer(struct stream_interface *si, struct st } chunk_appendf(&trash, - " flags=0x%x, conn_retries=%d, srv_conn=%p, pend_pos=%p waiting=%d\n", + " flags=0x%x, conn_retries=%d, srv_conn=%p, pend_pos=%p waiting=%d epoch=%#x\n", strm->flags, strm->si[1].conn_retries, strm->srv_conn, strm->pend_pos, - LIST_ADDED(&strm->buffer_wait.list)); + LIST_ADDED(&strm->buffer_wait.list), strm->stream_epoch); chunk_appendf(&trash, " frontend=%s (id=%u mode=%s), listener=%s (id=%u)", @@ -3185,6 +3188,11 @@ 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; + /* let's set our own stream's epoch to the current one and increment + * 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 @@ -3302,8 +3310,8 @@ static int cli_io_handler_dump_sess(struct appctx *appctx) } chunk_appendf(&trash, - " ts=%02x age=%s calls=%u rate=%u cpu=%llu lat=%llu", - curr_strm->task->state, + " ts=%02x epoch=%#x age=%s calls=%u rate=%u cpu=%llu lat=%llu", + curr_strm->task->state, curr_strm->stream_epoch, human_time(now.tv_sec - curr_strm->logs.tv_accept.tv_sec, 1), curr_strm->task->calls, read_freq_ctr(&curr_strm->call_rate), (unsigned long long)curr_strm->task->cpu_time, (unsigned long long)curr_strm->task->lat_time);