]> xenbits.xensource.com Git - libvirt.git/commitdiff
storage: Introduce virStoragePoolObjListForEach
authorJohn Ferlan <jferlan@redhat.com>
Sun, 8 Oct 2017 12:14:56 +0000 (08:14 -0400)
committerJohn Ferlan <jferlan@redhat.com>
Fri, 24 Nov 2017 12:26:06 +0000 (07:26 -0500)
Create an API to walk the pools->objs[] list in order to perform a
callback function for each element of the objs array that doesn't care
about whether the action succeeds or fails as the desire is to run the
code over every element in the array rather than fail as soon as or if
one fails.

src/conf/virstorageobj.c
src/conf/virstorageobj.h
src/libvirt_private.syms
src/storage/storage_driver.c

index 2ca8453139267c9079b68a10f9c73d469fe4f987..3cae34d97086df32e9d0e8a37bb87128c46010f9 100644 (file)
@@ -230,6 +230,35 @@ virStoragePoolObjListFree(virStoragePoolObjListPtr pools)
 }
 
 
+/**
+ * virStoragePoolObjListForEach
+ * @pools: Pointer to pools object
+ * @iter: Callback iteration helper
+ * @opaque: Opaque data to use as argument to helper
+ *
+ * For each object in @pools, call the @iter helper using @opaque as
+ * an argument.  This function doesn't care whether the @iter fails or
+ * not as it's being used for Autostart and UpdateAllState callers
+ * that want to iterate over all the @pools objects not stopping if
+ * one happens to fail.
+ */
+void
+virStoragePoolObjListForEach(virStoragePoolObjListPtr pools,
+                             virStoragePoolObjListIterator iter,
+                             const void *opaque)
+{
+    size_t i;
+    virStoragePoolObjPtr obj;
+
+    for (i = 0; i < pools->count; i++) {
+        obj = pools->objs[i];
+        virStoragePoolObjLock(obj);
+        iter(obj, opaque);
+        virStoragePoolObjUnlock(obj);
+    }
+}
+
+
 void
 virStoragePoolObjRemove(virStoragePoolObjListPtr pools,
                         virStoragePoolObjPtr obj)
index a4d7186d12e21c4446d88832cbe821de534b5e09..c84877694e66a412dcfd83f99926341597ae0ff9 100644 (file)
@@ -226,6 +226,15 @@ virStoragePoolObjFree(virStoragePoolObjPtr obj);
 void
 virStoragePoolObjListFree(virStoragePoolObjListPtr pools);
 
+typedef void
+(*virStoragePoolObjListIterator)(virStoragePoolObjPtr obj,
+                                 const void *opaque);
+
+void
+virStoragePoolObjListForEach(virStoragePoolObjListPtr pools,
+                             virStoragePoolObjListIterator iter,
+                             const void *opaque);
+
 void
 virStoragePoolObjRemove(virStoragePoolObjListPtr pools,
                         virStoragePoolObjPtr obj);
index ab1f1f5e60a6105f57e20c7fb9e144c27a5febae..9fb302b693d497585ef5c567dfcacd8acd0caafa 100644 (file)
@@ -1090,6 +1090,7 @@ virStoragePoolObjIsActive;
 virStoragePoolObjIsAutostart;
 virStoragePoolObjIsDuplicate;
 virStoragePoolObjListExport;
+virStoragePoolObjListForEach;
 virStoragePoolObjListFree;
 virStoragePoolObjLoadAllConfigs;
 virStoragePoolObjLoadAllState;
index 7cc3c518b4b4c4b50efc928f8a766b7c1bd5dab2..454b1b0df042ec4599e15ac0b8ed686fe8eec11b 100644 (file)
@@ -102,7 +102,8 @@ virStoragePoolUpdateInactive(virStoragePoolObjPtr *objptr)
 
 
 static void
-storagePoolUpdateState(virStoragePoolObjPtr obj)
+storagePoolUpdateStateCallback(virStoragePoolObjPtr obj,
+                               const void *opaque ATTRIBUTE_UNUSED)
 {
     virStoragePoolDefPtr def = virStoragePoolObjGetDef(obj);
     bool active = false;
@@ -157,24 +158,66 @@ storagePoolUpdateState(virStoragePoolObjPtr obj)
     return;
 }
 
+
 static void
 storagePoolUpdateAllState(void)
 {
-    size_t i;
+    virStoragePoolObjListForEach(&driver->pools,
+                                 storagePoolUpdateStateCallback,
+                                 NULL);
+}
 
-    for (i = 0; i < driver->pools.count; i++) {
-        virStoragePoolObjPtr obj = driver->pools.objs[i];
 
-        virStoragePoolObjLock(obj);
-        storagePoolUpdateState(obj);
-        virStoragePoolObjEndAPI(&obj);
+static void
+storageDriverAutostartCallback(virStoragePoolObjPtr obj,
+                               const void *opaque)
+{
+    virStoragePoolDefPtr def = virStoragePoolObjGetDef(obj);
+    virConnectPtr conn = (virConnectPtr) opaque;
+    virStorageBackendPtr backend;
+    bool started = false;
+
+    if (!(backend = virStorageBackendForType(def->type)))
+        return;
+
+    if (virStoragePoolObjIsAutostart(obj) &&
+        !virStoragePoolObjIsActive(obj)) {
+        if (backend->startPool &&
+            backend->startPool(conn, obj) < 0) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("Failed to autostart storage pool '%s': %s"),
+                           def->name, virGetLastErrorMessage());
+            return;
+        }
+        started = true;
+    }
+
+    if (started) {
+        char *stateFile;
+
+        virStoragePoolObjClearVols(obj);
+        stateFile = virFileBuildPath(driver->stateDir, def->name, ".xml");
+        if (!stateFile ||
+            virStoragePoolSaveState(stateFile, def) < 0 ||
+            backend->refreshPool(conn, obj) < 0) {
+            if (stateFile)
+                unlink(stateFile);
+            if (backend->stopPool)
+                backend->stopPool(conn, obj);
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("Failed to autostart storage pool '%s': %s"),
+                           def->name, virGetLastErrorMessage());
+        } else {
+            virStoragePoolObjSetActive(obj, true);
+        }
+        VIR_FREE(stateFile);
     }
 }
 
+
 static void
 storageDriverAutostart(void)
 {
-    size_t i;
     virConnectPtr conn = NULL;
 
     /* XXX Remove hardcoding of QEMU URI */
@@ -184,53 +227,9 @@ storageDriverAutostart(void)
         conn = virConnectOpen("qemu:///session");
     /* Ignoring NULL conn - let backends decide */
 
-    for (i = 0; i < driver->pools.count; i++) {
-        virStoragePoolObjPtr obj = driver->pools.objs[i];
-        virStoragePoolDefPtr def = virStoragePoolObjGetDef(obj);
-        virStorageBackendPtr backend;
-        bool started = false;
-
-        virStoragePoolObjLock(obj);
-        if ((backend = virStorageBackendForType(def->type)) == NULL) {
-            virStoragePoolObjEndAPI(&obj);
-            continue;
-        }
-
-        if (virStoragePoolObjIsAutostart(obj) &&
-            !virStoragePoolObjIsActive(obj)) {
-            if (backend->startPool &&
-                backend->startPool(conn, obj) < 0) {
-                virReportError(VIR_ERR_INTERNAL_ERROR,
-                               _("Failed to autostart storage pool '%s': %s"),
-                               def->name, virGetLastErrorMessage());
-                virStoragePoolObjEndAPI(&obj);
-                continue;
-            }
-            started = true;
-        }
-
-        if (started) {
-            char *stateFile;
-
-            virStoragePoolObjClearVols(obj);
-            stateFile = virFileBuildPath(driver->stateDir, def->name, ".xml");
-            if (!stateFile ||
-                virStoragePoolSaveState(stateFile, def) < 0 ||
-                backend->refreshPool(conn, obj) < 0) {
-                if (stateFile)
-                    unlink(stateFile);
-                if (backend->stopPool)
-                    backend->stopPool(conn, obj);
-                virReportError(VIR_ERR_INTERNAL_ERROR,
-                               _("Failed to autostart storage pool '%s': %s"),
-                               def->name, virGetLastErrorMessage());
-            } else {
-                virStoragePoolObjSetActive(obj, true);
-            }
-            VIR_FREE(stateFile);
-        }
-        virStoragePoolObjEndAPI(&obj);
-    }
+    virStoragePoolObjListForEach(&driver->pools,
+                                 storageDriverAutostartCallback,
+                                 conn);
 
     virObjectUnref(conn);
 }