A nice benefit of deleting all snapshots at undefine time is that
you don't have to do any reparenting or subtree identification - since
everything goes, this is an O(n) process whereas using multiple
virDomainSnapshotDelete calls would be O(n^2) or worse.
* src/qemu/qemu_driver.c (qemuDomainDestroyFlags)
(qemuDomainUndefineFlags): Honor new flags.
---
src/qemu/qemu_driver.c | 51 ++++++++++++++++++++++++++++++++++++++---------
1 files changed, 41 insertions(+), 10 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 08d5a27..bf82df4 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1713,7 +1713,8 @@ qemuDomainDestroyFlags(virDomainPtr dom,
qemuDomainObjPrivatePtr priv;
int nsnapshots;
- virCheckFlags(0, -1);
+ virCheckFlags(VIR_DOMAIN_DESTROY_SNAPSHOTS_METADATA |
+ VIR_DOMAIN_DESTROY_SNAPSHOTS_FULL, -1);
qemuDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
@@ -1727,10 +1728,24 @@ qemuDomainDestroyFlags(virDomainPtr dom,
if (!vm->persistent &&
(nsnapshots = virDomainSnapshotObjListNum(&vm->snapshots))) {
- qemuReportError(VIR_ERR_OPERATION_INVALID,
- _("cannot delete transient domain with %d snapshots"),
- nsnapshots);
- goto cleanup;
+ struct snap_remove rem;
+
+ if ((flags & (VIR_DOMAIN_DESTROY_SNAPSHOTS_METADATA |
+ VIR_DOMAIN_DESTROY_SNAPSHOTS_FULL)) == 0) {
+ qemuReportError(VIR_ERR_OPERATION_INVALID,
+ _("cannot delete transient domain with %d "
+ "snapshots"),
+ nsnapshots);
+ goto cleanup;
+ }
+
+ rem.driver = driver;
+ rem.vm = vm;
+ rem.metadata_only = !(flags & VIR_DOMAIN_DESTROY_SNAPSHOTS_FULL);
+ rem.err = 0;
+ virHashForEach(vm->snapshots.objs, qemuDomainSnapshotDiscardAll, &rem);
+ if (rem.err < 0)
+ goto cleanup;
}
priv = vm->privateData;
@@ -4854,7 +4869,9 @@ qemuDomainUndefineFlags(virDomainPtr dom,
int ret = -1;
int nsnapshots;
- virCheckFlags(VIR_DOMAIN_UNDEFINE_MANAGED_SAVE, -1);
+ virCheckFlags(VIR_DOMAIN_UNDEFINE_MANAGED_SAVE |
+ VIR_DOMAIN_UNDEFINE_SNAPSHOTS_METADATA |
+ VIR_DOMAIN_UNDEFINE_SNAPSHOTS_FULL, -1);
qemuDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
@@ -4874,10 +4891,24 @@ qemuDomainUndefineFlags(virDomainPtr dom,
"%s", _("cannot delete active domain"));
goto cleanup;
} else if ((nsnapshots = virDomainSnapshotObjListNum(&vm->snapshots))) {
- qemuReportError(VIR_ERR_OPERATION_INVALID,
- _("cannot delete inactive domain with %d snapshots"),
- nsnapshots);
- goto cleanup;
+ struct snap_remove rem;
+
+ if ((flags & (VIR_DOMAIN_UNDEFINE_SNAPSHOTS_METADATA |
+ VIR_DOMAIN_UNDEFINE_SNAPSHOTS_FULL)) == 0) {
+ qemuReportError(VIR_ERR_OPERATION_INVALID,
+ _("cannot delete inactive domain with %d "
+ "snapshots"),
+ nsnapshots);
+ goto cleanup;
+ }
+
+ rem.driver = driver;
+ rem.vm = vm;
+ rem.metadata_only = !(flags & VIR_DOMAIN_UNDEFINE_SNAPSHOTS_FULL);
+ rem.err = 0;
+ virHashForEach(vm->snapshots.objs, qemuDomainSnapshotDiscardAll, &rem);
+ if (rem.err < 0)
+ goto cleanup;
}
if (!vm->persistent) {
--
1.7.4.4