MEDIUM: mworker/cli: close child and parent fds, setup listeners

Basically, this is the continuation of the previous commits. So, here after the
fork, worker process closes the "master" end of the copied CLI sockpair and
binds its end, ipc_fd[1], to the GLOBAL proxy listener.
mworker_cli_global_proxy_new_listener() guarantees that GLOBAL proxy will be
created, if it wasn't the case before.

Master process, at first, allocates the MASTER proxy, creates master CLI listener
(-S command line option) and reload sockpair and then closes the "worker" end of
the copied CLI sockpair and binds its end, ipc_fd[0], to the created MASTER proxy.

Usage of the new PROC_O_INIT state helps to reduce test conditions to find the
newly forked worker.
This commit is contained in:
Valentine Krasnobaeva 2024-10-03 11:44:04 +02:00 committed by Willy Tarreau
parent 646299fc95
commit cf150fd73d

View File

@ -2104,11 +2104,6 @@ static void init(int argc, char **argv)
ha_alert("Cannot create worker master CLI socketpair.\n");
exit(EXIT_FAILURE);
}
if (mworker_cli_global_proxy_new_listener(tmproc) < 0) {
close(tmproc->ipc_fd[0]);
close(tmproc->ipc_fd[1]);
exit(EXIT_FAILURE);
}
LIST_APPEND(&proc_list, &tmproc->list);
}
@ -2158,6 +2153,7 @@ static void init(int argc, char **argv)
int worker_pid;
struct mworker_proc *child;
struct ring *tmp_startup_logs = NULL;
char *sock_name = NULL;
worker_pid = fork();
switch (worker_pid) {
@ -2176,41 +2172,34 @@ static void init(int argc, char **argv)
/* This one must not be exported, it's internal! */
unsetenv("HAPROXY_MWORKER_REEXEC");
ha_random_jump96(1);
list_for_each_entry(child, &proc_list, list) {
if ((child->options & PROC_O_TYPE_WORKER) && (child->options & PROC_O_INIT)) {
close(child->ipc_fd[0]);
child->ipc_fd[0] = -1;
/* proc_self needs to point to the new forked worker in
* worker's context, as it's dereferenced in
* mworker_sockpair_register_per_thread(), called for
* master and for worker.
*/
list_for_each_entry(child, &proc_list, list) {
if (child->options & PROC_O_TYPE_WORKER &&
child->reloads == 0 &&
child->pid == -1) {
proc_self = child;
break;
}
/* attach listener to GLOBAL proxy on child->ipc_fd[1] */
if (mworker_cli_global_proxy_new_listener(child) < 0) {
close(child->ipc_fd[1]);
exit(EXIT_FAILURE);
}
break;
}
}
break;
default:
/* in parent */
ha_notice("Initializing new worker (%d)\n", worker_pid);
master = 1;
atexit_flag = 1;
atexit(exit_on_failure);
ha_notice("Initializing new worker (%d)\n", worker_pid);
/* find the right mworker_proc */
list_for_each_entry(child, &proc_list, list) {
if (child->reloads == 0 && child->options & PROC_O_TYPE_WORKER && child->pid == -1) {
child->timestamp = date.tv_sec;
child->pid = worker_pid;
child->version = strdup(haproxy_version);
/* at this step the fd is bound for the worker, set it to -1 so
* it could be close in case of errors in mworker_cleanup_proc() */
child->ipc_fd[1] = -1;
break;
}
}
/* in exec mode, there's always exactly one thread. Failure to
* set these ones now will result in nbthread being detected
* automatically.
@ -2226,6 +2215,28 @@ static void init(int argc, char **argv)
/* creates reload sockpair and listeners for master CLI (-S) */
mworker_create_master_cli();
/* find the right mworker_proc */
list_for_each_entry(child, &proc_list, list) {
if ((child->options & PROC_O_TYPE_WORKER) && (child->options & PROC_O_INIT)) {
child->timestamp = date.tv_sec;
child->pid = worker_pid;
child->version = strdup(haproxy_version);
close(child->ipc_fd[1]);
child->ipc_fd[1] = -1;
/* attach listener to MASTER proxy on child->ipc_fd[0] */
memprintf(&sock_name, "sockpair@%d", child->ipc_fd[0]);
if (mworker_cli_master_proxy_new_listener(sock_name) == NULL) {
ha_free(&sock_name);
exit(EXIT_FAILURE);
}
ha_free(&sock_name);
break;
}
}
}
}