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);
}
if (!LIST_ISEMPTY(&mworker_cli_conf)) {
+ char *path = NULL;
if (mworker_cli_proxy_create() < 0) {
ha_alert("Can't create the master's CLI.\n");
free(c->s);
free(c);
}
+ /* Create the mcli_reload listener from the proc_self struct */
+ memprintf(&path, "sockpair@%d", proc_self->ipc_fd[1]);
+
+ if (mworker_cli_proxy_new_listener(path) < 0) {
+ ha_alert("Cannot create the mcli_reload listener.\n");
+ exit(EXIT_FAILURE);
+ }
+ ha_free(&path);
}
}
#define _GNU_SOURCE
#include <errno.h>
+#include <fcntl.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
+#include <unistd.h>
#if defined(USE_SYSTEMD)
#include <systemd/sd-daemon.h>
#include <haproxy/listener.h>
#include <haproxy/mworker.h>
#include <haproxy/peers.h>
+#include <haproxy/proto_sockpair.h>
#include <haproxy/proxy.h>
#include <haproxy/sc_strm.h>
#include <haproxy/signal.h>
minreloads = child->reloads;
if (child->pid > -1)
- memprintf(&msg, "%s|type=%c;fd=%d;pid=%d;reloads=%d;failedreloads=%d;timestamp=%d;id=%s;version=%s", msg ? msg : "", type, child->ipc_fd[0], child->pid, child->reloads, child->failedreloads, child->timestamp, child->id ? child->id : "", child->version);
+ memprintf(&msg, "%s|type=%c;fd=%d;cfd=%d;pid=%d;reloads=%d;failedreloads=%d;timestamp=%d;id=%s;version=%s", msg ? msg : "", type, child->ipc_fd[0], child->ipc_fd[1], child->pid, child->reloads, child->failedreloads, child->timestamp, child->id ? child->id : "", child->version);
}
if (msg)
setenv("HAPROXY_PROCESSES", msg, 1);
} else if (strncmp(subtoken, "fd=", 3) == 0) {
child->ipc_fd[0] = atoi(subtoken+3);
+ } else if (strncmp(subtoken, "cfd=", 4) == 0) {
+ child->ipc_fd[1] = atoi(subtoken+4);
} else if (strncmp(subtoken, "pid=", 4) == 0) {
child->pid = atoi(subtoken+4);
} else if (strncmp(subtoken, "reloads=", 8) == 0) {
/* reload the master process */
static int cli_parse_reload(char **args, char *payload, struct appctx *appctx, void *private)
{
+ struct stconn *scb = NULL;
+ struct stream *strm = NULL;
+ struct connection *conn = NULL;
+ int fd = -1;
+
if (!cli_has_level(appctx, ACCESS_LVL_OPER))
return 1;
+ /* This ask for a synchronous reload, which means we will keep this FD
+ instead of closing it. */
+
+ scb = appctx_sc(appctx);
+ if (scb)
+ strm = sc_strm(scb);
+ if (strm && strm->scf)
+ conn = sc_conn(strm->scf);
+ if (conn)
+ fd = conn_fd(conn);
+
+ /* Send the FD of the current session to the "cli_reload" FD, which won't be polled */
+ if (fd != -1 && send_fd_uxst(proc_self->ipc_fd[0], fd) == 0) {
+ close(fd); /* avoid the leak of the FD after sending it via the socketpair */
+ }
mworker_reload();
return 1;