提交 2ac0e647 编写于 作者: J John Ferlan

storage: Don't duplicate efforts of backend driver

https://bugzilla.redhat.com/show_bug.cgi?id=1206521

If the backend driver updates the pool available and/or allocation values,
then the storage_driver VolCreateXML, VolCreateXMLFrom, and VolDelete APIs
should not change the value; otherwise, it will appear as if the values
were "doubled" for each change.  Additionally since unsigned arithmetic will
be used depending on the size and operation, either or both values could be
appear to be much larger than they should be (in the EiB range).

Currently only the disk pool updates the values, but other pools could.
Assume a "fresh" disk pool of 500 MiB using /dev/sde:

$ virsh pool-info disk-pool
...
Capacity:       509.88 MiB
Allocation:     0.00 B
Available:      509.84 MiB

$ virsh vol-create-as disk-pool sde1 --capacity 300M

$ virsh pool-info disk-pool
...
Capacity:       509.88 MiB
Allocation:     600.47 MiB
Available:      16.00 EiB

Following assumes disk backend updated to refresh the disk pool at deletion
of primary partition as well as extended partition:

$ virsh vol-delete --pool disk-pool sde1
Vol sde1 deleted

$ virsh pool-info disk-pool
...
Capacity:       509.88 MiB
Allocation:     9.73 EiB
Available:      6.27 EiB

This patch will check if the backend updated the pool values and honor that
update.
上级 1ffd82bb
......@@ -1609,6 +1609,7 @@ storageVolDeleteInternal(virStorageVolPtr obj,
{
size_t i;
int ret = -1;
unsigned long long orig_pool_available, orig_pool_allocation;
if (!backend->deleteVol) {
virReportError(VIR_ERR_NO_SUPPORT,
......@@ -1617,6 +1618,9 @@ storageVolDeleteInternal(virStorageVolPtr obj,
goto cleanup;
}
orig_pool_available = pool->def->available;
orig_pool_allocation = pool->def->allocation;
if (backend->deleteVol(obj->conn, pool, vol, flags) < 0)
goto cleanup;
......@@ -1624,8 +1628,10 @@ storageVolDeleteInternal(virStorageVolPtr obj,
* in this module since the allocation/available weren't adjusted yet
*/
if (updateMeta) {
pool->def->allocation -= vol->target.allocation;
pool->def->available += vol->target.allocation;
if (orig_pool_allocation == pool->def->allocation)
pool->def->allocation -= vol->target.allocation;
if (orig_pool_available == pool->def->available)
pool->def->available += vol->target.allocation;
}
for (i = 0; i < pool->volumes.count; i++) {
......@@ -1744,6 +1750,7 @@ storageVolCreateXML(virStoragePoolPtr obj,
virStorageVolDefPtr voldef = NULL;
virStorageVolPtr ret = NULL, volobj = NULL;
virStorageVolDefPtr buildvoldef = NULL;
unsigned long long orig_pool_available, orig_pool_allocation;
virCheckFlags(VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA, NULL);
......@@ -1791,6 +1798,9 @@ storageVolCreateXML(virStoragePoolPtr obj,
goto cleanup;
}
orig_pool_available = pool->def->available;
orig_pool_allocation = pool->def->allocation;
/* Wipe any key the user may have suggested, as volume creation
* will generate the canonical key. */
VIR_FREE(voldef->key);
......@@ -1848,8 +1858,10 @@ storageVolCreateXML(virStoragePoolPtr obj,
goto cleanup;
/* Update pool metadata */
pool->def->allocation += buildvoldef->target.allocation;
pool->def->available -= buildvoldef->target.allocation;
if (orig_pool_allocation == pool->def->allocation)
pool->def->allocation += buildvoldef->target.allocation;
if (orig_pool_available == pool->def->available)
pool->def->available -= buildvoldef->target.allocation;
VIR_INFO("Creating volume '%s' in storage pool '%s'",
volobj->name, pool->def->name);
......@@ -1877,6 +1889,7 @@ storageVolCreateXMLFrom(virStoragePoolPtr obj,
virStorageVolDefPtr origvol = NULL, newvol = NULL;
virStorageVolPtr ret = NULL, volobj = NULL;
unsigned long long allocation;
unsigned long long orig_pool_available, orig_pool_allocation;
int buildret;
virCheckFlags(VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA |
......@@ -1979,6 +1992,9 @@ storageVolCreateXMLFrom(virStoragePoolPtr obj,
pool->volumes.count+1) < 0)
goto cleanup;
orig_pool_available = pool->def->available;
orig_pool_allocation = pool->def->allocation;
/* '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. */
......@@ -2032,8 +2048,10 @@ storageVolCreateXMLFrom(virStoragePoolPtr obj,
newvol = NULL;
/* Updating pool metadata */
pool->def->allocation += allocation;
pool->def->available -= allocation;
if (orig_pool_allocation == pool->def->allocation)
pool->def->allocation += allocation;
if (orig_pool_available == pool->def->available)
pool->def->available -= allocation;
VIR_INFO("Creating volume '%s' in storage pool '%s'",
volobj->name, pool->def->name);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册