}
+/* Update @snapshot to no longer have children. */
+void
+virDomainSnapshotDropChildren(virDomainSnapshotObjPtr snapshot)
+{
+ snapshot->nchildren = 0;
+ snapshot->first_child = NULL;
+}
+
+
+/* Add @snapshot to @parent's list of children. */
+void
+virDomainSnapshotSetParent(virDomainSnapshotObjPtr snapshot,
+ virDomainSnapshotObjPtr parent)
+{
+ snapshot->parent = parent;
+ parent->nchildren++;
+ snapshot->sibling = parent->first_child;
+ parent->first_child = snapshot;
+}
+
+
/* Take all children of @from and convert them into children of @to. */
void
virDomainSnapshotMoveChildren(virDomainSnapshotObjPtr from,
virHashIterator iter,
void *data);
void virDomainSnapshotDropParent(virDomainSnapshotObjPtr snapshot);
+void virDomainSnapshotDropChildren(virDomainSnapshotObjPtr snapshot);
void virDomainSnapshotMoveChildren(virDomainSnapshotObjPtr from,
virDomainSnapshotObjPtr to);
+void virDomainSnapshotSetParent(virDomainSnapshotObjPtr snapshot,
+ virDomainSnapshotObjPtr parent);
#endif /* LIBVIRT_VIRDOMAINSNAPSHOTOBJ_H */
_("incorrect flags for bulk parse"));
return -1;
}
- if (snapshots->metaroot.nchildren || snapshots->current) {
+ if (virDomainSnapshotObjListSize(snapshots) != 0) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("bulk define of snapshots only possible with "
"no existing snapshot"));
if (ret < 0) {
/* There were no snapshots before this call; so on error, just
* blindly delete anything created before the failure. */
- virHashRemoveAll(snapshots->objs);
- snapshots->metaroot.nchildren = 0;
- snapshots->metaroot.first_child = NULL;
+ virDomainSnapshotObjListRemoveAll(snapshots);
}
xmlXPathFreeContext(ctxt);
xmlFreeDoc(xml);
}
+/* Return the number of objects currently in the list */
+int
+virDomainSnapshotObjListSize(virDomainSnapshotObjListPtr snapshots)
+{
+ return virHashSize(snapshots->objs);
+}
+
+
/* Return the current snapshot, or NULL */
virDomainSnapshotObjPtr
virDomainSnapshotGetCurrent(virDomainSnapshotObjListPtr snapshots)
return ret;
}
+/* Remove all snapshots tracked in the list */
+void
+virDomainSnapshotObjListRemoveAll(virDomainSnapshotObjListPtr snapshots)
+{
+ virHashRemoveAll(snapshots->objs);
+ virDomainSnapshotDropChildren(&snapshots->metaroot);
+}
+
+
int
virDomainSnapshotForEach(virDomainSnapshotObjListPtr snapshots,
virHashIterator iter,
virDomainSnapshotObjPtr obj = payload;
struct snapshot_set_relation *curr = data;
virDomainSnapshotObjPtr tmp;
+ virDomainSnapshotObjPtr parent;
- obj->parent = virDomainSnapshotFindByName(curr->snapshots,
- obj->def->parent);
- if (!obj->parent) {
+ parent = virDomainSnapshotFindByName(curr->snapshots, obj->def->parent);
+ if (!parent) {
curr->err = -1;
- obj->parent = &curr->snapshots->metaroot;
+ parent = &curr->snapshots->metaroot;
VIR_WARN("snapshot %s lacks parent", obj->def->name);
} else {
- tmp = obj->parent;
+ tmp = parent;
while (tmp && tmp->def) {
if (tmp == obj) {
curr->err = -1;
- obj->parent = &curr->snapshots->metaroot;
+ parent = &curr->snapshots->metaroot;
VIR_WARN("snapshot %s in circular chain", obj->def->name);
break;
}
tmp = tmp->parent;
}
}
- obj->parent->nchildren++;
- obj->sibling = obj->parent->first_child;
- obj->parent->first_child = obj;
+ virDomainSnapshotSetParent(obj, parent);
return 0;
}
{
struct snapshot_set_relation act = { snapshots, 0 };
- snapshots->metaroot.nchildren = 0;
- snapshots->metaroot.first_child = NULL;
+ virDomainSnapshotDropChildren(&snapshots->metaroot);
virHashForEach(snapshots->objs, virDomainSnapshotSetRelations, &act);
if (act.err)
snapshots->current = NULL;
unsigned int flags);
virDomainSnapshotObjPtr virDomainSnapshotFindByName(virDomainSnapshotObjListPtr snapshots,
const char *name);
+int virDomainSnapshotObjListSize(virDomainSnapshotObjListPtr snapshots);
virDomainSnapshotObjPtr virDomainSnapshotGetCurrent(virDomainSnapshotObjListPtr snapshots);
const char *virDomainSnapshotGetCurrentName(virDomainSnapshotObjListPtr snapshots);
bool virDomainSnapshotIsCurrentName(virDomainSnapshotObjListPtr snapshots,
virDomainSnapshotObjPtr snapshot);
bool virDomainSnapshotObjListRemove(virDomainSnapshotObjListPtr snapshots,
virDomainSnapshotObjPtr snapshot);
+void virDomainSnapshotObjListRemoveAll(virDomainSnapshotObjListPtr snapshots);
int virDomainSnapshotForEach(virDomainSnapshotObjListPtr snapshots,
virHashIterator iter,
void *data);
# conf/virdomainsnapshotobj.h
+virDomainSnapshotDropChildren;
virDomainSnapshotDropParent;
virDomainSnapshotForEachChild;
virDomainSnapshotForEachDescendant;
virDomainSnapshotMoveChildren;
+virDomainSnapshotSetParent;
# conf/virdomainsnapshotobjlist.h
virDomainSnapshotObjListNum;
virDomainSnapshotObjListParse;
virDomainSnapshotObjListRemove;
+virDomainSnapshotObjListRemoveAll;
virDomainSnapshotSetCurrent;
virDomainSnapshotUpdateRelations;
rem.err = 0;
virDomainSnapshotForEach(vm->snapshots, qemuDomainSnapshotDiscardAll,
&rem);
- if (virDomainSnapshotUpdateRelations(vm->snapshots) < 0 && !rem.err)
- rem.err = -1;
+ virDomainSnapshotObjListRemoveAll(vm->snapshots);
return rem.err;
}
} else {
other = virDomainSnapshotFindByName(vm->snapshots,
snap->def->parent);
- snap->parent = other;
- other->nchildren++;
- snap->sibling = other->first_child;
- other->first_child = snap;
+ virDomainSnapshotSetParent(snap, other);
}
} else if (snap) {
virDomainSnapshotObjListRemove(vm->snapshots, snap);
}
if (flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY) {
- snap->nchildren = 0;
- snap->first_child = NULL;
+ virDomainSnapshotDropChildren(snap);
ret = 0;
} else {
ret = qemuDomainSnapshotDiscard(driver, vm, snap, true, metadata_only);
virDomainSnapshotSetCurrent(vm->snapshots, snap);
other = virDomainSnapshotFindByName(vm->snapshots,
snap->def->parent);
- snap->parent = other;
- other->nchildren++;
- snap->sibling = other->first_child;
- other->first_child = snap;
+ virDomainSnapshotSetParent(snap, other);
}
virDomainObjEndAPI(&vm);
}
}
if (flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY) {
- snap->nchildren = 0;
- snap->first_child = NULL;
+ virDomainSnapshotDropChildren(snap);
} else {
virDomainSnapshotDropParent(snap);
if (snap == virDomainSnapshotGetCurrent(vm->snapshots)) {