]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: mworker: proxy for the master CLI
authorWilliam Lallemand <wlallemand@haproxy.com>
Fri, 26 Oct 2018 12:47:35 +0000 (14:47 +0200)
committerWilly Tarreau <w@1wt.eu>
Sun, 28 Oct 2018 12:51:39 +0000 (13:51 +0100)
This patch implements a listen proxy within the master. It uses the
sockpair of all the workers as servers.

In the current state of the code, the proxy is only doing round robin on
the CLI of the workers. A CLI mode will be needed to know to which CLI
send the requests.

include/proto/cli.h
src/cli.c
src/haproxy.c

index de1305b9742cda85b9fcf8ca3865df2c990ff6b7..6d6ca35ffc981eaba084b73a6273b9545a622202 100644 (file)
@@ -28,6 +28,7 @@ void cli_register_kw(struct cli_kw_list *kw_list);
 
 int cli_has_level(struct appctx *appctx, int level);
 
+int mworker_cli_proxy_create();
 int mworker_cli_sockpair_new(struct mworker_proc *mworker_proc, int proc);
 
 #endif /* _PROTO_CLI_H */
index 2c17c6b8fa89b7dedbec68d3e37cbb6ff18f7674..161d1ebb06f8c6954323166250728f36ebb90fbd 100644 (file)
--- a/src/cli.c
+++ b/src/cli.c
@@ -93,6 +93,8 @@ static struct cli_kw_list cli_keywords = {
 
 extern const char *stat_status_codes[];
 
+static struct proxy *mworker_proxy; /* CLI proxy of the master */
+
 static char *cli_gen_usage_msg(struct appctx *appctx)
 {
        struct cli_kw_list *kw_list;
@@ -1565,6 +1567,89 @@ static int cli_parse_simple(char **args, char *payload, struct appctx *appctx, v
        return 1;
 }
 
+/*
+ * The mworker functions are used to initialize the CLI in the master process
+ */
+
+/*
+ * Create the mworker CLI proxy
+ */
+int mworker_cli_proxy_create()
+{
+       struct mworker_proc *child;
+
+       mworker_proxy = calloc(1, sizeof(*mworker_proxy));
+       if (!mworker_proxy)
+               return -1;
+
+       init_new_proxy(mworker_proxy);
+       mworker_proxy->next = proxies_list;
+       proxies_list = mworker_proxy;
+       mworker_proxy->id = strdup("MASTER");
+       mworker_proxy->mode = PR_MODE_TCP;
+       mworker_proxy->state = PR_STNEW;
+       mworker_proxy->last_change = now.tv_sec;
+       mworker_proxy->cap = PR_CAP_LISTEN; /* this is a listen section */
+       mworker_proxy->maxconn = 10;                 /* default to 10 concurrent connections */
+       mworker_proxy->timeout.client = 0; /* no timeout */
+       mworker_proxy->conf.file = strdup("MASTER");
+       mworker_proxy->conf.line = 0;
+       mworker_proxy->accept = frontend_accept;
+       mworker_proxy-> lbprm.algo = BE_LB_ALGO_NONE;
+
+       /* Does not init the default target the CLI applet, but must be done in
+        * the request parsing code */
+       mworker_proxy->default_target = NULL;
+
+       /* the check_config_validity() will get an ID for the proxy */
+       mworker_proxy->uuid = -1;
+
+       proxy_store_name(mworker_proxy);
+
+       /* create all servers using the mworker_proc list */
+       list_for_each_entry(child, &proc_list, list) {
+               char *msg = NULL;
+               struct server *newsrv = NULL;
+               struct sockaddr_storage *sk;
+               int port1, port2, port;
+               struct protocol *proto;
+               char *errmsg;
+
+               newsrv = new_server(mworker_proxy);
+               if (!newsrv)
+                       return -1;
+
+               /* we don't know the new pid yet */
+               if (child->pid == -1)
+                       memprintf(&msg, "cur-%d", child->relative_pid);
+               else
+                       memprintf(&msg, "old-%d", child->pid);
+
+               newsrv->next = mworker_proxy->srv;
+               mworker_proxy->srv = newsrv;
+               newsrv->conf.file = strdup(msg);
+               newsrv->id = strdup(msg);
+               newsrv->conf.line = 0;
+
+               memprintf(&msg, "sockpair@%d", child->ipc_fd[0]);
+               if ((sk = str2sa_range(msg, &port, &port1, &port2, &errmsg, NULL, NULL, 0)) == 0)
+                       return -1;
+
+               proto = protocol_by_family(sk->ss_family);
+               if (!proto || !proto->connect) {
+                       return -1;
+               }
+
+               /* no port specified */
+               newsrv->flags |= SRV_F_MAPPORTS;
+               newsrv->addr = *sk;
+               newsrv->iweight = 1;
+               newsrv->uweight = 1;
+               mworker_proxy->srv_act++;
+               srv_lb_commit_status(newsrv);
+       }
+       return 0;
+}
 
 /*
  * Create a new CLI socket using a socketpair for a worker process
index e466904322a45448818600ba41d254190291f319..5affcd208237a37ce2b02ae0e7fb4a725d9bc885 100644 (file)
@@ -1722,6 +1722,11 @@ static void init(int argc, char **argv)
                        LIST_ADDQ(&proc_list, &tmproc->list);
                }
                mworker_env_to_proc_list(); /* get the info of the children in the env */
+
+               if (mworker_cli_proxy_create() < 0) {
+                               ha_alert("Can't create the master's CLI.\n");
+                               exit(EXIT_FAILURE);
+               }
        }
 
        pattern_finalize_config();