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 7704849..f1b0aca 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -11252,32 +11252,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 c53b295..0d8aa99 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 f523404..9134fc3 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -9042,7 +9042,7 @@ qemuDomainSnapshotDiscardDescendant(void *payload, struct snap_reparent { struct qemud_driver *driver; - virDomainSnapshotObjPtr snap; + const char *parent; virDomainObjPtr vm; int err; }; @@ -9059,22 +9059,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, @@ -9122,11 +9120,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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list