MINOR: proxy: simplify parsing 'backend/server'

Several CLI handlers use a server argument specified with the format
'<backend>/<server>'. The parsing of this arguement is done in two
steps, first splitting the string with '/' delimiter and then use
get_backend_server() to retrieve the server instance.

Refactor this code sections with the following changes :
* splitting is reimplented using ist API
* get_backend_server() is removed. Instead use the already existing
  proxy_be_by_name() then server_find_by_name() which contains
  duplicated code with the now removed function.

No functional change occurs with this commit. However, it will be useful
to add new configuration options reusing the same '<backend>/<server>'
for reverse connect.
This commit is contained in:
Amaury Denoyelle 2023-08-07 16:24:24 +02:00
parent 9b47ed1a93
commit fbe35afaa4
3 changed files with 29 additions and 82 deletions

View File

@ -74,8 +74,6 @@ struct proxy *alloc_new_proxy(const char *name, unsigned int cap,
struct proxy *parse_new_proxy(const char *name, unsigned int cap,
const char *file, int linenum,
const struct proxy *defproxy);
int get_backend_server(const char *bk_name, const char *sv_name,
struct proxy **bk, struct server **sv);
void proxy_capture_error(struct proxy *proxy, int is_back,
struct proxy *other_end, enum obj_type *target,
const struct session *sess,

View File

@ -450,42 +450,6 @@ const char *proxy_find_best_option(const char *word, const char **extra)
return best_ptr;
}
/*
* This function scans the list of backends and servers to retrieve the first
* backend and the first server with the given names, and sets them in both
* parameters. It returns zero if either is not found, or non-zero and sets
* the ones it did not found to NULL. If a NULL pointer is passed for the
* backend, only the pointer to the server will be updated.
*/
int get_backend_server(const char *bk_name, const char *sv_name,
struct proxy **bk, struct server **sv)
{
struct proxy *p;
struct server *s;
int sid;
*sv = NULL;
sid = -1;
if (*sv_name == '#')
sid = atoi(sv_name + 1);
p = proxy_be_by_name(bk_name);
if (bk)
*bk = p;
if (!p)
return 0;
for (s = p->srv; s; s = s->next)
if ((sid >= 0 && s->puid == sid) ||
(sid < 0 && strcmp(s->id, sv_name) == 0))
break;
*sv = s;
if (!s)
return 0;
return 1;
}
/* This function parses a "timeout" statement in a proxy section. It returns
* -1 if there is any error, 1 for a warning, otherwise zero. If it does not
* return zero, it will write an error or warning message into a preallocated

View File

@ -4204,22 +4204,20 @@ struct server *cli_find_server(struct appctx *appctx, char *arg)
{
struct proxy *px;
struct server *sv;
char *line;
struct ist be_name, sv_name = ist(arg);
/* split "backend/server" and make <line> point to server */
for (line = arg; *line; line++)
if (*line == '/') {
*line++ = '\0';
break;
}
if (!*line || !*arg) {
cli_err(appctx, "Require 'backend/server'.\n");
be_name = istsplit(&sv_name, '/');
if (!istlen(sv_name)) {
cli_err(appctx, "Require 'backend/server'.");
return NULL;
}
if (!get_backend_server(arg, line, &px, &sv)) {
cli_err(appctx, px ? "No such server.\n" : "No such backend.\n");
if (!(px = proxy_be_by_name(ist0(be_name)))) {
cli_err(appctx, "No such backend.");
return NULL;
}
if (!(sv = server_find_by_name(px, ist0(sv_name)))) {
cli_err(appctx, "No such server.");
return NULL;
}
@ -4459,23 +4457,18 @@ static int cli_parse_set_server(char **args, char *payload, struct appctx *appct
static int cli_parse_get_weight(char **args, char *payload, struct appctx *appctx, void *private)
{
struct proxy *px;
struct proxy *be;
struct server *sv;
char *line;
struct ist be_name, sv_name = ist(args[2]);
be_name = istsplit(&sv_name, '/');
if (!istlen(sv_name))
return cli_err(appctx, "Require 'backend/server'.");
/* split "backend/server" and make <line> point to server */
for (line = args[2]; *line; line++)
if (*line == '/') {
*line++ = '\0';
break;
}
if (!*line)
return cli_err(appctx, "Require 'backend/server'.\n");
if (!get_backend_server(args[2], line, &px, &sv))
return cli_err(appctx, px ? "No such server.\n" : "No such backend.\n");
if (!(be = proxy_be_by_name(ist0(be_name))))
return cli_err(appctx, "No such backend.");
if (!(sv = server_find_by_name(be, ist0(sv_name))))
return cli_err(appctx, "No such server.");
/* return server's effective weight at the moment */
snprintf(trash.area, trash.size, "%d (initial %d)\n", sv->uweight,
@ -5067,27 +5060,14 @@ static int cli_parse_delete_server(char **args, char *payload, struct appctx *ap
{
struct proxy *be;
struct server *srv;
char *be_name, *sv_name;
struct server *prev_del;
struct ist be_name, sv_name;
if (!cli_has_level(appctx, ACCESS_LVL_ADMIN))
return 1;
++args;
sv_name = be_name = args[1];
/* split backend/server arg */
while (*sv_name && *(++sv_name)) {
if (*sv_name == '/') {
*sv_name = '\0';
++sv_name;
break;
}
}
if (!*sv_name)
return cli_err(appctx, "Require 'backend/server'.");
/* The proxy servers list is currently not protected by a lock so this
* requires thread isolation. In addition, any place referencing the
* server about to be deleted would be unsafe after our operation, so
@ -5096,13 +5076,18 @@ static int cli_parse_delete_server(char **args, char *payload, struct appctx *ap
*/
thread_isolate_full();
get_backend_server(be_name, sv_name, &be, &srv);
if (!be) {
cli_err(appctx, "No such backend.");
sv_name = ist(args[1]);
be_name = istsplit(&sv_name, '/');
if (!istlen(sv_name)) {
cli_err(appctx, "Require 'backend/server'.");
goto out;
}
if (!srv) {
if (!(be = proxy_be_by_name(ist0(be_name)))) {
cli_err(appctx, "No such backend.");
goto out;
}
if (!(srv = server_find_by_name(be, ist0(sv_name)))) {
cli_err(appctx, "No such server.");
goto out;
}