mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-04-26 15:14:42 +00:00
Storage: Introduce shadow vol for refresh while the main vol builds.
Libvirt periodically refreshes all volumes in a storage pool, including the volumes being cloned. While cloning a storage volume from parent, we drop pool locks. Subsequent volume refresh sometimes changes allocation for an ongoing copy, and leads to corrupt images. Fix: Introduce a shadow volume that isolates the volume object under refresh from the base which has a copy ongoing. Signed-off-by: Prerna Saxena <prerna@linux.vnet.ibm.com> Signed-off-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
parent
ea1c7b652b
commit
7e7dee4389
@ -1898,9 +1898,8 @@ storageVolCreateXMLFrom(virStoragePoolPtr obj,
|
|||||||
{
|
{
|
||||||
virStoragePoolObjPtr pool, origpool = NULL;
|
virStoragePoolObjPtr pool, origpool = NULL;
|
||||||
virStorageBackendPtr backend;
|
virStorageBackendPtr backend;
|
||||||
virStorageVolDefPtr origvol = NULL, newvol = NULL;
|
virStorageVolDefPtr origvol = NULL, newvol = NULL, shadowvol = NULL;
|
||||||
virStorageVolPtr ret = NULL, volobj = NULL;
|
virStorageVolPtr ret = NULL, volobj = NULL;
|
||||||
unsigned long long allocation;
|
|
||||||
int buildret;
|
int buildret;
|
||||||
|
|
||||||
virCheckFlags(VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA |
|
virCheckFlags(VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA |
|
||||||
@ -2010,6 +2009,15 @@ storageVolCreateXMLFrom(virStoragePoolPtr obj,
|
|||||||
if (backend->createVol(obj->conn, pool, newvol) < 0)
|
if (backend->createVol(obj->conn, pool, newvol) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
|
/* Make a shallow copy of the 'defined' volume definition, since the
|
||||||
|
* original allocation value will change as the user polls 'info',
|
||||||
|
* but we only need the initial requested values
|
||||||
|
*/
|
||||||
|
if (VIR_ALLOC(shadowvol) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
memcpy(shadowvol, newvol, sizeof(*newvol));
|
||||||
|
|
||||||
pool->volumes.objs[pool->volumes.count++] = newvol;
|
pool->volumes.objs[pool->volumes.count++] = newvol;
|
||||||
volobj = virGetStorageVol(obj->conn, pool->def->name, newvol->name,
|
volobj = virGetStorageVol(obj->conn, pool->def->name, newvol->name,
|
||||||
newvol->key, NULL, NULL);
|
newvol->key, NULL, NULL);
|
||||||
@ -2029,7 +2037,7 @@ storageVolCreateXMLFrom(virStoragePoolPtr obj,
|
|||||||
virStoragePoolObjUnlock(origpool);
|
virStoragePoolObjUnlock(origpool);
|
||||||
}
|
}
|
||||||
|
|
||||||
buildret = backend->buildVolFrom(obj->conn, pool, newvol, origvol, flags);
|
buildret = backend->buildVolFrom(obj->conn, pool, shadowvol, origvol, flags);
|
||||||
|
|
||||||
storageDriverLock();
|
storageDriverLock();
|
||||||
virStoragePoolObjLock(pool);
|
virStoragePoolObjLock(pool);
|
||||||
@ -2039,7 +2047,6 @@ storageVolCreateXMLFrom(virStoragePoolPtr obj,
|
|||||||
|
|
||||||
origvol->in_use--;
|
origvol->in_use--;
|
||||||
newvol->building = false;
|
newvol->building = false;
|
||||||
allocation = newvol->target.allocation;
|
|
||||||
pool->asyncjobs--;
|
pool->asyncjobs--;
|
||||||
|
|
||||||
if (origpool) {
|
if (origpool) {
|
||||||
@ -2059,8 +2066,8 @@ storageVolCreateXMLFrom(virStoragePoolPtr obj,
|
|||||||
* it updates the pool values
|
* it updates the pool values
|
||||||
*/
|
*/
|
||||||
if (pool->def->type != VIR_STORAGE_POOL_DISK) {
|
if (pool->def->type != VIR_STORAGE_POOL_DISK) {
|
||||||
pool->def->allocation += allocation;
|
pool->def->allocation += shadowvol->target.allocation;
|
||||||
pool->def->available -= allocation;
|
pool->def->available -= shadowvol->target.allocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
VIR_INFO("Creating volume '%s' in storage pool '%s'",
|
VIR_INFO("Creating volume '%s' in storage pool '%s'",
|
||||||
@ -2071,6 +2078,7 @@ storageVolCreateXMLFrom(virStoragePoolPtr obj,
|
|||||||
cleanup:
|
cleanup:
|
||||||
virObjectUnref(volobj);
|
virObjectUnref(volobj);
|
||||||
virStorageVolDefFree(newvol);
|
virStorageVolDefFree(newvol);
|
||||||
|
VIR_FREE(shadowvol);
|
||||||
if (pool)
|
if (pool)
|
||||||
virStoragePoolObjUnlock(pool);
|
virStoragePoolObjUnlock(pool);
|
||||||
if (origpool)
|
if (origpool)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user