mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-27 09:57:43 +03:00
qemu_snapshot: create: move snapshot create to separate function
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
parent
f4aae9726d
commit
9bad0fb809
@ -1756,6 +1756,81 @@ qemuSnapshotRedefine(virDomainObj *vm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static virDomainSnapshotPtr
|
||||||
|
qemuSnapshotCreate(virDomainObj *vm,
|
||||||
|
virDomainPtr domain,
|
||||||
|
virDomainSnapshotDef *def,
|
||||||
|
virQEMUDriver *driver,
|
||||||
|
virQEMUDriverConfig *cfg,
|
||||||
|
unsigned int flags)
|
||||||
|
{
|
||||||
|
|
||||||
|
virDomainMomentObj *snap = NULL;
|
||||||
|
virDomainMomentObj *current = NULL;
|
||||||
|
virDomainSnapshotPtr ret = NULL;
|
||||||
|
|
||||||
|
if (qemuSnapshotCreateAlignDisks(vm, def, driver, flags) < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (qemuSnapshotPrepare(vm, def, &flags) < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!(snap = virDomainSnapshotAssignDef(vm->snapshots, def)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
virObjectRef(def);
|
||||||
|
|
||||||
|
current = virDomainSnapshotGetCurrent(vm->snapshots);
|
||||||
|
if (current) {
|
||||||
|
snap->def->parent_name = g_strdup(current->def->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* actually do the snapshot */
|
||||||
|
if (virDomainObjIsActive(vm)) {
|
||||||
|
if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY ||
|
||||||
|
virDomainSnapshotObjGetDef(snap)->memory == VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL) {
|
||||||
|
/* external full system or disk snapshot */
|
||||||
|
if (qemuSnapshotCreateActiveExternal(driver, vm, snap, cfg, flags) < 0)
|
||||||
|
goto error;
|
||||||
|
} else {
|
||||||
|
/* internal full system */
|
||||||
|
if (qemuSnapshotCreateActiveInternal(driver, vm, snap, flags) < 0)
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* inactive; qemuSnapshotPrepare guaranteed that we
|
||||||
|
* aren't mixing internal and external, and altered flags to
|
||||||
|
* contain DISK_ONLY if there is an external disk. */
|
||||||
|
if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY) {
|
||||||
|
bool reuse = !!(flags & VIR_DOMAIN_SNAPSHOT_CREATE_REUSE_EXT);
|
||||||
|
|
||||||
|
if (qemuSnapshotCreateInactiveExternal(driver, vm, snap, reuse) < 0)
|
||||||
|
goto error;
|
||||||
|
} else {
|
||||||
|
if (qemuSnapshotCreateInactiveInternal(driver, vm, snap) < 0)
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(flags & VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA)) {
|
||||||
|
qemuSnapshotSetCurrent(vm, snap);
|
||||||
|
|
||||||
|
if (qemuSnapshotCreateWriteMetadata(vm, snap, driver, cfg) < 0)
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = virGetDomainSnapshot(domain, snap->def->name);
|
||||||
|
if (!ret)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
error:
|
||||||
|
virDomainSnapshotObjListRemove(vm->snapshots, snap);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
virDomainSnapshotPtr
|
virDomainSnapshotPtr
|
||||||
qemuSnapshotCreateXML(virDomainPtr domain,
|
qemuSnapshotCreateXML(virDomainPtr domain,
|
||||||
virDomainObj *vm,
|
virDomainObj *vm,
|
||||||
@ -1763,7 +1838,6 @@ qemuSnapshotCreateXML(virDomainPtr domain,
|
|||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
{
|
{
|
||||||
virQEMUDriver *driver = domain->conn->privateData;
|
virQEMUDriver *driver = domain->conn->privateData;
|
||||||
virDomainMomentObj *snap = NULL;
|
|
||||||
virDomainSnapshotPtr snapshot = NULL;
|
virDomainSnapshotPtr snapshot = NULL;
|
||||||
bool redefine = flags & VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE;
|
bool redefine = flags & VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE;
|
||||||
g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
|
g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
|
||||||
@ -1814,81 +1888,10 @@ qemuSnapshotCreateXML(virDomainPtr domain,
|
|||||||
|
|
||||||
if (redefine) {
|
if (redefine) {
|
||||||
snapshot = qemuSnapshotRedefine(vm, domain, def, driver, cfg, flags);
|
snapshot = qemuSnapshotRedefine(vm, domain, def, driver, cfg, flags);
|
||||||
goto endjob;
|
|
||||||
} else {
|
} else {
|
||||||
virDomainMomentObj *current = NULL;
|
snapshot = qemuSnapshotCreate(vm, domain, def, driver, cfg, flags);
|
||||||
|
|
||||||
if (qemuSnapshotCreateAlignDisks(vm, def, driver, flags) < 0)
|
|
||||||
goto endjob;
|
|
||||||
|
|
||||||
if (qemuSnapshotPrepare(vm, def, &flags) < 0)
|
|
||||||
goto endjob;
|
|
||||||
|
|
||||||
if (!(snap = virDomainSnapshotAssignDef(vm->snapshots, def)))
|
|
||||||
goto endjob;
|
|
||||||
|
|
||||||
def = NULL;
|
|
||||||
|
|
||||||
current = virDomainSnapshotGetCurrent(vm->snapshots);
|
|
||||||
if (current) {
|
|
||||||
snap->def->parent_name = g_strdup(current->def->name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* actually do the snapshot */
|
|
||||||
if (virDomainObjIsActive(vm)) {
|
|
||||||
if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY ||
|
|
||||||
virDomainSnapshotObjGetDef(snap)->memory == VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL) {
|
|
||||||
/* external full system or disk snapshot */
|
|
||||||
if (qemuSnapshotCreateActiveExternal(driver, vm, snap, cfg, flags) < 0)
|
|
||||||
goto endjob;
|
|
||||||
} else {
|
|
||||||
/* internal full system */
|
|
||||||
if (qemuSnapshotCreateActiveInternal(driver, vm, snap, flags) < 0)
|
|
||||||
goto endjob;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* inactive; qemuSnapshotPrepare guaranteed that we
|
|
||||||
* aren't mixing internal and external, and altered flags to
|
|
||||||
* contain DISK_ONLY if there is an external disk. */
|
|
||||||
if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY) {
|
|
||||||
bool reuse = !!(flags & VIR_DOMAIN_SNAPSHOT_CREATE_REUSE_EXT);
|
|
||||||
|
|
||||||
if (qemuSnapshotCreateInactiveExternal(driver, vm, snap, reuse) < 0)
|
|
||||||
goto endjob;
|
|
||||||
} else {
|
|
||||||
if (qemuSnapshotCreateInactiveInternal(driver, vm, snap) < 0)
|
|
||||||
goto endjob;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we fail after this point, there's not a whole lot we can
|
|
||||||
* do; we've successfully taken the snapshot, and we are now running
|
|
||||||
* on it, so we have to go forward the best we can
|
|
||||||
*/
|
|
||||||
if (!(snapshot = virGetDomainSnapshot(domain, snap->def->name)))
|
|
||||||
goto endjob;
|
|
||||||
|
|
||||||
if (!(flags & VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA)) {
|
|
||||||
if ((flags & VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT))
|
|
||||||
qemuSnapshotSetCurrent(vm, snap);
|
|
||||||
|
|
||||||
if (qemuSnapshotCreateWriteMetadata(vm, snap, driver, cfg) < 0) {
|
|
||||||
/* if writing of metadata fails, error out rather than trying
|
|
||||||
* to silently carry on without completing the snapshot */
|
|
||||||
virObjectUnref(snapshot);
|
|
||||||
snapshot = NULL;
|
|
||||||
goto endjob;
|
|
||||||
}
|
|
||||||
|
|
||||||
snap = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
endjob:
|
|
||||||
|
|
||||||
if (snap)
|
|
||||||
virDomainSnapshotObjListRemove(vm->snapshots, snap);
|
|
||||||
|
|
||||||
qemuDomainObjEndAsyncJob(driver, vm);
|
qemuDomainObjEndAsyncJob(driver, vm);
|
||||||
|
|
||||||
return snapshot;
|
return snapshot;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user