From a4a0f3d7c8903e01ce77d71a319f1feaf8227a96 Mon Sep 17 00:00:00 2001 From: Thierry FOURNIER Date: Fri, 23 Jan 2015 12:08:30 +0100 Subject: [PATCH] MINOR: lua: post initialisation bindings This system permits to execute some lua function after than HAProxy complete his initialisation. These functions are executed between the end of the configuration parsing and check and the begin of the scheduler. --- include/proto/hlua.h | 1 + include/types/hlua.h | 8 ++++++ src/haproxy.c | 4 +++ src/hlua.c | 59 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 72 insertions(+) diff --git a/include/proto/hlua.h b/include/proto/hlua.h index 20c329b3f..c8d1d3857 100644 --- a/include/proto/hlua.h +++ b/include/proto/hlua.h @@ -9,5 +9,6 @@ int hlua_ctx_init(struct hlua *lua, struct task *task); void hlua_ctx_destroy(struct hlua *lua); void hlua_init(); +int hlua_post_init(); #endif /* _PROTO_HLUA_H */ diff --git a/include/types/hlua.h b/include/types/hlua.h index b2c3997e5..d05f59c5e 100644 --- a/include/types/hlua.h +++ b/include/types/hlua.h @@ -41,4 +41,12 @@ struct hlua_com { struct task *task; /* The task to be wake if an event occurs. */ }; +/* This is a part of the list containing references to functions + * called at the initialisation time. + */ +struct hlua_init_function { + struct list l; + int function_ref; +}; + #endif /* _TYPES_HLUA_H */ diff --git a/src/haproxy.c b/src/haproxy.c index 76561676c..c3d6255af 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -1058,6 +1058,10 @@ void init(int argc, char **argv) if (!global.node) global.node = strdup(hostname); +#ifdef USE_LUA + if (!hlua_post_init()) + exit(1); +#endif } static void deinit_acl_cond(struct acl_cond *cond) diff --git a/src/hlua.c b/src/hlua.c index 00b88cad3..666aaf225 100644 --- a/src/hlua.c +++ b/src/hlua.c @@ -30,6 +30,9 @@ struct hlua gL; */ struct pool_head *pool2_hlua_com; +/* List head of the function called at the initialisation time. */ +struct list hlua_init_functions = LIST_HEAD_INIT(hlua_init_functions); + /* Store the fast lua context for coroutines. This tree uses the * Lua stack pointer value as indexed entry, and store the associated * hlua context. @@ -435,6 +438,30 @@ static enum hlua_exec hlua_ctx_resume(struct hlua *lua, int yield_allowed) return ret; } +/* This function is an LUA binding that register LUA function to be + * executed after the HAProxy configuration parsing and before the + * HAProxy scheduler starts. This function expect only one LUA + * argument that is a function. This function returns nothing, but + * throws if an error is encountered. + */ +__LJMP static int hlua_register_init(lua_State *L) +{ + struct hlua_init_function *init; + int ref; + + MAY_LJMP(check_args(L, 1, "register_init")); + + ref = MAY_LJMP(hlua_checkfunction(L, 1)); + + init = malloc(sizeof(*init)); + if (!init) + WILL_LJMP(luaL_error(L, "lua out of memory error.")); + + init->function_ref = ref; + LIST_ADDQ(&hlua_init_functions, &init->l); + return 0; +} + /* This function is called by the main configuration key "lua-load". It loads and * execute an lua file during the parsing of the HAProxy configuration file. It is * the main lua entry point. @@ -494,6 +521,35 @@ static struct cfg_kw_list cfg_kws = {{ },{ { 0, NULL, NULL }, }}; +int hlua_post_init() +{ + struct hlua_init_function *init; + const char *msg; + enum hlua_exec ret; + + list_for_each_entry(init, &hlua_init_functions, l) { + lua_rawgeti(gL.T, LUA_REGISTRYINDEX, init->function_ref); + ret = hlua_ctx_resume(&gL, 0); + switch (ret) { + case HLUA_E_OK: + lua_pop(gL.T, -1); + return 1; + case HLUA_E_AGAIN: + Alert("lua init: yield not allowed.\n"); + return 0; + case HLUA_E_ERRMSG: + msg = lua_tostring(gL.T, -1); + Alert("lua init: %s.\n", msg); + return 0; + case HLUA_E_ERR: + default: + Alert("lua init: unknown runtime error.\n"); + return 0; + } + } + return 1; +} + void hlua_init(void) { int i; @@ -536,6 +592,9 @@ void hlua_init(void) for (i=0; i