diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 9ca4ca33e5..54afb6dd7b 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -1,7 +1,7 @@ /* * qemu_domain.c: QEMU domain private state * - * Copyright (C) 2006-2016 Red Hat, Inc. + * Copyright (C) 2006-2019 Red Hat, Inc. * Copyright (C) 2006 Daniel P. Berrange * * This library is free software; you can redistribute it and/or @@ -8650,18 +8650,18 @@ qemuDomainSnapshotDiscard(virQEMUDriverPtr driver, } /* Hash iterator callback to discard multiple snapshots. */ -int qemuDomainSnapshotDiscardAll(void *payload, - const void *name ATTRIBUTE_UNUSED, - void *data) +int qemuDomainMomentDiscardAll(void *payload, + const void *name ATTRIBUTE_UNUSED, + void *data) { - virDomainMomentObjPtr snap = payload; - virQEMUSnapRemovePtr curr = data; + virDomainMomentObjPtr moment = payload; + virQEMUMomentRemovePtr curr = data; int err; - if (virDomainSnapshotGetCurrent(curr->vm->snapshots) == snap) - curr->current = true; - err = qemuDomainSnapshotDiscard(curr->driver, curr->vm, snap, false, - curr->metadata_only); + if (!curr->found && curr->current == moment) + curr->found = true; + err = curr->momentDiscard(curr->driver, curr->vm, moment, false, + curr->metadata_only); if (err && !curr->err) curr->err = err; return 0; @@ -8671,14 +8671,13 @@ int qemuDomainSnapshotDiscardAllMetadata(virQEMUDriverPtr driver, virDomainObjPtr vm) { - virQEMUSnapRemove rem; + virQEMUMomentRemove rem = { + .driver = driver, + .vm = vm, + .metadata_only = true + }; - rem.driver = driver; - rem.vm = vm; - rem.metadata_only = true; - rem.err = 0; - virDomainSnapshotForEach(vm->snapshots, qemuDomainSnapshotDiscardAll, - &rem); + virDomainSnapshotForEach(vm->snapshots, qemuDomainMomentDiscardAll, &rem); virDomainSnapshotObjListRemoveAll(vm->snapshots); return rem.err; diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index ca24de15e5..00b497e6a6 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -1,7 +1,7 @@ /* * qemu_domain.h: QEMU domain private state * - * Copyright (C) 2006-2016 Red Hat, Inc. + * Copyright (C) 2006-2019 Red Hat, Inc. * Copyright (C) 2006 Daniel P. Berrange * * This library is free software; you can redistribute it and/or @@ -38,6 +38,7 @@ # include "virchrdev.h" # include "virobject.h" # include "logging/log_manager.h" +# include "virdomainmomentobjlist.h" # define QEMU_DOMAIN_FORMAT_LIVE_FLAGS \ (VIR_DOMAIN_XML_SECURE) @@ -698,19 +699,22 @@ int qemuDomainSnapshotDiscard(virQEMUDriverPtr driver, bool update_current, bool metadata_only); -typedef struct _virQEMUSnapRemove virQEMUSnapRemove; -typedef virQEMUSnapRemove *virQEMUSnapRemovePtr; -struct _virQEMUSnapRemove { +typedef struct _virQEMUMomentRemove virQEMUMomentRemove; +typedef virQEMUMomentRemove *virQEMUMomentRemovePtr; +struct _virQEMUMomentRemove { virQEMUDriverPtr driver; virDomainObjPtr vm; int err; bool metadata_only; - bool current; + virDomainMomentObjPtr current; + bool found; + int (*momentDiscard)(virQEMUDriverPtr, virDomainObjPtr, + virDomainMomentObjPtr, bool, bool); }; -int qemuDomainSnapshotDiscardAll(void *payload, - const void *name, - void *data); +int qemuDomainMomentDiscardAll(void *payload, + const void *name, + void *data); int qemuDomainSnapshotDiscardAllMetadata(virQEMUDriverPtr driver, virDomainObjPtr vm); diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 930ce9d401..62d8d977c5 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -16126,6 +16126,7 @@ qemuDomainSnapshotCurrent(virDomainPtr domain, { virDomainObjPtr vm; virDomainSnapshotPtr snapshot = NULL; + const char *name; virCheckFlags(0, NULL); @@ -16135,13 +16136,14 @@ qemuDomainSnapshotCurrent(virDomainPtr domain, if (virDomainSnapshotCurrentEnsureACL(domain->conn, vm->def) < 0) goto cleanup; - if (!virDomainSnapshotGetCurrent(vm->snapshots)) { + name = virDomainSnapshotGetCurrentName(vm->snapshots); + if (!name) { virReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT, "%s", _("the domain does not have a current snapshot")); goto cleanup; } - snapshot = virGetDomainSnapshot(domain, virDomainSnapshotGetCurrentName(vm->snapshots)); + snapshot = virGetDomainSnapshot(domain, name); cleanup: virDomainObjEndAPI(&vm); @@ -16673,40 +16675,41 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, } -typedef struct _virQEMUSnapReparent virQEMUSnapReparent; -typedef virQEMUSnapReparent *virQEMUSnapReparentPtr; -struct _virQEMUSnapReparent { - virQEMUDriverConfigPtr cfg; +typedef struct _virQEMUMomentReparent virQEMUMomentReparent; +typedef virQEMUMomentReparent *virQEMUMomentReparentPtr; +struct _virQEMUMomentReparent { + const char *dir; virDomainMomentObjPtr parent; virDomainObjPtr vm; virCapsPtr caps; virDomainXMLOptionPtr xmlopt; int err; + int (*writeMetadata)(virDomainObjPtr, virDomainMomentObjPtr, + virCapsPtr, virDomainXMLOptionPtr, const char *); }; static int -qemuDomainSnapshotReparentChildren(void *payload, - const void *name ATTRIBUTE_UNUSED, - void *data) +qemuDomainMomentReparentChildren(void *payload, + const void *name ATTRIBUTE_UNUSED, + void *data) { - virDomainMomentObjPtr snap = payload; - virQEMUSnapReparentPtr rep = data; + virDomainMomentObjPtr moment = payload; + virQEMUMomentReparentPtr rep = data; if (rep->err < 0) return 0; - VIR_FREE(snap->def->parent); + VIR_FREE(moment->def->parent); if (rep->parent->def && - VIR_STRDUP(snap->def->parent, rep->parent->def->name) < 0) { + VIR_STRDUP(moment->def->parent, rep->parent->def->name) < 0) { rep->err = -1; return 0; } - rep->err = qemuDomainSnapshotWriteMetadata(rep->vm, snap, - rep->caps, rep->xmlopt, - rep->cfg->snapshotDir); + rep->err = rep->writeMetadata(rep->vm, moment, rep->caps, rep->xmlopt, + rep->dir); return 0; } @@ -16719,8 +16722,8 @@ qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot, virDomainObjPtr vm = NULL; int ret = -1; virDomainMomentObjPtr snap = NULL; - virQEMUSnapRemove rem; - virQEMUSnapReparent rep; + virQEMUMomentRemove rem; + virQEMUMomentReparent rep; bool metadata_only = !!(flags & VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY); int external = 0; virQEMUDriverConfigPtr cfg = NULL; @@ -16766,13 +16769,14 @@ qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot, rem.vm = vm; rem.metadata_only = metadata_only; rem.err = 0; - rem.current = false; - virDomainMomentForEachDescendant(snap, - qemuDomainSnapshotDiscardAll, + rem.current = virDomainSnapshotGetCurrent(vm->snapshots); + rem.found = false; + rem.momentDiscard = qemuDomainSnapshotDiscard; + virDomainMomentForEachDescendant(snap, qemuDomainMomentDiscardAll, &rem); if (rem.err < 0) goto endjob; - if (rem.current) { + if (rem.found) { virDomainSnapshotSetCurrent(vm->snapshots, snap); if (flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY) { if (qemuDomainSnapshotWriteMetadata(vm, snap, driver->caps, @@ -16787,14 +16791,15 @@ qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot, } } } else if (snap->nchildren) { - rep.cfg = cfg; + rep.dir = cfg->snapshotDir; rep.parent = snap->parent; rep.vm = vm; rep.err = 0; rep.caps = driver->caps; rep.xmlopt = driver->xmlopt; + rep.writeMetadata = qemuDomainSnapshotWriteMetadata; virDomainMomentForEachChild(snap, - qemuDomainSnapshotReparentChildren, + qemuDomainMomentReparentChildren, &rep); if (rep.err < 0) goto endjob;