[libvirt] [PATCHv3 09/43] snapshot: simplify acting on just children

Eric Blake eblake at redhat.com
Wed Aug 24 15:22:26 UTC 2011


Similar to the last patch in isolating the filtering from the
client actions, so that clients don't have to reinvent the
filtering.

* src/conf/domain_conf.h (virDomainSnapshotForEachChild): New
prototype.
* src/libvirt_private.syms (domain_conf.h): Export it.
* src/conf/domain_conf.c (virDomainSnapshotActOnChild)
(virDomainSnapshotForEachChild): New functions.
(virDomainSnapshotCountChildren): Delete.
(virDomainSnapshotHasChildren): Simplify.
* src/qemu/qemu_driver.c (qemuDomainSnapshotReparentChildren)
(qemuDomainSnapshotDelete): Likewise.
---
 src/conf/domain_conf.c   |   48 ++++++++++++++++++++++++++++++++-------------
 src/conf/domain_conf.h   |    4 +++
 src/libvirt_private.syms |    1 +
 src/qemu/qemu_driver.c   |   31 ++++++++++++++---------------
 4 files changed, 54 insertions(+), 30 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 75fa7f7..01bbd04 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -11238,32 +11238,52 @@ void virDomainSnapshotObjListRemove(virDomainSnapshotObjListPtr snapshots,
     virHashRemoveEntry(snapshots->objs, snapshot->def->name);
 }

-struct snapshot_has_children {
-    char *name;
+struct snapshot_act_on_child {
+    char *parent;
     int number;
+    virHashIterator iter;
+    void *data;
 };

-static void virDomainSnapshotCountChildren(void *payload,
-                                           const void *name ATTRIBUTE_UNUSED,
-                                           void *data)
+static void
+virDomainSnapshotActOnChild(void *payload,
+                            const void *name,
+                            void *data)
 {
     virDomainSnapshotObjPtr obj = payload;
-    struct snapshot_has_children *curr = data;
+    struct snapshot_act_on_child *curr = data;

-    if (obj->def->parent && STREQ(obj->def->parent, curr->name))
+    if (obj->def->parent && STREQ(curr->parent, obj->def->parent)) {
         curr->number++;
+        if (curr->iter)
+            (curr->iter)(payload, name, curr->data);
+    }
 }

-int virDomainSnapshotHasChildren(virDomainSnapshotObjPtr snap,
-                                virDomainSnapshotObjListPtr snapshots)
+/* Run iter(data) on all direct children of snapshot, while ignoring all
+ * other entries in snapshots.  Return the number of children
+ * visited.  No particular ordering is guaranteed.  */
+int
+virDomainSnapshotForEachChild(virDomainSnapshotObjListPtr snapshots,
+                              virDomainSnapshotObjPtr snapshot,
+                              virHashIterator iter,
+                              void *data)
 {
-    struct snapshot_has_children children;
+    struct snapshot_act_on_child act;

-    children.name = snap->def->name;
-    children.number = 0;
-    virHashForEach(snapshots->objs, virDomainSnapshotCountChildren, &children);
+    act.parent = snapshot->def->name;
+    act.number = 0;
+    act.iter = iter;
+    act.data = data;
+    virHashForEach(snapshots->objs, virDomainSnapshotActOnChild, &act);

-    return children.number;
+    return act.number;
+}
+
+int virDomainSnapshotHasChildren(virDomainSnapshotObjPtr snap,
+                                 virDomainSnapshotObjListPtr snapshots)
+{
+    return virDomainSnapshotForEachChild(snapshots, snap, NULL, NULL);
 }

 typedef enum {
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index d266605..5f752ec 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1343,6 +1343,10 @@ void virDomainSnapshotObjListRemove(virDomainSnapshotObjListPtr snapshots,
                                     virDomainSnapshotObjPtr snapshot);
 int virDomainSnapshotHasChildren(virDomainSnapshotObjPtr snap,
                                 virDomainSnapshotObjListPtr snapshots);
+int virDomainSnapshotForEachChild(virDomainSnapshotObjListPtr snapshots,
+                                  virDomainSnapshotObjPtr snapshot,
+                                  virHashIterator iter,
+                                  void *data);
 int virDomainSnapshotForEachDescendant(virDomainSnapshotObjListPtr snapshots,
                                        virDomainSnapshotObjPtr snapshot,
                                        virHashIterator iter,
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index fcce810..74c5ff4 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -384,6 +384,7 @@ virDomainSnapshotDefFormat;
 virDomainSnapshotDefFree;
 virDomainSnapshotDefParseString;
 virDomainSnapshotFindByName;
+virDomainSnapshotForEachChild;
 virDomainSnapshotForEachDescendant;
 virDomainSnapshotHasChildren;
 virDomainSnapshotObjListGetNames;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 1405b71..5101167 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -9050,7 +9050,7 @@ qemuDomainSnapshotDiscardDescendant(void *payload,

 struct snap_reparent {
     struct qemud_driver *driver;
-    virDomainSnapshotObjPtr snap;
+    const char *parent;
     virDomainObjPtr vm;
     int err;
 };
@@ -9067,22 +9067,20 @@ qemuDomainSnapshotReparentChildren(void *payload,
         return;
     }

-    if (snap->def->parent && STREQ(snap->def->parent, rep->snap->def->name)) {
-        VIR_FREE(snap->def->parent);
+    VIR_FREE(snap->def->parent);

-        if (rep->snap->def->parent != NULL) {
-            snap->def->parent = strdup(rep->snap->def->parent);
+    if (rep->parent != NULL) {
+        snap->def->parent = strdup(rep->parent);

-            if (snap->def->parent == NULL) {
-                virReportOOMError();
-                rep->err = -1;
-                return;
-            }
+        if (snap->def->parent == NULL) {
+            virReportOOMError();
+            rep->err = -1;
+            return;
         }
-
-        rep->err = qemuDomainSnapshotWriteMetadata(rep->vm, snap,
-                                                   rep->driver->snapshotDir);
     }
+
+    rep->err = qemuDomainSnapshotWriteMetadata(rep->vm, snap,
+                                               rep->driver->snapshotDir);
 }

 static int qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
@@ -9130,11 +9128,12 @@ static int qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
             goto endjob;
     } else {
         rep.driver = driver;
-        rep.snap = snap;
+        rep.parent = snap->def->parent;
         rep.vm = vm;
         rep.err = 0;
-        virHashForEach(vm->snapshots.objs, qemuDomainSnapshotReparentChildren,
-                       &rep);
+        virDomainSnapshotForEachChild(&vm->snapshots, snap,
+                                      qemuDomainSnapshotReparentChildren,
+                                      &rep);
         if (rep.err < 0)
             goto endjob;
     }
-- 
1.7.4.4




More information about the libvir-list mailing list