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

[libvirt] [PATCHv3 1/2] qemu: support vhost in attach-interface



* src/qemu/qemu_hotplug.c (qemuDomainAttachNetDevice): Honor vhost
designations, similar to qemu_command code paths.
* src/qemu/qemu_command.h (qemuOpenVhostNet): New prototype.
* src/qemu/qemu_command.c (qemuOpenVhostNet): Export.
---

Hmm, I just realized that it might be nice to have a --driver-name
flag in the virsh attach-interface wrapper command.  Oh well, that can
be a separate patch.

 src/qemu/qemu_command.c |    3 +-
 src/qemu/qemu_command.h |    4 +++
 src/qemu/qemu_hotplug.c |   54 ++++++++++++++++++++++++++++++++++++++++++----
 3 files changed, 54 insertions(+), 7 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 198a4e2..8cf1737 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -303,12 +303,11 @@ cleanup:
 }


-static int
+int
 qemuOpenVhostNet(virDomainNetDefPtr net,
                  virBitmapPtr qemuCaps,
                  int *vhostfd)
 {
-
     *vhostfd = -1;   /* assume we won't use vhost */

     /* If the config says explicitly to not use vhost, return now */
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index 1902472..2ae364c 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -129,6 +129,10 @@ int qemuPhysIfaceConnect(virConnectPtr conn,
                          const unsigned char *vmuuid,
                          enum virVMOperationType vmop);

+int qemuOpenVhostNet(virDomainNetDefPtr net,
+                     virBitmapPtr qemuCaps,
+                     int *vhostfd);
+
 int qemudCanonicalizeMachine(struct qemud_driver *driver,
                              virDomainDefPtr def);

diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 7895062..e8567ad 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -552,6 +552,8 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
     qemuDomainObjPrivatePtr priv = vm->privateData;
     char *tapfd_name = NULL;
     int tapfd = -1;
+    char *vhostfd_name = NULL;
+    int vhostfd = -1;
     char *nicstr = NULL;
     char *netstr = NULL;
     int ret = -1;
@@ -592,6 +594,24 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
             return -1;
     }

+    if (net->type == VIR_DOMAIN_NET_TYPE_NETWORK ||
+        net->type == VIR_DOMAIN_NET_TYPE_BRIDGE ||
+        net->type == VIR_DOMAIN_NET_TYPE_DIRECT) {
+        /* Attempt to use vhost-net mode for these types of
+           network device */
+        if (qemuOpenVhostNet(net, qemuCaps, &vhostfd) < 0)
+            goto cleanup;
+
+        if (vhostfd >= 0 &&
+            priv->monConfig->type != VIR_DOMAIN_CHR_TYPE_UNIX) {
+            qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                            _("network device type '%s' cannot be attached: "
+                            "qemu is not using a unix socket monitor"),
+                            virDomainNetTypeToString(net->type));
+            goto cleanup;
+        }
+    }
+
     if (VIR_REALLOC_N(vm->def->nets, vm->def->nnets+1) < 0)
         goto no_memory;

@@ -636,15 +656,32 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
         }
     }

-    /* FIXME - need to support vhost-net here (5th arg) */
+    if (vhostfd != -1) {
+        if (virAsprintf(&vhostfd_name, "vhostfd-%s", net->info.alias) < 0)
+            goto no_memory;
+
+        qemuDomainObjEnterMonitorWithDriver(driver, vm);
+        if (qemuMonitorSendFileHandle(priv->mon, vhostfd_name, vhostfd) < 0) {
+            qemuDomainObjExitMonitorWithDriver(driver, vm);
+            goto try_tapfd_close;
+        }
+        qemuDomainObjExitMonitorWithDriver(driver, vm);
+
+        if (!virDomainObjIsActive(vm)) {
+            qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                            _("guest unexpectedly quit"));
+            goto cleanup;
+        }
+    }
+
     if (qemuCapsGet(qemuCaps, QEMU_CAPS_NETDEV) &&
         qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
         if (!(netstr = qemuBuildHostNetStr(net, ',',
-                                           -1, tapfd_name, 0)))
+                                           -1, tapfd_name, vhostfd_name)))
             goto try_tapfd_close;
     } else {
         if (!(netstr = qemuBuildHostNetStr(net, ' ',
-                                           vlan, tapfd_name, 0)))
+                                           vlan, tapfd_name, vhostfd_name)))
             goto try_tapfd_close;
     }

@@ -666,6 +703,7 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
     qemuDomainObjExitMonitorWithDriver(driver, vm);

     VIR_FORCE_CLOSE(tapfd);
+    VIR_FORCE_CLOSE(vhostfd);

     if (!virDomainObjIsActive(vm)) {
         qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -720,6 +758,8 @@ cleanup:
     VIR_FREE(netstr);
     VIR_FREE(tapfd_name);
     VIR_FORCE_CLOSE(tapfd);
+    VIR_FREE(vhostfd_name);
+    VIR_FORCE_CLOSE(vhostfd);

     return ret;

@@ -759,10 +799,14 @@ try_tapfd_close:
     if (!virDomainObjIsActive(vm))
         goto cleanup;

-    if (tapfd_name) {
+    if (tapfd_name || vhostfd_name) {
         qemuDomainObjEnterMonitorWithDriver(driver, vm);
-        if (qemuMonitorCloseFileHandle(priv->mon, tapfd_name) < 0)
+        if (tapfd_name &&
+            qemuMonitorCloseFileHandle(priv->mon, tapfd_name) < 0)
             VIR_WARN("Failed to close tapfd with '%s'", tapfd_name);
+        if (vhostfd_name &&
+            qemuMonitorCloseFileHandle(priv->mon, vhostfd_name) < 0)
+            VIR_WARN("Failed to close vhostfd with '%s'", vhostfd_name);
         qemuDomainObjExitMonitorWithDriver(driver, vm);
     }

-- 
1.7.4


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