]> source.dussan.org Git - rspamd.git/commitdiff
More steps to support dynamic workers
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 12 Feb 2016 16:11:30 +0000 (16:11 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 12 Feb 2016 16:11:30 +0000 (16:11 +0000)
CMakeLists.txt
src/libserver/cfg_rcl.c
src/libserver/cfg_utils.c
src/libserver/worker_util.c
src/rspamd.h

index 55611a75ab6b8c33cb3968c2e4966db1062bfb5c..170a1c5415072aa687d80e473288a98c47f52ca5 100644 (file)
@@ -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
index 79d9c9e0e0511d9a89df54e29458a8aac314f2b0..9b05c1396b0b71e51f3ff7015ecc71cd8f82bc69 100644 (file)
@@ -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) {
index bd2aac89b92772d99e54f38453c65d93a6b5aaf4..eba9d66d9f7aa7a715f2271c2a34533f9f372428 100644 (file)
@@ -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;
+                                       }
                                }
                        }
 
index b18c36ec91d96a962b23e44d4addf2167c37941c..41f6e3ef2435ca393ac3c532bcc8c65ec6adf179 100644 (file)
@@ -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;
+                               }
                        }
                }
 
index 0c7668bfa22da0e8499b8afaa1b834fe287b5646..5fb40861c064848226f347c799de92f17b0d2317 100644 (file)
@@ -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