[libvirt] [PATCHv2 17/26] snapshot: support new undefine flags in qemu

Eric Blake eblake at redhat.com
Mon Aug 15 23:33:28 UTC 2011


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




More information about the libvir-list mailing list