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>
}
+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
virStorageVolDefFindByKey(virStoragePoolObjPtr obj,
const char *key)
virStoragePoolObjFindByName(virStoragePoolObjListPtr pools,
const char *name);
+int
+virStoragePoolObjAddVol(virStoragePoolObjPtr obj,
+ virStorageVolDefPtr voldef);
+
+void
+virStoragePoolObjRemoveVol(virStoragePoolObjPtr obj,
+ virStorageVolDefPtr voldef);
+
+size_t
+virStoragePoolObjGetVolumesCount(virStoragePoolObjPtr obj);
+
virStorageVolDefPtr
virStorageVolDefFindByKey(virStoragePoolObjPtr obj,
const char *key);
# conf/virstorageobj.h
+virStoragePoolObjAddVol;
virStoragePoolObjAssignDef;
virStoragePoolObjClearVols;
virStoragePoolObjDecrAsyncjobs;
virStoragePoolObjGetDef;
virStoragePoolObjGetNames;
virStoragePoolObjGetNewDef;
+virStoragePoolObjGetVolumesCount;
virStoragePoolObjIncrAsyncjobs;
virStoragePoolObjIsActive;
virStoragePoolObjIsAutostart;
virStoragePoolObjNumOfStoragePools;
virStoragePoolObjNumOfVolumes;
virStoragePoolObjRemove;
+virStoragePoolObjRemoveVol;
virStoragePoolObjSaveDef;
virStoragePoolObjSetActive;
virStoragePoolObjSetAutostart;
if (VIR_ALLOC(vol) < 0)
return -1;
if (VIR_STRDUP(vol->name, partname) < 0 ||
- VIR_APPEND_ELEMENT_COPY(pool->volumes.objs,
- pool->volumes.count, vol) < 0) {
+ virStoragePoolObjAddVol(pool, vol) < 0) {
virStorageVolDefFree(vol);
return -1;
}
break;
}
}
- if (i == pool->volumes.count) {
+ if (i == virStoragePoolObjGetVolumesCount(pool)) {
virReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("no extended partition found and no primary partition available"));
return -1;
if (okay < 0)
goto cleanup;
- if (vol && VIR_APPEND_ELEMENT(pool->volumes.objs, pool->volumes.count,
- vol) < 0)
+ if (vol && virStoragePoolObjAddVol(pool, vol) < 0)
goto cleanup;
}
if (errno) {
if (virStorageBackendLogicalParseVolExtents(vol, groups) < 0)
goto cleanup;
- if (is_new_vol &&
- VIR_APPEND_ELEMENT(pool->volumes.objs, pool->volumes.count, vol) < 0)
+ if (is_new_vol && virStoragePoolObjAddVol(pool, vol) < 0)
goto cleanup;
+ vol = NULL;
ret = 0;
if (VIR_STRDUP(vol->key, vol->target.path) < 0)
goto cleanup;
- if (VIR_APPEND_ELEMENT_COPY(pool->volumes.objs, pool->volumes.count, vol) < 0)
+ if (virStoragePoolObjAddVol(pool, vol) < 0)
goto cleanup;
+
pool->def->capacity += vol->target.capacity;
pool->def->allocation += vol->target.allocation;
ret = 0;
goto cleanup;
}
- if (VIR_APPEND_ELEMENT(pool->volumes.objs, pool->volumes.count, vol) < 0) {
+ if (virStoragePoolObjAddVol(pool, vol) < 0) {
virStorageVolDefFree(vol);
virStoragePoolObjClearVols(pool);
goto cleanup;
}
VIR_DEBUG("Found %zu images in RBD pool %s",
- pool->volumes.count, pool->def->source.name);
+ virStoragePoolObjGetVolumesCount(pool), pool->def->source.name);
ret = 0;
if (virStorageBackendSheepdogRefreshVol(conn, pool, vol) < 0)
goto error;
- if (VIR_EXPAND_N(pool->volumes.objs, pool->volumes.count, 1) < 0)
+ if (virStoragePoolObjAddVol(pool, vol) < 0)
goto error;
- pool->volumes.objs[pool->volumes.count - 1] = vol;
-
return 0;
error:
if (volume->target.allocation < volume->target.capacity)
volume->target.sparse = true;
- if (is_new_vol &&
- VIR_APPEND_ELEMENT(pool->volumes.objs,
- pool->volumes.count,
- volume) < 0)
+ if (is_new_vol && virStoragePoolObjAddVol(pool, volume) < 0)
goto cleanup;
+ volume = NULL;
ret = 0;
cleanup:
}
-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
storageVolDeleteInternal(virStorageVolPtr vol,
virStorageBackendPtr backend,
}
}
- storageVolRemoveFromPool(obj, voldef);
+ virStoragePoolObjRemoveVol(obj, voldef);
ret = 0;
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
* will generate the canonical key. */
VIR_FREE(voldef->key);
if (backend->createVol(pool->conn, obj, voldef) < 0)
goto cleanup;
- obj->volumes.objs[obj->volumes.count++] = voldef;
- newvol = virGetStorageVol(pool->conn, obj->def->name, voldef->name,
- voldef->key, NULL, NULL);
- if (!newvol) {
- obj->volumes.count--;
+ if (!(newvol = virGetStorageVol(pool->conn, obj->def->name, voldef->name,
+ voldef->key, NULL, NULL)))
goto cleanup;
- }
+ /* NB: Upon success voldef "owned" by storage pool for deletion purposes */
+ if (virStoragePoolObjAddVol(obj, voldef) < 0)
+ goto cleanup;
if (backend->buildVol) {
int buildret;
if (buildret < 0) {
/* buildVol handles deleting volume on failure */
- storageVolRemoveFromPool(obj, voldef);
+ virStoragePoolObjRemoveVol(obj, voldef);
voldef = NULL;
goto cleanup;
}
backend->refreshVol(pool->conn, obj, voldefsrc) < 0)
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.
* Wipe any key the user may have suggested, as volume creation
* will generate the canonical key. */
memcpy(shadowvol, voldef, sizeof(*voldef));
- obj->volumes.objs[obj->volumes.count++] = voldef;
- newvol = virGetStorageVol(pool->conn, obj->def->name, voldef->name,
- voldef->key, NULL, NULL);
- if (!newvol) {
- obj->volumes.count--;
+ if (!(newvol = virGetStorageVol(pool->conn, obj->def->name, voldef->name,
+ voldef->key, NULL, NULL)))
+ goto cleanup;
+
+ /* NB: Upon success voldef "owned" by storage pool for deletion purposes */
+ if (virStoragePoolObjAddVol(obj, voldef) < 0)
goto cleanup;
- }
/* Drop the pool lock during volume allocation */
obj->asyncjobs++;
goto cleanup;
}
- if (VIR_APPEND_ELEMENT(pool->volumes.objs, pool->volumes.count, vol) < 0)
+ if (virStoragePoolObjAddVol(pool, vol) < 0)
goto cleanup;
+ vol = NULL;
}
if (direrr < 0)
goto cleanup;
VIR_DIR_CLOSE(dir);
- vol = NULL;
if (VIR_ALLOC(target))
goto cleanup;
pool->def->capacity += vol->target.capacity;
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;
-
vol = NULL;
+
retval = 0;
cleanup:
if (!def->key && VIR_STRDUP(def->key, def->target.path) < 0)
goto error;
- if (VIR_APPEND_ELEMENT_COPY(obj->volumes.objs, obj->volumes.count, def) < 0)
+
+ if (virStoragePoolObjAddVol(obj, def) < 0)
goto error;
obj->def->allocation += def->target.allocation;
goto cleanup;
if (VIR_STRDUP(privvol->key, privvol->target.path) < 0 ||
- VIR_APPEND_ELEMENT_COPY(obj->volumes.objs,
- obj->volumes.count, privvol) < 0)
+ virStoragePoolObjAddVol(obj, privvol) < 0)
goto cleanup;
obj->def->allocation += privvol->target.allocation;
goto cleanup;
if (VIR_STRDUP(privvol->key, privvol->target.path) < 0 ||
- VIR_APPEND_ELEMENT_COPY(obj->volumes.objs,
- obj->volumes.count, privvol) < 0)
+ virStoragePoolObjAddVol(obj, privvol) < 0)
goto cleanup;
obj->def->allocation += privvol->target.allocation;
testDriverPtr privconn = vol->conn->privateData;
virStoragePoolObjPtr obj;
virStorageVolDefPtr privvol;
- size_t i;
int ret = -1;
virCheckFlags(0, -1);
obj->def->allocation -= privvol->target.allocation;
obj->def->available = (obj->def->capacity - obj->def->allocation);
- for (i = 0; i < obj->volumes.count; i++) {
- if (obj->volumes.objs[i] == privvol) {
- virStorageVolDefFree(privvol);
+ virStoragePoolObjRemoveVol(obj, privvol);
- VIR_DELETE_ELEMENT(obj->volumes.objs, i, obj->volumes.count);
- break;
- }
- }
ret = 0;
cleanup: