driver: add option to make missing drivers a fatal problem

Currently the driver module loading code does not report an error if the
driver module is physically missing on disk. This is useful for distro
packaging optional pieces. When the daemons are split up into one daemon
per driver, we will expect module loading to always succeed. If a driver
is not desired, the entire daemon should not be installed.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
Daniel P. Berrangé 2018-04-19 16:50:56 +01:00
parent 078d168d15
commit 8a062f5fe3
6 changed files with 34 additions and 24 deletions

View File

@ -103,15 +103,22 @@ virDriverLoadModuleFunc(void *handle,
*/
int
virDriverLoadModuleFull(const char *path,
const char *regfunc)
const char *regfunc,
bool required)
{
void *rethandle = NULL;
int (*regsym)(void);
int ret = -1;
if (!virFileExists(path)) {
VIR_INFO("Module '%s' does not exists", path);
return 1;
if (required) {
virReportSystemError(errno,
_("Failed to find module '%s'"), path);
return -1;
} else {
VIR_INFO("Module '%s' does not exist", path);
return 1;
}
}
if (!(rethandle = virDriverLoadModuleFile(path)))
@ -144,21 +151,29 @@ virDriverLoadModuleFull(const char *path,
#else /* ! HAVE_DLFCN_H */
int
virDriverLoadModuleFull(const char *path ATTRIBUTE_UNUSED,
const char *regfunc ATTRIBUTE_UNUSED)
const char *regfunc ATTRIBUTE_UNUSED,
bool required)
{
VIR_DEBUG("dlopen not available on this platform");
/* Since we have no dlopen(), but definition we have no
* loadable modules on disk, so we can resaonably
* return '1' instead of an error.
*/
return 1;
if (required) {
virReportSystemError(ENOSYS,
_("Failed to find module '%s': %s"), path);
return -1;
} else {
/* Since we have no dlopen(), but definition we have no
* loadable modules on disk, so we can resaonably
* return '1' instead of an error.
*/
return 1;
}
}
#endif /* ! HAVE_DLFCN_H */
int
virDriverLoadModule(const char *name,
const char *regfunc)
const char *regfunc,
bool required)
{
char *modfile = NULL;
int ret;
@ -173,7 +188,7 @@ virDriverLoadModule(const char *name,
"LIBVIRT_DRIVER_DIR")))
return -1;
ret = virDriverLoadModuleFull(modfile, regfunc);
ret = virDriverLoadModuleFull(modfile, regfunc, required);
VIR_FREE(modfile);

View File

@ -108,9 +108,11 @@ int virSetSharedSecretDriver(virSecretDriverPtr driver) ATTRIBUTE_RETURN_CHECK;
int virSetSharedStorageDriver(virStorageDriverPtr driver) ATTRIBUTE_RETURN_CHECK;
int virDriverLoadModule(const char *name,
const char *regfunc);
const char *regfunc,
bool required);
int virDriverLoadModuleFull(const char *path,
const char *regfunc);
const char *regfunc,
bool required);
virConnectPtr virGetConnectInterface(void);
virConnectPtr virGetConnectNetwork(void);

View File

@ -295,7 +295,7 @@ static int daemonErrorLogFilter(virErrorPtr err, int priority)
#define VIR_DAEMON_LOAD_MODULE(func, module) \
virDriverLoadModule(module, #func)
virDriverLoadModule(module, #func, false)
static void daemonInitialize(void)
{
/*

View File

@ -964,7 +964,7 @@ get_files(vahControl * ctl)
/* load the storage driver so that backing store can be accessed */
#ifdef WITH_STORAGE
virDriverLoadModule("storage", "storageRegister");
virDriverLoadModule("storage", "storageRegister", false);
#endif
for (i = 0; i < ctl->def->ndisks; i++) {

View File

@ -97,14 +97,7 @@ virStorageDriverLoadBackendModule(const char *name,
"LIBVIRT_STORAGE_BACKEND_DIR")))
return -1;
if ((ret = virDriverLoadModuleFull(modfile, regfunc)) != 0) {
if (forceload) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("failed to load storage backend module '%s'"),
name);
ret = -1;
}
}
ret = virDriverLoadModuleFull(modfile, regfunc, forceload);
VIR_FREE(modfile);

View File

@ -41,7 +41,7 @@ static int testDriverModule(const void *args)
const struct testDriverModuleData *data = args;
/* coverity[leaked_storage] */
if (virDriverLoadModule(data->module, data->regfunc) != 0)
if (virDriverLoadModule(data->module, data->regfunc, true) != 0)
return -1;
return 0;