[PATCH 26/37] qemu: Move opening of tap file descriptors for net devices into qemuBuildInterfaceConnect

Peter Krempa pkrempa at redhat.com
Tue May 10 15:20:02 UTC 2022


Use the new infrastructure which stores the fds inside 'qemuFDPass'
objects in the private data.

Signed-off-by: Peter Krempa <pkrempa at redhat.com>
---
 src/qemu/qemu_command.c | 82 ++++++++++++++++++++---------------------
 src/qemu/qemu_command.h |  1 +
 src/qemu/qemu_hotplug.c | 36 ++----------------
 3 files changed, 44 insertions(+), 75 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index d23baa54a2..78baa840a8 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -8661,6 +8661,7 @@ qemuInterfaceVhostuserConnect(virCommand *cmd,
 int
 qemuBuildInterfaceConnect(virDomainObj *vm,
                           virDomainNetDef *net,
+                          virNetDevVPortProfileOp vmop,
                           bool standalone)
 {

@@ -8668,19 +8669,33 @@ qemuBuildInterfaceConnect(virDomainObj *vm,
     virDomainNetType actualType = virDomainNetGetActualType(net);
     qemuDomainNetworkPrivate *netpriv = QEMU_DOMAIN_NETWORK_PRIVATE(net);
     VIR_AUTOCLOSE vdpafd = -1;
-    bool vhostfd = false;
+    bool vhostfd = false; /* also used to signal processing of tapfds */
+    size_t tapfdSize = net->driver.virtio.queues;
+    g_autofree int *tapfd = g_new0(int, tapfdSize + 1);
+
+    if (tapfdSize == 0)
+        tapfdSize = 1;

     switch (actualType) {
     case VIR_DOMAIN_NET_TYPE_NETWORK:
     case VIR_DOMAIN_NET_TYPE_BRIDGE:
         vhostfd = true;
+        if (qemuInterfaceBridgeConnect(vm->def, priv->driver, net,
+                                       tapfd, &tapfdSize) < 0)
+            return -1;
         break;

     case VIR_DOMAIN_NET_TYPE_DIRECT:
         vhostfd = true;
+        if (qemuInterfaceDirectConnect(vm->def, priv->driver, net,
+                                       tapfd, tapfdSize, vmop) < 0)
+            return -1;
         break;

     case VIR_DOMAIN_NET_TYPE_ETHERNET:
+        if (qemuInterfaceEthernetConnect(vm->def, priv->driver, net,
+                                         tapfd, tapfdSize) < 0)
+            return -1;
         vhostfd = true;
         break;

@@ -8706,6 +8721,29 @@ qemuBuildInterfaceConnect(virDomainObj *vm,
         break;
     }

+    /* 'vhostfd' is set to true in all cases when we need to process tapfds */
+    if (vhostfd) {
+        g_autofree char *prefix = g_strdup_printf("tapfd-%s", net->info.alias);
+        size_t i;
+
+        for (i = 0; i < tapfdSize; i++) {
+            g_autoptr(qemuFDPass) pass = qemuFDPassNewDirect(prefix, priv);
+            g_autofree char *suffix = g_strdup_printf("%zu", i);
+            int fd = tapfd[i]; /* we want to keep the array intact for security labeling*/
+
+            qemuFDPassAddFD(pass, &fd, suffix);
+            netpriv->tapfds = g_slist_prepend(netpriv->tapfds, g_steal_pointer(&pass));
+        }
+
+        netpriv->tapfds = g_slist_reverse(netpriv->tapfds);
+
+        for (i = 0; i < tapfdSize; i++) {
+            if (qemuSecuritySetTapFDLabel(priv->driver->securityManager,
+                                          vm->def, tapfd[i]) < 0)
+                return -1;
+        }
+    }
+
     if (vhostfd && !standalone) {
         if (qemuInterfaceOpenVhostNet(vm, net) < 0)
             return -1;
@@ -8746,54 +8784,14 @@ qemuBuildInterfaceCommandLine(virQEMUDriver *driver,
     if (qemuDomainValidateActualNetDef(net, qemuCaps) < 0)
         return -1;

-    if (qemuBuildInterfaceConnect(vm, net, standalone) < 0)
+    if (qemuBuildInterfaceConnect(vm, net, vmop, standalone) < 0)
         return -1;

     switch (actualType) {
     case VIR_DOMAIN_NET_TYPE_NETWORK:
     case VIR_DOMAIN_NET_TYPE_BRIDGE:
-        tapfdSize = net->driver.virtio.queues;
-        if (!tapfdSize)
-            tapfdSize = 1;
-
-        tapfd = g_new0(int, tapfdSize);
-        tapfdName = g_new0(char *, tapfdSize);
-
-        memset(tapfd, -1, tapfdSize * sizeof(tapfd[0]));
-
-        if (qemuInterfaceBridgeConnect(def, driver, net,
-                                       tapfd, &tapfdSize) < 0)
-            goto cleanup;
-        break;
-
     case VIR_DOMAIN_NET_TYPE_DIRECT:
-        tapfdSize = net->driver.virtio.queues;
-        if (!tapfdSize)
-            tapfdSize = 1;
-
-        tapfd = g_new0(int, tapfdSize);
-        tapfdName = g_new0(char *, tapfdSize);
-
-        memset(tapfd, -1, tapfdSize * sizeof(tapfd[0]));
-
-        if (qemuInterfaceDirectConnect(def, driver, net,
-                                       tapfd, tapfdSize, vmop) < 0)
-            goto cleanup;
-        break;
-
     case VIR_DOMAIN_NET_TYPE_ETHERNET:
-        tapfdSize = net->driver.virtio.queues;
-        if (!tapfdSize)
-            tapfdSize = 1;
-
-        tapfd = g_new0(int, tapfdSize);
-        tapfdName = g_new0(char *, tapfdSize);
-
-        memset(tapfd, -1, tapfdSize * sizeof(tapfd[0]));
-
-        if (qemuInterfaceEthernetConnect(def, driver, net,
-                                         tapfd, tapfdSize) < 0)
-            goto cleanup;
         break;

     case VIR_DOMAIN_NET_TYPE_HOSTDEV:
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index c26305927e..5a65d94d6f 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -94,6 +94,7 @@ qemuBuildHostNetProps(virDomainNetDef *net,
 int
 qemuBuildInterfaceConnect(virDomainObj *vm,
                           virDomainNetDef *net,
+                          virNetDevVPortProfileOp vmop,
                           bool standalone);

 /* Current, best practice */
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index f7d3b38a6a..9c6f9e673c 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1274,46 +1274,16 @@ qemuDomainAttachNetDevice(virQEMUDriver *driver,
      */
     VIR_APPEND_ELEMENT_COPY(vm->def->nets, vm->def->nnets, net);

-    if (qemuBuildInterfaceConnect(vm, net, false) < 0)
+    if (qemuBuildInterfaceConnect(vm, net, VIR_NETDEV_VPORT_PROFILE_OP_CREATE, false) < 0)
          return -1;

+    iface_connected = true;
+
     switch (actualType) {
     case VIR_DOMAIN_NET_TYPE_BRIDGE:
     case VIR_DOMAIN_NET_TYPE_NETWORK:
-        tapfdSize = net->driver.virtio.queues;
-        if (!tapfdSize)
-            tapfdSize = 1;
-        tapfd = g_new0(int, tapfdSize);
-        memset(tapfd, -1, sizeof(*tapfd) * tapfdSize);
-        if (qemuInterfaceBridgeConnect(vm->def, driver, net,
-                                       tapfd, &tapfdSize) < 0)
-            goto cleanup;
-        iface_connected = true;
-        break;
-
     case VIR_DOMAIN_NET_TYPE_DIRECT:
-        tapfdSize = net->driver.virtio.queues;
-        if (!tapfdSize)
-            tapfdSize = 1;
-        tapfd = g_new0(int, tapfdSize);
-        memset(tapfd, -1, sizeof(*tapfd) * tapfdSize);
-        if (qemuInterfaceDirectConnect(vm->def, driver, net,
-                                       tapfd, tapfdSize,
-                                       VIR_NETDEV_VPORT_PROFILE_OP_CREATE) < 0)
-            goto cleanup;
-        iface_connected = true;
-        break;
-
     case VIR_DOMAIN_NET_TYPE_ETHERNET:
-        tapfdSize = net->driver.virtio.queues;
-        if (!tapfdSize)
-            tapfdSize = 1;
-        tapfd = g_new0(int, tapfdSize);
-        memset(tapfd, -1, sizeof(*tapfd) * tapfdSize);
-        if (qemuInterfaceEthernetConnect(vm->def, driver, net,
-                                         tapfd, tapfdSize) < 0)
-            goto cleanup;
-        iface_connected = true;
         break;

     case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
-- 
2.35.1



More information about the libvir-list mailing list