[libvirt] [PATCH 20/34] conf: Introduce modular parser for virStorageSource

Peter Krempa pkrempa at redhat.com
Mon Mar 18 15:55:09 UTC 2019


Introduce a helper which parses XML into virStorageSource according to
XPath queries passed in for the various bits. The new parser will allow
to unify the parsing of the various XML formats we use in different
parts without the need to do custom parsers.

Signed-off-by: Peter Krempa <pkrempa at redhat.com>
---
 src/conf/domain_conf.c   | 94 ++++++++++++++++++++++++++++++++++++++++
 src/conf/domain_conf.h   | 12 +++++
 src/libvirt_private.syms |  1 +
 3 files changed, 107 insertions(+)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index bf3ad45397..d2cc199ed5 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -9111,6 +9111,100 @@ virDomainStorageSourceParse(xmlNodePtr node,
 }


+/**
+ * virDomainStorageSourceParseFull
+ * @typeXPath: XPath query string for the 'type' of virStorageSource
+ * @formatXPath: XPath query for the image format (may be NULL if caller wishes to parse it)
+ * @sourceXPath: XPath query for the <source> subelement
+ * @indexXPath: XPath query for 'id' in virStorageSource (may be NULL if skipped)
+ * @allowMissing: if true no errors are reported if the above fields are missing
+ * @ctxt: XPath context
+ * @flags: XML parser flags
+ * @xmlopt: XML parser callbacks
+ *
+ * Uses the XPath queries provided as arguments to parse a storage source XML
+ * into virStorageSource. If allowMissing is false the function reports error if
+ * any of the XML parts described by @typeXPath, @formatXPath or @sourceXPath
+ * are missing. @formatXPath and @indexXpath may be NULL if they should be omitted
+ * or if the caller parses the value separately.
+ *
+ * Returns the parsed source or NULL on error.
+ */
+virStorageSourcePtr
+virDomainStorageSourceParseFull(const char *typeXPath,
+                                const char *formatXPath,
+                                const char *sourceXPath,
+                                const char *indexXPath,
+                                bool allowMissing,
+                                xmlXPathContextPtr ctxt,
+                                unsigned int flags,
+                                virDomainXMLOptionPtr xmlopt)
+{
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
+    VIR_AUTOFREE(char *) type = NULL;
+    VIR_AUTOFREE(char *) format = NULL;
+    VIR_AUTOFREE(char *) idx = NULL;
+    xmlNodePtr sourceNode = NULL;
+    VIR_AUTOUNREF(virStorageSourcePtr) src = NULL;
+    virStorageSourcePtr ret = NULL;
+
+    if (!(type = virXPathString(typeXPath, ctxt)) &&
+        !allowMissing) {
+        virReportError(VIR_ERR_XML_ERROR, "%s", _("missing storage source type"));
+        return NULL;
+    }
+
+    if (formatXPath &&
+        !(format = virXPathString(formatXPath, ctxt)) &&
+        !allowMissing) {
+        virReportError(VIR_ERR_XML_ERROR, "%s", _("missing storage source format"));
+        return NULL;
+    }
+
+    if (!(sourceNode = virXPathNode(sourceXPath, ctxt)) &&
+        !allowMissing) {
+        virReportError(VIR_ERR_XML_ERROR, "%s", _("missing storage source data"));
+        return NULL;
+    }
+
+    if (!(src = virStorageSourceNew()))
+        return NULL;
+
+    if (type) {
+        if ((src->type = virStorageTypeFromString(type)) <= 0) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                           _("unknown storage source type '%s'"), type);
+            return NULL;
+        }
+    } else {
+        src->type = VIR_STORAGE_TYPE_FILE;
+    }
+
+    if (format &&
+        (src->format = virStorageFileFormatTypeFromString(format)) <= 0) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("unknown storage source format '%s'"), format);
+        return NULL;
+    }
+
+    if (indexXPath &&
+        !(flags & VIR_DOMAIN_DEF_PARSE_INACTIVE) &&
+        (idx = virXPathString(indexXPath, ctxt)) &&
+        virStrToLong_uip(idx, NULL, 10, &src->id) < 0) {
+        virReportError(VIR_ERR_XML_ERROR,
+                       _("invalid storage source index '%s'"), idx);
+        return NULL;
+    }
+
+    if (sourceNode &&
+        virDomainStorageSourceParse(sourceNode, ctxt, src, flags, xmlopt) < 0)
+        return NULL;
+
+    VIR_STEAL_PTR(ret, src);
+    return ret;
+}
+
+
 int
 virDomainDiskSourceParse(xmlNodePtr node,
                          xmlXPathContextPtr ctxt,
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 0b6d432871..a87e1b30b9 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -3476,6 +3476,18 @@ int virDomainStorageSourceParse(xmlNodePtr node,
                                 virDomainXMLOptionPtr xmlopt)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);

+virStorageSourcePtr
+virDomainStorageSourceParseFull(const char *typeXPath,
+                                const char *formatXPath,
+                                const char *sourceXPath,
+                                const char *indexXPath,
+                                bool allowMissing,
+                                xmlXPathContextPtr ctxt,
+                                unsigned int flags,
+                                virDomainXMLOptionPtr xmlopt)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3)
+    ATTRIBUTE_NONNULL(6);
+
 int virDomainDefGetVcpuPinInfoHelper(virDomainDefPtr def,
                                      int maplen,
                                      int ncpumaps,
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 010c8ac481..e4a695de9f 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -565,6 +565,7 @@ virDomainStateTypeToString;
 virDomainStorageNetworkParseHost;
 virDomainStorageSourceFormatFull;
 virDomainStorageSourceParse;
+virDomainStorageSourceParseFull;
 virDomainTaintTypeFromString;
 virDomainTaintTypeToString;
 virDomainTimerModeTypeFromString;
-- 
2.20.1




More information about the libvir-list mailing list