]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: proxy: add a list of orphaned defaults sections
authorWilly Tarreau <w@1wt.eu>
Fri, 20 Sep 2024 13:59:04 +0000 (15:59 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 20 Sep 2024 13:59:04 +0000 (15:59 +0200)
We'll soon delete unreferenced and duplicated named defaults sections
from the list of proxies. The problem with this is that this list (in
fact a name-based tree) is used to release all of them at the end. Let's
add a list of orphaned defaults sections, typically those containing
"http-check send" statements or various other rules, and that are
implicitly inherited by a proxy hence have a non-zero refcount while
also having a name. These now makes it possible to remove them from
the name index while still keeping their memory around for the lifetime
of the process, and cleaning it at the end.

include/haproxy/proxy.h
src/proxy.c

index 9a93e3afc834a289acf05ea642c7f6f0084c75eb..0f4636ea2f72910e234eac5201e24e1450bb890c 100644 (file)
@@ -68,6 +68,7 @@ void proxy_destroy_defaults(struct proxy *px);
 void proxy_destroy_all_unref_defaults(void);
 void proxy_ref_defaults(struct proxy *px, struct proxy *defpx);
 void proxy_unref_defaults(struct proxy *px);
+void proxy_unref_or_destroy_defaults(struct proxy *px);
 struct proxy *alloc_new_proxy(const char *name, unsigned int cap,
                               char **errmsg);
 struct proxy *parse_new_proxy(const char *name, unsigned int cap,
index a6e94f66cba9ee5437ef91642a53c0fb58f1c522..77cfe8654fe8c8673ec20b2a7ebd0ecdff072702 100644 (file)
@@ -61,6 +61,7 @@ struct proxy *proxies_list  = NULL;   /* list of all existing proxies */
 struct eb_root used_proxy_id = EB_ROOT;        /* list of proxy IDs in use */
 struct eb_root proxy_by_name = EB_ROOT; /* tree of proxies sorted by name */
 struct eb_root defproxy_by_name = EB_ROOT; /* tree of default proxies sorted by name (dups possible) */
+struct proxy *orphaned_default_proxies = NULL; /* deleted ones with refcount != 0 */
 unsigned int error_snapshot_id = 0;     /* global ID assigned to each error then incremented */
 
 /* CLI context used during "show servers {state|conn}" */
@@ -1528,15 +1529,43 @@ void proxy_destroy_defaults(struct proxy *px)
 void proxy_destroy_all_unref_defaults()
 {
        struct ebpt_node *n;
+       struct proxy *px, *nx;
 
        n = ebpt_first(&defproxy_by_name);
        while (n) {
-               struct proxy *px = container_of(n, struct proxy, conf.by_name);
+               px = container_of(n, struct proxy, conf.by_name);
                BUG_ON(!(px->cap & PR_CAP_DEF));
                n = ebpt_next(n);
                if (!px->conf.refcount)
                        proxy_destroy_defaults(px);
        }
+
+       px = orphaned_default_proxies;
+       while (px) {
+               BUG_ON(!(px->cap & PR_CAP_DEF));
+               nx = px->next;
+               if (!px->conf.refcount)
+                       proxy_destroy_defaults(px);
+               px = nx;
+       }
+}
+
+/* Try to destroy a defaults section, or just unreference it if still
+ * refcounted. In this case it's added to the orphaned_default_proxies list
+ * so that it can later be found.
+ */
+void proxy_unref_or_destroy_defaults(struct proxy *px)
+{
+       if (!px || !(px->cap & PR_CAP_DEF))
+               return;
+
+       ebpt_delete(&px->conf.by_name);
+       if (px->conf.refcount) {
+               /* still referenced just append it to the orphaned list */
+               px->next = orphaned_default_proxies;
+               orphaned_default_proxies = px;
+       } else
+               proxy_destroy_defaults(px);
 }
 
 /* Add a reference on the default proxy <defpx> for the proxy <px> Nothing is