BUG/MEDIUM: mworker: create the mcli_reload socketpairs in case of upgrade

In ticket #1956, it was reported that an upgrade from 2.6 to 2.7 via a
reload would stop the master process.

When upgrading the binary, the new process is considered reexec and does
not try to creates the socketpair for the mcli_reload listener, then
tries to bind on -1 since the socket doesn't exit. The failure provokes
an exit() of the master.

This patch fixes the issue by trying to create the mcli_reload sockets
only when they don't exist, instead of creating them at first start.
This way we also avoid possible fd leak since we always try to use the
existing FDs first.

Must be backported in 2.7.
This commit is contained in:
William Lallemand 2022-12-07 14:25:41 +01:00
parent 035058e8bf
commit e57b702e2b

View File

@ -2132,19 +2132,6 @@ static void init(int argc, char **argv)
tmproc->options |= PROC_O_TYPE_MASTER; /* master */
tmproc->pid = pid;
tmproc->timestamp = start_date.tv_sec;
/* Creates the mcli_reload listener, which is the listener used
* to retrieve the master CLI session which asked for the reload.
*
* ipc_fd[1] will be used as a listener, and ipc_fd[0]
* will be used to send the FD of the session.
*
* Both FDs will be kept in the master.
*/
if (socketpair(AF_UNIX, SOCK_STREAM, 0, tmproc->ipc_fd) < 0) {
ha_alert("cannot create the mcli_reload socketpair.\n");
exit(EXIT_FAILURE);
}
proc_self = tmproc;
LIST_APPEND(&proc_list, &tmproc->list);
@ -2199,6 +2186,21 @@ static void init(int argc, char **argv)
free(c->s);
free(c);
}
/* Creates the mcli_reload listener, which is the listener used
* to retrieve the master CLI session which asked for the reload.
*
* ipc_fd[1] will be used as a listener, and ipc_fd[0]
* will be used to send the FD of the session.
*
* Both FDs will be kept in the master. The sockets are
* created only if they weren't inherited.
*/
if ((proc_self->ipc_fd[1] == -1) &&
socketpair(AF_UNIX, SOCK_STREAM, 0, proc_self->ipc_fd) < 0) {
ha_alert("cannot create the mcli_reload socketpair.\n");
exit(EXIT_FAILURE);
}
/* Create the mcli_reload listener from the proc_self struct */
memprintf(&path, "sockpair@%d", proc_self->ipc_fd[1]);
mcli_reload_bind_conf = mworker_cli_proxy_new_listener(path);