From 42baae32bc212e9287e11afa685e2de77cdf48e4 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Mon, 5 Apr 2010 21:09:40 +0400 Subject: [PATCH] * Add initial version of lua configuration system --- CMakeLists.txt | 51 ++++------- src/cfg_file.h | 14 ++- src/cfg_utils.c | 31 ++++++- src/cfg_xml.c | 62 +++++++++++-- src/cfg_xml.h | 1 + src/lua/CMakeLists.txt | 3 +- src/lua/lua_cfg_file.c | 196 +++++++++++++++++++++++++++++++++++++++++ src/lua/lua_common.c | 5 +- src/lua/lua_common.h | 9 ++ src/main.c | 7 +- 10 files changed, 331 insertions(+), 48 deletions(-) create mode 100644 src/lua/lua_cfg_file.c diff --git a/CMakeLists.txt b/CMakeLists.txt index e7e713e1c..480fe88ce 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,7 +19,6 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6.0 FATAL_ERROR) OPTION(DEBUG_MODE "Enable debug output [default: ON]" ON) OPTION(ENABLE_OPTIMIZATION "Enable optimization [default: OFF]" OFF) OPTION(ENABLE_PERL "Enable perl support [default: OFF]" OFF) -OPTION(ENABLE_LUA "Enable lua support [default: ON]" ON) OPTION(SKIP_RELINK_RPATH "Skip relinking and full RPATH for the install tree" OFF) OPTION(ENABLE_REDIRECTOR "Enable redirector install [default: OFF]" OFF) OPTION(ENABLE_PROFILING "Enable profiling [default: OFF]" OFF) @@ -65,26 +64,20 @@ ELSE(ENABLE_PERL MATCHES "ON") SET(WITHOUT_PERL 1) ENDIF(ENABLE_PERL MATCHES "ON") -IF(ENABLE_LUA MATCHES "ON") - IF (ENABLE_PERL MATCHES "ON") - MESSAGE(FATAL_ERROR "Error: Perl and Lua support cannot be turned on together") - ENDIF (ENABLE_PERL MATCHES "ON") - - INCLUDE(FindLua51) - IF(NOT LUA_FOUND) - # Automatic check failed, check passed variable - IF(LUA_INCLUDE_DIR) - INCLUDE_DIRECTORIES("${LUA_INCLUDE_DIR}") - SET(WITH_LUA 1) - ELSE(LUA_INCLUDE_DIR) - SET(ENABLE_LUA "OFF") - MESSAGE(STATUS "Lua not found, lua support disabled") - ENDIF(LUA_INCLUDE_DIR) - ELSE(NOT LUA_FOUND) - SET(WITH_LUA 1) - INCLUDE_DIRECTORIES("${LUA_INCLUDE_DIR}") - ENDIF(NOT LUA_FOUND) -ENDIF(ENABLE_LUA MATCHES "ON") + +INCLUDE(FindLua51) +IF(NOT LUA_FOUND) + # Automatic check failed, check passed variable + IF(LUA_INCLUDE_DIR) + INCLUDE_DIRECTORIES("${LUA_INCLUDE_DIR}") + SET(WITH_LUA 1) + ELSE(LUA_INCLUDE_DIR) + MESSAGE(FATAL_ERROR "Lua not found, lua support is required for working") + ENDIF(LUA_INCLUDE_DIR) +ELSE(NOT LUA_FOUND) + SET(WITH_LUA 1) + INCLUDE_DIRECTORIES("${LUA_INCLUDE_DIR}") +ENDIF(NOT LUA_FOUND) # Lex and yacc FIND_PROGRAM(LEX_EXECUTABLE lex) @@ -429,9 +422,7 @@ SET(RSPAMDSRC src/modules.c IF(ENABLE_PERL MATCHES "ON") LIST(APPEND RSPAMDSRC src/perl.c) ENDIF(ENABLE_PERL MATCHES "ON") -IF(ENABLE_LUA MATCHES "ON") - ADD_SUBDIRECTORY(src/lua) -ENDIF(ENABLE_LUA MATCHES "ON") +ADD_SUBDIRECTORY(src/lua) ADD_SUBDIRECTORY(src/json) ADD_SUBDIRECTORY(src/evdns) @@ -545,10 +536,8 @@ IF(PERL_EXECUTABLE) ADD_DEPENDENCIES(rspamd perlmodule) ENDIF(PERL_EXECUTABLE) -IF(ENABLE_LUA MATCHES "ON") - TARGET_LINK_LIBRARIES(rspamd rspamd_lua) - TARGET_LINK_LIBRARIES(rspamd "${LUA_LIBRARY}") -ENDIF(ENABLE_LUA MATCHES "ON") +TARGET_LINK_LIBRARIES(rspamd rspamd_lua) +TARGET_LINK_LIBRARIES(rspamd "${LUA_LIBRARY}") TARGET_LINK_LIBRARIES(rspamd m) IF(LIBUTIL_LIBRARY) @@ -673,10 +662,8 @@ ENDIF(NOT EXISTS ${ETC_PREFIX}/rspamd/lotto.inc) INSTALL(FILES conf/rspamd.conf.sample DESTINATION ${ETC_PREFIX}/) # Lua plugins -IF(ENABLE_LUA MATCHES "ON") - INSTALL(CODE "EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E make_directory ${ETC_PREFIX}/rspamd/plugins)") - INSTALL(DIRECTORY src/plugins/lua DESTINATION ${ETC_PREFIX}/rspamd/plugins PATTERN "*.lua") -ENDIF(ENABLE_LUA MATCHES "ON") +INSTALL(CODE "EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E make_directory ${ETC_PREFIX}/rspamd/plugins)") +INSTALL(DIRECTORY src/plugins/lua DESTINATION ${ETC_PREFIX}/rspamd/plugins PATTERN "*.lua") # Perl lib IF(PERL_EXECUTABLE) diff --git a/src/cfg_file.h b/src/cfg_file.h index 3ec7391e4..225a940ac 100644 --- a/src/cfg_file.h +++ b/src/cfg_file.h @@ -98,8 +98,8 @@ struct memcached_server { * script module list item */ struct script_module { - gchar *name; /**< name of module */ - gchar *path; /**< path to module */ + gchar *name; /**< name of module */ + gchar *path; /**< path to module */ }; /** @@ -108,6 +108,15 @@ struct script_module { struct module_opt { gchar *param; /**< parameter name */ gchar *value; /**< paramater value */ + gpointer actual_data; /**< parsed data */ + gboolean is_lua; /**< actually this is lua variable */ + enum { + LUA_VAR_NUM, + LUA_VAR_BOOLEAN, + LUA_VAR_STRING, + LUA_VAR_FUNCTION, + LUA_VAR_UNKNOWN + } lua_type; /**< type of lua variable */ }; /** @@ -278,6 +287,7 @@ struct config_file { gchar* checksum; /**< real checksum of config file */ gchar* dump_checksum; /**< dump checksum of config file */ + gpointer lua_state; /**< pointer to lua state */ }; /** diff --git a/src/cfg_utils.c b/src/cfg_utils.c index 18677a1ca..9047340fb 100644 --- a/src/cfg_utils.c +++ b/src/cfg_utils.c @@ -243,6 +243,7 @@ get_module_opt (struct config_file *cfg, gchar *module_name, gchar *opt_name) { GList *cur_opt; struct module_opt *cur; + static char numbuf[64]; cur_opt = g_hash_table_lookup (cfg->modules_opts, module_name); if (cur_opt == NULL) { @@ -252,7 +253,31 @@ get_module_opt (struct config_file *cfg, gchar *module_name, gchar *opt_name) while (cur_opt) { cur = cur_opt->data; if (strcmp (cur->param, opt_name) == 0) { - return cur->value; + /* Check if it is lua variable */ + if (! cur->is_lua) { + /* Plain variable */ + return cur->value; + } + else { + /* Check type */ + switch (cur->lua_type) { + case LUA_VAR_NUM: + /* numbuf is static, so it is safe to return it "as is" */ + snprintf (numbuf, sizeof (numbuf), "%f", *(double *)cur->actual_data); + return numbuf; + case LUA_VAR_BOOLEAN: + snprintf (numbuf, sizeof (numbuf), "%s", *(gboolean *)cur->actual_data ? "yes" : "no"); + return numbuf; + case LUA_VAR_STRING: + return (char *)cur->actual_data; + case LUA_VAR_FUNCTION: + msg_info ("option %s is dynamic, so it cannot be aqquired statically", opt_name); + return NULL; + case LUA_VAR_UNKNOWN: + msg_info ("option %s has unknown type, maybe there is error in LUA code", opt_name); + return NULL; + } + } } cur_opt = g_list_next (cur_opt); } @@ -573,7 +598,9 @@ post_load_config (struct config_file *cfg) cfg->metrics_list = g_list_prepend (cfg->metrics_list, def_metric); g_hash_table_insert (cfg->metrics, DEFAULT_METRIC, def_metric); } - + + /* Lua options */ + (void)lua_post_load_config (cfg); } diff --git a/src/cfg_xml.c b/src/cfg_xml.c index aa9ccf2fe..872bd7a00 100644 --- a/src/cfg_xml.c +++ b/src/cfg_xml.c @@ -33,6 +33,7 @@ #include "util.h" #include "classifiers/classifiers.h" #include "tokenizers/tokenizers.h" +#include "lua/lua_common.h" /* Maximum attributes for param */ #define MAX_PARAM 64 @@ -80,6 +81,12 @@ static struct xml_parser_rule grammar[] = { G_STRUCT_OFFSET (struct config_file, pid_file), NULL }, + { + "lua", + handle_lua, + 0, + NULL + }, { "raw_mode", xml_handle_boolean, @@ -550,21 +557,29 @@ handle_factor (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTa gboolean handle_module_opt (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, int offset) { - char *name; + char *name, *val; GList *cur_opt; struct module_opt *cur; + gboolean is_lua = FALSE; if ((name = g_hash_table_lookup (attrs, "name")) == NULL) { msg_err ("param tag must have \"name\" attribute"); return FALSE; } - + + /* Check for lua */ + if ((val = g_hash_table_lookup (attrs, "lua")) != NULL) { + if (g_ascii_strcasecmp (val, "yes") == 0) { + is_lua = TRUE; + } + } cur_opt = g_hash_table_lookup (cfg->modules_opts, ctx->section_name); if (cur_opt == NULL) { /* Insert new option structure */ - cur = memory_pool_alloc (cfg->cfg_pool, sizeof (struct module_opt)); + cur = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct module_opt)); cur->param = name; cur->value = data; + cur->is_lua = is_lua; cur_opt = g_list_prepend (NULL, cur); g_hash_table_insert (cfg->modules_opts, memory_pool_strdup (cfg->cfg_pool, ctx->section_name), cur_opt); } @@ -575,15 +590,52 @@ handle_module_opt (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHa if (strcmp (cur->param, name) == 0) { /* cur->value is in pool */ cur->value = data; + cur->is_lua = is_lua; return TRUE; } cur_opt = g_list_next (cur_opt); } /* Not found, insert */ - cur = memory_pool_alloc (cfg->cfg_pool, sizeof (struct module_opt)); + cur = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct module_opt)); cur->param = name; cur->value = data; - cur_opt = g_list_prepend (cur_opt, cur); + cur->is_lua = is_lua; + /* Slow way, but we cannot prepend here as we need to modify pointer inside module_options hash */ + cur_opt = g_list_append (cur_opt, cur); + } + + return TRUE; +} + +/* Handle lua tag */ +gboolean +handle_lua (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, int offset) +{ + gchar *val; + lua_State *L = cfg->lua_state; + + /* First check for global variable 'config' */ + lua_getglobal (L, "config"); + + if (lua_isnil (L, 1)) { + /* Assign global table to set up attributes */ + lua_newtable (L); + lua_setglobal (L, "config"); + /* Now config table can be used for configuring rspamd */ + } + /* First check "src" attribute */ + if ((val = g_hash_table_lookup (attrs, "src")) != NULL) { + if (luaL_dofile (L, val) != 0) { + msg_err ("cannot load lua file %s: %s", val, lua_tostring (L, -1)); + return FALSE; + } + } + else if (data != NULL && *data != '\0') { + /* Try to load a string */ + if (luaL_dostring (L, data) != 0) { + msg_err ("cannot load lua chunk: %s", lua_tostring (L, -1)); + return FALSE; + } } return TRUE; diff --git a/src/cfg_xml.h b/src/cfg_xml.h index 38c86c3d6..ec0547ffe 100644 --- a/src/cfg_xml.h +++ b/src/cfg_xml.h @@ -92,6 +92,7 @@ gboolean handle_factor (struct config_file *cfg, struct rspamd_xml_userdata *ctx gboolean handle_module_opt (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, int offset); gboolean handle_log_type (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, int offset); gboolean handle_log_level (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, int offset); +gboolean handle_lua (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, int offset); /* Dumper functions */ diff --git a/src/lua/CMakeLists.txt b/src/lua/CMakeLists.txt index d0ac4f826..c17936862 100644 --- a/src/lua/CMakeLists.txt +++ b/src/lua/CMakeLists.txt @@ -3,7 +3,8 @@ SET(LUASRC lua_common.c lua_task.c lua_message.c lua_config.c - lua_classifier.c) + lua_classifier.c + lua_cfg_file.c) ADD_LIBRARY(rspamd_lua STATIC ${LUASRC}) TARGET_LINK_LIBRARIES(rspamd_lua ${LUALIB}) diff --git a/src/lua/lua_cfg_file.c b/src/lua/lua_cfg_file.c new file mode 100644 index 000000000..1ac334299 --- /dev/null +++ b/src/lua/lua_cfg_file.c @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2009, Rambler media + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY Rambler media ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Rambler BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "lua_common.h" + +/* + * This is implementation of lua routines to handle config file params + */ + + +/* Check element with specified name in list, and append it to list if no element with such name was found */ +static void +lua_check_element (memory_pool_t *pool, const gchar *name, GList *options, struct module_opt **opt) +{ + struct module_opt *cur; + GList *cur_opt; + gboolean found = FALSE; + + cur_opt = options; + + while (cur_opt) { + cur = cur_opt->data; + + if (g_ascii_strcasecmp (cur->param, name) == 0) { + found = TRUE; + break; + } + cur_opt = g_list_next (cur_opt); + } + + if (found) { + *opt = cur; + cur->is_lua = TRUE; + } + else { + /* New option */ + *opt = memory_pool_alloc0 (pool, sizeof (struct module_opt)); + (*opt)->is_lua = TRUE; + (void)g_list_append (options, *opt); + } +} + +/* Process a single item in 'config' table */ +static void +lua_process_module (lua_State *L, const gchar *param, struct config_file *cfg) +{ + GList *cur_opt; + struct module_opt *cur; + const char *name; + gboolean new_module = FALSE; + + /* Get module opt structure */ + if ((cur_opt = g_hash_table_lookup (cfg->modules_opts, param)) == NULL) { + new_module = TRUE; + } + + /* Now iterate throught module table */ + lua_gettable (L, -1); + for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) { + /* key - -2, value - -1 */ + name = luaL_checkstring (L, -2); + if (name != NULL) { + lua_check_element (cfg->cfg_pool, name, cur_opt, &cur); + lua_process_element (cfg, name, cur, -1); + } + } + + if (new_module && cur_opt != NULL) { + /* Insert new list into a hash */ + g_hash_table_insert (cfg->modules_opts, memory_pool_strdup (cfg->cfg_pool, param), cur_opt); + } +} + +/* Process single element */ +void +lua_process_element (struct config_file *cfg, const char *name, struct module_opt *opt, int idx) +{ + lua_State *L = cfg->lua_state; + int t; + double *num; + gboolean *flag; + + t = lua_type (L, idx); + /* Handle type */ + switch (t) { + case LUA_TNUMBER: + opt->actual_data = memory_pool_alloc (cfg->cfg_pool, sizeof (double)); + num = (double *)opt->actual_data; + *num = lua_tonumber (L, idx); + opt->lua_type = LUA_VAR_NUM; + break; + case LUA_TBOOLEAN: + opt->actual_data = memory_pool_alloc (cfg->cfg_pool, sizeof (gboolean)); + flag = (gboolean *)opt->actual_data; + *flag = lua_toboolean (L, idx); + opt->lua_type = LUA_VAR_BOOLEAN; + break; + case LUA_TSTRING: + opt->actual_data = memory_pool_strdup (cfg->cfg_pool, lua_tostring (L, idx)); + opt->lua_type = LUA_VAR_STRING; + break; + case LUA_TFUNCTION: + opt->actual_data = (gpointer)lua_topointer (L, idx); + opt->lua_type = LUA_VAR_FUNCTION; + break; + case LUA_TNIL: + case LUA_TTABLE: + case LUA_TUSERDATA: + case LUA_TTHREAD: + case LUA_TLIGHTUSERDATA: + msg_warn ("cannot handle variables of type %s as there is nothing to do with them", lua_typename (L, t)); + opt->lua_type = LUA_VAR_UNKNOWN; + break; + } +} + + +static void +lua_module_callback (gpointer key, gpointer value, gpointer ud) +{ + struct config_file *cfg = ud; + lua_State *L = cfg->lua_state; + GList *cur; + struct module_opt *opt; + + cur = value; + while (cur) { + opt = cur->data; + if (opt->is_lua && opt->actual_data == NULL) { + /* Try to extract variable name from config table first */ + lua_getglobal (L, "config"); + if (lua_istable (L, -1)) { + lua_pushstring (L, opt->param); + lua_gettable (L, -2); + if (lua_isnil (L, -1)) { + /* Try to get global variable */ + lua_getglobal (L, opt->param); + } + } + else { + /* Try to get global variable */ + lua_getglobal (L, opt->param); + } + lua_process_element (cfg, opt->param, opt, -1); + } + cur = g_list_next (cur); + } + +} + +/* Do post load initialization based on lua */ +void +lua_post_load_config (struct config_file *cfg) +{ + lua_State *L = cfg->lua_state; + const gchar *name; + + /* First check all module options that may be overriden in 'config' global */ + lua_getglobal (L, "config"); + + if (lua_istable (L, -1)) { + /* Iterate */ + for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) { + /* 'key' is at index -2 and 'value' is at index -1 */ + /* Key must be a string and value must be a table */ + name = luaL_checkstring (L, -2); + if (name != NULL && lua_istable (L, -1)) { + lua_process_module (L, name, cfg); + } + } + } + + /* Now parse all lua params */ + g_hash_table_foreach (cfg->modules_opts, lua_module_callback, cfg); +} diff --git a/src/lua/lua_common.c b/src/lua/lua_common.c index 1f39975d0..3d4e29b28 100644 --- a/src/lua/lua_common.c +++ b/src/lua/lua_common.c @@ -180,7 +180,7 @@ luaopen_logger (lua_State * L) return 1; } -static void +void init_lua () { if (L == NULL) { @@ -211,7 +211,6 @@ init_lua_filters (struct config_file *cfg) struct script_module *module; struct statfile *st; - init_lua (); cur = g_list_first (cfg->script_modules); while (cur) { module = cur->data; @@ -251,6 +250,8 @@ init_lua_filters (struct config_file *cfg) } cur = g_list_next (cur); } + /* Assign state */ + cfg->lua_state = L; } /* Callback functions */ diff --git a/src/lua/lua_common.h b/src/lua/lua_common.h index a1820d064..5de7bdc71 100644 --- a/src/lua/lua_common.h +++ b/src/lua/lua_common.h @@ -16,6 +16,7 @@ extern const luaL_reg null_reg[]; +/* Common utility functions */ void lua_newclass (lua_State *L, const char *classname, const struct luaL_reg *func); void lua_setclass (lua_State *L, const char *classname, int objidx); void lua_set_table_index (lua_State *L, const char *index, const char *value); @@ -29,17 +30,25 @@ int luaopen_hash_table (lua_State *L); int luaopen_textpart (lua_State *L); int luaopen_classifier (lua_State *L); int luaopen_statfile (lua_State * L); +void init_lua (); void init_lua_filters (struct config_file *cfg); +/* Filters functions */ int lua_call_filter (const char *function, struct worker_task *task); int lua_call_chain_filter (const char *function, struct worker_task *task, int *marks, unsigned int number); double lua_consolidation_func (struct worker_task *task, const char *metric_name, const char *function_name); void add_luabuf (const char *line); +/* Classify functions */ GList *call_classifier_pre_callbacks (struct classifier_config *ccf, struct worker_task *task); double call_classifier_post_callbacks (struct classifier_config *ccf, struct worker_task *task, double in); double lua_normalizer_func (double score, void *params); +/* Config file functions */ +void lua_post_load_config (struct config_file *cfg); +void lua_process_element (struct config_file *cfg, const char *name, struct module_opt *opt, int idx); + + #endif /* WITH_LUA */ #endif /* RSPAMD_LUA_H */ diff --git a/src/main.c b/src/main.c index 350199632..926d0e5c6 100644 --- a/src/main.c +++ b/src/main.c @@ -624,6 +624,7 @@ main (int argc, char **argv, char **env) #ifndef HAVE_SETPROCTITLE init_title (argc, argv, environ); #endif + init_lua (); f = fopen (rspamd->cfg->cfg_name, "r"); if (f == NULL) { @@ -677,9 +678,7 @@ main (int argc, char **argv, char **env) } l = g_list_next (l); } -#if defined(WITH_LUA) init_lua_filters (cfg); -#endif if (dump_vars) { dump_cfg_vars (); } @@ -784,10 +783,10 @@ main (int argc, char **argv, char **env) perl_construct (perl_interpreter); perl_parse (perl_interpreter, xs_init, 3, args, NULL); init_perl_filters (cfg); -#elif defined(WITH_LUA) - init_lua_filters (cfg); #endif + init_lua_filters (cfg); + /* Init symbols cache for each metric */ l = g_list_first (cfg->metrics_list); while (l) { -- 2.39.5