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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list