diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c
index ca051071aa..c2953c179b 100644
--- a/src/qemu/qemu_snapshot.c
+++ b/src/qemu/qemu_snapshot.c
@@ -986,6 +986,7 @@ qemuSnapshotDiskPrepareOne(virDomainObjPtr vm,
qemuSnapshotDiskDataPtr dd,
virHashTablePtr blockNamedNodeData,
bool reuse,
+ bool updateConfig,
qemuDomainAsyncJob asyncJob,
virJSONValuePtr actions)
{
@@ -1008,7 +1009,8 @@ qemuSnapshotDiskPrepareOne(virDomainObjPtr vm,
return -1;
/* modify disk in persistent definition only when the source is the same */
- if (vm->newDef &&
+ if (updateConfig &&
+ vm->newDef &&
(persistdisk = virDomainDiskByTarget(vm->newDef, dd->disk->dst)) &&
virStorageSourceIsSameLocation(dd->disk->src, persistdisk->src)) {
@@ -1116,6 +1118,55 @@ qemuSnapshotDiskPrepareActiveExternal(virDomainObjPtr vm,
snapctxt->dd + snapctxt->ndd++,
blockNamedNodeData,
reuse,
+ true,
+ asyncJob,
+ snapctxt->actions) < 0)
+ return NULL;
+ }
+
+ return g_steal_pointer(&snapctxt);
+}
+
+
+static qemuSnapshotDiskContextPtr
+qemuSnapshotDiskPrepareDisksTransient(virDomainObjPtr vm,
+ virQEMUDriverConfigPtr cfg,
+ virHashTablePtr blockNamedNodeData,
+ qemuDomainAsyncJob asyncJob)
+{
+ g_autoptr(qemuSnapshotDiskContext) snapctxt = NULL;
+ size_t i;
+
+ snapctxt = qemuSnapshotDiskContextNew(vm->def->ndisks, vm, asyncJob);
+
+ for (i = 0; i < vm->def->ndisks; i++) {
+ virDomainDiskDefPtr domdisk = vm->def->disks[i];
+ g_autoptr(virDomainSnapshotDiskDef) snapdisk = g_new0(virDomainSnapshotDiskDef, 1);
+
+ if (!domdisk->transient)
+ continue;
+
+ /* validation code makes sure that we do this only for local disks
+ * with a file source */
+ snapdisk->name = g_strdup(domdisk->dst);
+ snapdisk->snapshot = VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL;
+ snapdisk->src = virStorageSourceNew();
+ snapdisk->src->type = VIR_STORAGE_TYPE_FILE;
+ snapdisk->src->format = VIR_STORAGE_FILE_QCOW2;
+ snapdisk->src->path = g_strdup_printf("%s.TRANSIENT", domdisk->src->path);
+
+ if (virFileExists(snapdisk->src->path)) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
+ _("Overlay file '%s' for transient disk '%s' already exists"),
+ snapdisk->src->path, domdisk->dst);
+ return NULL;
+ }
+
+ if (qemuSnapshotDiskPrepareOne(vm, cfg, domdisk, snapdisk,
+ snapctxt->dd + snapctxt->ndd++,
+ blockNamedNodeData,
+ false,
+ false,
asyncJob,
snapctxt->actions) < 0)
return NULL;
@@ -1253,6 +1304,45 @@ qemuSnapshotCreateActiveExternalDisks(virDomainObjPtr vm,
}
+/**
+ * qemuSnapshotCreateDisksTransient:
+ * @vm: domain object
+ * @asyncJob: qemu async job type
+ *
+ * Creates overlays on top of disks which are configured as . Note
+ * that the validation code ensures that disks have appropriate
+ * configuration.
+ */
+int
+qemuSnapshotCreateDisksTransient(virDomainObjPtr vm,
+ qemuDomainAsyncJob asyncJob)
+{
+ qemuDomainObjPrivatePtr priv = vm->privateData;
+ virQEMUDriverPtr driver = priv->driver;
+ g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
+ g_autoptr(qemuSnapshotDiskContext) snapctxt = NULL;
+ g_autoptr(virHashTable) blockNamedNodeData = NULL;
+
+ if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV)) {
+ if (!(blockNamedNodeData = qemuBlockGetNamedNodeData(vm, asyncJob)))
+ return -1;
+
+ if (!(snapctxt = qemuSnapshotDiskPrepareDisksTransient(vm, cfg,
+ blockNamedNodeData,
+ asyncJob)))
+ return -1;
+
+ if (qemuSnapshotDiskCreate(snapctxt, cfg) < 0)
+ return -1;
+ }
+
+ /* the overlays are established, so they can be deleted on shutdown */
+ priv->inhibitDiskTransientDelete = false;
+
+ return 0;
+}
+
+
static int
qemuSnapshotCreateActiveExternal(virQEMUDriverPtr driver,
virDomainObjPtr vm,
diff --git a/src/qemu/qemu_snapshot.h b/src/qemu/qemu_snapshot.h
index 8b3ebe87b1..cf9bfec542 100644
--- a/src/qemu/qemu_snapshot.h
+++ b/src/qemu/qemu_snapshot.h
@@ -21,6 +21,7 @@
#include "virconftypes.h"
#include "datatypes.h"
#include "qemu_conf.h"
+#include "qemu_domainjob.h"
virDomainMomentObjPtr
qemuSnapObjFromName(virDomainObjPtr vm,
@@ -53,3 +54,7 @@ int
qemuSnapshotDelete(virDomainObjPtr vm,
virDomainSnapshotPtr snapshot,
unsigned int flags);
+
+int
+qemuSnapshotCreateDisksTransient(virDomainObjPtr vm,
+ qemuDomainAsyncJob asyncJob);