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.
This commit is contained in:
William Lallemand 2026-03-12 16:49:32 +01:00
parent 76ba026548
commit 13d13691b5

View File

@ -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.