When libvirt starts up all storage pools default to the inactive state, even if the underlying storage is already active on the host. This introduces a new API into the internal storage backend drivers that checks whether a storage pool is already active. If the pool is active at libvirtd startup, the volume list will be immediately populated. * src/storage/storage_backend.h: New internal API for checking storage pool state * src/storage/storage_driver.c: Check whether a pool is active upon driver startup * src/storage/storage_backend_fs.c, src/storage/storage_backend_iscsi.c, src/storage/storage_backend_logical.c, src/storage/storage_backend_mpath.c, src/storage/storage_backend_scsi.c: Add checks for pool state --- src/storage/storage_backend.h | 3 ++ src/storage/storage_backend_fs.c | 29 +++++++++++++++++++++++++++- src/storage/storage_backend_iscsi.c | 34 +++++++++++++++++++++++++++++++++ src/storage/storage_backend_logical.c | 24 +++++++++++++++++++++++ src/storage/storage_backend_mpath.c | 20 +++++++++++++++++++ src/storage/storage_backend_scsi.c | 25 ++++++++++++++++++++++++ src/storage/storage_driver.c | 31 ++++++++++++++++++++++------- 7 files changed, 157 insertions(+), 9 deletions(-) diff --git a/src/storage/storage_backend.h b/src/storage/storage_backend.h index 1165a45..6f395c7 100644 --- a/src/storage/storage_backend.h +++ b/src/storage/storage_backend.h @@ -25,10 +25,12 @@ # define __VIR_STORAGE_BACKEND_H__ # include <stdint.h> +# include <stdbool.h> # include "internal.h" # include "storage_conf.h" typedef char * (*virStorageBackendFindPoolSources)(virConnectPtr conn, const char *srcSpec, unsigned int flags); +typedef int (*virStorageBackendCheckPool)(virConnectPtr conn, virStoragePoolObjPtr pool, bool *active); typedef int (*virStorageBackendStartPool)(virConnectPtr conn, virStoragePoolObjPtr pool); typedef int (*virStorageBackendBuildPool)(virConnectPtr conn, virStoragePoolObjPtr pool, unsigned int flags); typedef int (*virStorageBackendRefreshPool)(virConnectPtr conn, virStoragePoolObjPtr pool); @@ -65,6 +67,7 @@ struct _virStorageBackend { int type; virStorageBackendFindPoolSources findPoolSources; + virStorageBackendCheckPool checkPool; virStorageBackendStartPool startPool; virStorageBackendBuildPool buildPool; virStorageBackendRefreshPool refreshPool; diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c index c2bc6c4..8cdf7c0 100644 --- a/src/storage/storage_backend_fs.c +++ b/src/storage/storage_backend_fs.c @@ -479,6 +479,31 @@ virStorageBackendFileSystemUnmount(virStoragePoolObjPtr pool) { #endif /* WITH_STORAGE_FS */ +static int +virStorageBackendFileSystemCheck(virConnectPtr conn ATTRIBUTE_UNUSED, + virStoragePoolObjPtr pool, + bool *isActive) +{ + *isActive = false; + if (pool->def->type == VIR_STORAGE_POOL_DIR) { + struct stat sb; + if (stat(pool->def->target.path, &sb) == 0) + *isActive = true; +#if WITH_STORAGE_FS + } else { + int ret; + if ((ret = virStorageBackendFileSystemIsMounted(pool)) != 0) { + if (ret < 0) + return -1; + *isActive = true; + } +#endif /* WITH_STORAGE_FS */ + } + + return 0; +} + +#if WITH_STORAGE_FS /** * @conn connection to report errors against * @pool storage pool to start @@ -489,7 +514,6 @@ virStorageBackendFileSystemUnmount(virStoragePoolObjPtr pool) { * * Returns 0 on success, -1 on error */ -#if WITH_STORAGE_FS static int virStorageBackendFileSystemStart(virConnectPtr conn ATTRIBUTE_UNUSED, virStoragePoolObjPtr pool) @@ -937,6 +961,7 @@ virStorageBackend virStorageBackendDirectory = { .type = VIR_STORAGE_POOL_DIR, .buildPool = virStorageBackendFileSystemBuild, + .checkPool = virStorageBackendFileSystemCheck, .refreshPool = virStorageBackendFileSystemRefresh, .deletePool = virStorageBackendFileSystemDelete, .buildVol = virStorageBackendFileSystemVolBuild, @@ -951,6 +976,7 @@ virStorageBackend virStorageBackendFileSystem = { .type = VIR_STORAGE_POOL_FS, .buildPool = virStorageBackendFileSystemBuild, + .checkPool = virStorageBackendFileSystemCheck, .startPool = virStorageBackendFileSystemStart, .refreshPool = virStorageBackendFileSystemRefresh, .stopPool = virStorageBackendFileSystemStop, @@ -965,6 +991,7 @@ virStorageBackend virStorageBackendNetFileSystem = { .type = VIR_STORAGE_POOL_NETFS, .buildPool = virStorageBackendFileSystemBuild, + .checkPool = virStorageBackendFileSystemCheck, .startPool = virStorageBackendFileSystemStart, .findPoolSources = virStorageBackendFileSystemNetFindPoolSources, .refreshPool = virStorageBackendFileSystemRefresh, diff --git a/src/storage/storage_backend_iscsi.c b/src/storage/storage_backend_iscsi.c index a67a428..2dcf714 100644 --- a/src/storage/storage_backend_iscsi.c +++ b/src/storage/storage_backend_iscsi.c @@ -639,6 +639,39 @@ cleanup: } static int +virStorageBackendISCSICheckPool(virConnectPtr conn ATTRIBUTE_UNUSED, + virStoragePoolObjPtr pool, + bool *isActive) +{ + char *session = NULL; + int ret = -1; + + *isActive = false; + + if (pool->def->source.host.name == NULL) { + virStorageReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("missing source host")); + return -1; + } + + if (pool->def->source.ndevice != 1 || + pool->def->source.devices[0].path == NULL) { + virStorageReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("missing source device")); + return -1; + } + + if ((session = virStorageBackendISCSISession(pool, 1)) != NULL) { + *isActive = true; + VIR_FREE(session); + } + ret = 0; + + return ret; +} + + +static int virStorageBackendISCSIStartPool(virConnectPtr conn ATTRIBUTE_UNUSED, virStoragePoolObjPtr pool) { @@ -735,6 +768,7 @@ cleanup: virStorageBackend virStorageBackendISCSI = { .type = VIR_STORAGE_POOL_ISCSI, + .checkPool = virStorageBackendISCSICheckPool, .startPool = virStorageBackendISCSIStartPool, .refreshPool = virStorageBackendISCSIRefreshPool, .stopPool = virStorageBackendISCSIStopPool, diff --git a/src/storage/storage_backend_logical.c b/src/storage/storage_backend_logical.c index e6c6938..c5bfda1 100644 --- a/src/storage/storage_backend_logical.c +++ b/src/storage/storage_backend_logical.c @@ -24,6 +24,7 @@ #include <config.h> #include <sys/wait.h> +#include <sys/types.h> #include <sys/stat.h> #include <stdio.h> #include <regex.h> @@ -361,6 +362,28 @@ virStorageBackendLogicalFindPoolSources(virConnectPtr conn ATTRIBUTE_UNUSED, static int +virStorageBackendLogicalCheckPool(virConnectPtr conn ATTRIBUTE_UNUSED, + virStoragePoolObjPtr pool, + bool *isActive) +{ + char *path; + + *isActive = false; + if (virAsprintf(&path, "/dev/%s", pool->def->source.name) < 0) { + virReportOOMError(); + return -1; + } + + struct stat sb; + if (stat(path, &sb) == 0) + *isActive = true; + + VIR_FREE(path); + + return 0; +} + +static int virStorageBackendLogicalStartPool(virConnectPtr conn ATTRIBUTE_UNUSED, virStoragePoolObjPtr pool) { @@ -684,6 +707,7 @@ virStorageBackend virStorageBackendLogical = { .type = VIR_STORAGE_POOL_LOGICAL, .findPoolSources = virStorageBackendLogicalFindPoolSources, + .checkPool = virStorageBackendLogicalCheckPool, .startPool = virStorageBackendLogicalStartPool, .buildPool = virStorageBackendLogicalBuildPool, .refreshPool = virStorageBackendLogicalRefreshPool, diff --git a/src/storage/storage_backend_mpath.c b/src/storage/storage_backend_mpath.c index 79ad4b8..d55a1c4 100644 --- a/src/storage/storage_backend_mpath.c +++ b/src/storage/storage_backend_mpath.c @@ -27,6 +27,8 @@ #include <stdio.h> #include <dirent.h> #include <fcntl.h> +#include <sys/stat.h> +#include <sys/types.h> #include <libdevmapper.h> @@ -291,6 +293,23 @@ out: return retval; } +static int +virStorageBackendMpathCheckPool(virConnectPtr conn ATTRIBUTE_UNUSED, + virStoragePoolObjPtr pool ATTRIBUTE_UNUSED, + bool *isActive) +{ + const char *path = "/dev/mpath"; + + *isActive = false; + + struct stat sb; + if (stat(path, &sb) == 0) + *isActive = true; + + return 0; +} + + static int virStorageBackendMpathRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED, @@ -313,5 +332,6 @@ virStorageBackendMpathRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED, virStorageBackend virStorageBackendMpath = { .type = VIR_STORAGE_POOL_MPATH, + .checkPool = virStorageBackendMpathCheckPool, .refreshPool = virStorageBackendMpathRefreshPool, }; diff --git a/src/storage/storage_backend_scsi.c b/src/storage/storage_backend_scsi.c index 28d6ac6..0d6b1ac 100644 --- a/src/storage/storage_backend_scsi.c +++ b/src/storage/storage_backend_scsi.c @@ -27,6 +27,9 @@ #include <stdio.h> #include <dirent.h> #include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/wait.h> #include "virterror_internal.h" #include "storage_backend_scsi.h" @@ -587,6 +590,27 @@ out: return retval; } +static int +virStorageBackendSCSICheckPool(virConnectPtr conn ATTRIBUTE_UNUSED, + virStoragePoolObjPtr pool, + bool *isActive) +{ + char *path; + + *isActive = false; + if (virAsprintf(&path, "/sys/class/scsi_host/%s", pool->def->source.adapter) < 0) { + virReportOOMError(); + return -1; + } + + struct stat sb; + if (stat(path, &sb) == 0) + *isActive = true; + + VIR_FREE(path); + + return 0; +} static int virStorageBackendSCSIRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED, @@ -621,5 +645,6 @@ out: virStorageBackend virStorageBackendSCSI = { .type = VIR_STORAGE_POOL_SCSI, + .checkPool = virStorageBackendSCSICheckPool, .refreshPool = virStorageBackendSCSIRefreshPool, }; diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c index f6672d9..9912429 100644 --- a/src/storage/storage_driver.c +++ b/src/storage/storage_driver.c @@ -68,17 +68,29 @@ storageDriverAutostart(virStorageDriverStatePtr driver) { for (i = 0 ; i < driver->pools.count ; i++) { virStoragePoolObjPtr pool = driver->pools.objs[i]; + virStorageBackendPtr backend; + bool started = false; virStoragePoolObjLock(pool); - if (pool->autostart && - !virStoragePoolObjIsActive(pool)) { - virStorageBackendPtr backend; - if ((backend = virStorageBackendForType(pool->def->type)) == NULL) { - VIR_ERROR(_("Missing backend %d"), pool->def->type); - virStoragePoolObjUnlock(pool); - continue; - } + if ((backend = virStorageBackendForType(pool->def->type)) == NULL) { + VIR_ERROR(_("Missing backend %d"), pool->def->type); + virStoragePoolObjUnlock(pool); + continue; + } + if (backend->checkPool && + backend->checkPool(NULL, pool, &started) < 0) { + virErrorPtr err = virGetLastError(); + VIR_ERROR(_("Failed to initialize storage pool '%s': %s"), + pool->def->name, err ? err->message : + "no error message found"); + virStoragePoolObjUnlock(pool); + continue; + } + + if (!started && + pool->autostart && + !virStoragePoolObjIsActive(pool)) { if (backend->startPool && backend->startPool(NULL, pool) < 0) { virErrorPtr err = virGetLastError(); @@ -88,7 +100,10 @@ storageDriverAutostart(virStorageDriverStatePtr driver) { virStoragePoolObjUnlock(pool); continue; } + started = true; + } + if (started) { if (backend->refreshPool(NULL, pool) < 0) { virErrorPtr err = virGetLastError(); if (backend->stopPool) -- 1.7.2.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list