From: Amaury Denoyelle Date: Wed, 8 Jul 2026 08:30:51 +0000 (+0200) Subject: MINOR: proxy: extend global tune.defaults.purge for default-server X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8a72637e06c28953e9eb02156c4ad5dad95128a4;p=thirdparty%2Fhaproxy.git MINOR: proxy: extend global tune.defaults.purge for default-server Previous patch changes behavior for default-server. They are now preserved after configuration during the whole process lifetime as dynamic servers may need them. A default-server is still purge though if it does not contain any particular setting. This relation between dynamic and default-server is similar to the one between dynamic backends and named default proxies sections, which are also kept by default at runtime. This patch extends tune.defaults.purge keyword which was previously used to force cleanup of named defaults section on post parsing. This now support an extra argument to instruct the type of elements to remove : supported values are "proxies" for named defaults sections and "servers" for default-server. Without any argument, the option only forces clean up of named defaults sections. This is the simplest method to preserve backward compatibility with previous releases. This new setting requires a dedicated code block for default-server purgeing in check_config_validity(). This cannot be performed during post-section parsing as this is a global setting which can be defined later. --- diff --git a/doc/configuration.txt b/doc/configuration.txt index c13837f7c..a52179c3a 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -4225,18 +4225,36 @@ tune.comp.maxlevel Each stream using compression initializes the compression algorithm with this value. The default value is 1. -tune.defaults.purge - For dynamic backends support, all named defaults sections are now kept in - memory after parsing. This is necessary as backend added at runtime must be - based on a named defaults for its configuration. - - This may consume significant memory if the number of defaults instances is - important. In this case and if dynamic backend feature is unnecessary, it's - possible to use this option to force deletion of defaults section after - parsing. It is still mandatory though to keep referenced defaults section - which contain settings whose cannot be copied by their referencing proxies. - For example, this is the case if the defaults section defines TCP/HTTP rules - or a tcpcheck ruleset. +tune.defaults.purge [] + Define what default instances to purge after configuration parsing. + + The elements to be purged are defined by a comma-delimited list of tokens. + The currently supported entries are : + - "proxies" to purge "defaults" sections + - "servers" to purge "default-server" instances + + If the list is empty, only proxies "defaults" sections will be purged. + + Default-server instances are kept in memory after parsing as they may be + reused for dynamic servers added at runtime. Similarly, named defaults + proxies sections are preserved as dynamic backends rely on them. + + This may consume a noticeable amount of memory if the number of default + instances is important. It's possible to reclaim this memory after the + configuration parsing if dynamic features are unneeded. + + In any case, referenced "defaults" sections which contain settings which + cannot be copied by their referencing proxies (e.g. TCP/HTTP rules or + tcpcheck ruleset) will be preserved, regardless of the global purge setting. + + Example: + # reclaim the maximum memory possible + tune.defaults.purge proxies,servers + + # purge proxies defaults sections + # both syntax are equivalent + tune.defaults.purge + tune.defaults.purge proxies tune.disable-fast-forward Disables the data fast-forwarding. It is a mechanism to optimize the data @@ -7380,9 +7398,11 @@ default-server [from ] [param*] A default-server with no parameter set will automatically be purged after parsing. As such, a final "default-server from none" statement will be - sufficient to release this unused memory. + sufficient to release this unused memory, regardless of the global setting + "tune.defaults.purge" value. - See also: "server" and section 5 about server options + See also: "server", section 5 about server options and global + "tune.defaults.purge" option default_backend diff --git a/include/haproxy/global-t.h b/include/haproxy/global-t.h index b02462ddf..b467f3353 100644 --- a/include/haproxy/global-t.h +++ b/include/haproxy/global-t.h @@ -80,7 +80,7 @@ #define GTUNE_DISABLE_ACTIVE_CLOSE (1<<22) #define GTUNE_QUICK_EXIT (1<<23) #define GTUNE_COLLECT_LIBS (1<<24) -/* (1<<25) unused */ +#define GTUNE_PURGE_DEF_SRV (1<<25) #define GTUNE_USE_FAST_FWD (1<<26) #define GTUNE_LISTENER_MQ_FAIR (1<<27) #define GTUNE_LISTENER_MQ_OPT (1<<28) diff --git a/src/cfgparse-global.c b/src/cfgparse-global.c index 34200cc41..e0b12f29e 100644 --- a/src/cfgparse-global.c +++ b/src/cfgparse-global.c @@ -1433,7 +1433,27 @@ static int cfg_parse_global_tune_opts(char **args, int section_type, return 0; } else if (strcmp(args[0], "tune.defaults.purge") == 0) { - global.tune.options |= GTUNE_PURGE_DEFAULTS; + if (args[1]) { + struct ist arg = ist(args[1]); + do { + struct ist token = istsplit(&arg, ','); + + if (isteq(token, ist("proxies"))) { + global.tune.options |= GTUNE_PURGE_DEFAULTS; + } + else if (isteq(token, ist("servers"))) { + global.tune.options |= GTUNE_PURGE_DEF_SRV; + } + else { + memprintf(err, "'%s' unknown directive '%s'.", args[0], ist0(token)); + return -1; + } + } while (istlen(arg)); + } + else { + /* default value if no argument : purge defaults proxies. */ + global.tune.options |= GTUNE_PURGE_DEFAULTS; + } } else if (strcmp(args[0], "tune.pattern.cache-size") == 0) { if (*(args[1]) == 0) { diff --git a/src/cfgparse.c b/src/cfgparse.c index 2e538ed66..78d298ec9 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -2429,6 +2429,14 @@ init_proxies_list_stage1: cfgerr++; } + /* Remove default-server if tune.defaults.purge is set for it. */ + if (curproxy->cap & PR_CAP_BE && (global.tune.options & GTUNE_PURGE_DEF_SRV)) { + if (curproxy->defsrv) { + srv_free_params(curproxy->defsrv); + srv_free(&curproxy->defsrv); + } + } + if (curproxy->flags & PR_FL_DISABLED) { /* ensure we don't keep listeners uselessly bound. We * can't disable their listeners yet (fdtab not