MINOR: proxy: prevent deletion of backend referenced by config elements

Define a new proxy flag PR_FL_NON_PURGEABLE. This is used to mark every
proxy instance explicitely referenced in the config. Such instances
cannot be deleted at runtime.

Static use_backend/default_backend rules are handled in
proxy_finalize(). Also, sample expression proxy references are protected
via smp_resolve_args().

Note that this last case also incidentally protects any proxies
referenced via a CLI "set var" expression. This should not be the case
as in this case variable value is instantly resolved so the proxy
reference is not needed anymore. This also affects dynamic servers.
This commit is contained in:
Amaury Denoyelle 2026-01-06 16:53:03 +01:00
parent 7bf3020952
commit 7f725f0754
4 changed files with 25 additions and 6 deletions

View file

@ -2130,10 +2130,12 @@ del backend <name>
This operation is only possible for TCP or HTTP proxies. To succeed, the
backend instance must have been first unpublished.
There is also additional restrictions which prevent backend removal.
Currently, this is the case when deprecated dispatch or option transparent
are used. Also, a backend cannot be removed if there is a stick-table
declared in it.
There is additional restrictions which prevent backend removal. First, a
backend cannot be removed if it is explicitely referenced by config elements,
for example via a use_backend rule or in sample expressions. Some proxies
options are also incompatible with runtime deletion. Currently, this is the
case when deprecated dispatch or option transparent are used. Also, a backend
cannot be removed if there is a stick-table declared in it.
This command is restricted and can only be issued on sockets configured for
level "admin". Moreover, this feature is still considered in development so it

View file

@ -248,6 +248,7 @@ enum PR_SRV_STATE_FILE {
#define PR_FL_CHECKED 0x00000040 /* The proxy configuration was fully checked (including postparsing checks) */
#define PR_FL_BE_UNPUBLISHED 0x00000080 /* The proxy cannot be targetted by content switching rules */
#define PR_FL_DELETED 0x00000100 /* Proxy has been deleted and must be manipulated with care */
#define PR_FL_NON_PURGEABLE 0x00000200 /* Proxy referenced by config elements which prevent its runtime removal. */
struct stream;

View file

@ -1982,6 +1982,8 @@ int proxy_finalize(struct proxy *px, int *err_code)
*/
px->options |= PR_O_HTTP_UPG;
}
target->flags |= PR_FL_NON_PURGEABLE;
}
}
@ -2058,6 +2060,8 @@ int proxy_finalize(struct proxy *px, int *err_code)
*/
px->options |= PR_O_HTTP_UPG;
}
target->flags |= PR_FL_NON_PURGEABLE;
}
*err_code |= warnif_tcp_http_cond(px, rule->cond);
}
@ -5014,6 +5018,11 @@ int be_check_for_deletion(const char *bename, struct proxy **pb, const char **pm
goto out;
}
if (be->cap & PR_CAP_FE) {
msg = "Cannot delete a listen section.";
goto out;
}
if (be->options & (PR_O_DISPATCH|PR_O_TRANSP)) {
msg = "Deletion of backend with deprecated dispatch/transparent options is not supported.";
goto out;
@ -5024,8 +5033,8 @@ int be_check_for_deletion(const char *bename, struct proxy **pb, const char **pm
goto out;
}
if (be->cap & PR_CAP_FE) {
msg = "Cannot delete a listen section.";
if (be->flags & PR_FL_NON_PURGEABLE) {
msg = "This proxy cannot be removed at runtime due to other configuration elements pointing to it.";
goto out;
}

View file

@ -1512,6 +1512,7 @@ int smp_resolve_args(struct proxy *p, char **err)
break;
}
/* TODO CLI set-var should not prevent server deletion as var value is instantly resolved. */
srv->flags |= SRV_F_NON_PURGEABLE;
chunk_destroy(&arg->data.str);
@ -1541,6 +1542,9 @@ int smp_resolve_args(struct proxy *p, char **err)
break;
}
/* TODO CLI set-var should not prevent proxy deletion as var value is instantly resolved. */
px->flags |= PR_FL_NON_PURGEABLE;
chunk_destroy(&arg->data.str);
arg->unresolved = 0;
arg->data.prx = px;
@ -1568,6 +1572,9 @@ int smp_resolve_args(struct proxy *p, char **err)
break;
}
/* TODO CLI set-var should not prevent proxy deletion as var value is instantly resolved. */
px->flags |= PR_FL_NON_PURGEABLE;
chunk_destroy(&arg->data.str);
arg->unresolved = 0;
arg->data.prx = px;