]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: config: Support per-proxy and per-server deinit functions callbacks
authorChristopher Faulet <cfaulet@haproxy.com>
Wed, 31 Jul 2019 06:44:12 +0000 (08:44 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Tue, 17 Sep 2019 08:18:54 +0000 (10:18 +0200)
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
src/haproxy.c

index 9ce1a168906811584999606d7c872fac217dbe72..12f888c622a32f062170b1f2f90faf68b7f037e0 100644 (file)
@@ -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))
index c490cead8b02387e7de5d52021ccd77e89e0f4e9..7b82139c93b979bd2e8ed4ff481a35360e8f8c6e 100644 (file)
@@ -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);