diff --git a/doc/internals/api/initcalls.txt b/doc/internals/api/initcalls.txt index 4829f500a..30d873720 100644 --- a/doc/internals/api/initcalls.txt +++ b/doc/internals/api/initcalls.txt @@ -114,6 +114,19 @@ make sure to respect this ordering when adding new ones. exit. See also hap_register_per_thread_alloc() for functions called before these ones. +- void hap_register_pre_check(int (*fct)()) + + This adds a call to function to the list of functions to be called at + the step just before the configuration validity checks. This is useful when you + need to create things like it would have been done during the configuration + parsing and where the initialization should continue in the configuration + check. + It could be used for example to generate a proxy with multiple servers using + the configuration parser itself. At this step the trash buffers are allocated. + Threads are not yet started so no protection is required. The function is + expected to return non-zero on success, or zero on failure. A failure will make + the process emit a succinct error message and immediately exit. + - void hap_register_post_check(int (*fct)()) This adds a call to function to the list of functions to be called at @@ -317,6 +330,10 @@ alphanumerically ordered: create_pool_callback() with these arguments at stage STG_POOL. Do not use it directly, use either DECLARE_POOL() or DECLARE_STATIC_POOL() instead. +- REGISTER_PRE_CHECK(fct) + + Registers a call to register_pre_check(fct) at stage STG_REGISTER. + - REGISTER_POST_CHECK(fct) Registers a call to register_post_check(fct) at stage STG_REGISTER. diff --git a/include/haproxy/init-t.h b/include/haproxy/init-t.h index dee86f867..110171b05 100644 --- a/include/haproxy/init-t.h +++ b/include/haproxy/init-t.h @@ -6,6 +6,11 @@ struct proxy; struct server; +struct pre_check_fct { + struct list list; + int (*fct)(); +}; + struct post_check_fct { struct list list; int (*fct)(); diff --git a/include/haproxy/init.h b/include/haproxy/init.h index 4e8f09e26..6e3047567 100644 --- a/include/haproxy/init.h +++ b/include/haproxy/init.h @@ -7,6 +7,7 @@ struct proxy; struct server; +extern struct list pre_check_list; extern struct list post_check_list; extern struct list post_proxy_check_list; extern struct list post_server_check_list; @@ -18,6 +19,7 @@ extern struct list server_deinit_list; extern struct list per_thread_free_list; extern struct list per_thread_deinit_list; +void hap_register_pre_check(int (*fct)()); 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 *)); @@ -30,6 +32,10 @@ void hap_register_per_thread_init(int (*fct)()); void hap_register_per_thread_deinit(void (*fct)()); void hap_register_per_thread_free(void (*fct)()); +/* simplified way to declare a pre-check callback in a file */ +#define REGISTER_PRE_CHECK(fct) \ + INITCALL1(STG_REGISTER, hap_register_pre_check, (fct)) + /* simplified way to declare a post-check callback in a file */ #define REGISTER_POST_CHECK(fct) \ INITCALL1(STG_REGISTER, hap_register_post_check, (fct)) diff --git a/src/haproxy.c b/src/haproxy.c index 0187bc641..f61a3abf9 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -1891,6 +1891,7 @@ static void init(int argc, char **argv) struct wordlist *wl; struct proxy *px; struct post_check_fct *pcf; + struct pre_check_fct *prcf; int ideal_maxconn; if (!init_trash_buffers(1)) { @@ -2107,6 +2108,8 @@ static void init(int argc, char **argv) /* destroy unreferenced defaults proxies */ proxy_destroy_all_unref_defaults(); + list_for_each_entry(prcf, &pre_check_list, list) + err_code |= prcf->fct(); err_code |= check_config_validity(); for (px = proxies_list; px; px = px->next) { diff --git a/src/init.c b/src/init.c index ad8066265..6367ac56f 100644 --- a/src/init.c +++ b/src/init.c @@ -4,6 +4,17 @@ #include #include +/* These functions are called just before a config validity check, which mean + * they are suited to use them in case we need to generate part of the + * configuration. It could be used for example to generate a proxy with + * multiple servers using the configuration parser itself. At this step the + * trash buffers are allocated. + * 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 pre_check_list = LIST_HEAD_INIT(pre_check_list); + /* These functions are called just after the point where the program exits * after a config validity check, so they are generally suited for resource * allocation and slow initializations that should be skipped during basic @@ -73,6 +84,20 @@ struct list per_thread_free_list = LIST_HEAD_INIT(per_thread_free_list); * valgrind mostly happy. */ struct list per_thread_deinit_list = LIST_HEAD_INIT(per_thread_deinit_list); +/* used to register some initialization functions to call before the checks. */ +void hap_register_pre_check(int (*fct)()) +{ + struct pre_check_fct *b; + + b = calloc(1, sizeof(*b)); + if (!b) { + fprintf(stderr, "out of memory\n"); + exit(1); + } + b->fct = fct; + LIST_APPEND(&pre_check_list, &b->list); +} + /* used to register some initialization functions to call after the checks. */ void hap_register_post_check(int (*fct)()) {