When the <driver> element (and its "name" attribute) was added to the domain XML's interface element, a "backend" enum was simply added to the toplevel of the virDomainNetDef struct. Ignoring the naming inconsistency ("name" vs. "backend"), this is fine when there's only a single item contained in the driver element of the XML, but doesn't scale well as we add more attributes that apply to the backend of the virtio-net driver, or add attributes applicable to other drivers. This patch changes virDomainNetDef in two ways: 1) Rename the item in the struct from "backend" to "name", so that it's the same in the XML and in the struct, hopefully avoiding confusion for someone unfamiliar with the function of the attribute. 2) Create a "driver" union within virDomainNetDef, and a "virtio" struct in that struct, which contains the "name" enum value. 3) Move around the virDomainNetParse and virDomainNetFormat functions to allow for simple plugin of new attributes without disturbing existing code. (you'll note that this results in a seemingly redundant if() in the format function, but that will no longer be the case as soon as a 2nd attribute is added). In the future, new attributes for the virtio driver backend can be added to the "virtio" struct, and any other network device backend that needs an attribute will have its own struct added to the "driver" union. --- src/conf/domain_conf.c | 35 +++++++++++++++++++++-------------- src/conf/domain_conf.h | 6 +++++- src/qemu/qemu_command.c | 12 ++++++------ 3 files changed, 32 insertions(+), 21 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 9369ed4..84b866b 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -2756,19 +2756,21 @@ virDomainNetDefParseXML(virCapsPtr caps, model = NULL; } - if ((backend != NULL) && - (def->model && STREQ(def->model, "virtio"))) { - int b; - if (((b = virDomainNetBackendTypeFromString(backend)) < 0) || - (b == VIR_DOMAIN_NET_BACKEND_TYPE_DEFAULT)) { - virDomainReportError(VIR_ERR_INTERNAL_ERROR, - _("Unknown interface <driver name='%s'> " - "has been specified"), - backend); - goto error; + if (def->model && STREQ(def->model, "virtio")) { + if (backend != NULL) { + int name; + if (((name = virDomainNetBackendTypeFromString(backend)) < 0) || + (name == VIR_DOMAIN_NET_BACKEND_TYPE_DEFAULT)) { + virDomainReportError(VIR_ERR_INTERNAL_ERROR, + _("Unknown interface <driver name='%s'> " + "has been specified"), + backend); + goto error; + } + def->driver.virtio.name = name; } - def->backend = b; } + if (filter != NULL) { switch (def->type) { case VIR_DOMAIN_NET_TYPE_ETHERNET: @@ -6805,9 +6807,14 @@ virDomainNetDefFormat(virBufferPtr buf, if (def->model) { virBufferEscapeString(buf, " <model type='%s'/>\n", def->model); - if (STREQ(def->model, "virtio") && def->backend) { - virBufferVSprintf(buf, " <driver name='%s'/>\n", - virDomainNetBackendTypeToString(def->backend)); + if (STREQ(def->model, "virtio") && + def->driver.virtio.name) { + virBufferAddLit(buf, " <driver"); + if (def->driver.virtio.name) { + virBufferVSprintf(buf, " name='%s'", + virDomainNetBackendTypeToString(def->driver.virtio.name)); + } + virBufferAddLit(buf, "/>\n"); } } if (def->filter) { diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 5d35e43..44d0a4b 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -338,7 +338,11 @@ struct _virDomainNetDef { enum virDomainNetType type; unsigned char mac[VIR_MAC_BUFLEN]; char *model; - enum virDomainNetBackendType backend; + union { + struct { + enum virDomainNetBackendType name; /* which driver backend to use */ + } virtio; + } driver; union { struct { char *dev; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index f78ce71..1b213da 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -311,7 +311,7 @@ qemuOpenVhostNet(virDomainNetDefPtr net, *vhostfd = -1; /* assume we won't use vhost */ /* If the config says explicitly to not use vhost, return now */ - if (net->backend == VIR_DOMAIN_NET_BACKEND_TYPE_QEMU) { + if (net->driver.virtio.name == VIR_DOMAIN_NET_BACKEND_TYPE_QEMU) { return 0; } @@ -321,7 +321,7 @@ qemuOpenVhostNet(virDomainNetDefPtr net, if (!(qemuCmdFlags & QEMUD_CMD_FLAG_VNET_HOST && qemuCmdFlags & QEMUD_CMD_FLAG_NETDEV && qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)) { - if (net->backend == VIR_DOMAIN_NET_BACKEND_TYPE_VHOST) { + if (net->driver.virtio.name == VIR_DOMAIN_NET_BACKEND_TYPE_VHOST) { qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("vhost-net is not supported with " "this QEMU binary")); @@ -332,7 +332,7 @@ qemuOpenVhostNet(virDomainNetDefPtr net, /* If the nic model isn't virtio, don't try to open. */ if (!(net->model && STREQ(net->model, "virtio"))) { - if (net->backend == VIR_DOMAIN_NET_BACKEND_TYPE_VHOST) { + if (net->driver.virtio.name == VIR_DOMAIN_NET_BACKEND_TYPE_VHOST) { qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("vhost-net is only supported for " "virtio network interfaces")); @@ -347,7 +347,7 @@ qemuOpenVhostNet(virDomainNetDefPtr net, * report an error. */ if ((*vhostfd < 0) && - (net->backend == VIR_DOMAIN_NET_BACKEND_TYPE_VHOST)) { + (net->driver.virtio.name == VIR_DOMAIN_NET_BACKEND_TYPE_VHOST)) { qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("vhost-net was requested for an interface, " "but is unavailable")); @@ -5012,9 +5012,9 @@ qemuParseCommandLineNet(virCapsPtr caps, values[i] = NULL; } else if (STREQ(keywords[i], "vhost")) { if ((values[i] == NULL) || STREQ(values[i], "on")) { - def->backend = VIR_DOMAIN_NET_BACKEND_TYPE_VHOST; + def->driver.virtio.name = VIR_DOMAIN_NET_BACKEND_TYPE_VHOST; } else if (STREQ(keywords[i], "off")) { - def->backend = VIR_DOMAIN_NET_BACKEND_TYPE_QEMU; + def->driver.virtio.name = VIR_DOMAIN_NET_BACKEND_TYPE_QEMU; } } else if (STREQ(keywords[i], "sndbuf") && values[i]) { if (virStrToLong_ul(values[i], NULL, 10, &def->tune.sndbuf) < 0) { -- 1.7.3.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list