Until now the <driver> subelement of <interface> was only parsed/used/formatted if the device model was "virtio". Making the driver member of the data object a struct instead of a union and refactoring the parsing/formatting code in this separate patch will make it easier to see exactly what is being added when an upcoming patch adds an attribute to <driver> that will be present/parsed regardless of whether or not the device model is "virtio". Signed-off-by: Laine Stump <laine@xxxxxxxxxx> --- src/conf/domain_conf.c | 443 +++++++++++++++++++++-------------------- src/conf/domain_conf.h | 52 ++--- 2 files changed, 254 insertions(+), 241 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 58f4a1c14b..1379ae1600 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -12059,205 +12059,210 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt, if (ifname_guest_actual != NULL) def->ifname_guest_actual = g_steal_pointer(&ifname_guest_actual); - if (def->type != VIR_DOMAIN_NET_TYPE_HOSTDEV && - virDomainNetIsVirtioModel(def)) { - if (backend != NULL) { - if ((val = virDomainNetBackendTypeFromString(backend)) < 0 || - val == VIR_DOMAIN_NET_BACKEND_TYPE_DEFAULT) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Unknown interface <driver name='%s'> " - "has been specified"), - backend); - goto error; - } - def->driver.virtio.name = val; - } - if (txmode != NULL) { - if ((val = virDomainNetVirtioTxModeTypeFromString(txmode)) < 0 || - val == VIR_DOMAIN_NET_VIRTIO_TX_MODE_DEFAULT) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Unknown interface <driver txmode='%s'> " - "has been specified"), - txmode); - goto error; - } - def->driver.virtio.txmode = val; - } - if (ioeventfd) { - if ((val = virTristateSwitchTypeFromString(ioeventfd)) <= 0) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("unknown interface ioeventfd mode '%s'"), - ioeventfd); - goto error; - } - def->driver.virtio.ioeventfd = val; - } - if (event_idx) { - if ((val = virTristateSwitchTypeFromString(event_idx)) <= 0) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("unknown interface event_idx mode '%s'"), - event_idx); - goto error; - } - def->driver.virtio.event_idx = val; - } - if (queues) { - unsigned int q; - if (virStrToLong_uip(queues, NULL, 10, &q) < 0) { - virReportError(VIR_ERR_XML_DETAIL, - _("'queues' attribute must be positive number: %s"), - queues); - goto error; - } - if (q > 1) - def->driver.virtio.queues = q; - } - if (rx_queue_size) { - unsigned int q; - if (virStrToLong_uip(rx_queue_size, NULL, 10, &q) < 0) { - virReportError(VIR_ERR_XML_DETAIL, - _("'rx_queue_size' attribute must be positive number: %s"), - rx_queue_size); - goto error; - } - def->driver.virtio.rx_queue_size = q; - } - if (tx_queue_size) { - unsigned int q; - if (virStrToLong_uip(tx_queue_size, NULL, 10, &q) < 0) { - virReportError(VIR_ERR_XML_DETAIL, - _("'tx_queue_size' attribute must be positive number: %s"), - tx_queue_size); - goto error; - } - def->driver.virtio.tx_queue_size = q; - } - - if ((tmpNode = virXPathNode("./driver/host", ctxt))) { - if ((str = virXMLPropString(tmpNode, "csum"))) { - if ((val = virTristateSwitchTypeFromString(str)) <= 0) { + if (def->type != VIR_DOMAIN_NET_TYPE_HOSTDEV) { + /* + * the <driver> subelement of <interface type='hostdev'> has + * already been parsed by virDomainHostdevDefParseXMLSubsys() + */ + if (virDomainNetIsVirtioModel(def)) { + if (backend != NULL) { + if ((val = virDomainNetBackendTypeFromString(backend)) < 0 || + val == VIR_DOMAIN_NET_BACKEND_TYPE_DEFAULT) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("unknown host csum mode '%s'"), - str); + _("Unknown interface <driver name='%s'> " + "has been specified"), + backend); goto error; } - def->driver.virtio.host.csum = val; + def->driver.virtio.name = val; } - VIR_FREE(str); - if ((str = virXMLPropString(tmpNode, "gso"))) { - if ((val = virTristateSwitchTypeFromString(str)) <= 0) { + if (txmode != NULL) { + if ((val = virDomainNetVirtioTxModeTypeFromString(txmode)) < 0 || + val == VIR_DOMAIN_NET_VIRTIO_TX_MODE_DEFAULT) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("unknown host gso mode '%s'"), - str); + _("Unknown interface <driver txmode='%s'> " + "has been specified"), + txmode); goto error; } - def->driver.virtio.host.gso = val; + def->driver.virtio.txmode = val; } - VIR_FREE(str); - if ((str = virXMLPropString(tmpNode, "tso4"))) { - if ((val = virTristateSwitchTypeFromString(str)) <= 0) { + if (ioeventfd) { + if ((val = virTristateSwitchTypeFromString(ioeventfd)) <= 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("unknown host tso4 mode '%s'"), - str); + _("unknown interface ioeventfd mode '%s'"), + ioeventfd); goto error; } - def->driver.virtio.host.tso4 = val; + def->driver.virtio.ioeventfd = val; } - VIR_FREE(str); - if ((str = virXMLPropString(tmpNode, "tso6"))) { - if ((val = virTristateSwitchTypeFromString(str)) <= 0) { + if (event_idx) { + if ((val = virTristateSwitchTypeFromString(event_idx)) <= 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("unknown host tso6 mode '%s'"), - str); + _("unknown interface event_idx mode '%s'"), + event_idx); goto error; } - def->driver.virtio.host.tso6 = val; + def->driver.virtio.event_idx = val; } - VIR_FREE(str); - if ((str = virXMLPropString(tmpNode, "ecn"))) { - if ((val = virTristateSwitchTypeFromString(str)) <= 0) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("unknown host ecn mode '%s'"), - str); + if (queues) { + unsigned int q; + if (virStrToLong_uip(queues, NULL, 10, &q) < 0) { + virReportError(VIR_ERR_XML_DETAIL, + _("'queues' attribute must be positive number: %s"), + queues); goto error; } - def->driver.virtio.host.ecn = val; + if (q > 1) + def->driver.virtio.queues = q; } - VIR_FREE(str); - if ((str = virXMLPropString(tmpNode, "ufo"))) { - if ((val = virTristateSwitchTypeFromString(str)) <= 0) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("unknown host ufo mode '%s'"), - str); + if (rx_queue_size) { + unsigned int q; + if (virStrToLong_uip(rx_queue_size, NULL, 10, &q) < 0) { + virReportError(VIR_ERR_XML_DETAIL, + _("'rx_queue_size' attribute must be positive number: %s"), + rx_queue_size); goto error; } - def->driver.virtio.host.ufo = val; + def->driver.virtio.rx_queue_size = q; } - VIR_FREE(str); - if ((str = virXMLPropString(tmpNode, "mrg_rxbuf"))) { - if ((val = virTristateSwitchTypeFromString(str)) <= 0) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("unknown host mrg_rxbuf mode '%s'"), - str); + if (tx_queue_size) { + unsigned int q; + if (virStrToLong_uip(tx_queue_size, NULL, 10, &q) < 0) { + virReportError(VIR_ERR_XML_DETAIL, + _("'tx_queue_size' attribute must be positive number: %s"), + tx_queue_size); goto error; } - def->driver.virtio.host.mrg_rxbuf = val; + def->driver.virtio.tx_queue_size = q; } - VIR_FREE(str); - } - if ((tmpNode = virXPathNode("./driver/guest", ctxt))) { - if ((str = virXMLPropString(tmpNode, "csum"))) { - if ((val = virTristateSwitchTypeFromString(str)) <= 0) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("unknown guest csum mode '%s'"), - str); - goto error; + if ((tmpNode = virXPathNode("./driver/host", ctxt))) { + if ((str = virXMLPropString(tmpNode, "csum"))) { + if ((val = virTristateSwitchTypeFromString(str)) <= 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown host csum mode '%s'"), + str); + goto error; + } + def->driver.virtio.host.csum = val; } - def->driver.virtio.guest.csum = val; - } - VIR_FREE(str); - if ((str = virXMLPropString(tmpNode, "tso4"))) { - if ((val = virTristateSwitchTypeFromString(str)) <= 0) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("unknown guest tso4 mode '%s'"), - str); - goto error; + VIR_FREE(str); + if ((str = virXMLPropString(tmpNode, "gso"))) { + if ((val = virTristateSwitchTypeFromString(str)) <= 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown host gso mode '%s'"), + str); + goto error; + } + def->driver.virtio.host.gso = val; } - def->driver.virtio.guest.tso4 = val; - } - VIR_FREE(str); - if ((str = virXMLPropString(tmpNode, "tso6"))) { - if ((val = virTristateSwitchTypeFromString(str)) <= 0) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("unknown guest tso6 mode '%s'"), - str); - goto error; + VIR_FREE(str); + if ((str = virXMLPropString(tmpNode, "tso4"))) { + if ((val = virTristateSwitchTypeFromString(str)) <= 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown host tso4 mode '%s'"), + str); + goto error; + } + def->driver.virtio.host.tso4 = val; } - def->driver.virtio.guest.tso6 = val; - } - VIR_FREE(str); - if ((str = virXMLPropString(tmpNode, "ecn"))) { - if ((val = virTristateSwitchTypeFromString(str)) <= 0) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("unknown guest ecn mode '%s'"), - str); - goto error; + VIR_FREE(str); + if ((str = virXMLPropString(tmpNode, "tso6"))) { + if ((val = virTristateSwitchTypeFromString(str)) <= 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown host tso6 mode '%s'"), + str); + goto error; + } + def->driver.virtio.host.tso6 = val; + } + VIR_FREE(str); + if ((str = virXMLPropString(tmpNode, "ecn"))) { + if ((val = virTristateSwitchTypeFromString(str)) <= 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown host ecn mode '%s'"), + str); + goto error; + } + def->driver.virtio.host.ecn = val; + } + VIR_FREE(str); + if ((str = virXMLPropString(tmpNode, "ufo"))) { + if ((val = virTristateSwitchTypeFromString(str)) <= 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown host ufo mode '%s'"), + str); + goto error; + } + def->driver.virtio.host.ufo = val; + } + VIR_FREE(str); + if ((str = virXMLPropString(tmpNode, "mrg_rxbuf"))) { + if ((val = virTristateSwitchTypeFromString(str)) <= 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown host mrg_rxbuf mode '%s'"), + str); + goto error; + } + def->driver.virtio.host.mrg_rxbuf = val; } - def->driver.virtio.guest.ecn = val; + VIR_FREE(str); } - VIR_FREE(str); - if ((str = virXMLPropString(tmpNode, "ufo"))) { - if ((val = virTristateSwitchTypeFromString(str)) <= 0) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("unknown guest ufo mode '%s'"), - str); - goto error; + + if ((tmpNode = virXPathNode("./driver/guest", ctxt))) { + if ((str = virXMLPropString(tmpNode, "csum"))) { + if ((val = virTristateSwitchTypeFromString(str)) <= 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown guest csum mode '%s'"), + str); + goto error; + } + def->driver.virtio.guest.csum = val; + } + VIR_FREE(str); + if ((str = virXMLPropString(tmpNode, "tso4"))) { + if ((val = virTristateSwitchTypeFromString(str)) <= 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown guest tso4 mode '%s'"), + str); + goto error; + } + def->driver.virtio.guest.tso4 = val; + } + VIR_FREE(str); + if ((str = virXMLPropString(tmpNode, "tso6"))) { + if ((val = virTristateSwitchTypeFromString(str)) <= 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown guest tso6 mode '%s'"), + str); + goto error; + } + def->driver.virtio.guest.tso6 = val; + } + VIR_FREE(str); + if ((str = virXMLPropString(tmpNode, "ecn"))) { + if ((val = virTristateSwitchTypeFromString(str)) <= 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown guest ecn mode '%s'"), + str); + goto error; + } + def->driver.virtio.guest.ecn = val; + } + VIR_FREE(str); + if ((str = virXMLPropString(tmpNode, "ufo"))) { + if ((val = virTristateSwitchTypeFromString(str)) <= 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown guest ufo mode '%s'"), + str); + goto error; + } + def->driver.virtio.guest.ufo = val; } - def->driver.virtio.guest.ufo = val; } + def->backend.vhost = g_steal_pointer(&vhost_path); } - def->backend.vhost = g_steal_pointer(&vhost_path); } def->linkstate = VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DEFAULT; @@ -25388,36 +25393,40 @@ virDomainVirtioNetDriverHostOptsFormat(char **outstr, static void -virDomainVirtioNetDriverFormat(char **outstr, - virDomainNetDefPtr def) +virDomainNetDriverAttributesFormat(char **outstr, + virDomainNetDefPtr def) { virBuffer buf = VIR_BUFFER_INITIALIZER; - if (def->driver.virtio.name) { - virBufferAsprintf(&buf, " name='%s'", - virDomainNetBackendTypeToString(def->driver.virtio.name)); - } - if (def->driver.virtio.txmode) { - virBufferAsprintf(&buf, " txmode='%s'", - virDomainNetVirtioTxModeTypeToString(def->driver.virtio.txmode)); - } - if (def->driver.virtio.ioeventfd) { - virBufferAsprintf(&buf, " ioeventfd='%s'", - virTristateSwitchTypeToString(def->driver.virtio.ioeventfd)); - } - if (def->driver.virtio.event_idx) { - virBufferAsprintf(&buf, " event_idx='%s'", - virTristateSwitchTypeToString(def->driver.virtio.event_idx)); - } - if (def->driver.virtio.queues) - virBufferAsprintf(&buf, " queues='%u'", def->driver.virtio.queues); - if (def->driver.virtio.rx_queue_size) - virBufferAsprintf(&buf, " rx_queue_size='%u'", - def->driver.virtio.rx_queue_size); - if (def->driver.virtio.tx_queue_size) - virBufferAsprintf(&buf, " tx_queue_size='%u'", - def->driver.virtio.tx_queue_size); - virDomainVirtioOptionsFormat(&buf, def->virtio); + if (virDomainNetIsVirtioModel(def)) { + + if (def->driver.virtio.name) { + virBufferAsprintf(&buf, " name='%s'", + virDomainNetBackendTypeToString(def->driver.virtio.name)); + } + if (def->driver.virtio.txmode) { + virBufferAsprintf(&buf, " txmode='%s'", + virDomainNetVirtioTxModeTypeToString(def->driver.virtio.txmode)); + } + if (def->driver.virtio.ioeventfd) { + virBufferAsprintf(&buf, " ioeventfd='%s'", + virTristateSwitchTypeToString(def->driver.virtio.ioeventfd)); + } + if (def->driver.virtio.event_idx) { + virBufferAsprintf(&buf, " event_idx='%s'", + virTristateSwitchTypeToString(def->driver.virtio.event_idx)); + } + if (def->driver.virtio.queues) + virBufferAsprintf(&buf, " queues='%u'", def->driver.virtio.queues); + if (def->driver.virtio.rx_queue_size) + virBufferAsprintf(&buf, " rx_queue_size='%u'", + def->driver.virtio.rx_queue_size); + if (def->driver.virtio.tx_queue_size) + virBufferAsprintf(&buf, " tx_queue_size='%u'", + def->driver.virtio.tx_queue_size); + + virDomainVirtioOptionsFormat(&buf, def->virtio); + } *outstr = virBufferContentAndReset(&buf); } @@ -25454,6 +25463,9 @@ virDomainNetDefFormat(virBufferPtr buf, char macstr[VIR_MAC_STRING_BUFLEN]; g_auto(virBuffer) attrBuf = VIR_BUFFER_INITIALIZER; const char *prefix = xmlopt ? xmlopt->config.netPrefix : NULL; + g_autofree char *driverstr = NULL; + g_autofree char *gueststr = NULL; + g_autofree char *hoststr = NULL; /* publicActual is true if we should report the current state in * def->data.network.actual *instead of* the config (*not* in @@ -25692,33 +25704,32 @@ virDomainNetDefFormat(virBufferPtr buf, if (virDomainNetGetModelString(def)) { virBufferEscapeString(buf, "<model type='%s'/>\n", virDomainNetGetModelString(def)); - if (virDomainNetIsVirtioModel(def)) { - g_autofree char *str = NULL; - g_autofree char *gueststr = NULL; - g_autofree char *hoststr = NULL; + } - virDomainVirtioNetDriverFormat(&str, def); - virDomainVirtioNetDriverGuestOptsFormat(&gueststr, def); - virDomainVirtioNetDriverHostOptsFormat(&hoststr, def); + virDomainNetDriverAttributesFormat(&driverstr, def); - if (!gueststr && !hoststr) { - if (str) - virBufferAsprintf(buf, "<driver%s/>\n", str); - } else { - if (str) - virBufferAsprintf(buf, "<driver%s>\n", str); - else - virBufferAddLit(buf, "<driver>\n"); - virBufferAdjustIndent(buf, 2); - if (hoststr) - virBufferAsprintf(buf, "<host %s/>\n", hoststr); - if (gueststr) - virBufferAsprintf(buf, "<guest %s/>\n", gueststr); - virBufferAdjustIndent(buf, -2); - virBufferAddLit(buf, "</driver>\n"); - } - } + if (virDomainNetIsVirtioModel(def)) { + virDomainVirtioNetDriverGuestOptsFormat(&gueststr, def); + virDomainVirtioNetDriverHostOptsFormat(&hoststr, def); + } + + if (!gueststr && !hoststr) { + if (driverstr) + virBufferAsprintf(buf, "<driver%s/>\n", driverstr); + } else { + if (driverstr) + virBufferAsprintf(buf, "<driver%s>\n", driverstr); + else + virBufferAddLit(buf, "<driver>\n"); + virBufferAdjustIndent(buf, 2); + if (hoststr) + virBufferAsprintf(buf, "<host %s/>\n", hoststr); + if (gueststr) + virBufferAsprintf(buf, "<guest %s/>\n", gueststr); + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</driver>\n"); } + if (def->backend.tap || def->backend.vhost) { virBufferAddLit(buf, "<backend"); virBufferEscapeString(buf, " tap='%s'", def->backend.tap); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 6ae89fa498..5a44113681 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -927,32 +927,34 @@ struct _virDomainNetDef { bool mac_generated; /* true if mac was *just now* auto-generated by libvirt */ int model; /* virDomainNetModelType */ char *modelstr; - union { - struct { - virDomainNetBackendType name; /* which driver backend to use */ - virDomainNetVirtioTxModeType txmode; - virTristateSwitch ioeventfd; - virTristateSwitch event_idx; - unsigned int queues; /* Multiqueue virtio-net */ - unsigned int rx_queue_size; - unsigned int tx_queue_size; - struct { - virTristateSwitch csum; - virTristateSwitch gso; - virTristateSwitch tso4; - virTristateSwitch tso6; - virTristateSwitch ecn; - virTristateSwitch ufo; - virTristateSwitch mrg_rxbuf; - } host; + struct { + union { struct { - virTristateSwitch csum; - virTristateSwitch tso4; - virTristateSwitch tso6; - virTristateSwitch ecn; - virTristateSwitch ufo; - } guest; - } virtio; + virDomainNetBackendType name; /* which driver backend to use */ + virDomainNetVirtioTxModeType txmode; + virTristateSwitch ioeventfd; + virTristateSwitch event_idx; + unsigned int queues; /* Multiqueue virtio-net */ + unsigned int rx_queue_size; + unsigned int tx_queue_size; + struct { + virTristateSwitch csum; + virTristateSwitch gso; + virTristateSwitch tso4; + virTristateSwitch tso6; + virTristateSwitch ecn; + virTristateSwitch ufo; + virTristateSwitch mrg_rxbuf; + } host; + struct { + virTristateSwitch csum; + virTristateSwitch tso4; + virTristateSwitch tso6; + virTristateSwitch ecn; + virTristateSwitch ufo; + } guest; + } virtio; + }; } driver; struct { char *tap; -- 2.24.1