};
-/* Parse a <snapshots> XML entry into snapshots, which must start
- * empty. Any <domain> sub-elements of a <domainsnapshot> must match
- * domain_uuid. @flags is virDomainSnapshotParseFlags. Return the
- * number of snapshots parsed, or -1 on error.
- */
-int
-virDomainSnapshotObjListParse(const char *xmlStr,
- const unsigned char *domain_uuid,
- virDomainSnapshotObjListPtr snapshots,
- virCapsPtr caps,
- virDomainXMLOptionPtr xmlopt,
- unsigned int flags)
-{
- int ret = -1;
- xmlDocPtr xml;
- xmlNodePtr root;
- xmlXPathContextPtr ctxt = NULL;
- int n;
- size_t i;
- int keepBlanksDefault = xmlKeepBlanksDefault(0);
- virDomainMomentObjPtr snap;
- VIR_AUTOFREE(xmlNodePtr *) nodes = NULL;
- VIR_AUTOFREE(char *) current = NULL;
-
- if (!(flags & VIR_DOMAIN_SNAPSHOT_PARSE_REDEFINE) ||
- (flags & VIR_DOMAIN_SNAPSHOT_PARSE_INTERNAL)) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("incorrect flags for bulk parse"));
- return -1;
- }
- if (virDomainMomentObjListSize(snapshots->base) != 0) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("bulk define of snapshots only possible with "
- "no existing snapshot"));
- return -1;
- }
-
- if (!(xml = virXMLParse(NULL, xmlStr, _("(domain_snapshot)"))))
- return -1;
-
- root = xmlDocGetRootElement(xml);
- if (!virXMLNodeNameEqual(root, "snapshots")) {
- virReportError(VIR_ERR_XML_ERROR,
- _("unexpected root element <%s>, "
- "expecting <snapshots>"), root->name);
- goto cleanup;
- }
- ctxt = xmlXPathNewContext(xml);
- if (ctxt == NULL) {
- virReportOOMError();
- goto cleanup;
- }
- ctxt->node = root;
- current = virXMLPropString(root, "current");
-
- if ((n = virXPathNodeSet("./domainsnapshot", ctxt, &nodes)) < 0)
- goto cleanup;
-
- for (i = 0; i < n; i++) {
- virDomainSnapshotDefPtr def;
-
- def = virDomainSnapshotDefParseNode(xml, nodes[i], caps, xmlopt, NULL,
- flags);
- if (!def)
- goto cleanup;
- if (!(snap = virDomainSnapshotAssignDef(snapshots, def))) {
- virDomainSnapshotDefFree(def);
- goto cleanup;
- }
- if (virDomainSnapshotRedefineValidate(def, domain_uuid, NULL, NULL,
- flags) < 0)
- goto cleanup;
- }
-
- if (virDomainSnapshotUpdateRelations(snapshots) < 0) {
- virReportError(VIR_ERR_XML_ERROR, "%s",
- _("<snapshots> contains inconsistent parent-child "
- "relationships"));
- goto cleanup;
- }
-
- if (current) {
- snap = virDomainSnapshotFindByName(snapshots, current);
- if (!snap) {
- virReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT,
- _("no snapshot matching current='%s'"), current);
- goto cleanup;
- }
- virDomainSnapshotSetCurrent(snapshots, snap);
- }
-
- ret = n;
- cleanup:
- if (ret < 0) {
- /* There were no snapshots before this call; so on error, just
- * blindly delete anything created before the failure. */
- virDomainMomentObjListRemoveAll(snapshots->base);
- }
- xmlXPathFreeContext(ctxt);
- xmlFreeDoc(xml);
- xmlKeepBlanksDefault(keepBlanksDefault);
- return ret;
-}
-
-
/* Struct and callback function used as a hash table callback; each call
* appends another snapshot XML to buf, with the caller clearing the
* buffer if any callback fails. */