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 f5e2ac9..3f3d2bb 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -11228,32 +11228,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 d1dd1d2..94e28e4 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 a96ec84..85e0f7d 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -9281,7 +9281,7 @@ qemuDomainSnapshotDiscardDescendant(void *payload,
struct snap_reparent {
struct qemud_driver *driver;
- virDomainSnapshotObjPtr snap;
+ const char *parent;
virDomainObjPtr vm;
int err;
};
@@ -9298,22 +9298,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,
@@ -9364,11 +9362,12 @@ static int qemuDomainSnapshotDelete(virDomainSnapshotPtr
snapshot,
vm->current_snapshot = snap;
} 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