commit 4572567aef57fd7435e4d5aafbd8a51a7595193c Author: Jacob Welsh AuthorDate: Sat Oct 29 03:10:41 2022 +0000 Commit: Jacob Welsh CommitDate: Sat Oct 29 19:16:54 2022 +0000 Type: new structure lib: begin adding true static module support diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index ac5c62b102..a59bb71c48 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -141,6 +141,8 @@ liblib_la_SOURCES = \ mmap-anon.c \ mmap-util.c \ module-dir.c \ + module-load-adm.c \ + module-load-mail.c \ mountpoint.c \ net.c \ nfs-workarounds.c \ diff --git a/src/lib/module-dir-load-adm.c b/src/lib/module-dir-load-adm.c new file mode 100644 index 0000000000..f800fc5838 --- /dev/null +++ b/src/lib/module-dir-load-adm.c @@ -0,0 +1,18 @@ +#include "module-dir.h" +#include "../plugins/fts/doveadm-fts.h" + +void module_dir_load_adm(struct module **modules, const char *mod_names) +{ + T_BEGIN { + const char **names = module_parse_names(mod_names); + + /* TODO: + * lib10_doveadm_acl_plugin + * lib10_doveadm_quota_plugin + */ + module_load_static(modules, names, "doveadm_fts", + doveadm_fts_plugin_init, + doveadm_fts_plugin_deinit); + + } T_END; +} diff --git a/src/lib/module-dir-load-mail.c b/src/lib/module-dir-load-mail.c new file mode 100644 index 0000000000..edc7fbb65c --- /dev/null +++ b/src/lib/module-dir-load-mail.c @@ -0,0 +1,18 @@ +#include "module-dir.h" +#include "../plugins/fts/fts-plugin.h" +#include "../plugins/fts-squat/fts-squat-plugin.h" + +void module_dir_load_mail(struct module **modules, const char *mod_names) +{ + T_BEGIN { + const char **names = module_parse_names(mod_names); + + module_load_static(modules, names, "fts", + fts_plugin_init, + fts_plugin_deinit); + module_load_static(modules, names, "fts_squat", + fts_squat_plugin_init, + fts_squat_plugin_deinit); /* requires: fts */ + + } T_END; +} diff --git a/src/lib/module-dir.c b/src/lib/module-dir.c index 26fdeac175..cc7c3e4718 100644 --- a/src/lib/module-dir.c +++ b/src/lib/module-dir.c @@ -60,13 +60,6 @@ static void module_free(struct module *module) { if (module->deinit != NULL && module->initialized) module->deinit(); - /* dlclose()ing removes all symbols from valgrind's visibility. - if GDB environment is set, don't actually unload the module - (the GDB environment is used elsewhere too) */ - if (getenv("GDB") == NULL) { - if (dlclose(module->handle) != 0) - i_error("dlclose(%s) failed: %m", module->path); - } i_free(module->path); i_free(module->name); i_free(module); @@ -287,19 +280,13 @@ static int module_name_cmp(const char *const *n1, const char *const *n2) return strcmp(s1, s2); } -static bool module_want_load(const struct module_dir_load_settings *set, - const char **names, const char *name) +static bool module_want_load(const char **names, const char *name) { - if (set->filter_callback != NULL) { - if (!set->filter_callback(name, set->filter_context)) - return FALSE; - } if (names == NULL) return TRUE; for (; *names != NULL; names++) { if (strcmp(*names, name) == 0) { - *names = ""; return TRUE; } } @@ -601,10 +588,6 @@ void module_dir_unload(struct module **modules) #else -#ifndef MODULE_SUFFIX -# define MODULE_SUFFIX ".so" /* just to avoid build failure */ -#endif - struct module * module_dir_load_missing(struct module *old_modules ATTR_UNUSED, const char *dir ATTR_UNUSED, @@ -651,6 +634,37 @@ void *module_get_symbol_quiet(struct module *module ATTR_UNUSED, return NULL; } +/* New static modules API */ + +void module_load_static(struct module **modules, + const char **module_names, const char *name, + void (*)(struct module *) init_func, void (*)(void) deinit_func) +{ + if (module_want_load(module_names, name) && + !module_is_loaded(*modules, name)) { + struct module *module = i_new(struct module, 1); + module->path = i_strdup("(static)"); + module->name = i_strdup(name); + module->init = init_func; + module->deinit = deinit_func; + + /* Append to linked list. Linear time, but so are module_want_load and module_is_loaded, and it doesn't much matter here while order does. */ + while (*modules) + modules = &(*modules)->next; + *modules = module; + } +} + +const char **module_parse_names(const char *module_names) +{ + if (module_names) { + const char **arr = t_strsplit_spaces(module_names, ", "); + module_names_fix(arr); + return arr; + } + return NULL; +} + #endif struct module *module_dir_load(const char *dir, const char *module_names, @@ -674,7 +688,7 @@ const char *module_file_get_name(const char *fname) if (*p == '_') fname = p + 1; - p = strstr(fname, MODULE_SUFFIX); + p = strstr(fname, ".so"); if (p == NULL) return fname; diff --git a/src/lib/module-dir.h b/src/lib/module-dir.h index f62e90677c..bce2447e49 100644 --- a/src/lib/module-dir.h +++ b/src/lib/module-dir.h @@ -56,6 +56,11 @@ int module_dir_try_load_missing(struct module **modules, const struct module_dir_load_settings *set, const char **error_r) ATTR_NULL(1, 3); + +/* Load modules of a given type (called a "module directory" due to the prior dlopen based implementation). mod_names is a space separated list of module names to load, or NULL for all available. Each function goes in a separate file so that each module collection links into only the binaries that require it. */ +void module_dir_load_adm(struct module **modules, const char *mod_names); +void module_dir_load_mail(struct module **modules, const char *mod_names); + /* Call init() in all modules */ void module_dir_init(struct module *modules); /* Call deinit() in all modules and mark them NULL so module_dir_unload()