[libvirt] [PATCH 2/2] Modify generic ethernet interface so it will work when sVirt is enabled with qemu
Eric Blake
eblake at redhat.com
Fri Sep 23 15:16:08 UTC 2011
On 09/20/2011 05:18 PM, Tyler Coumbes wrote:
> Update code to create generic ethernet interfaces using the new
> utility library tunctl making
> changes to create the TAP device in libvirt and pass it to qemu as a
> file descriptor.
This patch doesn't refactor src/util/bridge.c either, which means that
if applied, we would have two copies of very similar code in two
different files - that's a maintenance nightmare. We'll definitely need
a v2 patch series that refactors things with minimal duplication.
Or, can this patch directly use the existing br* interfaces, instead of
introducing a new file in patch 1/2?
>
> ---
>
> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
> index ee4b52b..181f56c 100644
> --- a/src/qemu/qemu_command.c
> +++ b/src/qemu/qemu_command.c
> @@ -396,6 +396,51 @@ qemuOpenVhostNet(virDomainDefPtr def,
> }
>
>
> +int qemuEthernetIfaceCreate(virDomainDefPtr def,
> + virDomainNetDefPtr net,
> + virBitmapPtr qemuCaps)
> +{
> + int tapfd;
> + int err;
> + int vnet_hdr = 0;
> + unsigned char tapmac[VIR_MAC_BUFLEN];
> +
> + if (qemuCapsGet(qemuCaps, QEMU_CAPS_VNET_HDR)&&
> + net->model&& STREQ(net->model, "virtio"))
> + vnet_hdr = 1;
> +
> + if (!net->ifname ||
> + STRPREFIX(net->ifname, "vnet") ||
> + strchr(net->ifname, '%')) {
> + VIR_FREE(net->ifname);
> + if (!(net->ifname = strdup("vnet%d"))) {
> + virReportOOMError();
> + return -1;
> + }
> + }
> +
> + err = createTap(&net->ifname, vnet_hdr,&tapfd);
> + virDomainAuditNetDevice(def, net, "/dev/net/tun", tapfd>= 0);
> + if (tapfd< 0 || err)
> + return -1;
> +
> + memcpy(tapmac, net->mac, VIR_MAC_BUFLEN);
> + /* Discourage bridge from using TAP dev MAC */
> + tapmac[0] = 0xFE;
> + err = tapSetInterfaceMac(net->ifname, tapmac);
> +
> + if (err)
> + return -1;
This leaks tapfd. Our style tends to use 'goto error' to ensure that
all cleanup occurs at the end, rather than 'return' in the middle of a
function.
> +
> + err = tapSetInterfaceUp(net->ifname, 1);
> +
> + if (err)
> + return -1;
> +
> + return tapfd;
> +}
> +
> +
> static int qemuDomainDeviceAliasIndex(virDomainDeviceInfoPtr info,
> const char *prefix)
> @@ -4064,6 +4112,18 @@ qemuBuildCommandLine(virConnectPtr conn,
> if (snprintf(tapfd_name, sizeof(tapfd_name), "%d",
> tapfd)>= sizeof(tapfd_name))
> goto no_memory;
> + } else if (actualType == VIR_DOMAIN_NET_TYPE_ETHERNET&&
> + !net->data.ethernet.script) {
> + int tapfd = qemuEthernetIfaceCreate(def, net, qemuCaps);
> + if (tapfd< 0)
> + goto error;
> +
> + last_good_net = i;
> + virCommandTransferFD(cmd, tapfd);
Check for failure to transfer the fd, and abort the command in that case
(hmm, that's a pre-existing problem with the other fd transfers in this
function).
--
Eric Blake eblake at redhat.com +1-801-349-2682
Libvirt virtualization library http://libvirt.org
More information about the libvir-list
mailing list