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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxx>


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,
+                      char *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,
+                          char *brmode);
+
 int         qemudProbeMachineTypes      (const char *binary,
                                          virCapsGuestMachinePtr **machines,
                                          int *nmachines);
--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list

[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]