From e2ed67a8b6ace6ecd8b2020fc191b59b99d5fd4f Mon Sep 17 00:00:00 2001 From: Michal Privoznik Date: Fri, 22 Jul 2011 16:07:25 +0200 Subject: [PATCH] bandwidth: Add parsing and free functions These functions parse given XML node and return pointer to the output. Unknown elements are silently ignored. Attributes must be integer and must fit in unsigned long long. Free function frees elements of virBandwidth structure. --- cfg.mk | 1 + src/conf/domain_conf.c | 5 ++ src/conf/domain_conf.h | 1 + src/conf/network_conf.c | 7 ++ src/conf/network_conf.h | 1 + src/libvirt_private.syms | 2 + src/util/network.c | 147 +++++++++++++++++++++++++++++++++++++++ src/util/network.h | 2 + 8 files changed, 166 insertions(+) diff --git a/cfg.mk b/cfg.mk index 977ea87a0b..2eb73e69db 100644 --- a/cfg.mk +++ b/cfg.mk @@ -84,6 +84,7 @@ useless_free_options = \ --name=qemuMigrationCookieFree \ --name=qemuMigrationCookieGraphicsFree \ --name=sexpr_free \ + --name=virBandwidthDefFree \ --name=virBitmapFree \ --name=virCPUDefFree \ --name=virCapabilitiesFree \ diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 919a75a762..e11ad987a6 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -810,6 +810,8 @@ void virDomainNetDefFree(virDomainNetDefPtr def) VIR_FREE(def->filter); virNWFilterHashTableFree(def->filterparams); + virBandwidthDefFree(def->bandwidth); + VIR_FREE(def); } @@ -2823,6 +2825,9 @@ virDomainNetDefParseXML(virCapsPtr caps, xmlStrEqual(cur->name, BAD_CAST "actual")) { if (virDomainActualNetDefParseXML(cur, ctxt, &actual) < 0) goto error; + } else if (xmlStrEqual(cur->name, BAD_CAST "bandwidth")) { + if (!(def->bandwidth = virBandwidthDefParseNode(cur))) + goto error; } } cur = cur->next; diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 551946b79b..212f0c5f0f 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -425,6 +425,7 @@ struct _virDomainNetDef { virDomainDeviceInfo info; char *filter; virNWFilterHashTablePtr filterparams; + virBandwidthPtr bandwidth; }; enum virDomainChrDeviceType { diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index 860eea3e42..01c094cba2 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -167,6 +167,8 @@ void virNetworkDefFree(virNetworkDefPtr def) virNetworkDNSDefFree(def->dns); + virBandwidthDefFree(def->bandwidth); + VIR_FREE(def); } @@ -814,6 +816,7 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt) int nIps, nPortGroups, nForwardIfs; char *forwardDev = NULL; xmlNodePtr save = ctxt->node; + xmlNodePtr bandwidthNode = NULL; if (VIR_ALLOC(def) < 0) { virReportOOMError(); @@ -848,6 +851,10 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt) /* Parse network domain information */ def->domain = virXPathString("string(./domain[1]/@name)", ctxt); + if ((bandwidthNode = virXPathNode("./bandwidth", ctxt)) != NULL && + (def->bandwidth = virBandwidthDefParseNode(bandwidthNode)) == NULL) + goto error; + /* Parse bridge information */ def->bridge = virXPathString("string(./bridge[1]/@name)", ctxt); stp = virXPathString("string(./bridge[1]/@stp)", ctxt); diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h index 92cc03eee0..6d0845e36c 100644 --- a/src/conf/network_conf.h +++ b/src/conf/network_conf.h @@ -154,6 +154,7 @@ struct _virNetworkDef { size_t nPortGroups; virPortGroupDefPtr portGroups; + virBandwidthPtr bandwidth; }; typedef struct _virNetworkObj virNetworkObj; diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index a3b78ad353..5d7faa0877 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -710,6 +710,8 @@ nlComm; # network.h +virBandwidthDefFree; +virBandwidthDefParseNode; virSocketAddrBroadcast; virSocketAddrBroadcastByPrefix; virSocketAddrIsNetmask; diff --git a/src/util/network.c b/src/util/network.c index 64f5645a91..2ba6f768fb 100644 --- a/src/util/network.c +++ b/src/util/network.c @@ -883,3 +883,150 @@ virVirtualPortProfileFormat(virBufferPtr buf, virBufferAsprintf(buf, "%s\n", indent); } + +static int +virBandwidthParseChildDefNode(xmlNodePtr node, virRatePtr rate) +{ + int ret = -1; + char *average = NULL; + char *peak = NULL; + char *burst = NULL; + + if (!node || !rate) { + virSocketError(VIR_ERR_INVALID_ARG, "%s", + _("invalid argument supplied")); + return -1; + } + + average = virXMLPropString(node, "average"); + peak = virXMLPropString(node, "peak"); + burst = virXMLPropString(node, "burst"); + + if (average) { + if (virStrToLong_ull(average, NULL, 10, &rate->average) < 0) { + virSocketError(VIR_ERR_CONFIG_UNSUPPORTED, + _("could not convert %s"), + average); + goto cleanup; + } + } else { + virSocketError(VIR_ERR_XML_DETAIL, "%s", + _("Missing mandatory average attribute")); + goto cleanup; + } + + if (peak && virStrToLong_ull(peak, NULL, 10, &rate->peak) < 0) { + virSocketError(VIR_ERR_CONFIG_UNSUPPORTED, + _("could not convert %s"), + peak); + goto cleanup; + } + + if (burst && virStrToLong_ull(burst, NULL, 10, &rate->burst) < 0) { + virSocketError(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 + * + * Parse bandwidth XML and return pointer to structure + * + * Returns !NULL on success, NULL on error. + */ +virBandwidthPtr +virBandwidthDefParseNode(xmlNodePtr node) +{ + virBandwidthPtr def = NULL; + xmlNodePtr cur = node->children; + xmlNodePtr in = NULL, out = NULL; + + if (VIR_ALLOC(def) < 0) { + virReportOOMError(); + return NULL; + } + + if (!node || !xmlStrEqual(node->name, BAD_CAST "bandwidth")) { + virSocketError(VIR_ERR_INVALID_ARG, "%s", + _("invalid argument supplied")); + goto error; + } + + while (cur) { + if (cur->type == XML_ELEMENT_NODE) { + if (xmlStrEqual(cur->name, BAD_CAST "inbound")) { + if (in) { + virSocketError(VIR_ERR_XML_DETAIL, "%s", + _("Only one child " + "element allowed")); + goto error; + } + in = cur; + } else if (xmlStrEqual(cur->name, BAD_CAST "outbound")) { + if (out) { + virSocketError(VIR_ERR_XML_DETAIL, "%s", + _("Only one child " + "element allowed")); + goto error; + } + out = cur; + } + /* Silently ignore unknown elements */ + } + cur = cur->next; + } + + if (in) { + if (VIR_ALLOC(def->in) < 0) { + virReportOOMError(); + goto error; + } + + if (virBandwidthParseChildDefNode(in, def->in) < 0) { + /* helper reported error for us */ + goto error; + } + } + + if (out) { + if (VIR_ALLOC(def->out) < 0) { + virReportOOMError(); + goto error; + } + + if (virBandwidthParseChildDefNode(out, def->out) < 0) { + /* helper reported error for us */ + goto error; + } + } + + return def; + +error: + virBandwidthDefFree(def); + return NULL; +} + +void +virBandwidthDefFree(virBandwidthPtr def) +{ + if (!def) + return; + + VIR_FREE(def->in); + VIR_FREE(def->out); + VIR_FREE(def); +} diff --git a/src/util/network.h b/src/util/network.h index 3c090d8399..4d35388c61 100644 --- a/src/util/network.h +++ b/src/util/network.h @@ -150,4 +150,6 @@ virVirtualPortProfileFormat(virBufferPtr buf, virVirtualPortProfileParamsPtr virtPort, const char *indent); +virBandwidthPtr virBandwidthDefParseNode(xmlNodePtr node); +void virBandwidthDefFree(virBandwidthPtr def); #endif /* __VIR_NETWORK_H__ */