]> xenbits.xensource.com Git - libvirt.git/commitdiff
snapshot: track current domain across deletion of children
authorEric Blake <eblake@redhat.com>
Wed, 24 Aug 2011 20:25:46 +0000 (14:25 -0600)
committerEric Blake <eblake@redhat.com>
Fri, 2 Sep 2011 22:07:41 +0000 (16:07 -0600)
Deleting a snapshot and all its descendants had problems with
tracking the current snapshot.  The deletion does not necessarily
proceed in depth-first order, so a parent could be deleted
before a child, wreaking havoc on passing the notion of the
current snapshot to the parent.  Furthermore, even if traversal
were depth-first, doing multiple file writes to pass current up
the chain one snapshot at a time is wasteful, comparing to a
single update to the current snapshot at the end of the algorithm.

* src/qemu/qemu_driver.c (snap_remove): Add field.
(qemuDomainSnapshotDiscard): Add parameter.
(qemuDomainSnapshotDiscardDescendant): Adjust accordingly.
(qemuDomainSnapshotDelete): Properly reset current.

src/qemu/qemu_driver.c

index 55cdc3f81ba163d4d1a3214132458063a6a7ed5f..0686f81926e1cbda47491f1b77d26d9853128a14 100644 (file)
@@ -9167,9 +9167,11 @@ cleanup:
     return ret;
 }
 
-static int qemuDomainSnapshotDiscard(struct qemud_driver *driver,
-                                     virDomainObjPtr vm,
-                                     virDomainSnapshotObjPtr snap)
+static int
+qemuDomainSnapshotDiscard(struct qemud_driver *driver,
+                          virDomainObjPtr vm,
+                          virDomainSnapshotObjPtr snap,
+                          bool update_current)
 {
     char *snapFile = NULL;
     int ret = -1;
@@ -9195,7 +9197,7 @@ static int qemuDomainSnapshotDiscard(struct qemud_driver *driver,
     }
 
     if (snap == vm->current_snapshot) {
-        if (snap->def->parent) {
+        if (update_current && snap->def->parent) {
             parentsnap = virDomainSnapshotFindByName(&vm->snapshots,
                                                      snap->def->parent);
             if (!parentsnap) {
@@ -9231,6 +9233,7 @@ struct snap_remove {
     struct qemud_driver *driver;
     virDomainObjPtr vm;
     int err;
+    bool current;
 };
 
 static void
@@ -9242,7 +9245,9 @@ qemuDomainSnapshotDiscardDescendant(void *payload,
     struct snap_remove *curr = data;
     int err;
 
-    err = qemuDomainSnapshotDiscard(curr->driver, curr->vm, snap);
+    if (snap->def->current)
+        curr->current = true;
+    err = qemuDomainSnapshotDiscard(curr->driver, curr->vm, snap, false);
     if (err && !curr->err)
         curr->err = err;
 }
@@ -9321,12 +9326,15 @@ static int qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
         rem.driver = driver;
         rem.vm = vm;
         rem.err = 0;
+        rem.current = false;
         virDomainSnapshotForEachDescendant(&vm->snapshots,
                                            snap,
                                            qemuDomainSnapshotDiscardDescendant,
                                            &rem);
         if (rem.err < 0)
             goto endjob;
+        if (rem.current)
+            vm->current_snapshot = snap;
     } else {
         rep.driver = driver;
         rep.snap = snap;
@@ -9338,7 +9346,7 @@ static int qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
             goto endjob;
     }
 
-    ret = qemuDomainSnapshotDiscard(driver, vm, snap);
+    ret = qemuDomainSnapshotDiscard(driver, vm, snap, true);
 
 endjob:
     if (qemuDomainObjEndJob(driver, vm) == 0)