Signed-off-by: Pavel Hrdina <phrdina@xxxxxxxxxx> --- src/qemu/qemu_snapshot.c | 149 ++++++++++++++++++++------------------- 1 file changed, 76 insertions(+), 73 deletions(-) diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c index d22f0522ed..c5f0a5afe8 100644 --- a/src/qemu/qemu_snapshot.c +++ b/src/qemu/qemu_snapshot.c @@ -1757,6 +1757,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 (qemuSnapshotAlignDisks(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 qemuSnapshotCreateXML(virDomainPtr domain, virDomainObj *vm, @@ -1764,7 +1839,6 @@ qemuSnapshotCreateXML(virDomainPtr domain, unsigned int flags) { virQEMUDriver *driver = domain->conn->privateData; - virDomainMomentObj *snap = NULL; virDomainSnapshotPtr snapshot = NULL; bool redefine = flags & VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE; g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); @@ -1815,81 +1889,10 @@ qemuSnapshotCreateXML(virDomainPtr domain, if (redefine) { snapshot = qemuSnapshotRedefine(vm, domain, def, driver, cfg, flags); - goto endjob; } else { - virDomainMomentObj *current = NULL; - - if (qemuSnapshotAlignDisks(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); - } + snapshot = qemuSnapshotCreate(vm, domain, def, driver, cfg, flags); } - /* 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); return snapshot; -- 2.31.1