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 | 57 +++++++++++++++++++++++++++++++++++++-----------
1 files changed, 44 insertions(+), 13 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index f4a4786..027fdee 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1488,7 +1488,7 @@ static int qemuDomainShutdown(virDomainPtr dom) {
}
if (!vm->persistent &&
- (nsnapshots = virDomainSnapshotObjListNum(&vm->snapshots))) {
+ (nsnapshots = virDomainSnapshotObjListNum(&vm->snapshots, 0))) {
qemuReportError(VIR_ERR_OPERATION_INVALID,
_("cannot delete transient domain with %d snapshots"),
nsnapshots);
@@ -1777,7 +1777,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);
@@ -1790,11 +1791,25 @@ 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;
+ (nsnapshots = virDomainSnapshotObjListNum(&vm->snapshots, 0))) {
+ 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;
@@ -4918,7 +4933,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);
@@ -4937,11 +4954,25 @@ qemuDomainUndefineFlags(virDomainPtr dom,
qemuReportError(VIR_ERR_OPERATION_INVALID,
"%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;
+ } else if ((nsnapshots = virDomainSnapshotObjListNum(&vm->snapshots, 0))) {
+ 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