]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: set default vhost-user ifname
authorMichal Privoznik <mprivozn@redhat.com>
Thu, 22 Dec 2016 09:33:28 +0000 (10:33 +0100)
committerMichal Privoznik <mprivozn@redhat.com>
Fri, 20 Jan 2017 14:42:12 +0000 (15:42 +0100)
Based on work of Mehdi Abaakouk <sileht@sileht.net>.

When parsing vhost-user interface XML and no ifname is found we
can try to fill it in in post parse callback. The way this works
is we try to make up interface name from given socket path and
then ask openvswitch whether it knows the interface.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
src/libvirt_private.syms
src/qemu/qemu_domain.c
src/util/virnetdevopenvswitch.c
src/util/virnetdevopenvswitch.h
tests/Makefile.am
tests/qemuxml2argvmock.c
tests/qemuxml2xmlmock.c [new file with mode: 0644]
tests/qemuxml2xmloutdata/qemuxml2xmlout-net-vhostuser.xml
tests/qemuxml2xmltest.c

index cfeb43cf0d6aebc09a3510b31659cef978b38042..a2866a3a06f0c9ff7d100b6decfca30f04b3e2fa 100644 (file)
@@ -2072,6 +2072,7 @@ virNetDevMidonetUnbindPort;
 # util/virnetdevopenvswitch.h
 virNetDevOpenvswitchAddPort;
 virNetDevOpenvswitchGetMigrateData;
+virNetDevOpenvswitchGetVhostuserIfname;
 virNetDevOpenvswitchInterfaceStats;
 virNetDevOpenvswitchRemovePort;
 virNetDevOpenvswitchSetMigrateData;
index c676042228a0eeb3faaa0578c6ed85da53f8003c..3df7e4bfc122b31c74eca33c6fe27ad144b9a0b9 100644 (file)
@@ -41,6 +41,7 @@
 #include "domain_addr.h"
 #include "domain_event.h"
 #include "virtime.h"
+#include "virnetdevopenvswitch.h"
 #include "virstoragefile.h"
 #include "virstring.h"
 #include "virthreadjob.h"
@@ -3004,12 +3005,20 @@ qemuDomainDeviceDefPostParse(virDomainDeviceDefPtr dev,
                                           def->emulator);
     }
 
-    if (dev->type == VIR_DOMAIN_DEVICE_NET &&
-        dev->data.net->type != VIR_DOMAIN_NET_TYPE_HOSTDEV &&
-        !dev->data.net->model) {
-        if (VIR_STRDUP(dev->data.net->model,
-                       qemuDomainDefaultNetModel(def, qemuCaps)) < 0)
-            goto cleanup;
+    if (dev->type == VIR_DOMAIN_DEVICE_NET) {
+        if (dev->data.net->type != VIR_DOMAIN_NET_TYPE_HOSTDEV &&
+            !dev->data.net->model) {
+            if (VIR_STRDUP(dev->data.net->model,
+                           qemuDomainDefaultNetModel(def, qemuCaps)) < 0)
+                goto cleanup;
+        }
+        if (dev->data.net->type == VIR_DOMAIN_NET_TYPE_VHOSTUSER &&
+            !dev->data.net->ifname) {
+            if (virNetDevOpenvswitchGetVhostuserIfname(
+                   dev->data.net->data.vhostuser->data.nix.path,
+                   &dev->data.net->ifname) < 0)
+                goto cleanup;
+        }
     }
 
     /* set default disk types and drivers */
index f003b3b134af13fdee17ab89eb24807acde2ea3e..e6cb096dfdea1d10dfaa0e7502b9f2a817213aa5 100644 (file)
@@ -377,3 +377,56 @@ virNetDevOpenvswitchInterfaceStats(const char *ifname,
     virCommandFree(cmd);
     return ret;
 }
+
+/**
+ * virNetDevOpenvswitchVhostuserGetIfname:
+ * @path: the path of the unix socket
+ * @ifname: the retrieved name of the interface
+ *
+ * Retreives the ovs ifname from vhostuser unix socket path.
+ *
+ * Returns: 1 if interface is an openvswitch interface,
+ *          0 if it is not, but no other error occurred,
+ *         -1 otherwise.
+ */
+int
+virNetDevOpenvswitchGetVhostuserIfname(const char *path,
+                                       char **ifname)
+{
+    virCommandPtr cmd = NULL;
+    char *tmpIfname = NULL;
+    char **tokens = NULL;
+    size_t ntokens = 0;
+    int status;
+    int ret = -1;
+
+    /* Openvswitch vhostuser path are hardcoded to
+     * /<runstatedir>/openvswitch/<ifname>
+     * for example: /var/run/openvswitch/dpdkvhostuser0
+     *
+     * so we pick the filename and check it's a openvswitch interface
+     */
+    if (!path ||
+        !(tmpIfname = strrchr(path, '/'))) {
+        ret = 0;
+        goto cleanup;
+    }
+
+    cmd = virCommandNewArgList(OVSVSCTL, "--timeout=5", "get", "Interface",
+                               tmpIfname, "name", NULL);
+    if (virCommandRun(cmd, &status) < 0 ||
+        status) {
+        /* it's not a openvswitch vhostuser interface. */
+        ret = 0;
+        goto cleanup;
+    }
+
+    if (VIR_STRDUP(*ifname, tmpIfname) < 0)
+        goto cleanup;
+    ret = 1;
+
+ cleanup:
+    virStringListFreeCount(tokens, ntokens);
+    virCommandFree(cmd);
+    return ret;
+}
index 0f9e1dfa66f7b0f0d51b7013d2b1a715098afe81..8f5faf14ed2137a1c671ffd3ae19115a342febc2 100644 (file)
@@ -52,4 +52,8 @@ int virNetDevOpenvswitchInterfaceStats(const char *ifname,
                                        virDomainInterfaceStatsPtr stats)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
 
+int virNetDevOpenvswitchGetVhostuserIfname(const char *path,
+                                           char **ifname)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
+
 #endif /* __VIR_NETDEV_OPENVSWITCH_H__ */
index 6d4af8cc9e4f854b03c11654d5c8842c774455c1..e923178f21ad778a866b9b9f5f5dfe163e188f75 100644 (file)
@@ -281,6 +281,7 @@ test_helpers += qemucapsprobe
 test_libraries += libqemumonitortestutils.la \
                libqemutestdriver.la \
                qemuxml2argvmock.la \
+               qemuxml2xmlmock.la \
                qemucaps2xmlmock.la \
                qemucapsprobemock.la \
                $(NULL)
@@ -558,6 +559,12 @@ qemuxml2argvmock_la_CFLAGS = $(AM_CFLAGS)
 qemuxml2argvmock_la_LDFLAGS = $(MOCKLIBS_LDFLAGS)
 qemuxml2argvmock_la_LIBADD = $(MOCKLIBS_LIBS)
 
+qemuxml2xmlmock_la_SOURCES = \
+       qemuxml2xmlmock.c
+qemuxml2xmlmock_la_CFLAGS = $(AM_CFLAGS)
+qemuxml2xmlmock_la_LDFLAGS = $(MOCKLIBS_LDFLAGS)
+qemuxml2xmlmock_la_LIBADD = $(MOCKLIBS_LIBS)
+
 qemuxml2xmltest_SOURCES = \
        qemuxml2xmltest.c testutilsqemu.c testutilsqemu.h \
        testutils.c testutils.h
index c501b59acb3d4e9e36fc638198a92d73a44838de..177b24e0a9538ba20db2c85a858d6b9eacd5c05f 100644 (file)
@@ -28,6 +28,7 @@
 #include "virnetdev.h"
 #include "virnetdevip.h"
 #include "virnetdevtap.h"
+#include "virnetdevopenvswitch.h"
 #include "virnuma.h"
 #include "virrandom.h"
 #include "virscsi.h"
@@ -180,3 +181,10 @@ virCryptoGenerateRandom(size_t nbytes)
 
     return buf;
 }
+
+int
+virNetDevOpenvswitchGetVhostuserIfname(const char *path ATTRIBUTE_UNUSED,
+                                       char **ifname)
+{
+    return VIR_STRDUP(*ifname, "vhost-user0");
+}
diff --git a/tests/qemuxml2xmlmock.c b/tests/qemuxml2xmlmock.c
new file mode 100644 (file)
index 0000000..0d3e6f2
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2016 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Author: Michal Privoznik <mprivozn@redhat.com>
+ */
+
+#include <config.h>
+
+#include "virnetdevopenvswitch.h"
+#include "virstring.h"
+
+#define VIR_FROM_THIS VIR_FROM_NONE
+
+int
+virNetDevOpenvswitchGetVhostuserIfname(const char *path ATTRIBUTE_UNUSED,
+                                       char **ifname)
+{
+    return VIR_STRDUP(*ifname, "vhost-user0");
+}
index ac1d7e1101442f792a57fdb25d531d5dfe42b33b..2bdcac358a4c4f936e87c596193fe657724b73b1 100644 (file)
     <interface type='vhostuser'>
       <mac address='52:54:00:ee:96:6b'/>
       <source type='unix' path='/tmp/vhost0.sock' mode='server'/>
+      <target dev='vhost-user0'/>
       <model type='virtio'/>
       <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
     </interface>
     <interface type='vhostuser'>
       <mac address='52:54:00:ee:96:6c'/>
       <source type='unix' path='/tmp/vhost1.sock' mode='client'/>
+      <target dev='vhost-user0'/>
       <model type='virtio'/>
       <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
     </interface>
index 5040b7a819413274ff44abaa293c873acd499b7f..53c0e71138ab610a9adab451360a2cc14ec016c6 100644 (file)
@@ -1059,7 +1059,7 @@ mymain(void)
     return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
 }
 
-VIRT_TEST_MAIN(mymain)
+VIRT_TEST_MAIN_PRELOAD(mymain, abs_builddir "/.libs/qemuxml2xmlmock.so")
 
 #else