Later patches will implement support for <transient/> disks in libvirt
by installing an overlay on top of the configured image. This will
require cleanup after the VM will be stopped so that the state is
correctly discarded.
Since the overlay will be installed only during the startup phase of the
VM we need to ensure that qemuProcessStop doesn't delete the original
file on some previous failure. This is solved by adding
'inhibitDiskTransientDelete' VM private data member which is set prior
to any startup step and will be cleared once transient disk overlays are
established.
Based on that we can then delete the overlays for any <transient/> disk.
Signed-off-by: Peter Krempa <pkrempa(a)redhat.com>
---
src/qemu/qemu_domain.c | 2 ++
src/qemu/qemu_domain.h | 4 ++++
src/qemu/qemu_process.c | 22 ++++++++++++++++++++++
3 files changed, 28 insertions(+)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 279de2997d..dc5949edfa 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -1792,6 +1792,8 @@ qemuDomainObjPrivateDataClear(qemuDomainObjPrivatePtr priv)
priv->dbusVMStateIds = NULL;
priv->dbusVMState = false;
+
+ priv->inhibitDiskTransientDelete = false;
}
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index c7c3c5c073..ec776ced72 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -263,6 +263,10 @@ struct _qemuDomainObjPrivate {
char **dbusVMStateIds;
/* true if -object dbus-vmstate was added */
bool dbusVMState;
+
+ /* prevent deletion of <transient> disk overlay files between startup and
+ * succesful setup of the overlays */
+ bool inhibitDiskTransientDelete;
};
#define QEMU_DOMAIN_PRIVATE(vm) \
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index f21b8f1585..ffb3afa9c5 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -5616,6 +5616,9 @@ qemuProcessInit(virQEMUDriverPtr driver,
if (virDomainObjSetDefTransient(driver->xmlopt, vm, priv->qemuCaps) < 0)
goto cleanup;
+ /* don't clean up files for <transient> disks until we set them up */
+ priv->inhibitDiskTransientDelete = true;
+
if (flags & VIR_QEMU_PROCESS_START_PRETEND) {
if (qemuDomainSetPrivatePaths(driver, vm) < 0) {
virDomainObjRemoveTransientDef(vm);
@@ -7710,6 +7713,18 @@ void qemuProcessStop(virQEMUDriverPtr driver,
}
qemuBlockRemoveImageMetadata(driver, vm, disk->dst, disk->src);
+
+ /* for now transient disks are forbidden with migration so they
+ * can be handled here */
+ if (disk->transient &&
+ !priv->inhibitDiskTransientDelete) {
+ VIR_DEBUG("Removing transient overlay '%s' of disk
'%s'",
+ disk->src->path, disk->dst);
+ if (qemuDomainStorageFileInit(driver, vm, disk->src, NULL) >= 0) {
+ virStorageFileUnlink(disk->src);
+ virStorageFileDeinit(disk->src);
+ }
+ }
}
}
@@ -8125,6 +8140,10 @@ qemuProcessReconnect(void *opaque)
cfg = virQEMUDriverGetConfig(driver);
priv = obj->privateData;
+ /* expect that libvirt might have crashed during VM start, so prevent
+ * cleanup of transient disks */
+ priv->inhibitDiskTransientDelete = true;
+
if (qemuDomainObjBeginJob(driver, obj, QEMU_JOB_MODIFY) < 0)
goto error;
jobStarted = true;
@@ -8228,6 +8247,9 @@ qemuProcessReconnect(void *opaque)
goto error;
}
+ /* vm startup complete, we can remove transient disks if required */
+ priv->inhibitDiskTransientDelete = false;
+
/* In case the domain shutdown while we were not running,
* we need to finish the shutdown process. And we need to do it after
* we have virQEMUCaps filled in.
--
2.26.2