[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

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



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


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]