提交 40630a8e 编写于 作者: J John Ferlan

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: NJohn Ferlan <jferlan@redhat.com>
上级 acd9a380
......@@ -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
virStorageVolDefFindByKey(virStoragePoolObjPtr obj,
const char *key)
......
......@@ -136,6 +136,17 @@ virStoragePoolObjPtr
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);
......
......@@ -1053,6 +1053,7 @@ virSecretObjSetValueSize;
# conf/virstorageobj.h
virStoragePoolObjAddVol;
virStoragePoolObjAssignDef;
virStoragePoolObjClearVols;
virStoragePoolObjDecrAsyncjobs;
......@@ -1066,6 +1067,7 @@ virStoragePoolObjGetConfigFile;
virStoragePoolObjGetDef;
virStoragePoolObjGetNames;
virStoragePoolObjGetNewDef;
virStoragePoolObjGetVolumesCount;
virStoragePoolObjIncrAsyncjobs;
virStoragePoolObjIsActive;
virStoragePoolObjIsAutostart;
......@@ -1079,6 +1081,7 @@ virStoragePoolObjNew;
virStoragePoolObjNumOfStoragePools;
virStoragePoolObjNumOfVolumes;
virStoragePoolObjRemove;
virStoragePoolObjRemoveVol;
virStoragePoolObjSaveDef;
virStoragePoolObjSetActive;
virStoragePoolObjSetAutostart;
......
......@@ -65,8 +65,7 @@ virStorageBackendDiskMakeDataVol(virStoragePoolObjPtr pool,
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;
}
......@@ -597,7 +596,7 @@ virStorageBackendDiskPartFormat(virStoragePoolObjPtr pool,
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;
......
......@@ -386,8 +386,7 @@ virStorageBackendGlusterRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED,
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) {
......
......@@ -356,9 +356,9 @@ virStorageBackendLogicalMakeVol(char **const groups,
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;
......
......@@ -71,8 +71,9 @@ virStorageBackendMpathNewVol(virStoragePoolObjPtr pool,
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;
......
......@@ -506,7 +506,7 @@ virStorageBackendRBDRefreshPool(virConnectPtr conn,
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;
......@@ -514,7 +514,7 @@ virStorageBackendRBDRefreshPool(virConnectPtr conn,
}
VIR_DEBUG("Found %zu images in RBD pool %s",
pool->volumes.count, pool->def->source.name);
virStoragePoolObjGetVolumesCount(pool), pool->def->source.name);
ret = 0;
......
......@@ -130,11 +130,9 @@ virStorageBackendSheepdogAddVolume(virConnectPtr conn ATTRIBUTE_UNUSED,
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:
......
......@@ -161,11 +161,9 @@ virStorageBackendZFSParseVol(virStoragePoolObjPtr pool,
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:
......
......@@ -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
storageVolDeleteInternal(virStorageVolPtr vol,
virStorageBackendPtr backend,
......@@ -1676,7 +1657,7 @@ storageVolDeleteInternal(virStorageVolPtr vol,
}
}
storageVolRemoveFromPool(obj, voldef);
virStoragePoolObjRemoveVol(obj, voldef);
ret = 0;
cleanup:
......@@ -1815,24 +1796,19 @@ storageVolCreateXML(virStoragePoolPtr pool,
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;
......@@ -1867,7 +1843,7 @@ storageVolCreateXML(virStoragePoolPtr pool,
if (buildret < 0) {
/* buildVol handles deleting volume on failure */
storageVolRemoveFromPool(obj, voldef);
virStoragePoolObjRemoveVol(obj, voldef);
voldef = NULL;
goto cleanup;
}
......@@ -2018,9 +1994,6 @@ storageVolCreateXMLFrom(virStoragePoolPtr pool,
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. */
......@@ -2037,13 +2010,13 @@ storageVolCreateXMLFrom(virStoragePoolPtr pool,
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++;
......
......@@ -3623,13 +3623,13 @@ virStorageBackendRefreshLocal(virConnectPtr conn ATTRIBUTE_UNUSED,
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;
......@@ -3811,10 +3811,10 @@ virStorageBackendSCSINewLun(virStoragePoolObjPtr pool,
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:
......
......@@ -1079,7 +1079,8 @@ testOpenVolumesForPool(const char *file,
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;
......@@ -5011,8 +5012,7 @@ testStorageVolCreateXML(virStoragePoolPtr pool,
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;
......@@ -5079,8 +5079,7 @@ testStorageVolCreateXMLFrom(virStoragePoolPtr pool,
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;
......@@ -5105,7 +5104,6 @@ testStorageVolDelete(virStorageVolPtr vol,
testDriverPtr privconn = vol->conn->privateData;
virStoragePoolObjPtr obj;
virStorageVolDefPtr privvol;
size_t i;
int ret = -1;
virCheckFlags(0, -1);
......@@ -5119,14 +5117,8 @@ testStorageVolDelete(virStorageVolPtr vol,
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:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册