提交 0e1404d4 编写于 作者: P Peter Krempa

driver: Split/refactor driver module loading

Split the convoluted driver loader function into simpler parts which
will potentially allow reuse.
上级 2e4e6aff
......@@ -43,13 +43,103 @@ VIR_LOG_INIT("driver");
# include <dlfcn.h>
# define DEFAULT_DRIVER_DIR LIBDIR "/libvirt/connection-driver"
static void *
virDriverLoadModuleFile(const char *file)
{
void *handle = NULL;
VIR_DEBUG("Load module file '%s'", file);
if (access(file, R_OK) < 0) {
VIR_INFO("Module %s not accessible", file);
return NULL;
}
virUpdateSelfLastChanged(file);
if (!(handle = dlopen(file, RTLD_NOW | RTLD_GLOBAL)))
VIR_ERROR(_("failed to load module %s %s"), file, dlerror());
return handle;
}
static void *
virDriverLoadModuleFunc(void *handle,
const char *funcname)
{
void *regsym;
VIR_DEBUG("Lookup function '%s'", funcname);
if (!(regsym = dlsym(handle, funcname)))
VIR_ERROR(_("Missing module registration symbol %s"), funcname);
return regsym;
}
/**
* virDriverLoadModuleFull:
* @path: filename of module to load
* @regfunc: name of the function that registers the module
* @handle: Returns handle of the loaded library if not NULL
*
* Loads a loadable module named @path and calls the
* registration function @regfunc. If @handle is not NULL the handle is returned
* in the variable. Otherwise the handle is leaked so that the module stays
* loaded forever.
*
* The module is automatically looked up in the appropriate place (git or
* installed directory).
*
* Returns 0 on success, 1 if the module was not found and -1 on any error.
*/
int
virDriverLoadModuleFull(const char *path,
const char *regfunc,
void **handle)
{
void *rethandle = NULL;
int (*regsym)(void);
int ret = -1;
if (!(rethandle = virDriverLoadModuleFile(path))) {
ret = 1;
goto cleanup;
}
if (!(regsym = virDriverLoadModuleFunc(rethandle, regfunc)))
goto cleanup;
if ((*regsym)() < 0) {
VIR_ERROR(_("Failed module registration %s"), regfunc);
goto cleanup;
}
if (handle)
VIR_STEAL_PTR(*handle, rethandle);
else
rethandle = NULL;
ret = 0;
cleanup:
if (rethandle)
dlclose(rethandle);
return ret;
}
void *
virDriverLoadModule(const char *name)
{
char *modfile = NULL, *regfunc = NULL, *fixedname = NULL;
char *modfile = NULL;
char *fixedname = NULL;
char *regfunc = NULL;
char *tmp;
void *handle = NULL;
int (*regsym)(void);
VIR_DEBUG("Module load %s", name);
......@@ -61,19 +151,6 @@ virDriverLoadModule(const char *name)
"LIBVIRT_DRIVER_DIR")))
return NULL;
if (access(modfile, R_OK) < 0) {
VIR_INFO("Module %s not accessible", modfile);
goto cleanup;
}
virUpdateSelfLastChanged(modfile);
handle = dlopen(modfile, RTLD_NOW | RTLD_GLOBAL);
if (!handle) {
VIR_ERROR(_("failed to load module %s %s"), modfile, dlerror());
goto cleanup;
}
if (VIR_STRDUP_QUIET(fixedname, name) < 0) {
VIR_ERROR(_("out of memory"));
goto cleanup;
......@@ -88,29 +165,13 @@ virDriverLoadModule(const char *name)
if (virAsprintfQuiet(&regfunc, "%sRegister", fixedname) < 0)
goto cleanup;
regsym = dlsym(handle, regfunc);
if (!regsym) {
VIR_ERROR(_("Missing module registration symbol %s"), regfunc);
goto cleanup;
}
if ((*regsym)() < 0) {
VIR_ERROR(_("Failed module registration %s"), regfunc);
goto cleanup;
}
VIR_FREE(modfile);
VIR_FREE(regfunc);
VIR_FREE(fixedname);
return handle;
virDriverLoadModuleFull(modfile, regfunc, &handle);
cleanup:
VIR_FREE(modfile);
VIR_FREE(regfunc);
VIR_FREE(fixedname);
if (handle)
dlclose(handle);
return NULL;
VIR_FREE(regfunc);
return handle;
}
......
......@@ -100,5 +100,8 @@ int virSetSharedSecretDriver(virSecretDriverPtr driver) ATTRIBUTE_RETURN_CHECK;
int virSetSharedStorageDriver(virStorageDriverPtr driver) ATTRIBUTE_RETURN_CHECK;
void *virDriverLoadModule(const char *name);
int virDriverLoadModuleFull(const char *name,
const char *regfunc,
void **handle);
#endif /* __VIR_DRIVER_H__ */
......@@ -4,6 +4,7 @@
# driver.h
virDriverLoadModule;
virDriverLoadModuleFull;
# Let emacs know we want case-insensitive sorting
# Local Variables:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册