diff options
author | Daniel P. Berrange <berrange@redhat.com> | 2010-11-11 20:09:20 +0000 |
---|---|---|
committer | Daniel P. Berrange <berrange@redhat.com> | 2010-11-23 15:00:35 +0000 |
commit | 1b7e0b1a9c3e94e77b2d9b09d6002167f02ad25e (patch) | |
tree | d81ff67f1a2cb6aaf2d0a90cfb3bd37a600b415e | |
parent | Remove bogus port handling code in virsh (diff) | |
download | libvirt-1b7e0b1a9c3e94e77b2d9b09d6002167f02ad25e.tar.gz libvirt-1b7e0b1a9c3e94e77b2d9b09d6002167f02ad25e.tar.bz2 libvirt-1b7e0b1a9c3e94e77b2d9b09d6002167f02ad25e.zip |
Check whether pools are already active upon libvirtd startup
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
-rw-r--r-- | src/storage/storage_backend.h | 3 | ||||
-rw-r--r-- | src/storage/storage_backend_fs.c | 28 | ||||
-rw-r--r-- | src/storage/storage_backend_iscsi.c | 34 | ||||
-rw-r--r-- | src/storage/storage_backend_logical.c | 22 | ||||
-rw-r--r-- | src/storage/storage_backend_mpath.c | 17 | ||||
-rw-r--r-- | src/storage/storage_backend_scsi.c | 21 | ||||
-rw-r--r-- | src/storage/storage_driver.c | 35 |
7 files changed, 149 insertions, 11 deletions
diff --git a/src/storage/storage_backend.h b/src/storage/storage_backend.h index 1165a45f3..6f395c767 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 85bd4ab4d..d916d2d19 100644 --- a/src/storage/storage_backend_fs.c +++ b/src/storage/storage_backend_fs.c @@ -479,6 +479,30 @@ 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) { + if (access(pool->def->target.path, F_OK) == 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 +513,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 +960,7 @@ virStorageBackend virStorageBackendDirectory = { .type = VIR_STORAGE_POOL_DIR, .buildPool = virStorageBackendFileSystemBuild, + .checkPool = virStorageBackendFileSystemCheck, .refreshPool = virStorageBackendFileSystemRefresh, .deletePool = virStorageBackendFileSystemDelete, .buildVol = virStorageBackendFileSystemVolBuild, @@ -951,6 +975,7 @@ virStorageBackend virStorageBackendFileSystem = { .type = VIR_STORAGE_POOL_FS, .buildPool = virStorageBackendFileSystemBuild, + .checkPool = virStorageBackendFileSystemCheck, .startPool = virStorageBackendFileSystemStart, .refreshPool = virStorageBackendFileSystemRefresh, .stopPool = virStorageBackendFileSystemStop, @@ -965,6 +990,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 b376de288..6eff5f5ba 100644 --- a/src/storage/storage_backend_iscsi.c +++ b/src/storage/storage_backend_iscsi.c @@ -634,6 +634,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) { @@ -730,6 +763,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 e6c69385f..203fe5d87 100644 --- a/src/storage/storage_backend_logical.c +++ b/src/storage/storage_backend_logical.c @@ -361,6 +361,27 @@ 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; + } + + if (access(path, F_OK) == 0) + *isActive = true; + + VIR_FREE(path); + + return 0; +} + +static int virStorageBackendLogicalStartPool(virConnectPtr conn ATTRIBUTE_UNUSED, virStoragePoolObjPtr pool) { @@ -684,6 +705,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 79ad4b8e1..be4db7878 100644 --- a/src/storage/storage_backend_mpath.c +++ b/src/storage/storage_backend_mpath.c @@ -291,6 +291,22 @@ out: return retval; } +static int +virStorageBackendMpathCheckPool(virConnectPtr conn ATTRIBUTE_UNUSED, + virStoragePoolObjPtr pool ATTRIBUTE_UNUSED, + bool *isActive) +{ + const char *path = "/dev/mpath"; + + *isActive = false; + + if (access(path, F_OK) == 0) + *isActive = true; + + return 0; +} + + static int virStorageBackendMpathRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED, @@ -313,5 +329,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 d0af7de69..8fa2f5246 100644 --- a/src/storage/storage_backend_scsi.c +++ b/src/storage/storage_backend_scsi.c @@ -587,6 +587,26 @@ 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; + } + + if (access(path, F_OK) == 0) + *isActive = true; + + VIR_FREE(path); + + return 0; +} static int virStorageBackendSCSIRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED, @@ -621,5 +641,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 6df706b32..6a4ad6d78 100644 --- a/src/storage/storage_driver.c +++ b/src/storage/storage_driver.c @@ -69,34 +69,49 @@ 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(); VIR_ERROR(_("Failed to autostart storage pool '%s': %s"), pool->def->name, err ? err->message : - "no error message found"); + _("no error message found")); virStoragePoolObjUnlock(pool); continue; } + started = true; + } + if (started) { if (backend->refreshPool(NULL, pool) < 0) { virErrorPtr err = virGetLastError(); if (backend->stopPool) backend->stopPool(NULL, pool); VIR_ERROR(_("Failed to autostart storage pool '%s': %s"), pool->def->name, err ? err->message : - "no error message found"); + _("no error message found")); virStoragePoolObjUnlock(pool); continue; } |