From f6b7bd4a01205e442d3aa06d8edc3634a12945b2 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 9 Sep 2011 22:41:28 +1000 Subject: lib/util: consolidate module loading Autobuild-User: Andrew Bartlett Autobuild-Date: Thu Oct 6 08:52:30 CEST 2011 on sn-devel-104 --- lib/util/modules.c | 62 +++++++++++++++++++++++--------------------- lib/util/samba_modules.h | 6 +++-- source4/torture/smbtorture.c | 2 +- 3 files changed, 37 insertions(+), 33 deletions(-) diff --git a/lib/util/modules.c b/lib/util/modules.c index 2c4622510b..52a04be457 100644 --- a/lib/util/modules.c +++ b/lib/util/modules.c @@ -28,18 +28,40 @@ /** * Obtain the init function from a shared library file */ -init_module_fn load_module(TALLOC_CTX *mem_ctx, const char *path) +init_module_fn load_module(const char *path, bool is_probe, void **handle_out) { void *handle; void *init_fn; + char *error; +#if _SAMBA_BUILD_ == 3 + /* Always try to use LAZY symbol resolving; if the plugin has + * backwards compatibility, there might be symbols in the + * plugin referencing to old (removed) functions + */ + handle = dlopen(path, RTLD_LAZY); +#else + /* This should be a WAF build, where modules should be built + * with no undefined symbols and are already linked against + * the libraries that they are loaded by */ handle = dlopen(path, RTLD_NOW); +#endif + + /* This call should reset any possible non-fatal errors that + occured since last call to dl* functions */ + error = dlerror(); + if (handle == NULL) { - DEBUG(0, ("Unable to open %s: %s\n", path, dlerror())); + int level = is_probe ? 5 : 0; + DEBUG(level, ("Error loading module '%s': %s\n", path, error ? error : "")); return NULL; } - init_fn = dlsym(handle, SAMBA_INIT_MODULE); + init_fn = (init_module_fn)dlsym(handle, SAMBA_INIT_MODULE); + + /* we could check dlerror() to determine if it worked, because + dlsym() can validly return NULL, but what would we do with + a NULL pointer as a module init function? */ if (init_fn == NULL) { DEBUG(0, ("Unable to find %s() in %s: %s\n", @@ -49,6 +71,10 @@ init_module_fn load_module(TALLOC_CTX *mem_ctx, const char *path) return NULL; } + if (handle_out) { + *handle_out = handle; + } + return (init_module_fn)init_fn; } @@ -78,7 +104,7 @@ static init_module_fn *load_modules(TALLOC_CTX *mem_ctx, const char *path) filename = talloc_asprintf(mem_ctx, "%s/%s", path, entry->d_name); - ret[success] = load_module(mem_ctx, filename); + ret[success] = load_module(filename, true, NULL); if (ret[success]) { ret = talloc_realloc(mem_ctx, ret, init_module_fn, success+2); success++; @@ -138,33 +164,9 @@ static NTSTATUS do_smb_load_module(const char *module_name, bool is_probe) void *handle; init_module_fn init; NTSTATUS status; - const char *error; - /* Always try to use LAZY symbol resolving; if the plugin has - * backwards compatibility, there might be symbols in the - * plugin referencing to old (removed) functions - */ - handle = dlopen(module_name, RTLD_LAZY); - - /* This call should reset any possible non-fatal errors that - occured since last call to dl* functions */ - error = dlerror(); - - if(!handle) { - int level = is_probe ? 3 : 0; - DEBUG(level, ("Error loading module '%s': %s\n", module_name, error ? error : "")); - return NT_STATUS_UNSUCCESSFUL; - } - - init = (init_module_fn)dlsym(handle, SAMBA_INIT_MODULE); - - /* we must check dlerror() to determine if it worked, because - dlsym() can validly return NULL */ - error = dlerror(); - if (error) { - DEBUG(0, ("Error trying to resolve symbol '" SAMBA_INIT_MODULE - "' in %s: %s\n", module_name, error)); - dlclose(handle); + init = load_module(module_name, is_probe, &handle); + if (!init) { return NT_STATUS_UNSUCCESSFUL; } diff --git a/lib/util/samba_modules.h b/lib/util/samba_modules.h index ae7895eb12..5eb2a0dd1c 100644 --- a/lib/util/samba_modules.h +++ b/lib/util/samba_modules.h @@ -33,9 +33,11 @@ NTSTATUS samba_init_module(void); #define SAMBA_INIT_MODULE "samba_init_module" /** - * Obtain the init function from a shared library file + * Obtain the init function from a shared library file. + * + * The handle to dlclose() in case of error is returns in *handle if handle is not NULL */ -init_module_fn load_module(TALLOC_CTX *mem_ctx, const char *path); +init_module_fn load_module(const char *path, bool is_probe, void **handle); /** * Run the specified init functions. diff --git a/source4/torture/smbtorture.c b/source4/torture/smbtorture.c index 81ae11253c..934e0a7b2f 100644 --- a/source4/torture/smbtorture.c +++ b/source4/torture/smbtorture.c @@ -602,7 +602,7 @@ int main(int argc,char *argv[]) } if (extra_module != NULL) { - init_module_fn fn = load_module(talloc_autofree_context(), poptGetOptArg(pc)); + init_module_fn fn = load_module(poptGetOptArg(pc), false, NULL); if (fn == NULL) d_printf("Unable to load module from %s\n", poptGetOptArg(pc)); -- cgit