From 3ea5cbe6a414e798b091715ae15f433c5f7f4856 Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Wed, 31 Jul 2019 08:44:12 +0200 Subject: [PATCH] MINOR: config: Support per-proxy and per-server deinit functions callbacks Most of times, when any allocation is done during configuration parsing because of a new keyword in proxy section or on the server line, we must add a call in the deinit() function to release allocated ressources. It is now possible to register a post-deinit callback because, at this stage, the proxies and the servers are already releases. Now, it is possible to register deinit callbacks per-proxy or per-server. These callbacks will be called for each proxy and server before releasing them. --- include/types/global.h | 10 +++++++ src/haproxy.c | 64 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/include/types/global.h b/include/types/global.h index 9ce1a1689..12f888c62 100644 --- a/include/types/global.h +++ b/include/types/global.h @@ -289,6 +289,8 @@ void deinit(void); void hap_register_build_opts(const char *str, int must_free); void hap_register_post_check(int (*fct)()); void hap_register_post_deinit(void (*fct)()); +void hap_register_proxy_deinit(void (*fct)(struct proxy *)); +void hap_register_server_deinit(void (*fct)(struct server *)); void hap_register_per_thread_alloc(int (*fct)()); void hap_register_per_thread_init(int (*fct)()); @@ -310,6 +312,14 @@ void mworker_reload(); #define REGISTER_POST_DEINIT(fct) \ INITCALL1(STG_REGISTER, hap_register_post_deinit, (fct)) +/* simplified way to declare a proxy-deinit callback in a file */ +#define REGISTER_PROXY_DEINIT(fct) \ + INITCALL1(STG_REGISTER, hap_register_proxy_deinit, (fct)) + +/* simplified way to declare a proxy-deinit callback in a file */ +#define REGISTER_SERVER_DEINIT(fct) \ + INITCALL1(STG_REGISTER, hap_register_server_deinit, (fct)) + /* simplified way to declare a per-thread allocation callback in a file */ #define REGISTER_PER_THREAD_ALLOC(fct) \ INITCALL1(STG_REGISTER, hap_register_per_thread_alloc, (fct)) diff --git a/src/haproxy.c b/src/haproxy.c index c490cead8..7b82139c9 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -299,6 +299,28 @@ struct post_deinit_fct { void (*fct)(); }; +/* These functions are called when freeing a proxy during the deinit, after + * everything isg stopped. They don't return anything. They should not release + * the proxy itself or any shared resources that are possibly used by other + * deinit functions, only close/release what is private. + */ +struct list proxy_deinit_list = LIST_HEAD_INIT(proxy_deinit_list); +struct proxy_deinit_fct { + struct list list; + void (*fct)(struct proxy *); +}; + +/* These functions are called when freeing a server during the deinit, after + * everything isg stopped. They don't return anything. They should not release + * the proxy itself or any shared resources that are possibly used by other + * deinit functions, only close/release what is private. + */ +struct list server_deinit_list = LIST_HEAD_INIT(server_deinit_list); +struct server_deinit_fct { + struct list list; + void (*fct)(struct server *); +}; + /* These functions are called when freeing the global sections at the end of * deinit, after the thread deinit functions, to release unneeded memory * allocations. They don't return anything, and they work in best effort mode @@ -371,6 +393,39 @@ void hap_register_post_deinit(void (*fct)()) LIST_ADDQ(&post_deinit_list, &b->list); } +/* used to register some per proxy de-initialization functions to call after + * everything has stopped. + */ +void hap_register_proxy_deinit(void (*fct)(struct proxy *)) +{ + struct proxy_deinit_fct *b; + + b = calloc(1, sizeof(*b)); + if (!b) { + fprintf(stderr, "out of memory\n"); + exit(1); + } + b->fct = fct; + LIST_ADDQ(&proxy_deinit_list, &b->list); +} + + +/* used to register some per server de-initialization functions to call after + * everything has stopped. + */ +void hap_register_server_deinit(void (*fct)(struct server *)) +{ + struct server_deinit_fct *b; + + b = calloc(1, sizeof(*b)); + if (!b) { + fprintf(stderr, "out of memory\n"); + exit(1); + } + b->fct = fct; + LIST_ADDQ(&server_deinit_list, &b->list); +} + /* used to register some allocation functions to call for each thread. */ void hap_register_per_thread_alloc(int (*fct)()) { @@ -2187,6 +2242,8 @@ void deinit(void) struct bind_conf *bind_conf, *bind_back; struct build_opts_str *bol, *bolb; struct post_deinit_fct *pdf; + struct proxy_deinit_fct *pxdf; + struct server_deinit_fct *srvdf; int i; deinit_signals(); @@ -2355,6 +2412,10 @@ void deinit(void) xprt_get(XPRT_SSL)->destroy_srv(s); } HA_SPIN_DESTROY(&s->lock); + + list_for_each_entry(srvdf, &server_deinit_list, list) + srvdf->fct(s); + free(s); s = s_next; }/* end while(s) */ @@ -2390,6 +2451,9 @@ void deinit(void) flt_deinit(p); + list_for_each_entry(pxdf, &proxy_deinit_list, list) + pxdf->fct(p); + free(p->desc); free(p->fwdfor_hdr_name);