From: Vsevolod Stakhov Date: Fri, 12 Feb 2016 16:11:30 +0000 (+0000) Subject: More steps to support dynamic workers X-Git-Tag: 1.2.0~251 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=20c9bfdc2db1066ac174b462c5e9e48287b63ee7;p=rspamd.git More steps to support dynamic workers --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 55611a75a..170a1c541 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -634,8 +634,12 @@ ELSE(ENABLE_LUAJIT MATCHES "ON") ENDIF(NOT LUA_FOUND) ENDIF(ENABLE_LUAJIT MATCHES "ON") -ProcessPackage(GLIB2 LIBRARY glib-2.0 INCLUDE glib.h INCLUDE_SUFFIXES include/glib +ProcessPackage(GLIB2 LIBRARY glib-2.0 INCLUDE glib.h + INCLUDE_SUFFIXES include/glib ROOT ${GLIB_ROOT_DIR} MODULES glib-2.0>=2.28) +ProcessPackage(GMODULE2 LIBRARY gmodule-2.0 INCLUDE glib.h + INCLUDE_SUFFIXES include/glib + ROOT ${GLIB_ROOT_DIR} MODULES gmodule-2.0>=2.28) IF(ENABLE_PCRE2 MATCHES "ON") ProcessPackage(PCRE LIBRARY pcre2 INCLUDE pcre2.h INCLUDE_SUFFIXES include/pcre2 diff --git a/src/libserver/cfg_rcl.c b/src/libserver/cfg_rcl.c index 79d9c9e0e..9b05c1396 100644 --- a/src/libserver/cfg_rcl.c +++ b/src/libserver/cfg_rcl.c @@ -528,9 +528,11 @@ rspamd_rcl_worker_handler (rspamd_mempool_t *pool, const ucl_object_t *obj, struct rspamd_rcl_section *section, GError **err) { const ucl_object_t *val, *cur, *cur_obj; + struct rspamd_dynamic_worker *dyn_wrk; + worker_t *dyn_ctx; ucl_object_t *robj; ucl_object_iter_t it = NULL; - const gchar *worker_type, *worker_bind; + const gchar *worker_type, *worker_bind, *lib_path; struct rspamd_config *cfg = ud; GQuark qtype; struct rspamd_worker_conf *wrk; @@ -541,6 +543,49 @@ rspamd_rcl_worker_handler (rspamd_mempool_t *pool, const ucl_object_t *obj, g_assert (key != NULL); worker_type = key; + val = ucl_object_find_any_key (obj, "module", "load", NULL); + + if (val != NULL && ucl_object_tostring_safe (val, &lib_path)) { + + if (!g_module_supported ()) { + msg_err_config ("modules are not supported, so load of %s is impossible", + worker_type); + + return FALSE; + } + + dyn_wrk = rspamd_mempool_alloc0 (cfg->cfg_pool, sizeof (*dyn_wrk)); + dyn_wrk->lib = g_module_open (lib_path, G_MODULE_BIND_LAZY); + + if (dyn_wrk->lib == NULL) { + msg_err_config ("cannot load %s at %s: %s", worker_type, + lib_path, strerror (errno)); + + return FALSE; + } + + if (!g_module_symbol (dyn_wrk->lib, "rspamd_dyn_worker", + (gpointer *)&dyn_ctx)) { + msg_err_config ("cannot load %s at %s: missing entry point", + worker_type, + lib_path); + g_module_close (dyn_wrk->lib); + + return FALSE; + } + + if (!rspamd_check_worker (cfg, dyn_ctx)) { + g_module_close (dyn_wrk->lib); + + return FALSE; + } + + memcpy (&dyn_wrk->wrk, dyn_ctx, sizeof (dyn_wrk->wrk)); + dyn_wrk->path = lib_path; + dyn_wrk->type = g_quark_from_static_string (worker_type); + cfg->dynamic_workers = g_list_prepend (cfg->dynamic_workers, dyn_wrk); + } + qtype = g_quark_try_string (worker_type); if (qtype != 0) { wrk = rspamd_config_new_worker (cfg, NULL); @@ -563,11 +608,8 @@ rspamd_rcl_worker_handler (rspamd_mempool_t *pool, const ucl_object_t *obj, return TRUE; } - val = ucl_object_find_key (obj, "bind_socket"); + val = ucl_object_find_any_key (obj, "bind_socket", "listen", "bind", NULL); /* This name is more logical */ - if (val == NULL) { - val = ucl_object_find_key (obj, "listen"); - } if (val != NULL) { it = ucl_object_iterate_new (val); while ((cur = ucl_object_iterate_safe (it, true)) != NULL) { diff --git a/src/libserver/cfg_utils.c b/src/libserver/cfg_utils.c index bd2aac89b..eba9d66d9 100644 --- a/src/libserver/cfg_utils.c +++ b/src/libserver/cfg_utils.c @@ -162,6 +162,10 @@ rspamd_config_new (void) void rspamd_config_free (struct rspamd_config *cfg) { + struct rspamd_dynamic_module *dyn_mod; + struct rspamd_dynamic_worker *dyn_wrk; + GList *cur; + rspamd_map_remove_all (cfg); ucl_object_unref (cfg->rcl_obj); ucl_object_unref (cfg->doc_strings); @@ -182,6 +186,28 @@ rspamd_config_free (struct rspamd_config *cfg) g_free (cfg->checksum); } + /* Unload dynamic workers/modules */ + cur = g_list_first (cfg->dynamic_modules); + while (cur) { + dyn_mod = cur->data; + + if (dyn_mod->lib) { + g_module_close (dyn_mod->lib); + } + + cur = g_list_next (cur); + } + cur = g_list_first (cfg->dynamic_workers); + while (cur) { + dyn_wrk = cur->data; + + if (dyn_wrk->lib) { + g_module_close (dyn_wrk->lib); + } + + cur = g_list_next (cur); + } + g_list_free (cfg->classifiers); g_list_free (cfg->metrics_list); rspamd_symbols_cache_destroy (cfg->cache); @@ -1192,6 +1218,7 @@ rspamd_init_filters (struct rspamd_config *cfg, bool reconfig) { GList *cur; module_t *mod, **pmod; + struct rspamd_dynamic_module *dyn_mod; struct module_ctx *mod_ctx; /* Init all compiled modules */ @@ -1214,16 +1241,20 @@ rspamd_init_filters (struct rspamd_config *cfg, bool reconfig) cur = g_list_first (cfg->dynamic_modules); while (cur) { - mod = cur->data; + dyn_mod = cur->data; - if (rspamd_check_module (cfg, mod)) { - mod_ctx = g_slice_alloc0 (sizeof (struct module_ctx)); + if (dyn_mod->lib) { + mod = &dyn_mod->mod; - if (mod->module_init_func (cfg, &mod_ctx) == 0) { - g_hash_table_insert (cfg->c_modules, - (gpointer) mod->name, - mod_ctx); - mod_ctx->mod = mod; + if (rspamd_check_module (cfg, mod)) { + mod_ctx = g_slice_alloc0 (sizeof (struct module_ctx)); + + if (mod->module_init_func (cfg, &mod_ctx) == 0) { + g_hash_table_insert (cfg->c_modules, + (gpointer) mod->name, + mod_ctx); + mod_ctx->mod = mod; + } } } diff --git a/src/libserver/worker_util.c b/src/libserver/worker_util.c index b18c36ec9..41f6e3ef2 100644 --- a/src/libserver/worker_util.c +++ b/src/libserver/worker_util.c @@ -50,6 +50,7 @@ worker_t * rspamd_get_worker_by_type (struct rspamd_config *cfg, GQuark type) { worker_t **pwrk, *wrk; + struct rspamd_dynamic_worker *dyn_wrk; GList *cur; pwrk = cfg->compiled_workers; @@ -65,11 +66,15 @@ rspamd_get_worker_by_type (struct rspamd_config *cfg, GQuark type) cur = g_list_first (cfg->dynamic_workers); while (cur) { - wrk = cur->data; + dyn_wrk = cur->data; - if (rspamd_check_worker (cfg, wrk)) { - if (g_quark_from_string (wrk->name) == type) { - return wrk; + if (dyn_wrk->lib) { + wrk = &dyn_wrk->wrk; + + if (rspamd_check_worker (cfg, wrk)) { + if (g_quark_from_string (wrk->name) == type) { + return wrk; + } } } diff --git a/src/rspamd.h b/src/rspamd.h index 0c7668bfa..5fb40861c 100644 --- a/src/rspamd.h +++ b/src/rspamd.h @@ -162,6 +162,20 @@ typedef struct worker_s { const gchar *rspamd_features; } worker_t; +struct rspamd_dynamic_module { + module_t mod; + GModule *lib; + const gchar *path; + GQuark type; +}; + +struct rspamd_dynamic_worker { + worker_t wrk; + GModule *lib; + GQuark type; + const gchar *path; +}; + /** * Check if loaded worker is compatible with rspamd * @param cfg