On 11/19/2012 11:51 AM, Michal Privoznik wrote: > 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. Interesting use of alias to find the original interface matching the class_id. But we already have a "status-only" subelement in every type='network' interface, so it will be much simpler to just store it there (conveniently in the bandwidth object, as I suggested in an earlier patch). (if <actual> wasn't already saved within <interface>, I might have considered doing it this way, but that ship has already sailed.) > --- > 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 bf23b77..37a8875 100644 > --- a/src/conf/domain_conf.c > +++ b/src/conf/domain_conf.c > @@ -10242,7 +10242,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; > @@ -14212,7 +14212,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 e0d6951..5312946 100644 > --- a/src/qemu/qemu_domain.c > +++ b/src/qemu/qemu_domain.c > @@ -258,9 +258,12 @@ 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; > enum qemuDomainJob job; > + bool do_class_id = false; > + int i; > > /* priv->monitor_chr is set only for qemu */ > if (priv->monConfig) { > @@ -283,7 +286,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]); > @@ -292,7 +294,6 @@ static int qemuDomainObjPrivateXMLFormat(virBufferPtr buf, void *data) > } > > if (priv->caps) { > - int i; > virBufferAddLit(buf, " <qemuCaps>\n"); > for (i = 0 ; i < QEMU_CAPS_LAST ; i++) { > if (qemuCapsGet(priv->caps, i)) { > @@ -326,15 +327,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; > qemuCapsPtr caps = NULL; > > @@ -471,6 +493,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) { > + virReportError(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) { > + virReportError(VIR_ERR_INTERNAL_ERROR, > + _("Malformed class_id attribute: %s"), > + class_id); > + } > + } > + VIR_FREE(alias); > + VIR_FREE(class_id); > + } > + > return 0; > > error: -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list