]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- For PR #93: dynlibmod can handle reloads and deinit and inits again,
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Mon, 18 May 2020 08:11:16 +0000 (10:11 +0200)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Mon, 18 May 2020 08:11:16 +0000 (10:11 +0200)
  with dlclose and dlopen of the library again.  Also for multiple
  modules.  Fix memory leak by not closing dlopened content.  Fix
  to allow one dynlibmod instance by unbound-checkconf.

doc/Changelog
dynlibmod/dynlibmod.c
dynlibmod/dynlibmod.h
smallapp/unbound-checkconf.c

index 86246ad6ec9cc6ab24071702baaaa85dcd13e154..637b3136861da6e5cf82fae3616a5d66f9eb7373 100644 (file)
@@ -1,3 +1,9 @@
+18 May 2020: Wouter
+       - For PR #93: dynlibmod can handle reloads and deinit and inits again,
+         with dlclose and dlopen of the library again.  Also for multiple
+         modules.  Fix memory leak by not closing dlopened content.  Fix
+         to allow one dynlibmod instance by unbound-checkconf.
+
 15 May 2020: Wouter
        - Merge PR #93: Add dynamic library support.
        - Fixed conflicts for PR #93 and make configure, yacc, lex.
index 4e022a82f0ff0fa8a27eac6d3a928bba4f99dc89..6ae23e86c6ccd42c386d2613641e0a6c027fbda0 100644 (file)
@@ -34,6 +34,11 @@ void log_dlerror() {
 HMODULE open_library(const char* fname) {
     return LoadLibrary(fname);
 }
+
+void close_library(const char* fname, __DYNMOD handle) {
+       (void)fname;
+       (void)handle;
+}
 #else
 #include <dlfcn.h>
 #define __DYNMOD void*
@@ -46,11 +51,20 @@ void log_dlerror() {
 void* open_library(const char* fname) {
     return dlopen(fname, RTLD_LAZY | RTLD_GLOBAL);
 }
+
+void close_library(const char* fname, __DYNMOD handle) {
+       if(!handle) return;
+       if(dlclose(handle) != 0) {
+               log_err("dlclose %s: %s", fname, strerror(errno));
+       }
+}
 #endif
 
+/** module counter for multiple dynlib modules */
+static int dynlib_mod_count = 0;
+
 /** dynlib module init */
 int dynlibmod_init(struct module_env* env, int id) {
-    static int dynlib_mod_count;
     int dynlib_mod_idx = dynlib_mod_count++;
     struct config_strlist* cfg_item = env->cfg->dynlib_file;
     struct dynlibmod_env* de = (struct dynlibmod_env*)calloc(1, sizeof(struct dynlibmod_env));
@@ -76,6 +90,7 @@ int dynlibmod_init(struct module_env* env, int id) {
     }
     verbose(VERB_ALGO, "dynlibmod[%d]: Trying to load library %s", dynlib_mod_idx, de->fname);
     dynamic_library = open_library(de->fname);
+    de->dynamic_library = (void*)dynamic_library;
     if (dynamic_library == NULL) {
         log_dlerror();
         log_err("dynlibmod[%d]: unable to load dynamic library \"%s\".", dynlib_mod_idx, de->fname);
@@ -147,6 +162,8 @@ void dynlibmod_deinit(struct module_env* env, int id) {
     if(de == NULL)
         return;
     de->func_deinit(env, id);
+    close_library(de->fname, (__DYNMOD)de->dynamic_library);
+    dynlib_mod_count--;
     de->fname = NULL;
     free(de);
 }
index 1097db1e73d30d0e4d02f76bf1c9fbf55d20d6b4..c34cf0e88d922a5bb7bd19d40a3c7fc797313fb1 100644 (file)
@@ -114,6 +114,8 @@ typedef int (*inplace_cb_register_wrapped_t)(void*, enum inplace_cb_list_type, v
 struct dynlibmod_env {
        /** Dynamic library filename. */
        const char* fname;
+       /** dynamic library handle */
+       void* dynamic_library;
        /** Module init function */
        func_init_t func_init;
        /** Module deinit function */
index 3fc638cae980794b78e6e1cfcb0b49812ac1c100..77c55898127b18aa58212c137de40f2e219bda77 100644 (file)
@@ -569,6 +569,54 @@ morechecks(struct config_file* cfg)
                && strcmp(cfg->module_conf, "python dns64 iterator") != 0
                && strcmp(cfg->module_conf, "python dns64 validator iterator") != 0
 #endif
+#ifdef WITH_DYNLIBMODULE
+               && strcmp(cfg->module_conf, "dynlib iterator") != 0
+               && strcmp(cfg->module_conf, "dynlib respip iterator") != 0
+               && strcmp(cfg->module_conf, "dynlib validator iterator") != 0
+               && strcmp(cfg->module_conf, "dynlib respip validator iterator") != 0
+               && strcmp(cfg->module_conf, "validator dynlib iterator") != 0
+               && strcmp(cfg->module_conf, "dns64 dynlib iterator") != 0
+               && strcmp(cfg->module_conf, "dns64 dynlib validator iterator") != 0
+               && strcmp(cfg->module_conf, "dns64 validator dynlib iterator") != 0
+               && strcmp(cfg->module_conf, "dynlib dns64 iterator") != 0
+               && strcmp(cfg->module_conf, "dynlib dns64 validator iterator") != 0
+               && strcmp(cfg->module_conf, "dynlib dns64 cachedb iterator") != 0
+               && strcmp(cfg->module_conf, "dynlib dns64 validator cachedb iterator") != 0
+               && strcmp(cfg->module_conf, "dns64 dynlib cachedb iterator") != 0
+               && strcmp(cfg->module_conf, "dns64 dynlib validator cachedb iterator") != 0
+               && strcmp(cfg->module_conf, "dynlib cachedb iterator") != 0
+               && strcmp(cfg->module_conf, "dynlib respip cachedb iterator") != 0
+               && strcmp(cfg->module_conf, "dynlib validator cachedb iterator") != 0
+               && strcmp(cfg->module_conf, "dynlib respip validator cachedb iterator") != 0
+               && strcmp(cfg->module_conf, "cachedb dynlib iterator") != 0
+               && strcmp(cfg->module_conf, "respip cachedb dynlib iterator") != 0
+               && strcmp(cfg->module_conf, "validator cachedb dynlib iterator") != 0
+               && strcmp(cfg->module_conf, "respip validator cachedb dynlib iterator") != 0
+               && strcmp(cfg->module_conf, "validator dynlib cachedb iterator") != 0
+               && strcmp(cfg->module_conf, "respip validator dynlib cachedb iterator") != 0
+               && strcmp(cfg->module_conf, "dynlib subnetcache iterator") != 0
+               && strcmp(cfg->module_conf, "dynlib respip subnetcache iterator") != 0
+               && strcmp(cfg->module_conf, "subnetcache dynlib iterator") != 0
+               && strcmp(cfg->module_conf, "respip subnetcache dynlib iterator") != 0
+               && strcmp(cfg->module_conf, "dynlib subnetcache validator iterator") != 0
+               && strcmp(cfg->module_conf, "dynlib respip subnetcache validator iterator") != 0
+               && strcmp(cfg->module_conf, "subnetcache dynlib validator iterator") != 0
+               && strcmp(cfg->module_conf, "respip subnetcache dynlib validator iterator") != 0
+               && strcmp(cfg->module_conf, "subnetcache validator dynlib iterator") != 0
+               && strcmp(cfg->module_conf, "respip subnetcache validator dynlib iterator") != 0
+               && strcmp(cfg->module_conf, "dynlib ipsecmod iterator") != 0
+               && strcmp(cfg->module_conf, "dynlib ipsecmod respip iterator") != 0
+               && strcmp(cfg->module_conf, "ipsecmod dynlib iterator") != 0
+               && strcmp(cfg->module_conf, "ipsecmod dynlib respip iterator") != 0
+               && strcmp(cfg->module_conf, "ipsecmod validator iterator") != 0
+               && strcmp(cfg->module_conf, "ipsecmod respip validator iterator") != 0
+               && strcmp(cfg->module_conf, "dynlib ipsecmod validator iterator") != 0
+               && strcmp(cfg->module_conf, "dynlib ipsecmod respip validator iterator") != 0
+               && strcmp(cfg->module_conf, "ipsecmod dynlib validator iterator") != 0
+               && strcmp(cfg->module_conf, "ipsecmod dynlib respip validator iterator") != 0
+               && strcmp(cfg->module_conf, "ipsecmod validator dynlib iterator") != 0
+               && strcmp(cfg->module_conf, "ipsecmod respip validator dynlib iterator") != 0
+#endif
 #ifdef USE_CACHEDB
                && strcmp(cfg->module_conf, "validator cachedb iterator") != 0
                && strcmp(cfg->module_conf, "respip validator cachedb iterator") != 0