void mworker_prepare_master(void);
void mworker_run_master(void);
+void mworker_apply_master_worker_mode(void);
#endif /* _HAPROXY_MWORKER_H_ */
DISGUISE(write(pidfd, pidstr, strlen(pidstr)));
}
-/* This function at first does master-worker fork. It creates then GLOBAL and
- * MASTER proxies, allocates listeners for these proxies and binds a GLOBAL
- * proxy listener in worker process on ipc_fd[1] and MASTER proxy listener
- * in master process on ipc_fd[0]. ipc_fd[0] and ipc_fd[1] are the "ends" of the
- * sockpair, created in prepare_master(). This sockpair is copied via fork to
- * each process and serves as communication channel between master and worker
- * (master CLI applet is attached in master process to MASTER proxy). This
- * function returns only if everything is OK. If something fails, it exits.
- */
-static void mworker_apply_master_worker_mode()
-{
- int worker_pid;
- struct mworker_proc *child;
- char *sock_name = NULL;
- char *errmsg = NULL;
-
- worker_pid = fork();
- switch (worker_pid) {
- case -1:
- ha_alert("[%s.main()] Cannot fork.\n", progname);
-
- exit(EXIT_FAILURE);
- case 0:
- /* 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.
- */
- proc_self = child;
- /* attach listener to GLOBAL proxy on child->ipc_fd[1] */
- if (mworker_cli_global_proxy_new_listener(child) < 0)
- exit(EXIT_FAILURE);
-
- break;
- }
-
- /* need to close reload sockpair fds, inherited after master's execvp and fork(),
- * we can't close these fds in master before the fork(), as ipc_fd[1] serves after
- * the mworker_reexec to obtain the MCLI client connection fd, like this we can
- * write to this connection fd the content of the startup_logs ring.
- */
- if (child->options & PROC_O_TYPE_MASTER) {
- if (child->ipc_fd[0] > 0)
- close(child->ipc_fd[0]);
- if (child->ipc_fd[1] > 0)
- close(child->ipc_fd[1]);
- }
- }
- break;
- default:
- /* in parent */
- ha_notice("Initializing new worker (%d)\n", worker_pid);
- master = 1;
-
- /* in exec mode, there's always exactly one thread. Failure to
- * set these ones now will result in nbthread being detected
- * automatically.
- */
- global.nbtgroups = 1;
- global.nbthread = 1;
-
- /* creates MASTER proxy */
- if (mworker_cli_create_master_proxy(&errmsg) < 0) {
- ha_alert("Can't create MASTER proxy: %s\n", errmsg);
- free(errmsg);
- exit(EXIT_FAILURE);
- }
-
- /* attaches servers to all existed workers on its shared MCLI sockpair ends, ipc_fd[0] */
- if (mworker_cli_attach_server(&errmsg) < 0) {
- ha_alert("Can't attach servers needed for master CLI %s\n", errmsg ? errmsg : "");
- free(errmsg);
- exit(EXIT_FAILURE);
- }
-
- /* 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;
- }
- }
- }
-}
-
static void get_listeners_fd()
{
/* Try to get the listeners FD from the previous process using
exit(0);
}
+/* This function at first does master-worker fork. It creates then GLOBAL and
+ * MASTER proxies, allocates listeners for these proxies and binds a GLOBAL
+ * proxy listener in worker process on ipc_fd[1] and MASTER proxy listener
+ * in master process on ipc_fd[0]. ipc_fd[0] and ipc_fd[1] are the "ends" of the
+ * sockpair, created in prepare_master(). This sockpair is copied via fork to
+ * each process and serves as communication channel between master and worker
+ * (master CLI applet is attached in master process to MASTER proxy). This
+ * function returns only if everything is OK. If something fails, it exits.
+ */
+void mworker_apply_master_worker_mode(void)
+{
+ int worker_pid;
+ struct mworker_proc *child;
+ char *sock_name = NULL;
+ char *errmsg = NULL;
+
+ worker_pid = fork();
+ switch (worker_pid) {
+ case -1:
+ ha_alert("[%s.main()] Cannot fork.\n", progname);
+
+ exit(EXIT_FAILURE);
+ case 0:
+ /* 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.
+ */
+ proc_self = child;
+ /* attach listener to GLOBAL proxy on child->ipc_fd[1] */
+ if (mworker_cli_global_proxy_new_listener(child) < 0)
+ exit(EXIT_FAILURE);
+
+ break;
+ }
+
+ /* need to close reload sockpair fds, inherited after master's execvp and fork(),
+ * we can't close these fds in master before the fork(), as ipc_fd[1] serves after
+ * the mworker_reexec to obtain the MCLI client connection fd, like this we can
+ * write to this connection fd the content of the startup_logs ring.
+ */
+ if (child->options & PROC_O_TYPE_MASTER) {
+ if (child->ipc_fd[0] > 0)
+ close(child->ipc_fd[0]);
+ if (child->ipc_fd[1] > 0)
+ close(child->ipc_fd[1]);
+ }
+ }
+ break;
+ default:
+ /* in parent */
+ ha_notice("Initializing new worker (%d)\n", worker_pid);
+ master = 1;
+
+ /* in exec mode, there's always exactly one thread. Failure to
+ * set these ones now will result in nbthread being detected
+ * automatically.
+ */
+ global.nbtgroups = 1;
+ global.nbthread = 1;
+
+ /* creates MASTER proxy */
+ if (mworker_cli_create_master_proxy(&errmsg) < 0) {
+ ha_alert("Can't create MASTER proxy: %s\n", errmsg);
+ free(errmsg);
+ exit(EXIT_FAILURE);
+ }
+
+ /* attaches servers to all existed workers on its shared MCLI sockpair ends, ipc_fd[0] */
+ if (mworker_cli_attach_server(&errmsg) < 0) {
+ ha_alert("Can't attach servers needed for master CLI %s\n", errmsg ? errmsg : "");
+ free(errmsg);
+ exit(EXIT_FAILURE);
+ }
+
+ /* 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;
+ }
+ }
+ }
+}
+
static struct cfg_kw_list mworker_kws = {{ }, {
{ CFG_GLOBAL, "mworker-max-reloads", mworker_parse_global_max_reloads, KWF_DISCOVERY },
{ 0, NULL, NULL },