]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: init: add REGISTER_POST_DEINIT_MASTER() hook
authorAurelien DARRAGON <adarragon@haproxy.com>
Thu, 26 Jun 2025 15:23:06 +0000 (17:23 +0200)
committerAurelien DARRAGON <adarragon@haproxy.com>
Thu, 7 Aug 2025 20:27:14 +0000 (22:27 +0200)
Similar to REGISTER_POST_DEINIT() hook (which is invoked during deinit)
but for master process only, when haproxy was started in master-worker
mode. The goal is to be able to register cleanup functions that will
only run for the master process right before exiting.

include/haproxy/init.h
src/init.c
src/mworker.c

index 3bf4f08878017d29fdd7e56947149b02c0c7d3e0..47333ffe4df6919647889e1b39fe8e627c530e7f 100644 (file)
@@ -14,6 +14,7 @@ extern struct list post_server_check_list;
 extern struct list per_thread_alloc_list;
 extern struct list per_thread_init_list;
 extern struct list post_deinit_list;
+extern struct list post_deinit_master_list;
 extern struct list proxy_deinit_list;
 extern struct list server_deinit_list;
 extern struct list per_thread_free_list;
@@ -24,6 +25,7 @@ void hap_register_post_check(int (*fct)());
 void hap_register_post_proxy_check(int (*fct)(struct proxy *));
 void hap_register_post_server_check(int (*fct)(struct server *));
 void hap_register_post_deinit(void (*fct)());
+void hap_register_post_deinit_master(void (*fct)());
 void hap_register_proxy_deinit(void (*fct)(struct proxy *));
 void hap_register_server_deinit(void (*fct)(struct server *));
 
@@ -63,6 +65,10 @@ void hap_register_unittest(const char *name, int (*fct)(int, char **));
 #define REGISTER_POST_DEINIT(fct) \
        INITCALL1(STG_REGISTER, hap_register_post_deinit, (fct))
 
+/* simplified way to declare a post-deinit (master process when launched in master/worker mode) callback in a file */
+#define REGISTER_POST_DEINIT_MASTER(fct) \
+       INITCALL1(STG_REGISTER, hap_register_post_deinit_master, (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))
index 6367ac56fa7bb5443b7e6d915fa0c65adb9c8cac..ac5ac7a2e9faf6f4c124b091e9f6acaa62fb2078 100644 (file)
@@ -57,6 +57,11 @@ struct list per_thread_init_list = LIST_HEAD_INIT(per_thread_init_list);
  */
 struct list post_deinit_list = LIST_HEAD_INIT(post_deinit_list);
 
+/* These functions after everything is stopped, right before exit(), for the master
+ * process when haproxy was started in master-worker mode. They don't return anything.
+ */
+struct list post_deinit_master_list = LIST_HEAD_INIT(post_deinit_master_list);
+
 /* 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
@@ -160,6 +165,22 @@ void hap_register_post_deinit(void (*fct)())
        LIST_APPEND(&post_deinit_list, &b->list);
 }
 
+/* used to register some de-initialization functions to call after everything
+ * has stopped, but only for the master process (when started in master-worker mode).
+ */
+void hap_register_post_deinit_master(void (*fct)())
+{
+       struct post_deinit_fct *b;
+
+       b = calloc(1, sizeof(*b));
+       if (!b) {
+               fprintf(stderr, "out of memory\n");
+               exit(1);
+       }
+       b->fct = fct;
+       LIST_APPEND(&post_deinit_master_list, &b->list);
+}
+
 /* used to register some per proxy de-initialization functions to call after
  * everything has stopped.
  */
index 88bcc1f052b6ed0610533bb4c506fb53c32244de..a2a4e7f07b72f278f18a69b432292d2015ed84ed 100644 (file)
@@ -29,6 +29,7 @@
 #include <haproxy/list.h>
 #include <haproxy/log.h>
 #include <haproxy/listener.h>
+#include <haproxy/list.h>
 #include <haproxy/mworker.h>
 #include <haproxy/peers.h>
 #include <haproxy/proto_sockpair.h>
@@ -625,7 +626,13 @@ restart_wait:
        }
        /* Better rely on the system than on a list of process to check if it was the last one */
        else if (exitpid == -1 && errno == ECHILD) {
+               struct post_deinit_fct *pdff;
+
                ha_warning("All workers exited. Exiting... (%d)\n", (exitcode > 0) ? exitcode : EXIT_SUCCESS);
+
+               list_for_each_entry(pdff, &post_deinit_master_list, list)
+                       pdff->fct();
+
                atexit_flag = 0;
                if (exitcode > 0)
                        exit(exitcode); /* parent must leave using the status code that provoked the exit */