mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
qemu: snapshot: move transient snapshot code to qemu_process
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@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com> Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
This commit is contained in:
parent
f9e8857eec
commit
b7583a5ba3
@ -6936,6 +6936,66 @@ 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 */
|
||||||
|
|
||||||
|
if (!(snapdisk = qemuSnapshotGetTransientDiskDef(domdisk)))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
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:
|
* qemuProcessLaunch:
|
||||||
*
|
*
|
||||||
@ -7290,7 +7350,7 @@ qemuProcessLaunch(virConnectPtr conn,
|
|||||||
|
|
||||||
if (!incoming && !snapshot) {
|
if (!incoming && !snapshot) {
|
||||||
VIR_DEBUG("Setting up transient disk");
|
VIR_DEBUG("Setting up transient disk");
|
||||||
if (qemuSnapshotCreateDisksTransient(vm, asyncJob) < 0)
|
if (qemuProcessSetupDisksTransient(vm, asyncJob) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -906,7 +906,7 @@ struct _qemuSnapshotDiskContext {
|
|||||||
typedef struct _qemuSnapshotDiskContext qemuSnapshotDiskContext;
|
typedef struct _qemuSnapshotDiskContext qemuSnapshotDiskContext;
|
||||||
|
|
||||||
|
|
||||||
static qemuSnapshotDiskContext *
|
qemuSnapshotDiskContext *
|
||||||
qemuSnapshotDiskContextNew(size_t ndisks,
|
qemuSnapshotDiskContextNew(size_t ndisks,
|
||||||
virDomainObj *vm,
|
virDomainObj *vm,
|
||||||
qemuDomainAsyncJob asyncJob)
|
qemuDomainAsyncJob asyncJob)
|
||||||
@ -925,7 +925,7 @@ qemuSnapshotDiskContextNew(size_t ndisks,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
void
|
||||||
qemuSnapshotDiskContextCleanup(qemuSnapshotDiskContext *snapctxt)
|
qemuSnapshotDiskContextCleanup(qemuSnapshotDiskContext *snapctxt)
|
||||||
{
|
{
|
||||||
if (!snapctxt)
|
if (!snapctxt)
|
||||||
@ -940,8 +940,6 @@ qemuSnapshotDiskContextCleanup(qemuSnapshotDiskContext *snapctxt)
|
|||||||
g_free(snapctxt);
|
g_free(snapctxt);
|
||||||
}
|
}
|
||||||
|
|
||||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(qemuSnapshotDiskContext, qemuSnapshotDiskContextCleanup);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* qemuSnapshotDiskBitmapsPropagate:
|
* qemuSnapshotDiskBitmapsPropagate:
|
||||||
@ -1032,7 +1030,7 @@ qemuSnapshotDiskPrepareOneBlockdev(virQEMUDriver *driver,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
int
|
||||||
qemuSnapshotDiskPrepareOne(qemuSnapshotDiskContext *snapctxt,
|
qemuSnapshotDiskPrepareOne(qemuSnapshotDiskContext *snapctxt,
|
||||||
virDomainDiskDef *disk,
|
virDomainDiskDef *disk,
|
||||||
virDomainSnapshotDiskDef *snapdisk,
|
virDomainSnapshotDiskDef *snapdisk,
|
||||||
@ -1170,7 +1168,7 @@ qemuSnapshotDiskPrepareActiveExternal(virDomainObj *vm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static virDomainSnapshotDiskDef *
|
virDomainSnapshotDiskDef *
|
||||||
qemuSnapshotGetTransientDiskDef(virDomainDiskDef *domdisk)
|
qemuSnapshotGetTransientDiskDef(virDomainDiskDef *domdisk)
|
||||||
{
|
{
|
||||||
g_autoptr(virDomainSnapshotDiskDef) snapdisk = g_new0(virDomainSnapshotDiskDef, 1);
|
g_autoptr(virDomainSnapshotDiskDef) snapdisk = g_new0(virDomainSnapshotDiskDef, 1);
|
||||||
@ -1193,40 +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 */
|
|
||||||
|
|
||||||
if (!(snapdisk = qemuSnapshotGetTransientDiskDef(domdisk)))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (qemuSnapshotDiskPrepareOne(snapctxt, domdisk, snapdisk,
|
|
||||||
blockNamedNodeData,
|
|
||||||
false,
|
|
||||||
false) < 0)
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return g_steal_pointer(&snapctxt);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
qemuSnapshotDiskUpdateSourceRenumber(virStorageSource *src)
|
qemuSnapshotDiskUpdateSourceRenumber(virStorageSource *src)
|
||||||
{
|
{
|
||||||
@ -1285,7 +1249,7 @@ qemuSnapshotDiskUpdateSource(virDomainObj *vm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
int
|
||||||
qemuSnapshotDiskCreate(qemuSnapshotDiskContext *snapctxt)
|
qemuSnapshotDiskCreate(qemuSnapshotDiskContext *snapctxt)
|
||||||
{
|
{
|
||||||
qemuDomainObjPrivate *priv = snapctxt->vm->privateData;
|
qemuDomainObjPrivate *priv = snapctxt->vm->privateData;
|
||||||
@ -1353,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
|
static int
|
||||||
qemuSnapshotCreateActiveExternal(virQEMUDriver *driver,
|
qemuSnapshotCreateActiveExternal(virQEMUDriver *driver,
|
||||||
virDomainObj *vm,
|
virDomainObj *vm,
|
||||||
|
@ -55,6 +55,28 @@ qemuSnapshotDelete(virDomainObj *vm,
|
|||||||
virDomainSnapshotPtr snapshot,
|
virDomainSnapshotPtr snapshot,
|
||||||
unsigned int flags);
|
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
|
int
|
||||||
qemuSnapshotCreateDisksTransient(virDomainObj *vm,
|
qemuSnapshotDiskPrepareOne(qemuSnapshotDiskContext *snapctxt,
|
||||||
qemuDomainAsyncJob asyncJob);
|
virDomainDiskDef *disk,
|
||||||
|
virDomainSnapshotDiskDef *snapdisk,
|
||||||
|
GHashTable *blockNamedNodeData,
|
||||||
|
bool reuse,
|
||||||
|
bool updateConfig);
|
||||||
|
int
|
||||||
|
qemuSnapshotDiskCreate(qemuSnapshotDiskContext *snapctxt);
|
||||||
|
|
||||||
|
virDomainSnapshotDiskDef *
|
||||||
|
qemuSnapshotGetTransientDiskDef(virDomainDiskDef *domdisk);
|
||||||
|
Loading…
Reference in New Issue
Block a user