[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH 08/11] 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
---
 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


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]