Interfaces keeps a class_id, which is an ID from which bridge
part of QoS settings is derived. We need to store class_id
in domain status file, so we can later pass it to
virNetDevBandwidthUnplug.
---
src/conf/domain_conf.c | 4 +-
src/qemu/qemu_domain.c | 66 ++++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 63 insertions(+), 7 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 250290e..f80cad7 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -8177,7 +8177,7 @@ static virDomainObjPtr virDomainObjParseXML(virCapsPtr caps,
VIR_FREE(nodes);
if (caps->privateDataXMLParse &&
- ((caps->privateDataXMLParse)(ctxt, obj->privateData)) < 0)
+ ((caps->privateDataXMLParse)(ctxt, obj)) < 0)
goto error;
return obj;
@@ -11859,7 +11859,7 @@ static char *virDomainObjFormat(virCapsPtr caps,
}
if (caps->privateDataXMLFormat &&
- ((caps->privateDataXMLFormat)(&buf, obj->privateData)) < 0)
+ ((caps->privateDataXMLFormat)(&buf, obj)) < 0)
goto error;
virBufferAdjustIndent(&buf, 2);
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 6b03c62..2f41a49 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -225,8 +225,11 @@ static void qemuDomainObjPrivateFree(void *data)
static int qemuDomainObjPrivateXMLFormat(virBufferPtr buf, void *data)
{
- qemuDomainObjPrivatePtr priv = data;
+ virDomainObjPtr vm = data;
+ qemuDomainObjPrivatePtr priv = vm->privateData;
const char *monitorpath;
+ bool do_class_id = false;
+ int i;
/* priv->monitor_chr is set only for qemu */
if (priv->monConfig) {
@@ -249,7 +252,6 @@ static int qemuDomainObjPrivateXMLFormat(virBufferPtr buf, void
*data)
if (priv->nvcpupids) {
- int i;
virBufferAddLit(buf, " <vcpus>\n");
for (i = 0 ; i < priv->nvcpupids ; i++) {
virBufferAsprintf(buf, " <vcpu pid='%d'/>\n",
priv->vcpupids[i]);
@@ -258,7 +260,6 @@ static int qemuDomainObjPrivateXMLFormat(virBufferPtr buf, void
*data)
}
if (priv->qemuCaps) {
- int i;
virBufferAddLit(buf, " <qemuCaps>\n");
for (i = 0 ; i < QEMU_CAPS_LAST ; i++) {
if (qemuCapsGet(priv->qemuCaps, i)) {
@@ -287,15 +288,36 @@ static int qemuDomainObjPrivateXMLFormat(virBufferPtr buf, void
*data)
if (priv->fakeReboot)
virBufferAsprintf(buf, " <fakereboot/>\n");
+ for (i = 0; i < vm->def->nnets; i++) {
+ if (vm->def->nets[i]->class_id) {
+ do_class_id = true;
+ break;
+ }
+ }
+
+ if (do_class_id) {
+ virBufferAddLit(buf, " <class_id>\n");
+ for ( ; i < vm->def->nnets; i++) {
+ virDomainNetDefPtr iface = vm->def->nets[i];
+ if (iface->class_id) {
+ virBufferAsprintf(buf, " <interface alias='%s' "
+ "class_id='%u'/>\n",
+ iface->info.alias, iface->class_id);
+ }
+ }
+ virBufferAddLit(buf, " </class_id>\n");
+ }
+
return 0;
}
static int qemuDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt, void *data)
{
- qemuDomainObjPrivatePtr priv = data;
+ virDomainObjPtr vm = data;
+ qemuDomainObjPrivatePtr priv = vm->privateData;
char *monitorpath;
char *tmp;
- int n, i;
+ int n, i, ii;
xmlNodePtr *nodes = NULL;
virBitmapPtr qemuCaps = NULL;
@@ -432,6 +454,40 @@ static int qemuDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt, void
*data)
priv->fakeReboot = virXPathBoolean("boolean(./fakereboot)", ctxt) == 1;
+ if ((n = virXPathNodeSet("./class_id/interface", ctxt, &nodes)) <
0)
+ goto error;
+
+ for (i = 0; i < n; i++) {
+ char *alias = virXMLPropString(nodes[i], "alias");
+ char *class_id = virXMLPropString(nodes[i], "class_id");
+ virDomainNetDefPtr iface = NULL;
+ if (alias && class_id) {
+ for (ii = 0; ii < vm->def->nnets; ii++) {
+ if (STREQ(vm->def->nets[ii]->info.alias, alias)) {
+ iface = vm->def->nets[ii];
+ break;
+ }
+ }
+
+ if (!iface) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ _("No such interface '%s'"),
+ alias);
+ VIR_FREE(alias);
+ VIR_FREE(class_id);
+ goto error;
+ }
+
+ if (virStrToLong_ui(class_id, NULL, 10, &iface->class_id) < 0) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Malformed class_id attribute: %s"),
+ class_id);
+ }
+ }
+ VIR_FREE(alias);
+ VIR_FREE(class_id);
+ }
+
return 0;
error:
--
1.7.3.4