From 82594569815c994f3035addda04c9b8642df55c5 Mon Sep 17 00:00:00 2001 From: Amaury Denoyelle Date: Tue, 26 Mar 2024 15:01:35 +0100 Subject: [PATCH] MINOR: server: implement GUID support This commit is similar to previous one, except that it implements GUID support for server instances. A guid_node field is inserted into server structure. A new "guid" server keyword is defined. --- doc/configuration.txt | 5 +++++ include/haproxy/server-t.h | 3 +++ src/guid.c | 10 ++++++++++ src/server.c | 28 ++++++++++++++++++++++++++++ 4 files changed, 46 insertions(+) diff --git a/doc/configuration.txt b/doc/configuration.txt index 240785cde..c42f9ea59 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -16922,6 +16922,11 @@ force-tlsv13 the server. This option is also available on global statement "ssl-default-server-options". See also "ssl-min-ver" and ssl-max-ver". +guid + Specify a case-sensitive global unique ID for this server. This must be + unique accross all haproxy configuration on every object types. See "guid" + proxy keyword description for more information on its format. + id May be used in the following contexts: tcp, http, log diff --git a/include/haproxy/server-t.h b/include/haproxy/server-t.h index 70489ff78..3bc2371e1 100644 --- a/include/haproxy/server-t.h +++ b/include/haproxy/server-t.h @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -466,6 +467,8 @@ struct server { event_hdl_sub_list e_subs; /* event_hdl: server's subscribers list (atomically updated) */ + struct guid_node guid; /* GUID global tree node */ + /* warning, these structs are huge, keep them at the bottom */ struct conn_src conn_src; /* connection source settings */ struct sockaddr_storage addr; /* the address to connect to, doesn't include the port */ diff --git a/src/guid.c b/src/guid.c index d0f5fbc07..af04f1a81 100644 --- a/src/guid.c +++ b/src/guid.c @@ -3,6 +3,7 @@ #include #include #include +#include #include /* GUID global tree */ @@ -45,6 +46,10 @@ int guid_insert(enum obj_type *objt, const char *uid, char **errmsg) guid = &__objt_proxy(objt)->guid; break; + case OBJ_TYPE_SERVER: + guid = &__objt_server(objt)->guid; + break; + default: /* No guid support for this objtype. */ ABORT_NOW(); @@ -110,12 +115,17 @@ char *guid_name(const struct guid_node *guid) { char *msg = NULL; struct proxy *px; + struct server *srv; switch (obj_type(guid->obj_type)) { case OBJ_TYPE_PROXY: px = __objt_proxy(guid->obj_type); return memprintf(&msg, "%s %s", proxy_cap_str(px->cap), px->id); + case OBJ_TYPE_SERVER: + srv = __objt_server(guid->obj_type); + return memprintf(&msg, "server %s/%s", srv->proxy->id, srv->id); + default: break; } diff --git a/src/server.c b/src/server.c index e537473e9..281afbf08 100644 --- a/src/server.c +++ b/src/server.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -926,6 +927,28 @@ static int srv_parse_error_limit(char **args, int *cur_arg, return 0; } +/* Parse the "guid" keyword */ +static int srv_parse_guid(char **args, int *cur_arg, + struct proxy *curproxy, struct server *newsrv, char **err) +{ + const char *guid; + char *guid_err = NULL; + + if (!*args[*cur_arg + 1]) { + memprintf(err, "'%s' : expects an argument", args[*cur_arg]); + return ERR_ALERT | ERR_FATAL; + } + + guid = args[*cur_arg + 1]; + if (guid_insert(&newsrv->obj_type, guid, &guid_err)) { + memprintf(err, "'%s': %s", args[*cur_arg], guid_err); + ha_free(&guid_err); + return ERR_ALERT | ERR_FATAL; + } + + return 0; +} + /* Parse the "ws" keyword */ static int srv_parse_ws(char **args, int *cur_arg, struct proxy *curproxy, struct server *newsrv, char **err) @@ -2251,6 +2274,7 @@ static struct srv_kw_list srv_kws = { "ALL", { }, { { "disabled", srv_parse_disabled, 0, 1, 1 }, /* Start the server in 'disabled' state */ { "enabled", srv_parse_enabled, 0, 1, 0 }, /* Start the server in 'enabled' state */ { "error-limit", srv_parse_error_limit, 1, 1, 1 }, /* Configure the consecutive count of check failures to consider a server on error */ + { "guid", srv_parse_guid, 1, 0, 1 }, /* Set global unique ID of the server */ { "ws", srv_parse_ws, 1, 1, 1 }, /* websocket protocol */ { "hash-key", srv_parse_hash_key, 1, 1, 1 }, /* Configure how chash keys are computed */ { "id", srv_parse_id, 1, 0, 1 }, /* set id# of server */ @@ -2856,6 +2880,8 @@ struct server *new_server(struct proxy *proxy) MT_LIST_INIT(&srv->sess_conns); + guid_init(&srv->guid); + srv->extra_counters = NULL; #ifdef USE_OPENSSL HA_RWLOCK_INIT(&srv->ssl_ctx.lock); @@ -2918,6 +2944,8 @@ struct server *srv_drop(struct server *srv) if (HA_ATOMIC_SUB_FETCH(&srv->refcount, 1)) goto end; + guid_remove(&srv->guid); + /* make sure we are removed from our 'next->prev_deleted' list * This doesn't require full thread isolation as we're using mt lists * However this could easily be turned into regular list if required