MINOR: proxy: add a list of orphaned defaults sections

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.
This commit is contained in:
Willy Tarreau 2024-09-20 15:59:04 +02:00
parent cb4c236fac
commit c8b813771d
2 changed files with 31 additions and 1 deletions

View 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,

View 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