aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel P. Berrange <berrange@redhat.com>2010-11-11 20:09:20 +0000
committerDaniel P. Berrange <berrange@redhat.com>2010-11-23 15:00:35 +0000
commit1b7e0b1a9c3e94e77b2d9b09d6002167f02ad25e (patch)
treed81ff67f1a2cb6aaf2d0a90cfb3bd37a600b415e
parentRemove bogus port handling code in virsh (diff)
downloadlibvirt-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.h3
-rw-r--r--src/storage/storage_backend_fs.c28
-rw-r--r--src/storage/storage_backend_iscsi.c34
-rw-r--r--src/storage/storage_backend_logical.c22
-rw-r--r--src/storage/storage_backend_mpath.c17
-rw-r--r--src/storage/storage_backend_scsi.c21
-rw-r--r--src/storage/storage_driver.c35
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;
}