]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: config: Support per-proxy and per-server post-check functions callbacks
authorChristopher Faulet <cfaulet@haproxy.com>
Mon, 12 Aug 2019 07:51:07 +0000 (09:51 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Tue, 17 Sep 2019 08:18:54 +0000 (10:18 +0200)
Most of times, when a keyword is added in proxy section or on the server line,
we need to have a post-parser callback to check the config validity for the
proxy or the server which uses this keyword.

It is possible to register a global post-parser callback. But all these
callbacks need to loop on the proxies and servers to do their job. It is neither
handy nor efficient. Instead, it is now possible to register per-proxy and
per-server post-check callbacks.

include/types/global.h
src/haproxy.c

index 12f888c622a32f062170b1f2f90faf68b7f037e0..bd08db142bc8d6151f68011b4e314579883005b0 100644 (file)
@@ -288,6 +288,8 @@ int delete_oldpid(int pid);
 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_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_proxy_deinit(void (*fct)(struct proxy *));
 void hap_register_server_deinit(void (*fct)(struct server *));
@@ -308,6 +310,14 @@ void mworker_reload();
 #define REGISTER_POST_CHECK(fct) \
        INITCALL1(STG_REGISTER, hap_register_post_check, (fct))
 
+/* simplified way to declare a post-proxy-check callback in a file */
+#define REGISTER_POST_PROXY_CHECK(fct) \
+       INITCALL1(STG_REGISTER, hap_register_post_proxy_check, (fct))
+
+/* simplified way to declare a post-server-check callback in a file */
+#define REGISTER_POST_SERVER_CHECK(fct) \
+       INITCALL1(STG_REGISTER, hap_register_post_server_check, (fct))
+
 /* simplified way to declare a post-deinit callback in a file */
 #define REGISTER_POST_DEINIT(fct) \
        INITCALL1(STG_REGISTER, hap_register_post_deinit, (fct))
index 7b82139c93b979bd2e8ed4ff481a35360e8f8c6e..cc3da92af6aaf45fc6526118ae27b1bff040c064 100644 (file)
@@ -268,6 +268,28 @@ struct post_check_fct {
        int (*fct)();
 };
 
+/* These functions are called for each proxy just after the config validity
+ * check. The functions must return 0 on success, or a combination of ERR_*
+ * flags (ERR_WARN, ERR_ABORT, ERR_FATAL, ...). The 2 latter cause and immediate
+ * exit, so the function must have emitted any useful error.
+ */
+struct list post_proxy_check_list = LIST_HEAD_INIT(post_proxy_check_list);
+struct post_proxy_check_fct {
+       struct list list;
+       int (*fct)(struct proxy *);
+};
+
+/* These functions are called for each server just after the config validity
+ * check. The functions must return 0 on success, or a combination of ERR_*
+ * flags (ERR_WARN, ERR_ABORT, ERR_FATAL, ...). The 2 latter cause and immediate
+ * exit, so the function must have emitted any useful error.
+ */
+struct list post_server_check_list = LIST_HEAD_INIT(post_server_check_list);
+struct post_server_check_fct {
+       struct list list;
+       int (*fct)(struct server *);
+};
+
 /* These functions are called for each thread just after the thread creation
  * and before running the init functions. They should be used to do per-thread
  * (re-)allocations that are needed by subsequent functoins. They must return 0
@@ -377,6 +399,38 @@ void hap_register_post_check(int (*fct)())
        LIST_ADDQ(&post_check_list, &b->list);
 }
 
+/* used to register some initialization functions to call for each proxy after
+ * the checks.
+ */
+void hap_register_post_proxy_check(int (*fct)(struct proxy *))
+{
+       struct post_proxy_check_fct *b;
+
+       b = calloc(1, sizeof(*b));
+       if (!b) {
+               fprintf(stderr, "out of memory\n");
+               exit(1);
+       }
+       b->fct = fct;
+       LIST_ADDQ(&post_proxy_check_list, &b->list);
+}
+
+/* used to register some initialization functions to call for each server after
+ * the checks.
+ */
+void hap_register_post_server_check(int (*fct)(struct server *))
+{
+       struct post_server_check_fct *b;
+
+       b = calloc(1, sizeof(*b));
+       if (!b) {
+               fprintf(stderr, "out of memory\n");
+               exit(1);
+       }
+       b->fct = fct;
+       LIST_ADDQ(&post_server_check_list, &b->list);
+}
+
 /* used to register some de-initialization functions to call after everything
  * has stopped.
  */
@@ -1799,6 +1853,18 @@ static void init(int argc, char **argv)
        }
 
        err_code |= check_config_validity();
+       for (px = proxies_list; px; px = px->next) {
+               struct server *srv;
+               struct post_proxy_check_fct *ppcf;
+               struct post_server_check_fct *pscf;
+
+               list_for_each_entry(pscf, &post_server_check_list, list) {
+                       for (srv = px->srv; srv; srv = srv->next)
+                               err_code |= pscf->fct(srv);
+               }
+               list_for_each_entry(ppcf, &post_proxy_check_list, list)
+                       err_code |= ppcf->fct(px);
+       }
        if (err_code & (ERR_ABORT|ERR_FATAL)) {
                ha_alert("Fatal errors found in configuration.\n");
                exit(1);