The code deals with the startup of the VM and just uses the snapshot code to achieve the desired outcome. Signed-off-by: Peter Krempa <pkrempa@xxxxxxxxxx> --- src/qemu/qemu_process.c | 61 +++++++++++++++++++++++++++++- src/qemu/qemu_snapshot.c | 82 +++------------------------------------- src/qemu/qemu_snapshot.h | 26 ++++++++++++- 3 files changed, 89 insertions(+), 80 deletions(-) diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 543b50f875..9222f16caa 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -6937,6 +6937,65 @@ qemuProcessEnablePerf(virDomainObj *vm) } +static int +qemuProcessSetupDisksTransientSnapshot(virDomainObj *vm, + qemuDomainAsyncJob asyncJob) +{ + qemuDomainObjPrivate *priv = vm->privateData; + g_autoptr(qemuSnapshotDiskContext) snapctxt = NULL; + g_autoptr(GHashTable) blockNamedNodeData = NULL; + size_t i; + + if (!(blockNamedNodeData = qemuBlockGetNamedNodeData(vm, asyncJob))) + return -1; + + snapctxt = qemuSnapshotDiskContextNew(vm->def->ndisks, vm, asyncJob); + + for (i = 0; i < vm->def->ndisks; i++) { + virDomainDiskDef *domdisk = vm->def->disks[i]; + g_autoptr(virDomainSnapshotDiskDef) snapdisk = NULL; + + if (!domdisk->transient) + continue; + + /* validation code makes sure that we do this only for local disks + * with a file source */ + + snapdisk = qemuSnapshotGetTransientDiskDef(domdisk); + + if (qemuSnapshotDiskPrepareOne(snapctxt, domdisk, snapdisk, + blockNamedNodeData, + false, + false) < 0) + return -1; + } + + if (qemuSnapshotDiskCreate(snapctxt) < 0) + return -1; + + /* the overlays are established, so they can be deleted on shutdown */ + priv->inhibitDiskTransientDelete = false; + + return 0; +} + + +static int +qemuProcessSetupDisksTransient(virDomainObj *vm, + qemuDomainAsyncJob asyncJob) +{ + qemuDomainObjPrivate *priv = vm->privateData; + + if (!(virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV))) + return 0; + + if (qemuProcessSetupDisksTransientSnapshot(vm, asyncJob) < 0) + return -1; + + return 0; +} + + /** * qemuProcessLaunch: * @@ -7291,7 +7350,7 @@ qemuProcessLaunch(virConnectPtr conn, if (!incoming && !snapshot) { VIR_DEBUG("Setting up transient disk"); - if (qemuSnapshotCreateDisksTransient(vm, asyncJob) < 0) + if (qemuProcessSetupDisksTransient(vm, asyncJob) < 0) goto cleanup; } diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c index 8855a019cb..928b7af287 100644 --- a/src/qemu/qemu_snapshot.c +++ b/src/qemu/qemu_snapshot.c @@ -906,7 +906,7 @@ struct _qemuSnapshotDiskContext { typedef struct _qemuSnapshotDiskContext qemuSnapshotDiskContext; -static qemuSnapshotDiskContext * +qemuSnapshotDiskContext * qemuSnapshotDiskContextNew(size_t ndisks, virDomainObj *vm, qemuDomainAsyncJob asyncJob) @@ -925,7 +925,7 @@ qemuSnapshotDiskContextNew(size_t ndisks, } -static void +void qemuSnapshotDiskContextCleanup(qemuSnapshotDiskContext *snapctxt) { if (!snapctxt) @@ -940,8 +940,6 @@ qemuSnapshotDiskContextCleanup(qemuSnapshotDiskContext *snapctxt) g_free(snapctxt); } -G_DEFINE_AUTOPTR_CLEANUP_FUNC(qemuSnapshotDiskContext, qemuSnapshotDiskContextCleanup); - /** * qemuSnapshotDiskBitmapsPropagate: @@ -1032,7 +1030,7 @@ qemuSnapshotDiskPrepareOneBlockdev(virQEMUDriver *driver, } -static int +int qemuSnapshotDiskPrepareOne(qemuSnapshotDiskContext *snapctxt, virDomainDiskDef *disk, virDomainSnapshotDiskDef *snapdisk, @@ -1170,7 +1168,7 @@ qemuSnapshotDiskPrepareActiveExternal(virDomainObj *vm, } -static virDomainSnapshotDiskDef * +virDomainSnapshotDiskDef * qemuSnapshotGetTransientDiskDef(virDomainDiskDef *domdisk) { g_autoptr(virDomainSnapshotDiskDef) snapdisk = g_new0(virDomainSnapshotDiskDef, 1); @@ -1193,39 +1191,6 @@ qemuSnapshotGetTransientDiskDef(virDomainDiskDef *domdisk) } -static qemuSnapshotDiskContext * -qemuSnapshotDiskPrepareDisksTransient(virDomainObj *vm, - GHashTable *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++) { - virDomainDiskDef *domdisk = vm->def->disks[i]; - g_autoptr(virDomainSnapshotDiskDef) snapdisk = NULL; - - if (!domdisk->transient) - continue; - - /* validation code makes sure that we do this only for local disks - * with a file source */ - - snapdisk = qemuSnapshotGetTransientDiskDef(domdisk); - - if (qemuSnapshotDiskPrepareOne(snapctxt, domdisk, snapdisk, - blockNamedNodeData, - false, - false) < 0) - return NULL; - } - - return g_steal_pointer(&snapctxt); -} - - static void qemuSnapshotDiskUpdateSourceRenumber(virStorageSource *src) { @@ -1284,7 +1249,7 @@ qemuSnapshotDiskUpdateSource(virDomainObj *vm, } -static int +int qemuSnapshotDiskCreate(qemuSnapshotDiskContext *snapctxt) { qemuDomainObjPrivate *priv = snapctxt->vm->privateData; @@ -1352,43 +1317,6 @@ qemuSnapshotCreateActiveExternalDisks(virDomainObj *vm, } -/** - * qemuSnapshotCreateDisksTransient: - * @vm: domain object - * @asyncJob: qemu async job type - * - * Creates overlays on top of disks which are configured as <transient/>. Note - * that the validation code ensures that <transient> disks have appropriate - * configuration. - */ -int -qemuSnapshotCreateDisksTransient(virDomainObj *vm, - qemuDomainAsyncJob asyncJob) -{ - qemuDomainObjPrivate *priv = vm->privateData; - g_autoptr(qemuSnapshotDiskContext) snapctxt = NULL; - g_autoptr(GHashTable) blockNamedNodeData = NULL; - - if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV)) { - if (!(blockNamedNodeData = qemuBlockGetNamedNodeData(vm, asyncJob))) - return -1; - - if (!(snapctxt = qemuSnapshotDiskPrepareDisksTransient(vm, - blockNamedNodeData, - asyncJob))) - return -1; - - if (qemuSnapshotDiskCreate(snapctxt) < 0) - return -1; - } - - /* the overlays are established, so they can be deleted on shutdown */ - priv->inhibitDiskTransientDelete = false; - - return 0; -} - - static int qemuSnapshotCreateActiveExternal(virQEMUDriver *driver, virDomainObj *vm, diff --git a/src/qemu/qemu_snapshot.h b/src/qemu/qemu_snapshot.h index 62ff22221d..4fba7e4e24 100644 --- a/src/qemu/qemu_snapshot.h +++ b/src/qemu/qemu_snapshot.h @@ -55,6 +55,28 @@ qemuSnapshotDelete(virDomainObj *vm, virDomainSnapshotPtr snapshot, unsigned int flags); + +typedef struct _qemuSnapshotDiskContext qemuSnapshotDiskContext; + +qemuSnapshotDiskContext * +qemuSnapshotDiskContextNew(size_t ndisks, + virDomainObj *vm, + qemuDomainAsyncJob asyncJob); + +void +qemuSnapshotDiskContextCleanup(qemuSnapshotDiskContext *snapctxt); + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(qemuSnapshotDiskContext, qemuSnapshotDiskContextCleanup); + +int +qemuSnapshotDiskPrepareOne(qemuSnapshotDiskContext *snapctxt, + virDomainDiskDef *disk, + virDomainSnapshotDiskDef *snapdisk, + GHashTable *blockNamedNodeData, + bool reuse, + bool updateConfig); int -qemuSnapshotCreateDisksTransient(virDomainObj *vm, - qemuDomainAsyncJob asyncJob); +qemuSnapshotDiskCreate(qemuSnapshotDiskContext *snapctxt); + +virDomainSnapshotDiskDef * +qemuSnapshotGetTransientDiskDef(virDomainDiskDef *domdisk); -- 2.31.1