mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2024-12-22 12:30:07 +00:00
MINOR: proxy: Be able to reference the defaults section used by a proxy
A proxy may now references the defaults section it is used. To do so, a pointer on the default proxy was added in the proxy structure. And a refcount must be used to track proxies using a default proxy. A default proxy is destroyed iff its refcount is equal to zero and when it drops to zero. All this stuff must be performed during init/deinit staged for now. All unreferenced default proxies are removed after the configuration parsing. This patch is mandatory to support TCP/HTTP rules in defaults sections.
This commit is contained in:
parent
b40542000d
commit
27c8d20451
@ -275,6 +275,7 @@ struct proxy {
|
||||
struct proxy *be; /* default backend, or NULL if none set */
|
||||
char *name; /* default backend name during config parse */
|
||||
} defbe;
|
||||
struct proxy *defpx; /* default proxy used to init this one (may be NULL) */
|
||||
struct list acl; /* ACL declared on this proxy */
|
||||
struct list http_req_rules; /* HTTP request rules: allow/deny/... */
|
||||
struct list http_res_rules; /* HTTP response rules: allow/deny/... */
|
||||
@ -421,6 +422,7 @@ struct proxy {
|
||||
struct list listeners; /* list of listeners belonging to this frontend */
|
||||
struct list errors; /* list of all custom error files */
|
||||
struct arg_list args; /* sample arg list that need to be resolved */
|
||||
unsigned int refcount; /* refcount on this proxy (only used for default proxy for now) */
|
||||
struct ebpt_node by_name; /* proxies are stored sorted by name here */
|
||||
char *logformat_string; /* log format string */
|
||||
char *lfs_file; /* file name where the logformat string appears (strdup) */
|
||||
|
@ -61,7 +61,9 @@ void init_new_proxy(struct proxy *p);
|
||||
void proxy_preset_defaults(struct proxy *defproxy);
|
||||
void proxy_free_defaults(struct proxy *defproxy);
|
||||
void proxy_destroy_defaults(struct proxy *px);
|
||||
void proxy_destroy_all_defaults(void);
|
||||
void proxy_destroy_all_unref_defaults(void);
|
||||
void proxy_ref_defaults(struct proxy *px, struct proxy *defpx);
|
||||
void proxy_unref_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,
|
||||
|
@ -1990,8 +1990,9 @@ static void init(int argc, char **argv)
|
||||
ha_warning("a master CLI socket was defined, but master-worker mode (-W) is not enabled.\n");
|
||||
}
|
||||
|
||||
/* defaults sections are not needed anymore */
|
||||
proxy_destroy_all_defaults();
|
||||
/* destroy unreferenced defaults proxies */
|
||||
proxy_destroy_all_unref_defaults();
|
||||
|
||||
|
||||
err_code |= check_config_validity();
|
||||
for (px = proxies_list; px; px = px->next) {
|
||||
@ -2483,6 +2484,9 @@ void deinit(void)
|
||||
free_proxy(p0);
|
||||
}/* end while(p) */
|
||||
|
||||
/* destroy all referenced defaults proxies */
|
||||
proxy_destroy_all_unref_defaults();
|
||||
|
||||
while (ua) {
|
||||
struct stat_scope *scope, *scopep;
|
||||
|
||||
|
42
src/proxy.c
42
src/proxy.c
@ -146,6 +146,7 @@ void free_proxy(struct proxy *p)
|
||||
if (!p)
|
||||
return;
|
||||
|
||||
proxy_unref_defaults(p);
|
||||
free(p->conf.file);
|
||||
free(p->id);
|
||||
free(p->cookie_name);
|
||||
@ -1471,22 +1472,57 @@ void proxy_destroy_defaults(struct proxy *px)
|
||||
return;
|
||||
if (!(px->cap & PR_CAP_DEF))
|
||||
return;
|
||||
BUG_ON(px->conf.refcount != 0);
|
||||
ebpt_delete(&px->conf.by_name);
|
||||
proxy_free_defaults(px);
|
||||
free(px);
|
||||
}
|
||||
|
||||
void proxy_destroy_all_defaults()
|
||||
/* delete all unreferenced default proxies. A default proxy is unreferenced if
|
||||
* its refcount is equal to zero.
|
||||
*/
|
||||
void proxy_destroy_all_unref_defaults()
|
||||
{
|
||||
struct ebpt_node *n;
|
||||
|
||||
while ((n = ebpt_first(&defproxy_by_name))) {
|
||||
n = ebpt_first(&defproxy_by_name);
|
||||
while (n) {
|
||||
struct proxy *px = container_of(n, struct proxy, conf.by_name);
|
||||
BUG_ON(!(px->cap & PR_CAP_DEF));
|
||||
proxy_destroy_defaults(px);
|
||||
n = ebpt_next(n);
|
||||
if (!px->conf.refcount)
|
||||
proxy_destroy_defaults(px);
|
||||
}
|
||||
}
|
||||
|
||||
/* Add a reference on the default proxy <defpx> for the proxy <px> Nothing is
|
||||
* done if <px> already references <defpx>. Otherwise, the default proxy
|
||||
* refcount is incremented by one. For now, this operation is not thread safe
|
||||
* and is perform during init stage only.
|
||||
*/
|
||||
void proxy_ref_defaults(struct proxy *px, struct proxy *defpx)
|
||||
{
|
||||
if (px->defpx == defpx)
|
||||
return;
|
||||
BUG_ON(px->defpx != NULL);
|
||||
px->defpx = defpx;
|
||||
defpx->conf.refcount++;
|
||||
}
|
||||
|
||||
/* proxy <px> removes its reference on its default proxy. The default proxy
|
||||
* refcount is decremented by one. If it was the last reference, the
|
||||
* corresponding default proxy is destroyed. For now this operation is not
|
||||
* thread safe and is performed during deinit staged only.
|
||||
*/
|
||||
void proxy_unref_defaults(struct proxy *px)
|
||||
{
|
||||
if (px->defpx == NULL)
|
||||
return;
|
||||
if (!--px->defpx->conf.refcount)
|
||||
proxy_destroy_defaults(px->defpx);
|
||||
px->defpx = NULL;
|
||||
}
|
||||
|
||||
/* Allocates a new proxy <name> of type <cap>.
|
||||
* Returns the proxy instance on success. On error, NULL is returned.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user