]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: guid: introduce global UID module
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Mon, 25 Mar 2024 10:27:23 +0000 (11:27 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Fri, 5 Apr 2024 13:40:42 +0000 (15:40 +0200)
Define a new module guid. Its purpose is to be able to attach a global
identifier for various objects such as proxies, servers and listeners.

A new type guid_node is defined. It will be stored in the objects which
can be referenced by such GUID. Several functions are implemented to
properly initialized, insert, remove and lookup GUID in a global tree.
Modification operations should only be conducted under thread isolation.

Makefile
include/haproxy/guid-t.h [new file with mode: 0644]
include/haproxy/guid.h [new file with mode: 0644]
src/guid.c [new file with mode: 0644]

index 0987595dfa8d1a7b35193c889a11c1bd0fbd4a5e..af40c7b79c2b55f7970560e025bc6073fce71f31 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -947,7 +947,8 @@ OBJS += src/mux_h2.o src/mux_fcgi.o src/mux_h1.o src/tcpcheck.o               \
         src/base64.o src/auth.o src/uri_auth.o src/time.o src/ebistree.o      \
         src/dynbuf.o src/wdt.o src/pipe.o src/init.o src/http_acl.o           \
         src/hpack-huff.o src/hpack-enc.o src/dict.o src/freq_ctr.o            \
-        src/ebtree.o src/hash.o src/dgram.o src/version.o src/proto_rhttp.o
+        src/ebtree.o src/hash.o src/dgram.o src/version.o src/proto_rhttp.o   \
+        src/guid.o
 
 ifneq ($(TRACE),)
   OBJS += src/calltrace.o
diff --git a/include/haproxy/guid-t.h b/include/haproxy/guid-t.h
new file mode 100644 (file)
index 0000000..41645d7
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef _HAPROXY_GUID_T_H
+#define _HAPROXY_GUID_T_H
+
+#include <import/ebtree-t.h>
+#include <haproxy/obj_type-t.h>
+
+struct guid_node {
+       struct ebpt_node node;   /* attach point into GUID global tree */
+       enum obj_type *obj_type; /* pointer to GUID obj owner */
+};
+
+#endif /* _HAPROXY_GUID_T_H */
diff --git a/include/haproxy/guid.h b/include/haproxy/guid.h
new file mode 100644 (file)
index 0000000..8c88a88
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef _HAPROXY_GUID_H
+#define _HAPROXY_GUID_H
+
+#include <haproxy/guid-t.h>
+
+extern struct eb_root guid_tree;
+
+void guid_init(struct guid_node *node);
+int guid_insert(enum obj_type *obj_type, const char *uid, char **errmsg);
+void guid_remove(struct guid_node *guid);
+struct guid_node *guid_lookup(const char *uid);
+
+char *guid_name(const struct guid_node *guid);
+
+#endif /* _HAPROXY_GUID_H */
diff --git a/src/guid.c b/src/guid.c
new file mode 100644 (file)
index 0000000..178353b
--- /dev/null
@@ -0,0 +1,99 @@
+#include <haproxy/guid.h>
+
+#include <import/ebistree.h>
+#include <haproxy/obj_type.h>
+#include <haproxy/tools.h>
+
+/* GUID global tree */
+struct eb_root guid_tree = EB_ROOT_UNIQUE;
+
+/* Initialize <guid> members. */
+void guid_init(struct guid_node *guid)
+{
+       guid->node.key = NULL;
+       guid->node.node.leaf_p = NULL;
+}
+
+/* Insert <objt> into GUID global tree with key <uid>. Must only be called on
+ * thread isolation. On failure, <errmsg> will be allocated with an error
+ * description. Caller is responsible to free it.
+ *
+ * Returns 0 on success else non-zero.
+ */
+int guid_insert(enum obj_type *objt, const char *uid, char **errmsg)
+{
+       struct guid_node *guid = NULL;
+       struct guid_node *dup;
+       struct ebpt_node *node;
+       char *dup_name = NULL;
+
+       switch (obj_type(objt)) {
+       default:
+               /* No guid support for this objtype. */
+               ABORT_NOW();
+               return 0;
+       }
+
+       guid->node.key = strdup(uid);
+       if (!guid->node.key) {
+               memprintf(errmsg, "key alloc failure");
+               goto err;
+       }
+
+       node = ebis_insert(&guid_tree, &guid->node);
+       if (node != &guid->node) {
+               dup = ebpt_entry(node, struct guid_node, node);
+               dup_name = guid_name(dup);
+               memprintf(errmsg, "duplicate entry with %s", dup_name);
+               goto err;
+       }
+
+       guid->obj_type = objt;
+       return 0;
+
+ err:
+       ha_free(&guid->node.key);
+       ha_free(&dup_name);
+       return 1;
+}
+
+/* Remove <guid> node from GUID global tree. Must only be called on thread
+ * isolation. Safe to call even if node is not currently stored.
+ */
+void guid_remove(struct guid_node *guid)
+{
+       ebpt_delete(&guid->node);
+       ha_free(&guid->node.key);
+}
+
+/* Retrieve an instance from GUID global tree with key <uid>.
+ *
+ * Returns the GUID instance or NULL if key not found.
+ */
+struct guid_node *guid_lookup(const char *uid)
+{
+       struct ebpt_node *node = NULL;
+       struct guid_node *guid = NULL;
+
+       node = ebis_lookup(&guid_tree, uid);
+       if (node)
+               guid = ebpt_entry(node, struct guid_node, node);
+
+       return guid;
+}
+
+/* Generate a user-friendly description for the instance attached via <guid>
+ * node. The string is dynamically allocated and the caller is responsible to
+ * free it.
+ *
+ * Returns a pointer to the dynamically allocated message.
+ */
+char *guid_name(const struct guid_node *guid)
+{
+       switch (obj_type(guid->obj_type)) {
+       default:
+               break;
+       }
+
+       return NULL;
+}