mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-24 06:35:24 +00:00
storage: Introduce storage volume add, delete, count APIs
Create/use virStoragePoolObjAddVol in order to add volumes onto list. Create/use virStoragePoolObjRemoveVol in order to remove volumes from list. Create/use virStoragePoolObjGetVolumesCount to get count of volumes on list. For the storage driver, the logic alters when the volumes.obj list grows to after we've fetched the volobj. This is an optimization of sorts, but also doesn't "needlessly" grow the volumes.objs list and then just decr the count if the virGetStorageVol fails. Signed-off-by: John Ferlan <jferlan@redhat.com>
This commit is contained in:
parent
acd9a38069
commit
40630a8e45
@ -282,6 +282,43 @@ virStoragePoolObjClearVols(virStoragePoolObjPtr obj)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
virStoragePoolObjAddVol(virStoragePoolObjPtr obj,
|
||||||
|
virStorageVolDefPtr voldef)
|
||||||
|
{
|
||||||
|
if (VIR_APPEND_ELEMENT(obj->volumes.objs, obj->volumes.count, voldef) < 0)
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
virStoragePoolObjRemoveVol(virStoragePoolObjPtr obj,
|
||||||
|
virStorageVolDefPtr voldef)
|
||||||
|
{
|
||||||
|
virStoragePoolDefPtr def = virStoragePoolObjGetDef(obj);
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < obj->volumes.count; i++) {
|
||||||
|
if (obj->volumes.objs[i] == voldef) {
|
||||||
|
VIR_INFO("Deleting volume '%s' from storage pool '%s'",
|
||||||
|
voldef->name, def->name);
|
||||||
|
virStorageVolDefFree(voldef);
|
||||||
|
|
||||||
|
VIR_DELETE_ELEMENT(obj->volumes.objs, i, obj->volumes.count);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t
|
||||||
|
virStoragePoolObjGetVolumesCount(virStoragePoolObjPtr obj)
|
||||||
|
{
|
||||||
|
return obj->volumes.count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
virStorageVolDefPtr
|
virStorageVolDefPtr
|
||||||
virStorageVolDefFindByKey(virStoragePoolObjPtr obj,
|
virStorageVolDefFindByKey(virStoragePoolObjPtr obj,
|
||||||
const char *key)
|
const char *key)
|
||||||
|
@ -136,6 +136,17 @@ virStoragePoolObjPtr
|
|||||||
virStoragePoolObjFindByName(virStoragePoolObjListPtr pools,
|
virStoragePoolObjFindByName(virStoragePoolObjListPtr pools,
|
||||||
const char *name);
|
const char *name);
|
||||||
|
|
||||||
|
int
|
||||||
|
virStoragePoolObjAddVol(virStoragePoolObjPtr obj,
|
||||||
|
virStorageVolDefPtr voldef);
|
||||||
|
|
||||||
|
void
|
||||||
|
virStoragePoolObjRemoveVol(virStoragePoolObjPtr obj,
|
||||||
|
virStorageVolDefPtr voldef);
|
||||||
|
|
||||||
|
size_t
|
||||||
|
virStoragePoolObjGetVolumesCount(virStoragePoolObjPtr obj);
|
||||||
|
|
||||||
virStorageVolDefPtr
|
virStorageVolDefPtr
|
||||||
virStorageVolDefFindByKey(virStoragePoolObjPtr obj,
|
virStorageVolDefFindByKey(virStoragePoolObjPtr obj,
|
||||||
const char *key);
|
const char *key);
|
||||||
|
@ -1053,6 +1053,7 @@ virSecretObjSetValueSize;
|
|||||||
|
|
||||||
|
|
||||||
# conf/virstorageobj.h
|
# conf/virstorageobj.h
|
||||||
|
virStoragePoolObjAddVol;
|
||||||
virStoragePoolObjAssignDef;
|
virStoragePoolObjAssignDef;
|
||||||
virStoragePoolObjClearVols;
|
virStoragePoolObjClearVols;
|
||||||
virStoragePoolObjDecrAsyncjobs;
|
virStoragePoolObjDecrAsyncjobs;
|
||||||
@ -1066,6 +1067,7 @@ virStoragePoolObjGetConfigFile;
|
|||||||
virStoragePoolObjGetDef;
|
virStoragePoolObjGetDef;
|
||||||
virStoragePoolObjGetNames;
|
virStoragePoolObjGetNames;
|
||||||
virStoragePoolObjGetNewDef;
|
virStoragePoolObjGetNewDef;
|
||||||
|
virStoragePoolObjGetVolumesCount;
|
||||||
virStoragePoolObjIncrAsyncjobs;
|
virStoragePoolObjIncrAsyncjobs;
|
||||||
virStoragePoolObjIsActive;
|
virStoragePoolObjIsActive;
|
||||||
virStoragePoolObjIsAutostart;
|
virStoragePoolObjIsAutostart;
|
||||||
@ -1079,6 +1081,7 @@ virStoragePoolObjNew;
|
|||||||
virStoragePoolObjNumOfStoragePools;
|
virStoragePoolObjNumOfStoragePools;
|
||||||
virStoragePoolObjNumOfVolumes;
|
virStoragePoolObjNumOfVolumes;
|
||||||
virStoragePoolObjRemove;
|
virStoragePoolObjRemove;
|
||||||
|
virStoragePoolObjRemoveVol;
|
||||||
virStoragePoolObjSaveDef;
|
virStoragePoolObjSaveDef;
|
||||||
virStoragePoolObjSetActive;
|
virStoragePoolObjSetActive;
|
||||||
virStoragePoolObjSetAutostart;
|
virStoragePoolObjSetAutostart;
|
||||||
|
@ -65,8 +65,7 @@ virStorageBackendDiskMakeDataVol(virStoragePoolObjPtr pool,
|
|||||||
if (VIR_ALLOC(vol) < 0)
|
if (VIR_ALLOC(vol) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (VIR_STRDUP(vol->name, partname) < 0 ||
|
if (VIR_STRDUP(vol->name, partname) < 0 ||
|
||||||
VIR_APPEND_ELEMENT_COPY(pool->volumes.objs,
|
virStoragePoolObjAddVol(pool, vol) < 0) {
|
||||||
pool->volumes.count, vol) < 0) {
|
|
||||||
virStorageVolDefFree(vol);
|
virStorageVolDefFree(vol);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -597,7 +596,7 @@ virStorageBackendDiskPartFormat(virStoragePoolObjPtr pool,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i == pool->volumes.count) {
|
if (i == virStoragePoolObjGetVolumesCount(pool)) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
"%s", _("no extended partition found and no primary partition available"));
|
"%s", _("no extended partition found and no primary partition available"));
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -386,8 +386,7 @@ virStorageBackendGlusterRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|||||||
|
|
||||||
if (okay < 0)
|
if (okay < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
if (vol && VIR_APPEND_ELEMENT(pool->volumes.objs, pool->volumes.count,
|
if (vol && virStoragePoolObjAddVol(pool, vol) < 0)
|
||||||
vol) < 0)
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
if (errno) {
|
if (errno) {
|
||||||
|
@ -356,9 +356,9 @@ virStorageBackendLogicalMakeVol(char **const groups,
|
|||||||
if (virStorageBackendLogicalParseVolExtents(vol, groups) < 0)
|
if (virStorageBackendLogicalParseVolExtents(vol, groups) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (is_new_vol &&
|
if (is_new_vol && virStoragePoolObjAddVol(pool, vol) < 0)
|
||||||
VIR_APPEND_ELEMENT(pool->volumes.objs, pool->volumes.count, vol) < 0)
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
vol = NULL;
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
|
@ -71,8 +71,9 @@ virStorageBackendMpathNewVol(virStoragePoolObjPtr pool,
|
|||||||
if (VIR_STRDUP(vol->key, vol->target.path) < 0)
|
if (VIR_STRDUP(vol->key, vol->target.path) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (VIR_APPEND_ELEMENT_COPY(pool->volumes.objs, pool->volumes.count, vol) < 0)
|
if (virStoragePoolObjAddVol(pool, vol) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
pool->def->capacity += vol->target.capacity;
|
pool->def->capacity += vol->target.capacity;
|
||||||
pool->def->allocation += vol->target.allocation;
|
pool->def->allocation += vol->target.allocation;
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
@ -506,7 +506,7 @@ virStorageBackendRBDRefreshPool(virConnectPtr conn,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (VIR_APPEND_ELEMENT(pool->volumes.objs, pool->volumes.count, vol) < 0) {
|
if (virStoragePoolObjAddVol(pool, vol) < 0) {
|
||||||
virStorageVolDefFree(vol);
|
virStorageVolDefFree(vol);
|
||||||
virStoragePoolObjClearVols(pool);
|
virStoragePoolObjClearVols(pool);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@ -514,7 +514,7 @@ virStorageBackendRBDRefreshPool(virConnectPtr conn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
VIR_DEBUG("Found %zu images in RBD pool %s",
|
VIR_DEBUG("Found %zu images in RBD pool %s",
|
||||||
pool->volumes.count, pool->def->source.name);
|
virStoragePoolObjGetVolumesCount(pool), pool->def->source.name);
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
|
@ -130,11 +130,9 @@ virStorageBackendSheepdogAddVolume(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|||||||
if (virStorageBackendSheepdogRefreshVol(conn, pool, vol) < 0)
|
if (virStorageBackendSheepdogRefreshVol(conn, pool, vol) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (VIR_EXPAND_N(pool->volumes.objs, pool->volumes.count, 1) < 0)
|
if (virStoragePoolObjAddVol(pool, vol) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
pool->volumes.objs[pool->volumes.count - 1] = vol;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
@ -161,11 +161,9 @@ virStorageBackendZFSParseVol(virStoragePoolObjPtr pool,
|
|||||||
if (volume->target.allocation < volume->target.capacity)
|
if (volume->target.allocation < volume->target.capacity)
|
||||||
volume->target.sparse = true;
|
volume->target.sparse = true;
|
||||||
|
|
||||||
if (is_new_vol &&
|
if (is_new_vol && virStoragePoolObjAddVol(pool, volume) < 0)
|
||||||
VIR_APPEND_ELEMENT(pool->volumes.objs,
|
|
||||||
pool->volumes.count,
|
|
||||||
volume) < 0)
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
volume = NULL;
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
cleanup:
|
cleanup:
|
||||||
|
@ -1626,25 +1626,6 @@ storagePoolLookupByTargetPath(virConnectPtr conn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
storageVolRemoveFromPool(virStoragePoolObjPtr obj,
|
|
||||||
virStorageVolDefPtr voldef)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
for (i = 0; i < obj->volumes.count; i++) {
|
|
||||||
if (obj->volumes.objs[i] == voldef) {
|
|
||||||
VIR_INFO("Deleting volume '%s' from storage pool '%s'",
|
|
||||||
voldef->name, obj->def->name);
|
|
||||||
virStorageVolDefFree(voldef);
|
|
||||||
|
|
||||||
VIR_DELETE_ELEMENT(obj->volumes.objs, i, obj->volumes.count);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
storageVolDeleteInternal(virStorageVolPtr vol,
|
storageVolDeleteInternal(virStorageVolPtr vol,
|
||||||
virStorageBackendPtr backend,
|
virStorageBackendPtr backend,
|
||||||
@ -1676,7 +1657,7 @@ storageVolDeleteInternal(virStorageVolPtr vol,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
storageVolRemoveFromPool(obj, voldef);
|
virStoragePoolObjRemoveVol(obj, voldef);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
@ -1815,24 +1796,19 @@ storageVolCreateXML(virStoragePoolPtr pool,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (VIR_REALLOC_N(obj->volumes.objs,
|
|
||||||
obj->volumes.count + 1) < 0)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
/* Wipe any key the user may have suggested, as volume creation
|
/* Wipe any key the user may have suggested, as volume creation
|
||||||
* will generate the canonical key. */
|
* will generate the canonical key. */
|
||||||
VIR_FREE(voldef->key);
|
VIR_FREE(voldef->key);
|
||||||
if (backend->createVol(pool->conn, obj, voldef) < 0)
|
if (backend->createVol(pool->conn, obj, voldef) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
obj->volumes.objs[obj->volumes.count++] = voldef;
|
if (!(newvol = virGetStorageVol(pool->conn, obj->def->name, voldef->name,
|
||||||
newvol = virGetStorageVol(pool->conn, obj->def->name, voldef->name,
|
voldef->key, NULL, NULL)))
|
||||||
voldef->key, NULL, NULL);
|
|
||||||
if (!newvol) {
|
|
||||||
obj->volumes.count--;
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
|
||||||
|
|
||||||
|
/* NB: Upon success voldef "owned" by storage pool for deletion purposes */
|
||||||
|
if (virStoragePoolObjAddVol(obj, voldef) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
if (backend->buildVol) {
|
if (backend->buildVol) {
|
||||||
int buildret;
|
int buildret;
|
||||||
@ -1867,7 +1843,7 @@ storageVolCreateXML(virStoragePoolPtr pool,
|
|||||||
|
|
||||||
if (buildret < 0) {
|
if (buildret < 0) {
|
||||||
/* buildVol handles deleting volume on failure */
|
/* buildVol handles deleting volume on failure */
|
||||||
storageVolRemoveFromPool(obj, voldef);
|
virStoragePoolObjRemoveVol(obj, voldef);
|
||||||
voldef = NULL;
|
voldef = NULL;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
@ -2018,9 +1994,6 @@ storageVolCreateXMLFrom(virStoragePoolPtr pool,
|
|||||||
backend->refreshVol(pool->conn, obj, voldefsrc) < 0)
|
backend->refreshVol(pool->conn, obj, voldefsrc) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (VIR_REALLOC_N(obj->volumes.objs, obj->volumes.count + 1) < 0)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
/* 'Define' the new volume so we get async progress reporting.
|
/* 'Define' the new volume so we get async progress reporting.
|
||||||
* Wipe any key the user may have suggested, as volume creation
|
* Wipe any key the user may have suggested, as volume creation
|
||||||
* will generate the canonical key. */
|
* will generate the canonical key. */
|
||||||
@ -2037,13 +2010,13 @@ storageVolCreateXMLFrom(virStoragePoolPtr pool,
|
|||||||
|
|
||||||
memcpy(shadowvol, voldef, sizeof(*voldef));
|
memcpy(shadowvol, voldef, sizeof(*voldef));
|
||||||
|
|
||||||
obj->volumes.objs[obj->volumes.count++] = voldef;
|
if (!(newvol = virGetStorageVol(pool->conn, obj->def->name, voldef->name,
|
||||||
newvol = virGetStorageVol(pool->conn, obj->def->name, voldef->name,
|
voldef->key, NULL, NULL)))
|
||||||
voldef->key, NULL, NULL);
|
goto cleanup;
|
||||||
if (!newvol) {
|
|
||||||
obj->volumes.count--;
|
/* NB: Upon success voldef "owned" by storage pool for deletion purposes */
|
||||||
|
if (virStoragePoolObjAddVol(obj, voldef) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
|
||||||
|
|
||||||
/* Drop the pool lock during volume allocation */
|
/* Drop the pool lock during volume allocation */
|
||||||
obj->asyncjobs++;
|
obj->asyncjobs++;
|
||||||
|
@ -3623,13 +3623,13 @@ virStorageBackendRefreshLocal(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (VIR_APPEND_ELEMENT(pool->volumes.objs, pool->volumes.count, vol) < 0)
|
if (virStoragePoolObjAddVol(pool, vol) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
vol = NULL;
|
||||||
}
|
}
|
||||||
if (direrr < 0)
|
if (direrr < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
VIR_DIR_CLOSE(dir);
|
VIR_DIR_CLOSE(dir);
|
||||||
vol = NULL;
|
|
||||||
|
|
||||||
if (VIR_ALLOC(target))
|
if (VIR_ALLOC(target))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@ -3811,10 +3811,10 @@ virStorageBackendSCSINewLun(virStoragePoolObjPtr pool,
|
|||||||
pool->def->capacity += vol->target.capacity;
|
pool->def->capacity += vol->target.capacity;
|
||||||
pool->def->allocation += vol->target.allocation;
|
pool->def->allocation += vol->target.allocation;
|
||||||
|
|
||||||
if (VIR_APPEND_ELEMENT(pool->volumes.objs, pool->volumes.count, vol) < 0)
|
if (virStoragePoolObjAddVol(pool, vol) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
vol = NULL;
|
vol = NULL;
|
||||||
|
|
||||||
retval = 0;
|
retval = 0;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
@ -1079,7 +1079,8 @@ testOpenVolumesForPool(const char *file,
|
|||||||
|
|
||||||
if (!def->key && VIR_STRDUP(def->key, def->target.path) < 0)
|
if (!def->key && VIR_STRDUP(def->key, def->target.path) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
if (VIR_APPEND_ELEMENT_COPY(obj->volumes.objs, obj->volumes.count, def) < 0)
|
|
||||||
|
if (virStoragePoolObjAddVol(obj, def) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
obj->def->allocation += def->target.allocation;
|
obj->def->allocation += def->target.allocation;
|
||||||
@ -5011,8 +5012,7 @@ testStorageVolCreateXML(virStoragePoolPtr pool,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (VIR_STRDUP(privvol->key, privvol->target.path) < 0 ||
|
if (VIR_STRDUP(privvol->key, privvol->target.path) < 0 ||
|
||||||
VIR_APPEND_ELEMENT_COPY(obj->volumes.objs,
|
virStoragePoolObjAddVol(obj, privvol) < 0)
|
||||||
obj->volumes.count, privvol) < 0)
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
obj->def->allocation += privvol->target.allocation;
|
obj->def->allocation += privvol->target.allocation;
|
||||||
@ -5079,8 +5079,7 @@ testStorageVolCreateXMLFrom(virStoragePoolPtr pool,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (VIR_STRDUP(privvol->key, privvol->target.path) < 0 ||
|
if (VIR_STRDUP(privvol->key, privvol->target.path) < 0 ||
|
||||||
VIR_APPEND_ELEMENT_COPY(obj->volumes.objs,
|
virStoragePoolObjAddVol(obj, privvol) < 0)
|
||||||
obj->volumes.count, privvol) < 0)
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
obj->def->allocation += privvol->target.allocation;
|
obj->def->allocation += privvol->target.allocation;
|
||||||
@ -5105,7 +5104,6 @@ testStorageVolDelete(virStorageVolPtr vol,
|
|||||||
testDriverPtr privconn = vol->conn->privateData;
|
testDriverPtr privconn = vol->conn->privateData;
|
||||||
virStoragePoolObjPtr obj;
|
virStoragePoolObjPtr obj;
|
||||||
virStorageVolDefPtr privvol;
|
virStorageVolDefPtr privvol;
|
||||||
size_t i;
|
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
virCheckFlags(0, -1);
|
virCheckFlags(0, -1);
|
||||||
@ -5119,14 +5117,8 @@ testStorageVolDelete(virStorageVolPtr vol,
|
|||||||
obj->def->allocation -= privvol->target.allocation;
|
obj->def->allocation -= privvol->target.allocation;
|
||||||
obj->def->available = (obj->def->capacity - obj->def->allocation);
|
obj->def->available = (obj->def->capacity - obj->def->allocation);
|
||||||
|
|
||||||
for (i = 0; i < obj->volumes.count; i++) {
|
virStoragePoolObjRemoveVol(obj, privvol);
|
||||||
if (obj->volumes.objs[i] == privvol) {
|
|
||||||
virStorageVolDefFree(privvol);
|
|
||||||
|
|
||||||
VIR_DELETE_ELEMENT(obj->volumes.objs, i, obj->volumes.count);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
Loading…
Reference in New Issue
Block a user