storage: Introduce APIs to search/scan storage pool volumes list

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>
This commit is contained in:
John Ferlan 2017-05-09 08:18:33 -04:00
parent 40630a8e45
commit 5bf9b65501
4 changed files with 107 additions and 35 deletions

View 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)

View 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);

View 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;

View 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;