[libvirt] [PATCH 5/5] qemu: Implement virConnectGetEmulatorCapabilities

Michal Privoznik mprivozn at redhat.com
Fri Jun 20 14:19:10 UTC 2014


The commit produces this nice output:

virsh # emulatorcaps /usr/bin/qemu-system-x86_64 kvm pc-1.3
<emulatorCapabilities>
  <path>/usr/bin/qemu-system-x86_64</path>
  <domain>kvm</domain>
  <machine>pc-1.3</machine>
  <arch>x86_64</arch>
  <vcpu>255</vcpu>
  <devices>
    <hostdev>
      <driver>
        <enum name='driver'>
          <value>kvm</value>
          <value>vfio</value>
        </enum>
      </driver>
    </hostdev>
  </devices>
</emulatorCapabilities>

Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
---
 docs/formatemulatorcaps.html.in                    | 63 +++++++++++++++
 docs/schemas/emulatorcapability.rng                | 49 ++++++++++++
 src/libvirt_private.syms                           |  1 +
 src/qemu/qemu_capabilities.c                       | 78 ++++++++++--------
 src/qemu/qemu_capabilities.h                       |  3 +
 src/qemu/qemu_capabilitiespriv.h                   | 55 +++++++++++++
 src/qemu/qemu_driver.c                             | 92 ++++++++++++++++++++++
 tests/Makefile.am                                  | 18 +++++
 .../viremulatorcaps-qemu-kvm-vfio.xml              | 17 ++++
 tests/viremulatorcapabilitiestest.c                | 72 ++++++++++++++++-
 tests/virhostdevmock.c                             | 40 ++++++++++
 11 files changed, 456 insertions(+), 32 deletions(-)
 create mode 100644 src/qemu/qemu_capabilitiespriv.h
 create mode 100644 tests/viremulatorcapabilitiesdata/viremulatorcaps-qemu-kvm-vfio.xml
 create mode 100644 tests/virhostdevmock.c

diff --git a/docs/formatemulatorcaps.html.in b/docs/formatemulatorcaps.html.in
index beea1a9..ba87ff1 100644
--- a/docs/formatemulatorcaps.html.in
+++ b/docs/formatemulatorcaps.html.in
@@ -48,5 +48,68 @@
       <dd>The domain's <a href="formatdomain.html#elementsOSBIOS">machine
           type</a>.</dd>
     </dl>
+
+    <p>Besides these three elements, depending on the hypervisor and the driver
+    used other elements may occur. For example:</p>
+<pre>
+<arch>x86_64</arch>
+<vcpu>255</vcpu>
+<devices/>
+</pre>
+    <p>Where:</p>
+    <dl>
+      <dt>arch</dt>
+      <dd>Denotes the <a
+        href="formatdomain.html#elementsOSBIOS">architecture</a> of the
+      domain.</dd>
+
+      <dt>vcpu</dt>
+      <dd>Tells the maximum virtual CPU count supported by the underlying
+      hypervisor.</dd>
+
+      <dt>devices</dt>
+      <dd>Contains info on supported <a href="#elementsDevices">devices</a> features</dd>
+    </dl>
+
+    <h3><a name="elementsDevices">Devices</a></h3>
+    <p>The final set of XML elements is used to describe device capabilities
+    with respect to the hypervisor and host capabilities. For example:</p>
+<pre>
+<devices>
+  <hostdev>
+    <driver>
+      <enum name='driver'>
+        <value>kvm</value>
+        <value>vfio</value>
+      </enum>
+    </driver>
+  </hostdev>
+</devices>
+</pre>
+    <p>The aim is to keep the element names as consistent with <a
+      href="formatdomain.html">domain element names</a> as possible.</p>
+
+    <h4><a name="elementsHostDev">Host device assignment</a></h4>
+    <p>When deciding on the most suitable device passthrough mode, look into
+    this part of the XML document. For instance, in the following snippet both
+    VFIO and legacy KVM passthrough are supported:</p>
+<pre>
+<devices>
+  <hostdev>
+    <driver>
+      <enum name='driver'>
+        <value>kvm</value>
+        <value>vfio</value>
+      </enum>
+    </driver>
+  </hostdev>
+</devices>
+</pre>
+
+    <p>The <code>hostdev</code> element can contain the following elements:</p>
+    <dl>
+      <dt><code>driver</code></dt>
+      <dd>Here are the information on hostdev driver gathered.</dd>
+    </dl>
   </body>
 </html>
diff --git a/docs/schemas/emulatorcapability.rng b/docs/schemas/emulatorcapability.rng
index 2548cef..0c4a0cb 100644
--- a/docs/schemas/emulatorcapability.rng
+++ b/docs/schemas/emulatorcapability.rng
@@ -20,7 +20,56 @@
         <element name='machine'>
           <text/>
         </element>
+        <optional>
+          <element name='arch'>
+            <text/>
+          </element>
+          <element name='vcpu'>
+            <ref name='unsignedInt'/>
+          </element>
+          <ref name='devices'/>
+        </optional>
       </interleave>
     </element>
   </define>
+
+  <define name='devices'>
+    <element name='devices'>
+      <interleave>
+        <ref name='hostdev'/>
+      </interleave>
+    </element>
+  </define>
+
+  <define name='hostdev'>
+    <element name='hostdev'>
+      <interleave>
+        <ref name='driver'/>
+      </interleave>
+    </element>
+  </define>
+
+  <define name='driver'>
+    <element name='driver'>
+      <interleave>
+        <ref name='enum-driver'/>
+      </interleave>
+    </element>
+  </define>
+
+  <define name='enum-driver'>
+    <element name='enum'>
+      <attribute name='name'>
+        <value>driver</value>
+      </attribute>
+      <zeroOrMore>
+        <element name='value'>
+          <choice>
+            <value>kvm</value>
+            <value>vfio</value>
+          </choice>
+        </element>
+      </zeroOrMore>
+    </element>
+  </define>
 </grammar>
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 2784610..68ad1c7 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -426,6 +426,7 @@ virDomainVideoTypeFromString;
 virDomainVideoTypeToString;
 virDomainVirtioEventIdxTypeFromString;
 virDomainVirtioEventIdxTypeToString;
+virDomainVirtTypeFromString;
 virDomainVirtTypeToString;
 virDomainWatchdogActionTypeFromString;
 virDomainWatchdogActionTypeToString;
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 245d6b5..68828e3 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -24,6 +24,7 @@
 #include <config.h>
 
 #include "qemu_capabilities.h"
+#include "qemu_capabilitiespriv.h"
 #include "viralloc.h"
 #include "vircrypto.h"
 #include "virlog.h"
@@ -39,6 +40,7 @@
 #include "virnodesuspend.h"
 #include "qemu_monitor.h"
 #include "virstring.h"
+#include "virhostdev.h"
 
 #include <fcntl.h>
 #include <sys/stat.h>
@@ -259,37 +261,6 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST,
     );
 
 
-/*
- * Update the XML parser/formatter when adding more
- * information to this struct so that it gets cached
- * correctly. It does not have to be ABI-stable, as
- * the cache will be discarded & repopulated if the
- * timestamp on the libvirtd binary changes.
- */
-struct _virQEMUCaps {
-    virObject object;
-
-    bool usedQMP;
-
-    char *binary;
-    time_t ctime;
-
-    virBitmapPtr flags;
-
-    unsigned int version;
-    unsigned int kvmVersion;
-
-    virArch arch;
-
-    size_t ncpuDefinitions;
-    char **cpuDefinitions;
-
-    size_t nmachineTypes;
-    char **machineTypes;
-    char **machineAliases;
-    unsigned int *machineMaxCpus;
-};
-
 struct _virQEMUCapsCache {
     virMutex lock;
     virHashTablePtr binaries;
@@ -3509,3 +3480,48 @@ virQEMUCapsSupportsChardev(virDomainDefPtr def,
             (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE &&
              chr->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_VIRTIO));
 }
+
+int
+virQEMUCapsFormatBuf(virBufferPtr buf,
+                     void *opaque,
+                     const char *machine)
+{
+    virQEMUCapsPtr qemuCaps = (virQEMUCapsPtr) opaque;
+    bool hostkvm = virHostdevHostSupportsPassthroughLegacy();
+    bool hostvfio = virHostdevHostSupportsPassthroughVFIO();
+    bool qemukvm = virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCIDEVICE) ||
+                   virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE);
+    bool qemuvfio = virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI);
+    int maxcpus = virQEMUCapsGetMachineMaxCpus(qemuCaps, machine);
+
+    virBufferAsprintf(buf, "<arch>%s</arch>\n", virArchToString(qemuCaps->arch));
+
+    if (maxcpus > 0)
+        virBufferAsprintf(buf, "<vcpu>%d</vcpu>\n", maxcpus);
+
+    /* So far we want to print the rest iff both host and qemu support kvm/vfio */
+    if (!((hostkvm && qemukvm) || (hostvfio && qemuvfio)))
+        return 0;
+
+    virBufferAddLit(buf, "<devices>\n");
+    virBufferAdjustIndent(buf, 2);
+    virBufferAddLit(buf, "<hostdev>\n");
+    virBufferAdjustIndent(buf, 2);
+    virBufferAddLit(buf, "<driver>\n");
+    virBufferAdjustIndent(buf, 2);
+    virBufferAddLit(buf, "<enum name='driver'>\n");
+    virBufferAdjustIndent(buf, 2);
+    if (hostkvm && qemukvm)
+        virBufferAddLit(buf, "<value>kvm</value>\n");
+    if (hostvfio && qemuvfio)
+        virBufferAddLit(buf, "<value>vfio</value>\n");
+    virBufferAdjustIndent(buf, -2);
+    virBufferAddLit(buf, "</enum>\n");
+    virBufferAdjustIndent(buf, -2);
+    virBufferAddLit(buf, "</driver>\n");
+    virBufferAdjustIndent(buf, -2);
+    virBufferAddLit(buf, "</hostdev>\n");
+    virBufferAdjustIndent(buf, -2);
+    virBufferAddLit(buf, "</devices>\n");
+    return 0;
+}
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index d755caa..121d1ba 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -307,4 +307,7 @@ int virQEMUCapsInitGuestFromBinary(virCapsPtr caps,
                                    virQEMUCapsPtr kvmbinCaps,
                                    virArch guestarch);
 
+int virQEMUCapsFormatBuf(virBufferPtr buf,
+                         void *opaque,
+                         const char *machine);
 #endif /* __QEMU_CAPABILITIES_H__*/
diff --git a/src/qemu/qemu_capabilitiespriv.h b/src/qemu/qemu_capabilitiespriv.h
new file mode 100644
index 0000000..9ed6853
--- /dev/null
+++ b/src/qemu/qemu_capabilitiespriv.h
@@ -0,0 +1,55 @@
+/*
+ * qemu_capabilitiespriv.h: private declarations for QEMU capabilities
+ *
+ * Copyright (C) 2014 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/>.
+ */
+
+#ifndef __QEMU_CAPABILITIESPRIV_H__
+# define __QEMU_CAPABILITIESPRIV_H__
+
+/*
+ * Update the XML parser/formatter when adding more
+ * information to this struct so that it gets cached
+ * correctly. It does not have to be ABI-stable, as
+ * the cache will be discarded & repopulated if the
+ * timestamp on the libvirtd binary changes.
+ */
+struct _virQEMUCaps {
+    virObject object;
+
+    bool usedQMP;
+
+    char *binary;
+    time_t ctime;
+
+    virBitmapPtr flags;
+
+    unsigned int version;
+    unsigned int kvmVersion;
+
+    virArch arch;
+
+    size_t ncpuDefinitions;
+    char **cpuDefinitions;
+
+    size_t nmachineTypes;
+    char **machineTypes;
+    char **machineAliases;
+    unsigned int *machineMaxCpus;
+};
+
+#endif /* __QEMU_CAPABILITIESPRIV_H__*/
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index ac6aee5..b449770 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -95,6 +95,7 @@
 #include "viraccessapicheckqemu.h"
 #include "storage/storage_driver.h"
 #include "virhostdev.h"
+#include "viremulator_capabilities.h"
 
 #define VIR_FROM_THIS VIR_FROM_QEMU
 
@@ -16897,6 +16898,96 @@ qemuNodeGetFreePages(virConnectPtr conn,
 }
 
 
+static char *
+qemuConnectGetEmulatorCapabilities(virConnectPtr conn,
+                                   const char *emulatorbin,
+                                   const char *machine,
+                                   const char *virttype_str,
+                                   unsigned int flags)
+{
+    char *ret = NULL;
+    virQEMUDriverPtr driver = conn->privateData;
+    virQEMUCapsPtr qemuCaps = NULL;
+    virEmulatorCapabilitiesPtr emulCaps = NULL;
+    int virttype; /* virDomainVirtType */
+    size_t ncanonicalMachine, i;
+    const char **canonicalMachine;
+
+    virCheckFlags(0, ret);
+    virCheckNonNullArgGoto(emulatorbin, cleanup);
+    virCheckNonNullArgGoto(virttype_str, cleanup);
+
+    if (virConnectGetEmulatorCapabilitiesEnsureACL(conn) < 0)
+        goto cleanup;
+
+    if ((virttype = virDomainVirtTypeFromString(virttype_str)) < 0) {
+        virReportError(VIR_ERR_INVALID_ARG,
+                       _("unknown virttype: %s"), virttype_str);
+        goto cleanup;
+    }
+
+    if (!(qemuCaps = virQEMUCapsCacheLookup(driver->qemuCapsCache,
+                                            emulatorbin)))
+        goto cleanup;
+
+    if (machine) {
+        const char *machine_tmp;
+
+        if (!(machine_tmp = virQEMUCapsGetCanonicalMachine(qemuCaps,
+                                                           machine))) {
+            /* This should never ever happen (TM) */
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("an error that should never "
+                             "ever happen just occurred"));
+            goto cleanup;
+        }
+        machine = machine_tmp;
+    }
+
+    /* The virQEMUCapsGetMachineTypes expects char *** but we want to stress
+     * the fact that we are not going to change machine types array, so we are
+     * using const char *** */
+    if (!(ncanonicalMachine = virQEMUCapsGetMachineTypes(qemuCaps,
+                                                         (char ***) &canonicalMachine))) {
+        virReportError(VIR_ERR_INVALID_ARG,
+                       _(" emulator doesn't support any machines: %s"),
+                       emulatorbin);
+        goto cleanup;
+    }
+
+    if (machine) {
+        for (i = 0; i < ncanonicalMachine; i++) {
+            if (STREQ(machine, canonicalMachine[i]))
+                break;
+        }
+
+        if (i == ncanonicalMachine) {
+            virReportError(VIR_ERR_INVALID_ARG,
+                           _("the machine '%s' is not supported by emulator '%s'"),
+                           machine, emulatorbin);
+            goto cleanup;
+        }
+    } else {
+        /* The default machine type is at the first position */
+        machine = canonicalMachine[0];
+    }
+
+    if (!(emulCaps = virEmulatorCapabilitiesNew(emulatorbin,
+                                                machine,
+                                                virttype)))
+        goto cleanup;
+
+    virEmulatorCapabilitiesSetPrivate(emulCaps, qemuCaps, virQEMUCapsFormatBuf);
+
+    ret = virEmulatorCapabilitiesFormat(emulCaps);
+
+ cleanup:
+    virObjectUnref(emulCaps);
+    virObjectUnref(qemuCaps);
+    return ret;
+}
+
+
 static virDriver qemuDriver = {
     .no = VIR_DRV_QEMU,
     .name = QEMU_DRIVER_NAME,
@@ -17092,6 +17183,7 @@ static virDriver qemuDriver = {
     .domainGetTime = qemuDomainGetTime, /* 1.2.5 */
     .domainSetTime = qemuDomainSetTime, /* 1.2.5 */
     .nodeGetFreePages = qemuNodeGetFreePages, /* 1.2.6 */
+    .connectGetEmulatorCapabilities = qemuConnectGetEmulatorCapabilities, /* 1.2.6 */
 };
 
 
diff --git a/tests/Makefile.am b/tests/Makefile.am
index e7d9f94..fcd65b5 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -388,6 +388,9 @@ if WITH_QEMU
 test_libraries += libqemumonitortestutils.la \
 		qemuxml2argvmock.la \
 		$(NULL)
+if WITH_LINUX
+test_libraries += virhostdevmock.la
+endif WITH_LINUX
 endif WITH_QEMU
 
 if WITH_BHYVE
@@ -831,6 +834,21 @@ vircaps2xmltest_LDADD = $(LDADDS)
 viremulatorcapabilitiestest_SOURCES = \
 	viremulatorcapabilitiestest.c testutils.h testutils.c
 viremulatorcapabilitiestest_LDADD = $(LDADDS)
+if WITH_QEMU
+viremulatorcapabilitiestest_LDADD += $(qemu_LDADDS)
+endif WITH_QEMU
+
+if WITH_LINUX
+virhostdevmock_la_SOURCES = \
+	virhostdevmock.c
+virhostdevmock_la_CFLAGS = $(AM_CFLAGS)
+virhostdevmock_la_LIBADD = $(GNULIB_LIBS) \
+						   ../src/libvirt.la
+virhostdevmock_la_LDFLAGS = -module -avoid-version \
+        -rpath /evil/libtool/hack/to/force/shared/lib/creation
+else ! WITH_LINUX
+	EXTRA_DIST += virhostdevmock.c
+endif ! WITH_LINUX
 
 if WITH_LIBVIRTD
 libvirtdconftest_SOURCES = \
diff --git a/tests/viremulatorcapabilitiesdata/viremulatorcaps-qemu-kvm-vfio.xml b/tests/viremulatorcapabilitiesdata/viremulatorcaps-qemu-kvm-vfio.xml
new file mode 100644
index 0000000..e1d4bab
--- /dev/null
+++ b/tests/viremulatorcapabilitiesdata/viremulatorcaps-qemu-kvm-vfio.xml
@@ -0,0 +1,17 @@
+<emulatorCapabilities>
+  <path>/usr/bin/qemu-system-x86_64</path>
+  <domain>kvm</domain>
+  <machine>pc-i440fx-2.1</machine>
+  <arch>x86_64</arch>
+  <vcpu>255</vcpu>
+  <devices>
+    <hostdev>
+      <driver>
+        <enum name='driver'>
+          <value>kvm</value>
+          <value>vfio</value>
+        </enum>
+      </driver>
+    </hostdev>
+  </devices>
+</emulatorCapabilities>
diff --git a/tests/viremulatorcapabilitiestest.c b/tests/viremulatorcapabilitiestest.c
index 448f0cf..25076a7 100644
--- a/tests/viremulatorcapabilitiestest.c
+++ b/tests/viremulatorcapabilitiestest.c
@@ -24,7 +24,8 @@
 
 #include "testutils.h"
 #include "viremulator_capabilities.h"
-
+#include "qemu/qemu_capabilities.h"
+#include "qemu/qemu_capabilitiespriv.h"
 
 #define VIR_FROM_THIS VIR_FROM_NONE
 
@@ -96,11 +97,50 @@ test_virEmulatorCapabilitiesFormat(const void *opaque)
     return ret;
 }
 
+static virQEMUCapsPtr
+buildQEMUCaps(void)
+{
+    virQEMUCapsPtr qemuCaps = NULL;
+
+    if (!(qemuCaps = virQEMUCapsNew()))
+        return NULL;
+
+    if (VIR_ALLOC_N(qemuCaps->machineTypes, 1) < 0 ||
+        VIR_ALLOC_N(qemuCaps->machineAliases, 1) < 0 ||
+        VIR_ALLOC_N(qemuCaps->machineMaxCpus, 1) < 0)
+        goto error;
+
+    if (VIR_STRDUP(qemuCaps->machineTypes[0], "pc-i440fx-2.1") < 0 ||
+        VIR_STRDUP(qemuCaps->machineAliases[0], "pc") < 0)
+        goto error;
+    qemuCaps->machineMaxCpus[0] = 255;
+    qemuCaps->nmachineTypes++;
+
+    qemuCaps->arch = VIR_ARCH_X86_64;
+
+    virQEMUCapsSet(qemuCaps, QEMU_CAPS_PCIDEVICE);
+    virQEMUCapsSet(qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI);
+
+    return qemuCaps;
+ error:
+    virObjectUnref(qemuCaps);
+    return NULL;
+}
+
 static int
 mymain(void)
 {
     int ret = 0;
 
+#ifdef WITH_QEMU
+    virQEMUCapsPtr qemuCaps;
+
+    if (!(qemuCaps = buildQEMUCaps())) {
+        fprintf(stderr, "unable to build QEMU capabilities\n");
+        return EXIT_FAILURE;
+    }
+#endif
+
 #define DO_TEST(Filename, Emulatorbin, Machine, Type, ...)                          \
     do {                                                                            \
         struct test_virEmulatorCapabilitiesFormatData data = {.filename = Filename, \
@@ -109,9 +149,39 @@ mymain(void)
         ret = -1;                                                                   \
     } while (0)
 
+#ifdef WITH_QEMU
+# define DO_TEST_QEMU(Filename, Emulatorbin, Machine, Type, ...)                    \
+    do {                                                                            \
+        struct test_virEmulatorCapabilitiesFormatData data = {.filename = Filename, \
+            .emulatorbin = Emulatorbin, .machine = Machine, .type = Type,           \
+            .privateData = qemuCaps, .formatFunc = virQEMUCapsFormatBuf,  __VA_ARGS__}; \
+        if (virtTestRun(Filename, test_virEmulatorCapabilitiesFormat, &data) < 0)   \
+        ret = -1;                                                                   \
+    } while (0)
+#endif
+
     DO_TEST("basic", "/bin/emulatorbin", "my-machine-type", VIR_DOMAIN_VIRT_UML);
 
+#ifdef WITH_QEMU
+    /* In the following test we are expecting host to support both KVM and
+     * VFIO. However, this is something we must mock and therefore the test can
+     * be run on the Linux platform only. */
+# ifdef __linux__
+    DO_TEST_QEMU("qemu-kvm-vfio", "/usr/bin/qemu-system-x86_64",
+                 "pc-i440fx-2.1", VIR_DOMAIN_VIRT_KVM);
+# else
+#  error Port me
+# endif
+#endif
+
+#ifdef WITH_QEMU
+    virObjectUnref(qemuCaps);
+#endif
     return ret;
 }
 
+#ifdef __linux__
+VIRT_TEST_MAIN_PRELOAD(mymain, abs_builddir "/.libs/virhostdevmock.so")
+#else
 VIRT_TEST_MAIN(mymain)
+#endif
diff --git a/tests/virhostdevmock.c b/tests/virhostdevmock.c
new file mode 100644
index 0000000..cb08034
--- /dev/null
+++ b/tests/virhostdevmock.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2014 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 at redhat.com>
+ */
+
+#include <config.h>
+
+#ifdef __linux__
+# include "virhostdev.h"
+
+bool
+virHostdevHostSupportsPassthroughLegacy(void)
+{
+    return true;
+}
+
+bool
+virHostdevHostSupportsPassthroughVFIO(void)
+{
+    return true;
+}
+
+#else
+/* Nothing to override on non-__linux__ platforms */
+#endif
-- 
1.8.5.5




More information about the libvir-list mailing list