Calling the monitor was convenient for the implementation in
qemuDomainBlockCopyCommon, but causes the snapshot code to call
query-named-block-nodes for every disk.
Fix this by removing the monitor call from
qemuBlockStorageSourceCreateDetectSize so that the data can be reused in
loops.
Signed-off-by: Peter Krempa <pkrempa(a)redhat.com>
---
src/qemu/qemu_block.c | 26 +++++---------------------
src/qemu/qemu_block.h | 5 ++---
src/qemu/qemu_driver.c | 33 ++++++++++++++++++++++++++++-----
3 files changed, 35 insertions(+), 29 deletions(-)
diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
index 4dc4f2922d..c966b24cb6 100644
--- a/src/qemu/qemu_block.c
+++ b/src/qemu/qemu_block.c
@@ -2578,10 +2578,9 @@ qemuBlockStorageSourceCreate(virDomainObjPtr vm,
/**
* qemuBlockStorageSourceCreateDetectSize:
- * @vm: domain object
+ * @blockNamedNodeData: hash table filled with qemuBlockNamedNodeData
* @src: storage source to update size/capacity on
* @templ: storage source template
- * @asyncJob: qemu asynchronous job type
*
* When creating a storage source via blockdev-create we need to know the size
* and capacity of the original volume (e.g. when creating a snapshot or copy).
@@ -2589,28 +2588,13 @@ qemuBlockStorageSourceCreate(virDomainObjPtr vm,
* to the detected sizes from @templ.
*/
int
-qemuBlockStorageSourceCreateDetectSize(virDomainObjPtr vm,
+qemuBlockStorageSourceCreateDetectSize(virHashTablePtr blockNamedNodeData,
virStorageSourcePtr src,
- virStorageSourcePtr templ,
- qemuDomainAsyncJob asyncJob)
+ virStorageSourcePtr templ)
{
- qemuDomainObjPrivatePtr priv = vm->privateData;
- g_autoptr(virHashTable) stats = NULL;
- qemuBlockStatsPtr entry;
- int rc;
-
- if (!(stats = virHashCreate(10, virHashValueFree)))
- return -1;
-
- if (qemuDomainObjEnterMonitorAsync(priv->driver, vm, asyncJob) < 0)
- return -1;
-
- rc = qemuMonitorBlockStatsUpdateCapacityBlockdev(priv->mon, stats);
-
- if (qemuDomainObjExitMonitor(priv->driver, vm) < 0 || rc < 0)
- return -1;
+ qemuBlockNamedNodeDataPtr entry;
- if (!(entry = virHashLookup(stats, templ->nodeformat))) {
+ if (!(entry = virHashLookup(blockNamedNodeData, templ->nodeformat))) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("failed to update capacity data for block node
'%s'"),
templ->nodeformat);
diff --git a/src/qemu/qemu_block.h b/src/qemu/qemu_block.h
index be39c9b472..5ddeeaf6e2 100644
--- a/src/qemu/qemu_block.h
+++ b/src/qemu/qemu_block.h
@@ -194,7 +194,6 @@ qemuBlockStorageSourceCreate(virDomainObjPtr vm,
qemuDomainAsyncJob asyncJob);
int
-qemuBlockStorageSourceCreateDetectSize(virDomainObjPtr vm,
+qemuBlockStorageSourceCreateDetectSize(virHashTablePtr blockNamedNodeData,
virStorageSourcePtr src,
- virStorageSourcePtr templ,
- qemuDomainAsyncJob asyncJob);
+ virStorageSourcePtr templ);
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index e50f2277d2..e908331a93 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -15252,6 +15252,7 @@ qemuDomainSnapshotDiskPrepareOne(virQEMUDriverPtr driver,
virDomainDiskDefPtr disk,
virDomainSnapshotDiskDefPtr snapdisk,
qemuDomainSnapshotDiskDataPtr dd,
+ virHashTablePtr blockNamedNodeData,
bool reuse,
bool blockdev,
qemuDomainAsyncJob asyncJob)
@@ -15355,8 +15356,8 @@ qemuDomainSnapshotDiskPrepareOne(virQEMUDriverPtr driver,
if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
return -1;
} else {
- if (qemuBlockStorageSourceCreateDetectSize(vm, dd->src,
dd->disk->src,
- asyncJob) < 0)
+ if (qemuBlockStorageSourceCreateDetectSize(blockNamedNodeData,
+ dd->src, dd->disk->src)
< 0)
return -1;
if (qemuBlockStorageSourceCreate(vm, dd->src, dd->disk->src,
@@ -15385,6 +15386,7 @@ qemuDomainSnapshotDiskPrepare(virQEMUDriverPtr driver,
virQEMUDriverConfigPtr cfg,
bool reuse,
bool blockdev,
+ virHashTablePtr blockNamedNodeData,
qemuDomainAsyncJob asyncJob,
qemuDomainSnapshotDiskDataPtr *rdata,
size_t *rndata)
@@ -15404,7 +15406,9 @@ qemuDomainSnapshotDiskPrepare(virQEMUDriverPtr driver,
if (qemuDomainSnapshotDiskPrepareOne(driver, vm, cfg, vm->def->disks[i],
snapdef->disks + i,
- data + ndata++, reuse, blockdev,
+ data + ndata++,
+ blockNamedNodeData,
+ reuse, blockdev,
asyncJob) < 0)
goto cleanup;
}
@@ -15495,6 +15499,7 @@ qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr driver,
qemuDomainSnapshotDiskDataPtr diskdata = NULL;
size_t ndiskdata = 0;
bool blockdev = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV);
+ g_autoptr(virHashTable) blockNamedNodeData = NULL;
if (virDomainObjCheckActive(vm) < 0)
return -1;
@@ -15502,10 +15507,21 @@ qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr driver,
if (!(actions = virJSONValueNewArray()))
return -1;
+ if (blockdev) {
+ if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+ return -1;
+
+ blockNamedNodeData = qemuMonitorBlockGetNamedNodeData(priv->mon);
+
+ if (qemuDomainObjExitMonitor(driver, vm) < 0 || !blockNamedNodeData)
+ return -1;
+ }
+
/* prepare a list of objects to use in the vm definition so that we don't
* have to roll back later */
if (qemuDomainSnapshotDiskPrepare(driver, vm, snap, cfg, reuse, blockdev,
- asyncJob, &diskdata, &ndiskdata) < 0)
+ blockNamedNodeData, asyncJob,
+ &diskdata, &ndiskdata) < 0)
goto cleanup;
/* check whether there's anything to do */
@@ -18018,6 +18034,7 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm,
g_autoptr(qemuBlockStorageSourceChainData) crdata = NULL;
virStorageSourcePtr n;
virStorageSourcePtr mirrorBacking = NULL;
+ g_autoptr(virHashTable) blockNamedNodeData = NULL;
int rc = 0;
/* Preliminaries: find the disk we are editing, sanity checks */
@@ -18179,7 +18196,13 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm,
priv->qemuCaps)))
goto endjob;
} else {
- if (qemuBlockStorageSourceCreateDetectSize(vm, mirror, disk->src,
QEMU_ASYNC_JOB_NONE) < 0)
+ qemuDomainObjEnterMonitor(driver, vm);
+ blockNamedNodeData = qemuMonitorBlockGetNamedNodeData(priv->mon);
+ if (qemuDomainObjExitMonitor(driver, vm) < 0 || !blockNamedNodeData)
+ goto endjob;
+
+ if (qemuBlockStorageSourceCreateDetectSize(blockNamedNodeData,
+ mirror, disk->src))
goto endjob;
if (mirror_shallow) {
--
2.21.0