Use the code for creating or attaching new storage source in the
snapshot code and switch to 'blockdev-snapshot' for creating the
snapshot itself.
Signed-off-by: Peter Krempa
---
src/qemu/qemu_driver.c | 104 ++---
1 file changed, 88 insertions(+), 16 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 6e10b691e9..c22f74adaa 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -15270,6 +15270,8 @@ struct _qemuDomainSnapshotDiskData {
bool prepared; /* @src was prepared using
qemuDomainStorageSourceAccessAllow */
virDomainDiskDefPtr disk;
char *relPath; /* relative path component to fill into original disk */
+qemuBlockStorageSourceChainDataPtr crdata;
+bool blockdevadded;
virStorageSourcePtr persistsrc;
virDomainDiskDefPtr persistdisk;
@@ -15283,7 +15285,8 @@ static void
qemuDomainSnapshotDiskDataCleanup(qemuDomainSnapshotDiskDataPtr data,
size_t ndata,
virQEMUDriverPtr driver,
- virDomainObjPtr vm)
+ virDomainObjPtr vm,
+ qemuDomainAsyncJob asyncJob)
{
size_t i;
@@ -15294,6 +15297,15 @@
qemuDomainSnapshotDiskDataCleanup(qemuDomainSnapshotDiskDataPtr data,
/* on success of the snapshot the 'src' and 'persistsrc' properties
will
* be set to NULL by qemuDomainSnapshotUpdateDiskSources */
if (data[i].src) {
+if (data[i].blockdevadded) {
+if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) == 0)
{
+
+
qemuBlockStorageSourceAttachRollback(qemuDomainGetMonitor(vm),
+
data[i].crdata->srcdata[0]);
+ignore_value(qemuDomainObjExitMonitor(driver, vm));
+}
+}
+
if (data[i].created &&
virStorageFileUnlink(data[i].src) < 0) {
VIR_WARN("Unable to remove just-created %s",
@@ -15312,6 +15324,7 @@
qemuDomainSnapshotDiskDataCleanup(qemuDomainSnapshotDiskDataPtr data,
VIR_FREE(data[i].relPath);
}
+qemuBlockStorageSourceChainDataFree(data[i].crdata);
VIR_FREE(data);
}
@@ -15319,15 +15332,20 @@
qemuDomainSnapshotDiskDataCleanup(qemuDomainSnapshotDiskDataPtr data,
static int
qemuDomainSnapshotDiskDataCollectOne(virQEMUDriverPtr driver,
virDomainObjPtr vm,
+ virQEMUDriverConfigPtr cfg,
virDomainDiskDefPtr disk,
virDomainSnapshotDiskDefPtr snapdisk,
qemuDomainSnapshotDiskDataPtr dd,
- bool reuse)
+ bool reuse,
+ bool blockdev,
+ qemuDomainAsyncJob asyncJob)
{
+qemuDomainObjPrivatePtr priv = vm->privateData;
char *backingStoreStr;
virDomainDiskDefPtr persistdisk;
bool supportsCreate;
bool supportsBacking;
+int rc;
dd->disk = disk;
@@ -15393,6 +15411,44 @@ qemuDomainSnapshotDiskDataCollectOne(virQEMUDriverPtr
driver,
dd->prepared = true;
+if (blockdev) {
+/* create a terminator for the snapsot disks so that qemu does not try
+ * to open them at first */
+virObjectUnref(dd->src->backingStore);
+if (!(dd->src->backingStore = virStorageSourceNew()))
+return -1;
+
+if (qemuDomainPrepareStorageSourceBlockdev(dd->disk, dd->src,
+ priv, cfg) < 0)
+return -1;
+
+if (!(dd->crdata =
qemuBuildStorageSourceChainAttachPrepareBlockdevTop(dd->src,
+
priv->qemuCaps)))
+return -1;
+
+if (reuse) {
+if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+return -1;
+
+rc = qemuBlockStorageSourceAttachApply(qemuDomainGetMonitor(vm),
+ dd->crdata->srcdata[0]);
+
+if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
+return -1;
+} else {
+if (qemuBlockStorageSourceCreateDetectSize(vm, dd->src,
dd->disk->src,
+ asyncJob) < 0)
+return -1;
+
+if (qemuBlockStorageSourceCreate(vm, dd->src, dd->disk->src,
+ NULL, dd->crdata->srcdata[0],
+ asyncJob) < 0)
+return -1;
+}
+
+dd->blockdevadded = true;
+}
+
return 0;
}
@@ -15407,7 +15463,10 @@ static int