]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
storage: Introduce APIs to search/scan storage pool volumes list
authorJohn Ferlan <jferlan@redhat.com>
Tue, 9 May 2017 12:18:33 +0000 (08:18 -0400)
committerJohn Ferlan <jferlan@redhat.com>
Tue, 19 Sep 2017 12:28:50 +0000 (08:28 -0400)
Introduce virStoragePoolObjForEachVolume to scan each volume
calling the passed callback function until all volumes have been
processed in the storage pool volume list, unless the callback
function returns an error.

Introduce virStoragePoolObjSearchVolume to search each volume
calling the passed callback function until it returns true
indicating that the desired volume was found.

Signed-off-by: John Ferlan <jferlan@redhat.com>
src/conf/virstorageobj.c
src/conf/virstorageobj.h
src/libvirt_private.syms
src/storage/storage_backend_disk.c

index 912c27a62d90910b03af6fe3ce077cc677224ec8..8ee40e22967414b4bd934d568645f1e3c7a84eb2 100644 (file)
@@ -319,6 +319,38 @@ virStoragePoolObjGetVolumesCount(virStoragePoolObjPtr obj)
 }
 
 
+int
+virStoragePoolObjForEachVolume(virStoragePoolObjPtr obj,
+                               virStorageVolObjListIterator iter,
+                               const void *opaque)
+{
+    size_t i;
+
+    for (i = 0; i < obj->volumes.count; i++) {
+        if (iter(obj->volumes.objs[i], opaque) < 0)
+            return -1;
+    }
+
+    return 0;
+}
+
+
+virStorageVolDefPtr
+virStoragePoolObjSearchVolume(virStoragePoolObjPtr obj,
+                              virStorageVolObjListSearcher iter,
+                              const void *opaque)
+{
+    size_t i;
+
+    for (i = 0; i < obj->volumes.count; i++) {
+        if (iter(obj->volumes.objs[i], opaque))
+            return obj->volumes.objs[i];
+    }
+
+    return NULL;
+}
+
+
 virStorageVolDefPtr
 virStorageVolDefFindByKey(virStoragePoolObjPtr obj,
                           const char *key)
index d1a1247adeceecb0343355830d0744ddd8dface7..c2f3f23bfb388db3acfc4cb72c6b3e9eb16b101b 100644 (file)
@@ -147,6 +147,24 @@ virStoragePoolObjRemoveVol(virStoragePoolObjPtr obj,
 size_t
 virStoragePoolObjGetVolumesCount(virStoragePoolObjPtr obj);
 
+typedef int
+(*virStorageVolObjListIterator)(virStorageVolDefPtr voldef,
+                                const void *opaque);
+
+int
+virStoragePoolObjForEachVolume(virStoragePoolObjPtr obj,
+                               virStorageVolObjListIterator iter,
+                               const void *opaque);
+
+typedef bool
+(*virStorageVolObjListSearcher)(virStorageVolDefPtr voldef,
+                                const void *opaque);
+
+virStorageVolDefPtr
+virStoragePoolObjSearchVolume(virStoragePoolObjPtr obj,
+                              virStorageVolObjListSearcher iter,
+                              const void *opaque);
+
 virStorageVolDefPtr
 virStorageVolDefFindByKey(virStoragePoolObjPtr obj,
                           const char *key);
index 9432d23af57de8e13cdd379c3db35810c636e1a9..5b1bc5e4fe91cd30f4d25f95a39339e4e152b15f 100644 (file)
@@ -1061,6 +1061,7 @@ virStoragePoolObjDefUseNewDef;
 virStoragePoolObjDeleteDef;
 virStoragePoolObjFindByName;
 virStoragePoolObjFindByUUID;
+virStoragePoolObjForEachVolume;
 virStoragePoolObjGetAsyncjobs;
 virStoragePoolObjGetAutostartLink;
 virStoragePoolObjGetConfigFile;
@@ -1083,6 +1084,7 @@ virStoragePoolObjNumOfVolumes;
 virStoragePoolObjRemove;
 virStoragePoolObjRemoveVol;
 virStoragePoolObjSaveDef;
+virStoragePoolObjSearchVolume;
 virStoragePoolObjSetActive;
 virStoragePoolObjSetAutostart;
 virStoragePoolObjSetConfigFile;
index aad0272d86b2f45ba9c2df10ab6db62cd706eb6a..a0f94512e3a842e30ac17a03d688159d56ea8cf7 100644 (file)
@@ -43,6 +43,17 @@ VIR_LOG_INIT("storage.storage_backend_disk");
 
 #define SECTOR_SIZE 512
 
+static bool
+virStorageVolPartFindExtended(virStorageVolDefPtr def,
+                              const void *opaque ATTRIBUTE_UNUSED)
+{
+    if (def->source.partType == VIR_STORAGE_VOL_DISK_TYPE_EXTENDED)
+        return true;
+
+    return false;
+}
+
+
 static int
 virStorageBackendDiskMakeDataVol(virStoragePoolObjPtr pool,
                                  char **const groups,
@@ -191,16 +202,13 @@ virStorageBackendDiskMakeDataVol(virStoragePoolObjPtr pool,
 
     /* Find the extended partition and increase the allocation value */
     if (vol->source.partType == VIR_STORAGE_VOL_DISK_TYPE_LOGICAL) {
-        size_t i;
+        virStorageVolDefPtr voldef;
 
-        for (i = 0; i < pool->volumes.count; i++) {
-            if (pool->volumes.objs[i]->source.partType ==
-                VIR_STORAGE_VOL_DISK_TYPE_EXTENDED) {
-                pool->volumes.objs[i]->target.allocation +=
-                    vol->target.allocation;
-                break;
-            }
-        }
+        voldef = virStoragePoolObjSearchVolume(pool,
+                                               virStorageVolPartFindExtended,
+                                               NULL);
+        if (voldef)
+            voldef->target.allocation += vol->target.allocation;
     }
 
     if (STRNEQ(groups[2], "metadata"))
@@ -523,6 +531,25 @@ virStorageBackendDiskBuildPool(virConnectPtr conn ATTRIBUTE_UNUSED,
     return ret;
 }
 
+
+struct virStorageVolNumData {
+    int count;
+};
+
+static int
+virStorageVolNumOfPartTypes(virStorageVolDefPtr def,
+                            const void *opaque)
+{
+    struct virStorageVolNumData *data = (struct virStorageVolNumData *)opaque;
+
+    if (def->source.partType == VIR_STORAGE_VOL_DISK_TYPE_PRIMARY ||
+        def->source.partType == VIR_STORAGE_VOL_DISK_TYPE_EXTENDED)
+        data->count++;
+
+    return 0;
+}
+
+
 /**
  * Decides what kind of partition type that should be created.
  * Important when the partition table is of msdos type
@@ -530,19 +557,16 @@ virStorageBackendDiskBuildPool(virConnectPtr conn ATTRIBUTE_UNUSED,
 static int
 virStorageBackendDiskPartTypeToCreate(virStoragePoolObjPtr pool)
 {
+    struct virStorageVolNumData data = { .count = 0 };
+
     if (pool->def->source.format == VIR_STORAGE_POOL_DISK_DOS) {
         /* count primary and extended partitions,
            can't be more than 3 to create a new primary partition */
-        size_t i;
-        int count = 0;
-        for (i = 0; i < pool->volumes.count; i++) {
-            int partType = pool->volumes.objs[i]->source.partType;
-            if (partType == VIR_STORAGE_VOL_DISK_TYPE_PRIMARY ||
-                partType == VIR_STORAGE_VOL_DISK_TYPE_EXTENDED)
-                count++;
+        if (virStoragePoolObjForEachVolume(pool, virStorageVolNumOfPartTypes,
+                                           &data) == 0) {
+            if (data.count >= 4)
+                return VIR_STORAGE_VOL_DISK_TYPE_LOGICAL;
         }
-        if (count >= 4)
-            return VIR_STORAGE_VOL_DISK_TYPE_LOGICAL;
     }
 
     /* for all other cases, all partitions are primary */
@@ -554,7 +578,6 @@ virStorageBackendDiskPartFormat(virStoragePoolObjPtr pool,
                                 virStorageVolDefPtr vol,
                                 char** partFormat)
 {
-    size_t i;
     if (pool->def->source.format == VIR_STORAGE_POOL_DISK_DOS) {
         const char *partedFormat;
         partedFormat = virStoragePartedFsTypeToString(vol->target.format);
@@ -565,13 +588,12 @@ virStorageBackendDiskPartFormat(virStoragePoolObjPtr pool,
         }
         if (vol->target.format == VIR_STORAGE_VOL_DISK_EXTENDED) {
             /* make sure we don't have an extended partition already */
-            for (i = 0; i < pool->volumes.count; i++) {
-                if (pool->volumes.objs[i]->source.partType ==
-                    VIR_STORAGE_VOL_DISK_TYPE_EXTENDED) {
+            if (virStoragePoolObjSearchVolume(pool,
+                                              virStorageVolPartFindExtended,
+                                              NULL)) {
                     virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                                    _("extended partition already exists"));
                     return -1;
-                }
             }
             if (VIR_STRDUP(*partFormat, partedFormat) < 0)
                 return -1;
@@ -587,18 +609,16 @@ virStorageBackendDiskPartFormat(virStoragePoolObjPtr pool,
                 break;
             case VIR_STORAGE_VOL_DISK_TYPE_LOGICAL:
                 /* make sure we have an extended partition */
-                for (i = 0; i < pool->volumes.count; i++) {
-                    if (pool->volumes.objs[i]->source.partType ==
-                        VIR_STORAGE_VOL_DISK_TYPE_EXTENDED) {
-                        if (virAsprintf(partFormat, "logical %s",
-                                        partedFormat) < 0)
-                            return -1;
-                        break;
-                    }
-                }
-                if (i == virStoragePoolObjGetVolumesCount(pool)) {
-                    virReportError(VIR_ERR_INTERNAL_ERROR,
-                                   "%s", _("no extended partition found and no primary partition available"));
+                if (virStoragePoolObjSearchVolume(pool,
+                                                  virStorageVolPartFindExtended,
+                                                  NULL)) {
+                    if (virAsprintf(partFormat, "logical %s",
+                                    partedFormat) < 0)
+                        return -1;
+                } else {
+                    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                                   _("no extended partition found and no "
+                                     "primary partition available"));
                     return -1;
                 }
                 break;