On 5/14/19 11:48 AM, Daniel P. Berrangé wrote:
The domain conf actual network def stores a <class
id='3'/> element
separately from the <bandwidth>. The class ID should really just be
an attribute on the <bandwidth> element. We can't change existing
XML, and this isn't visible to users since it is internal XML only.
When we expose the new network port XML to users though, we should
get the design right.
Signed-off-by: Daniel P. Berrangé <berrange(a)redhat.com>
---
src/conf/domain_conf.c | 6 ++++--
src/conf/netdev_bandwidth_conf.c | 30 ++++++++++++++++++++++++++++--
src/conf/netdev_bandwidth_conf.h | 2 ++
src/conf/network_conf.c | 8 ++++----
tests/virnetdevbandwidthtest.c | 1 +
5 files changed, 39 insertions(+), 8 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index a3a514136b..011d789feb 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -11270,6 +11270,7 @@ virDomainActualNetDefParseXML(xmlNodePtr node,
bandwidth_node = virXPathNode("./bandwidth", ctxt);
if (bandwidth_node &&
virNetDevBandwidthParse(&actual->bandwidth,
+ NULL,
bandwidth_node,
actual->type == VIR_DOMAIN_NET_TYPE_NETWORK) <
0)
goto error;
@@ -11609,6 +11610,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
}
} else if (virXMLNodeNameEqual(cur, "bandwidth")) {
if (virNetDevBandwidthParse(&def->bandwidth,
+ NULL,
cur,
def->type ==
VIR_DOMAIN_NET_TYPE_NETWORK) < 0)
goto error;
@@ -25006,7 +25008,7 @@ virDomainActualNetDefContentsFormat(virBufferPtr buf,
return -1;
if (virNetDevVPortProfileFormat(virDomainNetGetActualVirtPortProfile(def), buf)
< 0)
return -1;
- if (virNetDevBandwidthFormat(virDomainNetGetActualBandwidth(def), buf) < 0)
+ if (virNetDevBandwidthFormat(virDomainNetGetActualBandwidth(def), 0, buf) < 0)
return -1;
return 0;
}
@@ -25383,7 +25385,7 @@ virDomainNetDefFormat(virBufferPtr buf,
return -1;
if (virNetDevVPortProfileFormat(def->virtPortProfile, buf) < 0)
return -1;
- if (virNetDevBandwidthFormat(def->bandwidth, buf) < 0)
+ if (virNetDevBandwidthFormat(def->bandwidth, 0, buf) < 0)
return -1;
/* ONLY for internal status storage - format the ActualNetDef
diff --git a/src/conf/netdev_bandwidth_conf.c b/src/conf/netdev_bandwidth_conf.c
index 014941836d..9af2173b7b 100644
--- a/src/conf/netdev_bandwidth_conf.c
+++ b/src/conf/netdev_bandwidth_conf.c
@@ -99,6 +99,7 @@ virNetDevBandwidthParseRate(xmlNodePtr node, virNetDevBandwidthRatePtr
rate)
/**
* virNetDevBandwidthParse:
* @bandwidth: parsed bandwidth
+ * @class_id: parsed class ID
* @node: XML node
* @allowFloor: whether "floor" setting is supported
*
@@ -110,6 +111,7 @@ virNetDevBandwidthParseRate(xmlNodePtr node,
virNetDevBandwidthRatePtr rate)
*/
int
virNetDevBandwidthParse(virNetDevBandwidthPtr *bandwidth,
+ unsigned int *class_id,
Is there a reason you keep it separate from virNetDevBandwidthPtr,
rather than just making it an attribute of the object, just as it is an
object of the XML element? You'd still need to pass a bool into the
Parse and Format functions, but it might make the code simpler (or at
least easier to understand) elsewhere. Or it might be a NOP; I haven't
thought it through.
Anyway, this is something that can be changed later if we deem it
worthwhile, so if this works then it's okay for now at the very least.
xmlNodePtr node,
bool allowFloor)
{
@@ -117,6 +119,7 @@ virNetDevBandwidthParse(virNetDevBandwidthPtr *bandwidth,
virNetDevBandwidthPtr def = NULL;
xmlNodePtr cur;
xmlNodePtr in = NULL, out = NULL;
+ char *class_id_prop = NULL;
if (VIR_ALLOC(def) < 0)
return ret;
@@ -127,6 +130,22 @@ virNetDevBandwidthParse(virNetDevBandwidthPtr *bandwidth,
goto cleanup;
}
+ class_id_prop = virXMLPropString(node, "classID");
+1 on changing it from a single attribute inside its own element to a
simple attribute :-)
Reviewed-by: Laine Stump <laine(a)laine.org>
(I'm fine with keeping class_id separate, just thought I'd mention it.
Oh, and I assume later patches will end up adding stuff to test this
addition to the parsing/formatting :-))
+ if (class_id_prop) {
+ if (!class_id) {
+ virReportError(VIR_ERR_XML_DETAIL, "%s",
+ _("classID attribute not supported on <bandwidth>
"
+ "in this usage context"));
+ goto cleanup;
+ }
+ if (virStrToLong_ui(class_id_prop, NULL, 10, class_id) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Unable to parse class id '%s'"),
+ class_id_prop);
+ goto cleanup;
+ }
+ }
+
cur = node->children;
while (cur) {
@@ -194,6 +213,7 @@ virNetDevBandwidthParse(virNetDevBandwidthPtr *bandwidth,
ret = 0;
cleanup:
+ VIR_FREE(class_id_prop);
virNetDevBandwidthFree(def);
return ret;
}
@@ -231,6 +251,7 @@ virNetDevBandwidthRateFormat(virNetDevBandwidthRatePtr def,
/**
* virNetDevBandwidthFormat:
* @def: Data source
+ * @class_id: the class ID to format, 0 to skip
* @buf: Buffer to print to
*
* Formats bandwidth and prepend each line with @indent.
@@ -239,7 +260,9 @@ virNetDevBandwidthRateFormat(virNetDevBandwidthRatePtr def,
* Returns 0 on success, else -1.
*/
int
-virNetDevBandwidthFormat(virNetDevBandwidthPtr def, virBufferPtr buf)
+virNetDevBandwidthFormat(virNetDevBandwidthPtr def,
+ unsigned int class_id,
+ virBufferPtr buf)
{
int ret = -1;
@@ -251,7 +274,10 @@ virNetDevBandwidthFormat(virNetDevBandwidthPtr def, virBufferPtr
buf)
goto cleanup;
}
- virBufferAddLit(buf, "<bandwidth>\n");
+ virBufferAddLit(buf, "<bandwidth");
+ if (class_id)
+ virBufferAsprintf(buf, " classID='%u'", class_id);
+ virBufferAddLit(buf, ">\n");
virBufferAdjustIndent(buf, 2);
if (virNetDevBandwidthRateFormat(def->in, buf, "inbound") < 0 ||
virNetDevBandwidthRateFormat(def->out, buf, "outbound") < 0)
diff --git a/src/conf/netdev_bandwidth_conf.h b/src/conf/netdev_bandwidth_conf.h
index 7fe750ce27..b91222321a 100644
--- a/src/conf/netdev_bandwidth_conf.h
+++ b/src/conf/netdev_bandwidth_conf.h
@@ -26,10 +26,12 @@
# include "domain_conf.h"
int virNetDevBandwidthParse(virNetDevBandwidthPtr *bandwidth,
+ unsigned int *class_id,
xmlNodePtr node,
bool allowFloor)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
int virNetDevBandwidthFormat(virNetDevBandwidthPtr def,
+ unsigned int class_id,
virBufferPtr buf);
void virDomainClearNetBandwidth(virDomainObjPtr vm)
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index 91562de269..09e379ae9a 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -1188,7 +1188,7 @@ virNetworkPortGroupParseXML(virPortGroupDefPtr def,
bandwidth_node = virXPathNode("./bandwidth", ctxt);
if (bandwidth_node &&
- virNetDevBandwidthParse(&def->bandwidth, bandwidth_node, false) < 0)
+ virNetDevBandwidthParse(&def->bandwidth, NULL, bandwidth_node, false)
< 0)
goto cleanup;
vlanNode = virXPathNode("./vlan", ctxt);
@@ -1682,7 +1682,7 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
}
if ((bandwidthNode = virXPathNode("./bandwidth", ctxt)) &&
- virNetDevBandwidthParse(&def->bandwidth, bandwidthNode, false) < 0)
+ virNetDevBandwidthParse(&def->bandwidth, NULL, bandwidthNode, false) <
0)
goto error;
vlanNode = virXPathNode("./vlan", ctxt);
@@ -2311,7 +2311,7 @@ virPortGroupDefFormat(virBufferPtr buf,
return -1;
if (virNetDevVPortProfileFormat(def->virtPortProfile, buf) < 0)
return -1;
- virNetDevBandwidthFormat(def->bandwidth, buf);
+ virNetDevBandwidthFormat(def->bandwidth, 0, buf);
virBufferAdjustIndent(buf, -2);
virBufferAddLit(buf, "</portgroup>\n");
return 0;
@@ -2566,7 +2566,7 @@ virNetworkDefFormatBuf(virBufferPtr buf,
if (virNetDevVlanFormat(&def->vlan, buf) < 0)
goto error;
- if (virNetDevBandwidthFormat(def->bandwidth, buf) < 0)
+ if (virNetDevBandwidthFormat(def->bandwidth, 0, buf) < 0)
goto error;
for (i = 0; i < def->nips; i++) {
diff --git a/tests/virnetdevbandwidthtest.c b/tests/virnetdevbandwidthtest.c
index 23788b4164..2c0b6a6713 100644
--- a/tests/virnetdevbandwidthtest.c
+++ b/tests/virnetdevbandwidthtest.c
@@ -54,6 +54,7 @@ struct testSetStruct {
goto cleanup; \
\
rc = virNetDevBandwidthParse(&(var), \
+ NULL, \
ctxt->node, \
true); \
xmlFreeDoc(doc); \