When creating a new volume, it is possible to copy data into it from another already existing volume (referred to as @origvol). Obviously, the read-only access to @origvol is required, which is thread safe (probably not performance-wise though). However, with current code both @newvol and @origvol are marked as building for the time of copying data from the @origvol to @newvol. The rationale behind is to disallow some operations on both @origvol and @newvol, e.g. vol-wipe, vol-delete, vol-download. While it makes sense to not allow such operations on partly copied mirror, but it doesn't make sense to disallow the operations on the source (@origvol). Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> --- Diff to v1: -introduced a counter in addition to not marking origvol as building src/conf/storage_conf.h | 1 + src/storage/storage_driver.c | 14 +++++++------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h index 9ad38e1..eae959c 100644 --- a/src/conf/storage_conf.h +++ b/src/conf/storage_conf.h @@ -64,6 +64,7 @@ struct _virStorageVolDef { int type; /* enum virStorageVolType */ unsigned int building; + unsigned int in_use; virStorageVolSource source; virStorageSource target; diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c index 2cb8347..a953dfd 100644 --- a/src/storage/storage_driver.c +++ b/src/storage/storage_driver.c @@ -1640,7 +1640,7 @@ storageVolDelete(virStorageVolPtr obj, if (virStorageVolDeleteEnsureACL(obj->conn, pool->def, vol) < 0) goto cleanup; - if (vol->building) { + if (vol->building || vol->in_use) { virReportError(VIR_ERR_OPERATION_INVALID, _("volume '%s' is still being allocated."), vol->name); @@ -1912,8 +1912,8 @@ storageVolCreateXMLFrom(virStoragePoolPtr obj, /* Drop the pool lock during volume allocation */ pool->asyncjobs++; - origvol->building = 1; newvol->building = 1; + origvol->in_use++; virStoragePoolObjUnlock(pool); if (origpool) { @@ -1929,7 +1929,7 @@ storageVolCreateXMLFrom(virStoragePoolPtr obj, virStoragePoolObjLock(origpool); storageDriverUnlock(driver); - origvol->building = 0; + origvol->in_use--; newvol->building = 0; allocation = newvol->target.allocation; pool->asyncjobs--; @@ -2010,7 +2010,7 @@ storageVolDownload(virStorageVolPtr obj, if (virStorageVolDownloadEnsureACL(obj->conn, pool->def, vol) < 0) goto cleanup; - if (vol->building) { + if (vol->building || vol->in_use) { virReportError(VIR_ERR_OPERATION_INVALID, _("volume '%s' is still being allocated."), vol->name); @@ -2076,7 +2076,7 @@ storageVolUpload(virStorageVolPtr obj, if (virStorageVolUploadEnsureACL(obj->conn, pool->def, vol) < 0) goto cleanup; - if (vol->building) { + if (vol->building || vol->in_use) { virReportError(VIR_ERR_OPERATION_INVALID, _("volume '%s' is still being allocated."), vol->name); @@ -2167,7 +2167,7 @@ storageVolResize(virStorageVolPtr obj, if (virStorageVolResizeEnsureACL(obj->conn, pool->def, vol) < 0) goto cleanup; - if (vol->building) { + if (vol->building || vol->in_use) { virReportError(VIR_ERR_OPERATION_INVALID, _("volume '%s' is still being allocated."), vol->name); @@ -2474,7 +2474,7 @@ storageVolWipePattern(virStorageVolPtr obj, if (virStorageVolWipePatternEnsureACL(obj->conn, pool->def, vol) < 0) goto cleanup; - if (vol->building) { + if (vol->building || vol->in_use) { virReportError(VIR_ERR_OPERATION_INVALID, _("volume '%s' is still being allocated."), vol->name); -- 1.9.0 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list