[libvirt] [PATCH 3/5] macvtap support for libvirt -- qemu support

Daniel P. Berrange berrange at redhat.com
Wed Feb 10 18:23:30 UTC 2010


On Mon, Feb 08, 2010 at 02:37:18PM -0500, Stefan Berger wrote:
> This part adds support for qemu making a macvtap tap device available
> via file descriptor passed to qemu command line. This also attempts to
> tear down the macvtap device when a VM terminates. This includes support
> for attachment and detachment to/from running VM.
> 
> Signed-off-by: Stefan Berger <stefanb at us.ibm.com>
> 
> 
> 

> Index: libvirt-macvtap/src/qemu/qemu_conf.c
> ===================================================================
> --- libvirt-macvtap.orig/src/qemu/qemu_conf.c
> +++ libvirt-macvtap/src/qemu/qemu_conf.c
> @@ -52,6 +52,7 @@
>  #include "nodeinfo.h"
>  #include "logging.h"
>  #include "network.h"
> +#include "macvtap.h"
>  #include "cpu/cpu.h"
>  
>  #define VIR_FROM_THIS VIR_FROM_QEMU
> @@ -1423,6 +1424,43 @@ int qemudExtractVersion(virConnectPtr co
>  
>  
>  int
> +qemudPhysIfaceConnect(virConnectPtr conn,
> +                      virDomainNetDefPtr net,
> +                      char *linkdev,
> +                      int brmode)
> +{
> +    int rc;
> +#if defined(WITH_MACVTAP)
> +    char *res_ifname = NULL;
> +    int hasBusyDev = 0;
> +
> +    delMacvtapByMACAddress(conn, net->mac, &hasBusyDev);
> +
> +    if (hasBusyDev) {
> +        virReportSystemError(NULL, errno, "%s",
> +                             _("A macvtap with the same MAC address is in use"));
> +        return -1;
> +    }
> +
> +    rc = openMacvtapTap(conn, net->ifname, net->mac, linkdev, brmode,
> +                        &res_ifname);
> +    if (rc > 0) {
> +        VIR_FREE(net->ifname);
> +        net->ifname = res_ifname;
> +    }
> +#else
> +    (void)net;
> +    (void)linkdev;
> +    (void)brmode;
> +    qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
> +                     "%s", _("No support for macvtap device"));
> +    rc = -1;
> +#endif
> +    return rc;
> +}
> +
> +
> +int
>  qemudNetworkIfaceConnect(virConnectPtr conn,
>                           struct qemud_driver *driver,
>                           virDomainNetDefPtr net,
> @@ -2520,6 +2558,7 @@ qemuBuildHostNetStr(virConnectPtr conn,
>      switch (net->type) {
>      case VIR_DOMAIN_NET_TYPE_NETWORK:
>      case VIR_DOMAIN_NET_TYPE_BRIDGE:
> +    case VIR_DOMAIN_NET_TYPE_DIRECT:
>          virBufferAddLit(&buf, "tap");
>          virBufferVSprintf(&buf, "%cfd=%s", type_sep, tapfd);
>          type_sep = ',';
> @@ -3636,6 +3675,22 @@ int qemudBuildCommandLine(virConnectPtr 
>  
>                  if (snprintf(tapfd_name, sizeof(tapfd_name), "%d", tapfd) >= sizeof(tapfd_name))
>                      goto no_memory;
> +            } else if (net->type == VIR_DOMAIN_NET_TYPE_DIRECT) {
> +                int tapfd = qemudPhysIfaceConnect(conn, net,
> +                                                  net->data.direct.linkdev,
> +                                                  net->data.direct.mode);
> +                if (tapfd < 0)
> +                    goto error;
> +
> +                if (VIR_REALLOC_N(*tapfds, (*ntapfds)+1) < 0) {
> +                    close(tapfd);
> +                    goto no_memory;
> +                }
> +
> +                (*tapfds)[(*ntapfds)++] = tapfd;
> +
> +                if (snprintf(tapfd_name, sizeof(tapfd_name), "%d", tapfd) >= sizeof(tapfd_name))
> +                    goto no_memory;
>              }
>  
>              /* Possible combinations:
> Index: libvirt-macvtap/src/qemu/qemu_driver.c
> ===================================================================
> --- libvirt-macvtap.orig/src/qemu/qemu_driver.c
> +++ libvirt-macvtap/src/qemu/qemu_driver.c
> @@ -75,6 +75,7 @@
>  #include "libvirt_internal.h"
>  #include "xml.h"
>  #include "cpu/cpu.h"
> +#include "macvtap.h"
>  
>  
>  #define VIR_FROM_THIS VIR_FROM_QEMU
> @@ -2825,6 +2826,8 @@ static void qemudShutdownVMDaemon(virCon
>      int retries = 0;
>      qemuDomainObjPrivatePtr priv = vm->privateData;
>      virErrorPtr orig_err;
> +    virDomainDefPtr def;
> +    int i;
>  
>      if (!virDomainObjIsActive(vm))
>          return;
> @@ -2836,8 +2839,7 @@ static void qemudShutdownVMDaemon(virCon
>      orig_err = virSaveLastError();
>  
>      if (driver->macFilter) {
> -        int i;
> -        virDomainDefPtr def = vm->def;
> +        def = vm->def;
>          for (i = 0 ; i < def->nnets ; i++) {
>              virDomainNetDefPtr net = def->nets[i];
>              if (net->ifname == NULL)
> @@ -2851,6 +2853,17 @@ static void qemudShutdownVMDaemon(virCon
>          }
>      }
>  
> +#if defined(WITH_MACVTAP)
> +    def = vm->def;
> +    for (i = 0; i < def->nnets; i++) {
> +        virDomainNetDefPtr net = def->nets[i];
> +        if (net->type == VIR_DOMAIN_NET_TYPE_DIRECT) {
> +            int dummy;
> +            delMacvtapByMACAddress(conn, net->mac, &dummy);
> +        }
> +    }
> +#endif
> +
>      if (virKillProcess(vm->pid, 0) == 0 &&
>          virKillProcess(vm->pid, SIGTERM) < 0)
>          virReportSystemError(conn, errno,
> @@ -5629,6 +5642,19 @@ static int qemudDomainAttachNetDevice(vi
>  
>          if ((tapfd = qemudNetworkIfaceConnect(conn, driver, net, qemuCmdFlags)) < 0)
>              return -1;
> +    } else if (net->type == VIR_DOMAIN_NET_TYPE_DIRECT) {
> +        if (priv->monConfig->type != VIR_DOMAIN_CHR_TYPE_UNIX) {
> +            qemudReportError(conn, dom, NULL, VIR_ERR_NO_SUPPORT,
> +                             _("direct device type '%s' cannot be attached: "
> +                               "qemu is not using a unix socket monitor"),
> +                             virDomainNetTypeToString(net->type));
> +            return -1;
> +        }
> +
> +        if ((tapfd = qemudPhysIfaceConnect(conn, net,
> +                                           net->data.direct.linkdev,
> +                                           net->data.direct.mode)) < 0)
> +            return -1;
>      }
>  
>      if (VIR_REALLOC_N(vm->def->nets, vm->def->nnets+1) < 0)
> @@ -6242,6 +6268,11 @@ qemudDomainDetachNetDevice(virConnectPtr
>      }
>      qemuDomainObjExitMonitorWithDriver(driver, vm);
>  
> +    if (detach->type == VIR_DOMAIN_NET_TYPE_DIRECT) {
> +        int dummy;
> +        delMacvtapByMACAddress(conn, detach->mac, &dummy);
> +    }
> +
>      if ((driver->macFilter) && (detach->ifname != NULL)) {
>          if ((errno = networkDisallowMacOnPort(conn,
>                                                driver,
> Index: libvirt-macvtap/src/qemu/qemu_conf.h
> ===================================================================
> --- libvirt-macvtap.orig/src/qemu/qemu_conf.h
> +++ libvirt-macvtap/src/qemu/qemu_conf.h
> @@ -247,6 +247,11 @@ int         qemudNetworkIfaceConnect    
>                                           virDomainNetDefPtr net,
>                                           int qemuCmdFlags);
>  
> +int qemudPhysIfaceConnect(virConnectPtr conn,
> +                          virDomainNetDefPtr net,
> +                          char *linkdev,
> +                          int brmode);
> +
>  int         qemudProbeMachineTypes      (const char *binary,
>                                           virCapsGuestMachinePtr **machines,
>                                           int *nmachines);

ACK


Daniel
-- 
|: Red Hat, Engineering, London   -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org  -o-  http://virt-manager.org  -o-  http://ovirt.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-  F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|




More information about the libvir-list mailing list