Friday, 21 May
2021
Fri, 21 May
'21
7:47 a.m.
In preparation for hotplug of <transient> disks we'll need to track
whether the overlay file was created individually per-disk.
Add 'transientOverlayCreated' to 'struct _qemuDomainDiskPrivate' and
remove 'inhibitDiskTransientDelete' from 'qemuDomainObjPrivate' and
adjust the code for the change.
Signed-off-by: Peter Krempa <pkrempa(a)redhat.com>
---
src/qemu/qemu_domain.c | 2 --
src/qemu/qemu_domain.h | 7 +++----
src/qemu/qemu_process.c | 33 +++++++++++++++++++--------------
3 files changed, 22 insertions(+), 20 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 10641846b3..c5f994c4a5 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -1880,8 +1880,6 @@ qemuDomainObjPrivateDataClear(qemuDomainObjPrivate *priv)
g_slist_free_full(g_steal_pointer(&priv->dbusVMStateIds), g_free);
priv->dbusVMState = false;
-
- priv->inhibitDiskTransientDelete = false;
}
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 4fc1969d9e..9cebf9e426 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -258,10 +258,6 @@ struct _qemuDomainObjPrivate {
GSList *dbusVMStateIds;
/* true if -object dbus-vmstate was added */
bool dbusVMState;
-
- /* prevent deletion of <transient> disk overlay files between startup and
- * successful setup of the overlays */
- bool inhibitDiskTransientDelete;
};
#define QEMU_DOMAIN_PRIVATE(vm) \
@@ -292,6 +288,9 @@ struct _qemuDomainDiskPrivate {
unsigned int effectiveBootindex; /* boot index of the disk based on one
of the two ways we use to select a boot
device */
+
+ bool transientOverlayCreated; /* the overlay image of a transient disk was
+ created and the definition was updated */
};
#define QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(src) \
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 7fe051505b..9302180403 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -5709,9 +5709,6 @@ qemuProcessInit(virQEMUDriver *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);
@@ -7007,7 +7004,6 @@ static int
qemuProcessSetupDisksTransientSnapshot(virDomainObj *vm,
qemuDomainAsyncJob asyncJob)
{
- qemuDomainObjPrivate *priv = vm->privateData;
g_autoptr(qemuSnapshotDiskContext) snapctxt = NULL;
g_autoptr(GHashTable) blockNamedNodeData = NULL;
size_t i;
@@ -7039,8 +7035,14 @@ qemuProcessSetupDisksTransientSnapshot(virDomainObj *vm,
if (qemuSnapshotDiskCreate(snapctxt) < 0)
return -1;
- /* the overlays are established, so they can be deleted on shutdown */
- priv->inhibitDiskTransientDelete = false;
+ for (i = 0; i < vm->def->ndisks; i++) {
+ virDomainDiskDef *domdisk = vm->def->disks[i];
+
+ if (!domdisk->transient)
+ continue;
+
+ QEMU_DOMAIN_DISK_PRIVATE(domdisk)->transientOverlayCreated = true;
+ }
return 0;
}
@@ -8077,7 +8079,7 @@ void qemuProcessStop(virQEMUDriver *driver,
/* for now transient disks are forbidden with migration so they
* can be handled here */
if (disk->transient &&
- !priv->inhibitDiskTransientDelete) {
+ QEMU_DOMAIN_DISK_PRIVATE(disk)->transientOverlayCreated) {
VIR_DEBUG("Removing transient overlay '%s' of disk
'%s'",
disk->src->path, disk->dst);
if (qemuDomainStorageFileInit(driver, vm, disk->src, NULL) >= 0) {
@@ -8505,10 +8507,6 @@ qemuProcessReconnect(void *opaque)
if (oldjob.asyncJob == QEMU_ASYNC_JOB_BACKUP && priv->backup)
priv->backup->apiFlags = oldjob.apiFlags;
- /* 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;
@@ -8611,9 +8609,6 @@ 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.
@@ -8662,6 +8657,16 @@ qemuProcessReconnect(void *opaque)
if (qemuProcessRefreshDisks(driver, obj, QEMU_ASYNC_JOB_NONE) < 0)
goto error;
+ /* At this point we've already checked that the startup of the VM was
+ * completed successfully before, thus that also implies that all transient
+ * disk overlays were created. */
+ for (i = 0; i < obj->def->ndisks; i++) {
+ virDomainDiskDef *disk = obj->def->disks[i];
+
+ if (disk->transient)
+ QEMU_DOMAIN_DISK_PRIVATE(disk)->transientOverlayCreated = true;
+ }
+
if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV) &&
qemuBlockNodeNamesDetect(driver, obj, QEMU_ASYNC_JOB_NONE) < 0)
goto error;
--
2.31.1