From fbe35afaa4e3d5e9c24e9408547c0322c308a066 Mon Sep 17 00:00:00 2001 From: Amaury Denoyelle Date: Mon, 7 Aug 2023 16:24:24 +0200 Subject: [PATCH] MINOR: proxy: simplify parsing 'backend/server' Several CLI handlers use a server argument specified with the format '/'. 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 '/' for reverse connect. --- include/haproxy/proxy.h | 2 -- src/proxy.c | 36 -------------------- src/server.c | 73 ++++++++++++++++------------------------- 3 files changed, 29 insertions(+), 82 deletions(-) diff --git a/include/haproxy/proxy.h b/include/haproxy/proxy.h index 39a46376f..177e71783 100644 --- a/include/haproxy/proxy.h +++ b/include/haproxy/proxy.h @@ -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, diff --git a/src/proxy.c b/src/proxy.c index a15acc13b..ad94802fa 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -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 diff --git a/src/server.c b/src/server.c index d2190de01..b1bbc3838 100644 --- a/src/server.c +++ b/src/server.c @@ -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 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 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; }