From c3f94fbd9b49a140c10dd6036585d3b76779feb4 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Tue, 9 Sep 2025 07:05:26 +0200 Subject: [PATCH] DEBUG: stream: count the number of passes in the connect loop Normally the connect loop cannot loop, but some recent traces can easily convince one of the opposite. Let's add a counter, including in panic dumps, in order to avoid the repeated long head scratching sessions starting with "and what if...". In addition, if it's found to loop, this time it will be certain and will indicate what to zoom in. This should be backported to 3.2. --- include/haproxy/stream-t.h | 2 ++ src/stream.c | 8 +++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/include/haproxy/stream-t.h b/include/haproxy/stream-t.h index 83db4cc20..06f7e4be0 100644 --- a/include/haproxy/stream-t.h +++ b/include/haproxy/stream-t.h @@ -274,10 +274,12 @@ struct stream { uint64_t lat_time; /* total latency time experienced */ uint64_t cpu_time; /* total CPU time consumed */ struct freq_ctr call_rate; /* stream task call rate without making progress */ + uint32_t passes_connect; /* number of passes on the connect processing loop */ uint32_t passes_stconn; /* number of passes on the stconn evaluation code */ uint32_t passes_reqana; /* number of passes on the req analysers block */ uint32_t passes_resana; /* number of passes on the res analysers block */ uint32_t passes_propag; /* number of passes on the shut/err propag code */ + /* 4 unused bytes here */ unsigned short max_retries; /* Maximum number of connection retried (=0 is backend is not set) */ short store_count; diff --git a/src/stream.c b/src/stream.c index 470079d06..c6e2d33f1 100644 --- a/src/stream.c +++ b/src/stream.c @@ -424,7 +424,7 @@ struct stream *stream_new(struct session *sess, struct stconn *sc, struct buffer s->lat_time = s->cpu_time = 0; s->call_rate.curr_tick = s->call_rate.curr_ctr = s->call_rate.prev_ctr = 0; - s->passes_stconn = s->passes_reqana = s->passes_resana = s->passes_propag = 0; + s->passes_connect = s->passes_stconn = s->passes_reqana = s->passes_resana = s->passes_propag = 0; s->pcli_next_pid = 0; s->pcli_flags = 0; s->unique_id = IST_NULL; @@ -2359,6 +2359,8 @@ struct task *process_stream(struct task *t, void *context, unsigned int state) } do { + s->passes_connect++; + /* nb: step 1 might switch from QUE to ASS, but we first want * to give a chance to step 2 to perform a redirect if needed. */ @@ -3378,8 +3380,8 @@ static void __strm_dump_to_buffer(struct buffer *buf, const struct show_sess_ctx strm->conn_err_type, strm->srv_conn, strm->pend_pos, LIST_INLIST(&strm->buffer_wait.list), strm->stream_epoch); - chunk_appendf(buf, "%s p_stc=%u p_req=%u p_res=%u p_prp=%u\n", pfx, - strm->passes_stconn, strm->passes_reqana, strm->passes_resana, strm->passes_propag); + chunk_appendf(buf, "%s p_con=%u p_stc=%u p_req=%u p_res=%u p_prp=%u\n", pfx, + strm->passes_connect, strm->passes_stconn, strm->passes_reqana, strm->passes_resana, strm->passes_propag); chunk_appendf(buf, "%s frontend=%s (id=%u mode=%s), listener=%s (id=%u)", pfx,