snapshot: simplify acting on just children

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.
This commit is contained in:
Eric Blake 2011-08-13 11:56:15 -06:00
parent 90ea06b88a
commit 67555b2434
4 changed files with 55 additions and 31 deletions

View File

@ -11650,32 +11650,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);
}
}
/* 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_act_on_child act;
act.parent = snapshot->def->name;
act.number = 0;
act.iter = iter;
act.data = data;
virHashForEach(snapshots->objs, virDomainSnapshotActOnChild, &act);
return act.number;
}
int virDomainSnapshotHasChildren(virDomainSnapshotObjPtr snap,
virDomainSnapshotObjListPtr snapshots)
virDomainSnapshotObjListPtr snapshots)
{
struct snapshot_has_children children;
children.name = snap->def->name;
children.number = 0;
virHashForEach(snapshots->objs, virDomainSnapshotCountChildren, &children);
return children.number;
return virDomainSnapshotForEachChild(snapshots, snap, NULL, NULL);
}
typedef enum {

View File

@ -1426,6 +1426,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,

View File

@ -391,6 +391,7 @@ virDomainSnapshotDefFormat;
virDomainSnapshotDefFree;
virDomainSnapshotDefParseString;
virDomainSnapshotFindByName;
virDomainSnapshotForEachChild;
virDomainSnapshotForEachDescendant;
virDomainSnapshotHasChildren;
virDomainSnapshotObjListGetNames;

View File

@ -9254,7 +9254,7 @@ qemuDomainSnapshotDiscardDescendant(void *payload,
struct snap_reparent {
struct qemud_driver *driver;
virDomainSnapshotObjPtr snap;
const char *parent;
virDomainObjPtr vm;
int err;
};
@ -9271,22 +9271,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,
@ -9337,11 +9335,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;
}