From 13d13691b5dd16e6da48a270894d85e66c315b77 Mon Sep 17 00:00:00 2001 From: William Lallemand Date: Thu, 12 Mar 2026 16:49:32 +0100 Subject: [PATCH] BUG/MINOR: mworker: always stop the receiving listener Upon _send_status, always stop the listener from which the request was received, rather than looking it up from the proc_list entry via fdtab[proc->ipc_fd[0]].owner. A BUG_ON is added to verify that the listener which received the request is the one expected for the reported PID. This means it is no longer possible to send "_send_status READY XXX" manually through the master CLI for testing, as that would trigger the BUG_ON. Must be backported as far as 3.1. --- src/cli.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/src/cli.c b/src/cli.c index ee53961f0..104b7175d 100644 --- a/src/cli.c +++ b/src/cli.c @@ -2614,8 +2614,9 @@ static int cli_parse_echo(char **args, char *payload, struct appctx *appctx, voi static int _send_status(char **args, char *payload, struct appctx *appctx, void *private) { - struct listener *mproxy_li; struct mworker_proc *proc; + struct stconn *sc = appctx_sc(appctx); + struct listener *mproxy_li = strm_li(__sc_strm(sc)); char *msg = "READY\n"; int pid; @@ -2625,19 +2626,18 @@ static int _send_status(char **args, char *payload, struct appctx *appctx, void pid = atoi(args[2]); list_for_each_entry(proc, &proc_list, list) { + /* update status of the new worker */ if (proc->pid == pid) { proc->options &= ~PROC_O_INIT; - /* the sockpair between the master and the worker is - * used temporarly as a listener to receive - * _send_status. Once it is received we don't want to - * use this FD as a listener anymore, but only as a - * server, to allow only connections from the master to - * the worker for the master CLI */ - mproxy_li = fdtab[proc->ipc_fd[0]].owner; - BUG_ON(mproxy_li == NULL); - stop_listener(mproxy_li, 0, 0, 0); + + /* the proxy used to receive the _send_status must be + * the one corresponding to the PID we received in + * argument */ + BUG_ON(proc->ipc_fd[0] < 0); + BUG_ON(mproxy_li != fdtab[proc->ipc_fd[0]].owner); } + /* send TERM to workers, which have exceeded max_reloads counter */ if (max_reloads != -1) { if ((proc->options & PROC_O_TYPE_WORKER) && @@ -2649,6 +2649,15 @@ static int _send_status(char **args, char *payload, struct appctx *appctx, void } } + /* the sockpair between the master and the worker is + * used temporarly as a listener to receive + * _send_status. Once it is received we don't want to + * use this FD as a listener anymore, but only as a + * server, to allow only connections from the master to + * the worker for the master CLI */ + BUG_ON(mproxy_li == NULL); + stop_listener(mproxy_li, 0, 0, 0); + /* At this point we are sure, that newly forked worker is started, * so we can write our PID in a pidfile, if provided. Master doesn't * perform chroot.