[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