[libvirt] [PATCH] automatic create tap device with network type ethernet

Vasiliy Tolstov v.tolstov at selfip.ru
Mon Nov 24 21:31:30 UTC 2014


If use not specify script in network type ethernet, assume that user
needs simple tap device created with libvirt.
This patch does not need to run external script to create tap device.

Signed-off-by: Vasiliy Tolstov <v.tolstov at selfip.ru>
---
 src/qemu/qemu_command.c | 88 ++++++++++++++++++++++++++++++++-----------------
 src/qemu/qemu_hotplug.c | 10 ++----
 src/qemu/qemu_process.c |  4 +++
 3 files changed, 64 insertions(+), 38 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index cbdef9c..5f9833e 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -319,7 +319,7 @@ qemuNetworkIfaceConnect(virDomainDefPtr def,
     } else if (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE) {
         if (VIR_STRDUP(brname, virDomainNetGetActualBridgeName(net)) < 0)
             return ret;
-    } else {
+    } else if (actualType != VIR_DOMAIN_NET_TYPE_ETHERNET) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("Network type %d is not supported"),
                        virDomainNetGetActualType(net));
@@ -341,30 +341,42 @@ qemuNetworkIfaceConnect(virDomainDefPtr def,
         tap_create_flags |= VIR_NETDEV_TAP_CREATE_VNET_HDR;
     }
 
-    if (cfg->privileged) {
-        if (virNetDevTapCreateInBridgePort(brname, &net->ifname, &net->mac,
-                                           def->uuid, tunpath, tapfd, *tapfdSize,
-                                           virDomainNetGetActualVirtPortProfile(net),
-                                           virDomainNetGetActualVlan(net),
-                                           tap_create_flags) < 0) {
+    if (actualType == VIR_DOMAIN_NET_TYPE_ETHERNET) {
+        if (virNetDevTapCreate(&net->ifname, tunpath, tapfd, *tapfdSize,
+                               tap_create_flags) < 0) {
             virDomainAuditNetDevice(def, net, tunpath, false);
             goto cleanup;
         }
-    } else {
-        if (qemuCreateInBridgePortWithHelper(cfg, brname,
-                                             &net->ifname,
-                                             tapfd, tap_create_flags) < 0) {
-            virDomainAuditNetDevice(def, net, tunpath, false);
+        if (virNetDevSetMAC(net->ifname, &net->mac) < 0)
             goto cleanup;
+        if (virNetDevSetOnline(net->ifname, !!(tap_create_flags & VIR_NETDEV_TAP_CREATE_IFUP)) < 0)
+            goto cleanup;
+    } else {
+        if (cfg->privileged) {
+            if (virNetDevTapCreateInBridgePort(brname, &net->ifname, &net->mac,
+                                               def->uuid, tunpath, tapfd, *tapfdSize,
+                                               virDomainNetGetActualVirtPortProfile(net),
+                                               virDomainNetGetActualVlan(net),
+                                               tap_create_flags) < 0) {
+                virDomainAuditNetDevice(def, net, tunpath, false);
+                goto cleanup;
+            }
+        } else {
+            if (qemuCreateInBridgePortWithHelper(cfg, brname,
+                                                 &net->ifname,
+                                                 tapfd, tap_create_flags) < 0) {
+                virDomainAuditNetDevice(def, net, tunpath, false);
+                goto cleanup;
+            }
+            /* qemuCreateInBridgePortWithHelper can only create a single FD */
+            if (*tapfdSize > 1) {
+                VIR_WARN("Ignoring multiqueue network request");
+                *tapfdSize = 1;
+            }
         }
-        /* qemuCreateInBridgePortWithHelper can only create a single FD */
-        if (*tapfdSize > 1) {
-            VIR_WARN("Ignoring multiqueue network request");
-            *tapfdSize = 1;
-        }
-    }
 
-    virDomainAuditNetDevice(def, net, tunpath, true);
+        virDomainAuditNetDevice(def, net, tunpath, true);
+    }
 
     if (cfg->macFilter &&
         ebtablesAddForwardAllowIn(driver->ebtables,
@@ -4540,18 +4552,32 @@ qemuBuildHostNetStr(virDomainNetDefPtr net,
         break;
 
     case VIR_DOMAIN_NET_TYPE_ETHERNET:
-        virBufferAddLit(&buf, "tap");
+      virBufferAddLit(&buf, "tap");
+      type_sep = ',';
+      if (net->script) {
         if (net->ifname) {
-            virBufferAsprintf(&buf, "%cifname=%s", type_sep, net->ifname);
-            type_sep = ',';
+          virBufferAsprintf(&buf, "%cifname=%s", type_sep, net->ifname);
+          type_sep = ',';
         }
-        if (net->script) {
-            virBufferAsprintf(&buf, "%cscript=%s", type_sep,
-                              net->script);
-            type_sep = ',';
+        virBufferAsprintf(&buf, "%cscript=%s", type_sep, net->script);
+        type_sep = ',';
+      } else {
+        /* for one tapfd 'fd=' shall be used,
+         * for more than one 'fds=' is the right choice */
+        if (tapfdSize == 1) {
+          virBufferAsprintf(&buf, "%cfd=%s", type_sep, tapfd[0]);
+        } else {
+          virBufferAsprintf(&buf, "%cfds=", type_sep);
+          for (i = 0; i < tapfdSize; i++) {
+            if (i)
+              virBufferAddChar(&buf, ':');
+            virBufferAdd(&buf, tapfd[i], -1);
+          }
         }
-        is_tap = true;
-        break;
+        type_sep = ',';
+      }
+      is_tap = true;
+      break;
 
     case VIR_DOMAIN_NET_TYPE_CLIENT:
        virBufferAsprintf(&buf, "socket%cconnect=%s:%d",
@@ -7348,7 +7374,8 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
     /* Currently nothing besides TAP devices supports multiqueue. */
     if (net->driver.virtio.queues > 0 &&
         !(actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
-          actualType == VIR_DOMAIN_NET_TYPE_BRIDGE)) {
+          actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
+          actualType == VIR_DOMAIN_NET_TYPE_ETHERNET)) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                        _("Multiqueue network is not supported for: %s"),
                        virDomainNetTypeToString(actualType));
@@ -7356,7 +7383,8 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
     }
 
     if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
-        actualType == VIR_DOMAIN_NET_TYPE_BRIDGE) {
+        actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
+        actualType == VIR_DOMAIN_NET_TYPE_ETHERNET) {
         tapfdSize = net->driver.virtio.queues;
         if (!tapfdSize)
             tapfdSize = 1;
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index b00fd8f..bf92e4d 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -908,7 +908,8 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
     }
 
     if (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
-        actualType == VIR_DOMAIN_NET_TYPE_NETWORK) {
+        actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
+        actualType == VIR_DOMAIN_NET_TYPE_ETHERNET) {
         tapfdSize = vhostfdSize = net->driver.virtio.queues;
         if (!tapfdSize)
             tapfdSize = vhostfdSize = 1;
@@ -939,13 +940,6 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
         iface_connected = true;
         if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, vhostfd, &vhostfdSize) < 0)
             goto cleanup;
-    } else if (actualType == VIR_DOMAIN_NET_TYPE_ETHERNET) {
-        vhostfdSize = 1;
-        if (VIR_ALLOC(vhostfd) < 0)
-            goto cleanup;
-        *vhostfd = -1;
-        if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, vhostfd, &vhostfdSize) < 0)
-            goto cleanup;
     }
 
     /* Set Bandwidth */
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index c3ee40b..8bc4d81 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -5085,6 +5085,10 @@ void qemuProcessStop(virQEMUDriverPtr driver,
                              cfg->stateDir));
             VIR_FREE(net->ifname);
             break;
+        case VIR_DOMAIN_NET_TYPE_ETHERNET:
+          ignore_value(virNetDevTapDelete(net->ifname, net->backend.tap));
+          VIR_FREE(net->ifname);
+          break;
         case VIR_DOMAIN_NET_TYPE_BRIDGE:
         case VIR_DOMAIN_NET_TYPE_NETWORK:
 #ifdef VIR_NETDEV_TAP_REQUIRE_MANUAL_CLEANUP
-- 
2.1.3




More information about the libvir-list mailing list