From nobody Sun Feb 8 23:03:42 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1551756975143935.6634227567795; Mon, 4 Mar 2019 19:36:15 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 79C23307EA8B; Tue, 5 Mar 2019 03:36:12 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 4F328608DA; Tue, 5 Mar 2019 03:36:12 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 07FDF3D391; Tue, 5 Mar 2019 03:36:12 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x253Yvrb004197 for ; Mon, 4 Mar 2019 22:34:57 -0500 Received: by smtp.corp.redhat.com (Postfix) id 2F55960A9A; Tue, 5 Mar 2019 03:34:57 +0000 (UTC) Received: from blue.redhat.com (ovpn-118-35.phx2.redhat.com [10.3.118.35]) by smtp.corp.redhat.com (Postfix) with ESMTP id D4D9160C7F; Tue, 5 Mar 2019 03:34:56 +0000 (UTC) From: Eric Blake To: libvir-list@redhat.com Date: Mon, 4 Mar 2019 21:34:38 -0600 Message-Id: <20190305033445.17140-12-eblake@redhat.com> In-Reply-To: <20190305033445.17140-1-eblake@redhat.com> References: <20190305033445.17140-1-eblake@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-loop: libvir-list@redhat.com Cc: nsoffer@redhat.com Subject: [libvirt] [PATCH v3 11/18] snapshot: Add virDomainSnapshotObjListParse X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.44]); Tue, 05 Mar 2019 03:36:14 +0000 (UTC) Content-Type: text/plain; charset="utf-8" Add a new function to make it possible to parse a list of snapshots at once. This is a counterpart to an earlier patch making it possible to produce all snapshots in a single XML string, and intentionally parses the same top-level element with an optional attribute current=3D'name'. Note that since we know we started with no relations at all, and since checking parent relationships per-snapshot is not viable as we don't control which order the snapshots appear in, that we are fine with doing a final pass to update all parent/child relationships among the definitions. Signed-off-by: Eric Blake Reviewed-by: John Ferlan --- src/conf/snapshot_conf.h | 7 +++ src/conf/snapshot_conf.c | 111 +++++++++++++++++++++++++++++++++++++++ src/libvirt_private.syms | 1 + 3 files changed, 119 insertions(+) diff --git a/src/conf/snapshot_conf.h b/src/conf/snapshot_conf.h index 69a7750b0b..f8af991907 100644 --- a/src/conf/snapshot_conf.h +++ b/src/conf/snapshot_conf.h @@ -132,6 +132,13 @@ virDomainSnapshotDefPtr virDomainSnapshotDefParseNode(= xmlDocPtr xml, virCapsPtr caps, virDomainXMLOptionPt= r xmlopt, unsigned int flags); +int virDomainSnapshotObjListParse(const char *xmlStr, + const unsigned char *domain_uuid, + virDomainSnapshotObjListPtr snapshots, + virDomainSnapshotObjPtr *current_snap, + virCapsPtr caps, + virDomainXMLOptionPtr xmlopt, + unsigned int flags); void virDomainSnapshotDefFree(virDomainSnapshotDefPtr def); char *virDomainSnapshotDefFormat(const char *uuidstr, virDomainSnapshotDefPtr def, diff --git a/src/conf/snapshot_conf.c b/src/conf/snapshot_conf.c index a5b05eadf4..52742d82d6 100644 --- a/src/conf/snapshot_conf.c +++ b/src/conf/snapshot_conf.c @@ -507,6 +507,117 @@ virDomainSnapshotRedefineValidate(virDomainSnapshotDe= fPtr def, } +/* Parse a XML entry into snapshots, which must start empty. + * Any sub-elements of a must match domain_uuid. + */ +int +virDomainSnapshotObjListParse(const char *xmlStr, + const unsigned char *domain_uuid, + virDomainSnapshotObjListPtr snapshots, + virDomainSnapshotObjPtr *current_snap, + virCapsPtr caps, + virDomainXMLOptionPtr xmlopt, + unsigned int flags) +{ + int ret =3D -1; + xmlDocPtr xml; + xmlNodePtr root; + xmlXPathContextPtr ctxt =3D NULL; + int n; + size_t i; + int keepBlanksDefault =3D xmlKeepBlanksDefault(0); + VIR_AUTOFREE(xmlNodePtr *) nodes =3D NULL; + VIR_AUTOFREE(char *) current =3D 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 (snapshots->metaroot.nchildren || *current_snap) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("bulk define of snapshots only possible with " + "no existing snapshot")); + return -1; + } + + if (!(xml =3D virXMLParse(NULL, xmlStr, _("(domain_snapshot)")))) + goto cleanup; + + root =3D xmlDocGetRootElement(xml); + if (!virXMLNodeNameEqual(root, "snapshots")) { + virReportError(VIR_ERR_XML_ERROR, + _("unexpected root element <%s>, " + "expecting "), root->name); + goto cleanup; + } + ctxt =3D xmlXPathNewContext(xml); + if (ctxt =3D=3D NULL) { + virReportOOMError(); + goto cleanup; + } + ctxt->node =3D root; + current =3D virXMLPropString(root, "current"); + + if ((n =3D virXPathNodeSet("./domainsnapshot", ctxt, &nodes)) < 0) + goto cleanup; + if (!n) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("expected at least one child")); + goto cleanup; + } + + for (i =3D 0; i < n; i++) { + virDomainSnapshotDefPtr def; + virDomainSnapshotObjPtr snap; + + def =3D virDomainSnapshotDefParseNode(xml, nodes[i], caps, xmlopt,= flags); + if (!def) + goto cleanup; + if (!(snap =3D 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", + _(" contains inconsistent parent-child " + "relationships")); + goto cleanup; + } + + if (current) { + if (!(*current_snap =3D virDomainSnapshotFindByName(snapshots, + current))) { + virReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT, + _("no snapshot matching current=3D'%s'"), curre= nt); + goto cleanup; + } + (*current_snap)->def->current =3D true; + } + + ret =3D 0; + cleanup: + 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 =3D 0; + snapshots->metaroot.first_child =3D NULL; + } + VIR_FREE(current); + xmlXPathFreeContext(ctxt); + xmlFreeDoc(xml); + xmlKeepBlanksDefault(keepBlanksDefault); + return ret; +} + + /** * virDomainSnapshotDefAssignExternalNames: * @def: snapshot def object diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 35e0c6d9dc..395e1f8764 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -899,6 +899,7 @@ virDomainSnapshotObjListFree; virDomainSnapshotObjListGetNames; virDomainSnapshotObjListNew; virDomainSnapshotObjListNum; +virDomainSnapshotObjListParse; virDomainSnapshotObjListRemove; virDomainSnapshotRedefinePrep; virDomainSnapshotStateTypeFromString; --=20 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list