Skip to content

Commit

Permalink
MEDIUM: mworker: proxy for the master CLI
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
wlallemand authored and wtarreau committed Oct 28, 2018
1 parent 6e0db2f commit 8a02257
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 0 deletions.
1 change: 1 addition & 0 deletions include/proto/cli.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
85 changes: 85 additions & 0 deletions src/cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions src/haproxy.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down

0 comments on commit 8a02257

Please sign in to comment.