[libvirt] [PATCH 3/7] bandwidth: Add parsing functions

Michal Privoznik mprivozn at redhat.com
Mon Jul 18 20:05:37 UTC 2011


These functions parse given XML node and store the output at given
pointer. Unknown elements are silently ignored. Attributes must be
integer and must fit in unsigned long.
---
 src/conf/domain_conf.c   |    3 +
 src/conf/domain_conf.h   |    1 +
 src/conf/network_conf.c  |    5 ++
 src/conf/network_conf.h  |    1 +
 src/libvirt_private.syms |    1 +
 src/util/network.c       |  112 ++++++++++++++++++++++++++++++++++++++++++++++
 src/util/network.h       |    2 +
 7 files changed, 125 insertions(+), 0 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 8c3e44e..0d8c7e7 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -2854,6 +2854,9 @@ virDomainNetDefParseXML(virCapsPtr caps,
                 if (virDomainDeviceBootParseXML(cur, &def->bootIndex,
                                                 bootMap))
                     goto error;
+            } else if (xmlStrEqual(cur->name, BAD_CAST "bandwidth")) {
+                if (virBandwidthDefParseNode(cur, &def->bandwidth) < 0)
+                    goto error;
             }
         }
         cur = cur->next;
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 172d3c2..06cea02 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -398,6 +398,7 @@ struct _virDomainNetDef {
     virDomainDeviceInfo info;
     char *filter;
     virNWFilterHashTablePtr filterparams;
+    virBandwidth bandwidth;
 };
 
 enum virDomainChrDeviceType {
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index ae479bf..c9929e2 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -742,6 +742,7 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
     char *tmp;
     xmlNodePtr *ipNodes = NULL;
     xmlNodePtr dnsNode = NULL;
+    xmlNodePtr bandwidthNode = NULL;
     int nIps;
 
     if (VIR_ALLOC(def) < 0) {
@@ -777,6 +778,10 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
     /* Parse network domain information */
     def->domain = virXPathString("string(./domain[1]/@name)", ctxt);
 
+    if ((bandwidthNode = virXPathNode("./bandwidth", ctxt)) != NULL &&
+        virBandwidthDefParseNode(bandwidthNode, &def->bandwidth) < 0)
+        goto error;
+
     /* Parse bridge information */
     def->bridge = virXPathString("string(./bridge[1]/@name)", ctxt);
     tmp = virXPathString("string(./bridge[1]/@stp)", ctxt);
diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h
index 5edcf27..565a464 100644
--- a/src/conf/network_conf.h
+++ b/src/conf/network_conf.h
@@ -127,6 +127,7 @@ struct _virNetworkDef {
     virNetworkIpDefPtr ips; /* ptr to array of IP addresses on this network */
 
     virNetworkDNSDefPtr dns; /* ptr to dns related configuration */
+    virBandwidth bandwidth;
 };
 
 typedef struct _virNetworkObj virNetworkObj;
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 3e3b1dd..12db3d7 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -700,6 +700,7 @@ nlComm;
 
 
 # network.h
+virBandwidthDefParseNode;
 virSocketAddrBroadcast;
 virSocketAddrBroadcastByPrefix;
 virSocketAddrIsNetmask;
diff --git a/src/util/network.c b/src/util/network.c
index eb16e0c..ce949c7 100644
--- a/src/util/network.c
+++ b/src/util/network.c
@@ -21,6 +21,9 @@
     virReportErrorHelper(VIR_FROM_THIS, code, __FILE__,                 \
                          __FUNCTION__, __LINE__, __VA_ARGS__)
 
+#define virBandwidthError(code, ...)                                    \
+    virReportErrorHelper(VIR_FROM_THIS, code, __FILE__,                 \
+                         __FUNCTION__, __LINE__, __VA_ARGS__)
 /*
  * Helpers to extract the IP arrays from the virSocketAddrPtr
  * That part is the less portable of the module
@@ -674,3 +677,112 @@ virSocketAddrPrefixToNetmask(unsigned int prefix,
 error:
     return result;
 }
+
+static int
+virBandwidthParseChildDefNode(xmlNodePtr node, virRatePtr rate)
+{
+    int ret = -1;
+    char *average = NULL;
+    char *peak = NULL;
+    char *burst = NULL;
+
+    if (!node || !rate)
+        return -1;
+
+    average = virXMLPropString(node, "average");
+    peak = virXMLPropString(node, "peak");
+    burst = virXMLPropString(node, "burst");
+
+    if (average) {
+        if (virStrToLong_ul(average, NULL, 10, &rate->average) < 0) {
+            virBandwidthError(VIR_ERR_CONFIG_UNSUPPORTED,
+                              _("could not convert %s"),
+                              average);
+            goto cleanup;
+        }
+    } else {
+        virBandwidthError(VIR_ERR_XML_DETAIL, "%s",
+                          _("Missing mandatory average attribute"));
+        goto cleanup;
+    }
+
+    if (peak && virStrToLong_ul(peak, NULL, 10, &rate->peak) < 0) {
+        virBandwidthError(VIR_ERR_CONFIG_UNSUPPORTED,
+                          _("could not convert %s"),
+                          peak);
+        goto cleanup;
+    }
+
+    if (burst && virStrToLong_ul(burst, NULL, 10, &rate->burst) < 0) {
+        virBandwidthError(VIR_ERR_CONFIG_UNSUPPORTED,
+                          _("could not convert %s"),
+                          burst);
+        goto cleanup;
+    }
+
+    ret = 0;
+
+cleanup:
+    VIR_FREE(average);
+    VIR_FREE(peak);
+    VIR_FREE(burst);
+
+    return ret;
+}
+
+/**
+ * virBandwidthDefParseNode:
+ * @node: XML node
+ * @def: where to store the parsed result
+ *
+ * Parse bandwidth XML and store into given pointer
+ *
+ * Returns 0 on success, -1 on error.
+ */
+int
+virBandwidthDefParseNode(xmlNodePtr node, virBandwidthPtr def)
+{
+    int ret = -1;
+    xmlNodePtr cur = node->children;
+    xmlNodePtr in = NULL, out = NULL;
+
+    if (!node || !def ||
+        !xmlStrEqual(node->name, BAD_CAST "bandwidth"))
+        return -1;
+
+    memset(def, 0, sizeof(*def));
+    while (cur) {
+        if (cur->type == XML_ELEMENT_NODE) {
+            if (xmlStrEqual(cur->name, BAD_CAST "inbound")) {
+                if (in) {
+                    virBandwidthError(VIR_ERR_XML_DETAIL, "%s",
+                                      _("Only one child <inbound> "
+                                        "element allowed"));
+                    goto cleanup;
+                }
+                in = cur;
+            } else if (xmlStrEqual(cur->name, BAD_CAST "outbound")) {
+                if (out) {
+                    virBandwidthError(VIR_ERR_XML_DETAIL, "%s",
+                                      _("Only one child <outbound> "
+                                        "element allowed"));
+                    goto cleanup;
+                }
+                out = cur;
+            }
+            /* Silently ignore unknown elements */
+        }
+        cur = cur->next;
+    }
+
+    if (in && virBandwidthParseChildDefNode(in, &def->in) < 0)
+        goto cleanup;
+
+    if (out && virBandwidthParseChildDefNode(out, &def->out) < 0)
+        goto cleanup;
+
+    ret = 0;
+
+cleanup:
+    return ret;
+}
diff --git a/src/util/network.h b/src/util/network.h
index af32558..54f7aad 100644
--- a/src/util/network.h
+++ b/src/util/network.h
@@ -20,6 +20,7 @@
 # endif
 # include <netdb.h>
 # include <netinet/in.h>
+# include "xml.h"
 
 typedef struct {
     union {
@@ -104,4 +105,5 @@ int virSocketAddrPrefixToNetmask(unsigned int prefix,
                                  virSocketAddrPtr netmask,
                                  int family);
 
+int virBandwidthDefParseNode(xmlNodePtr node, virBandwidthPtr def);
 #endif /* __VIR_NETWORK_H__ */
-- 
1.7.5.rc3




More information about the libvir-list mailing list