[libvirt] [PATCH 2/4] libxl: implement connectGetDomainCapabilities

Jim Fehlig jfehlig at suse.com
Wed Apr 20 21:14:33 UTC 2016


Add domain capabilities for PV and HVM domains.

Signed-off-by: Jim Fehlig <jfehlig at suse.com>
---
 src/libxl/libxl_capabilities.c                  | 103 ++++++++++++++++++++++++
 src/libxl/libxl_capabilities.h                  |   4 +
 src/libxl/libxl_driver.c                        |  68 ++++++++++++++++
 tests/Makefile.am                               |   5 ++
 tests/domaincapsschemadata/domaincaps-xenfv.xml |  51 ++++++++++++
 tests/domaincapsschemadata/domaincaps-xenpv.xml |  44 ++++++++++
 tests/domaincapstest.c                          |  33 ++++++++
 tests/testutilsxen.h                            |   1 +
 8 files changed, 309 insertions(+)

diff --git a/src/libxl/libxl_capabilities.c b/src/libxl/libxl_capabilities.c
index 6734b2a..f5fa90e 100644
--- a/src/libxl/libxl_capabilities.c
+++ b/src/libxl/libxl_capabilities.c
@@ -29,8 +29,10 @@
 #include "virlog.h"
 #include "virerror.h"
 #include "viralloc.h"
+#include "virstring.h"
 #include "domain_conf.h"
 #include "capabilities.h"
+#include "domain_capabilities.h"
 #include "vircommand.h"
 #include "libxl_capabilities.h"
 
@@ -395,6 +397,76 @@ libxlCapsInitGuests(libxl_ctx *ctx, virCapsPtr caps)
     return 0;
 }
 
+static int
+libxlMakeDomainOSCaps(const char *machine, virDomainCapsOSPtr os)
+{
+    virDomainCapsLoaderPtr capsLoader = &os->loader;
+
+    os->supported = true;
+
+    if (STREQ(machine, "xenpv"))
+        return 0;
+
+    capsLoader->supported = true;
+    if (VIR_ALLOC_N(capsLoader->values.values, 2) < 0)
+        return -1;
+
+    if (VIR_STRDUP(capsLoader->values.values[0],
+                   LIBXL_FIRMWARE_DIR "/hvmloader") < 0)
+        return -1;
+    if (VIR_STRDUP(capsLoader->values.values[1],
+                   LIBXL_FIRMWARE_DIR "/ovmf.bin") < 0)
+        return -1;
+    capsLoader->values.nvalues = 2;
+    VIR_DOMAIN_CAPS_ENUM_SET(capsLoader->type,
+                             VIR_DOMAIN_LOADER_TYPE_ROM);
+
+    return 0;
+}
+
+static int
+libxlMakeDomainDeviceDiskCaps(virDomainCapsDeviceDiskPtr disk)
+{
+    disk->supported = true;
+
+    VIR_DOMAIN_CAPS_ENUM_SET(disk->diskDevice,
+                             VIR_DOMAIN_DISK_DEVICE_DISK,
+                             VIR_DOMAIN_DISK_DEVICE_CDROM);
+
+    VIR_DOMAIN_CAPS_ENUM_SET(disk->bus,
+                             VIR_DOMAIN_DISK_BUS_IDE,
+                             VIR_DOMAIN_DISK_BUS_SCSI,
+                             VIR_DOMAIN_DISK_BUS_XEN);
+
+    return 0;
+}
+
+static int
+libxlMakeDomainDeviceHostdevCaps(virDomainCapsDeviceHostdevPtr hostdev)
+{
+    hostdev->supported = true;
+    /* VIR_DOMAIN_HOSTDEV_MODE_CAPABILITIES is for containers only */
+    VIR_DOMAIN_CAPS_ENUM_SET(hostdev->mode,
+                             VIR_DOMAIN_HOSTDEV_MODE_SUBSYS);
+
+    VIR_DOMAIN_CAPS_ENUM_SET(hostdev->startupPolicy,
+                             VIR_DOMAIN_STARTUP_POLICY_DEFAULT,
+                             VIR_DOMAIN_STARTUP_POLICY_MANDATORY,
+                             VIR_DOMAIN_STARTUP_POLICY_REQUISITE,
+                             VIR_DOMAIN_STARTUP_POLICY_OPTIONAL);
+
+    VIR_DOMAIN_CAPS_ENUM_SET(hostdev->subsysType,
+                             VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI);
+
+    /* No virDomainHostdevCapsType for libxl */
+    virDomainCapsEnumClear(&hostdev->capsType);
+
+    virDomainCapsEnumClear(&hostdev->pciBackend);
+    VIR_DOMAIN_CAPS_ENUM_SET(hostdev->pciBackend,
+                             VIR_DOMAIN_HOSTDEV_PCI_BACKEND_XEN);
+    return 0;
+}
+
 virCapsPtr
 libxlMakeCapabilities(libxl_ctx *ctx)
 {
@@ -423,6 +495,37 @@ libxlMakeCapabilities(libxl_ctx *ctx)
     return NULL;
 }
 
+
+/*
+ * Currently Xen has no interface to report maxvcpus supported
+ * for the various domain types (PV, HVM, PVH). HVM_MAX_VCPUS
+ * is defined in $xensrc/xen/include/public/hvm/hvm_info_table.h
+ * PV has no equivalent and is relunctantly set here until Xen
+ * can report such capabilities.
+ */
+#define HVM_MAX_VCPUS 128
+#define PV_MAX_VCPUS  512
+
+int
+libxlMakeDomainCapabilities(virDomainCapsPtr domCaps)
+{
+    virDomainCapsOSPtr os = &domCaps->os;
+    virDomainCapsDeviceDiskPtr disk = &domCaps->disk;
+    virDomainCapsDeviceHostdevPtr hostdev = &domCaps->hostdev;
+
+    if (STREQ(domCaps->machine, "xenfv"))
+        domCaps->maxvcpus = HVM_MAX_VCPUS;
+    else
+        domCaps->maxvcpus = PV_MAX_VCPUS;
+
+    if (libxlMakeDomainOSCaps(domCaps->machine, os) < 0 ||
+        libxlMakeDomainDeviceDiskCaps(disk) < 0 ||
+        libxlMakeDomainDeviceHostdevCaps(hostdev) < 0)
+        return -1;
+    return 0;
+}
+
+
 #define LIBXL_QEMU_DM_STR  "Options specific to the Xen version:"
 
 int
diff --git a/src/libxl/libxl_capabilities.h b/src/libxl/libxl_capabilities.h
index df1c327..b101ef0 100644
--- a/src/libxl/libxl_capabilities.h
+++ b/src/libxl/libxl_capabilities.h
@@ -27,6 +27,7 @@
 
 # include "virobject.h"
 # include "capabilities.h"
+# include "domain_capabilities.h"
 
 
 # ifndef LIBXL_FIRMWARE_DIR
@@ -45,6 +46,9 @@ virCapsPtr
 libxlMakeCapabilities(libxl_ctx *ctx);
 
 int
+libxlMakeDomainCapabilities(virDomainCapsPtr domCaps);
+
+int
 libxlDomainGetEmulatorType(const virDomainDef *def);
 
 #endif /* LIBXL_CAPABILITIES_H */
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index b0df58c..b3c3ab6 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -5421,6 +5421,73 @@ static int libxlNodeGetSecurityModel(virConnectPtr conn,
     return 0;
 }
 
+static char *
+libxlConnectGetDomainCapabilities(virConnectPtr conn,
+                                  const char *emulatorbin,
+                                  const char *arch_str,
+                                  const char *machine,
+                                  const char *virttype_str,
+                                  unsigned int flags)
+{
+    char *ret = NULL;
+    int virttype = VIR_DOMAIN_VIRT_XEN;
+    virDomainCapsPtr domCaps = NULL;
+    int arch = virArchFromHost(); /* virArch */
+
+    virCheckFlags(0, ret);
+
+    if (virConnectGetDomainCapabilitiesEnsureACL(conn) < 0)
+        return ret;
+
+    if (virttype_str &&
+        (virttype = virDomainVirtTypeFromString(virttype_str)) < 0) {
+        virReportError(VIR_ERR_INVALID_ARG,
+                       _("unknown virttype: %s"),
+                       virttype_str);
+        goto cleanup;
+    }
+
+    if (virttype != VIR_DOMAIN_VIRT_XEN) {
+        virReportError(VIR_ERR_INVALID_ARG,
+                       _("unknown virttype: %s"),
+                       virttype_str);
+        goto cleanup;
+    }
+
+    if (arch_str && (arch = virArchFromString(arch_str)) == VIR_ARCH_NONE) {
+        virReportError(VIR_ERR_INVALID_ARG,
+                       _("unknown architecture: %s"),
+                       arch_str);
+        goto cleanup;
+    }
+
+    if (emulatorbin == NULL)
+        emulatorbin = "/usr/bin/qemu-system-x86_64";
+
+    if (machine) {
+        if (STRNEQ(machine, "xenpv") && STRNEQ(machine, "xenfv")) {
+            virReportError(VIR_ERR_INVALID_ARG, "%s",
+                           _("Xen only supports 'xenpv' and 'xenfv' machines"));
+            goto cleanup;
+        }
+    } else {
+        machine = "xenpv";
+    }
+
+    if (!(domCaps = virDomainCapsNew(emulatorbin, machine, arch, virttype)))
+        goto cleanup;
+
+    if (libxlMakeDomainCapabilities(domCaps) < 0)
+        goto cleanup;
+
+    ret = virDomainCapsFormat(domCaps);
+
+ cleanup:
+    virObjectUnref(domCaps);
+    return ret;
+}
+
+
 static virHypervisorDriver libxlHypervisorDriver = {
     .name = LIBXL_DRIVER_NAME,
     .connectOpen = libxlConnectOpen, /* 0.9.0 */
@@ -5521,6 +5588,7 @@ static virHypervisorDriver libxlHypervisorDriver = {
     .domainMigrateFinish3Params = libxlDomainMigrateFinish3Params, /* 1.2.6 */
     .domainMigrateConfirm3Params = libxlDomainMigrateConfirm3Params, /* 1.2.6 */
     .nodeGetSecurityModel = libxlNodeGetSecurityModel, /* 1.2.16 */
+    .connectGetDomainCapabilities = libxlConnectGetDomainCapabilities, /* 1.3.4 */
 };
 
 static virConnectDriver libxlConnectDriver = {
diff --git a/tests/Makefile.am b/tests/Makefile.am
index db4f88b..f79b552 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -925,6 +925,11 @@ domaincapstest_SOURCES += testutilsqemu.c testutilsqemu.h
 domaincapstest_LDADD += $(qemu_LDADDS) $(GNULIB_LIBS)
 endif WITH_QEMU
 
+if WITH_LIBXL
+domaincapstest_SOURCES += testutilsxen.h
+domaincapstest_LDADD += $(libxl_LDADDS)
+endif WITH_LIBXL
+
 if WITH_LIBVIRTD
 libvirtdconftest_SOURCES = \
 	libvirtdconftest.c testutils.h testutils.c \
diff --git a/tests/domaincapsschemadata/domaincaps-xenfv.xml b/tests/domaincapsschemadata/domaincaps-xenfv.xml
new file mode 100644
index 0000000..205853c
--- /dev/null
+++ b/tests/domaincapsschemadata/domaincaps-xenfv.xml
@@ -0,0 +1,51 @@
+<domainCapabilities>
+  <path>/usr/bin/qemu-system-x86_64</path>
+  <domain>xen</domain>
+  <machine>xenfv</machine>
+  <arch>x86_64</arch>
+  <vcpu max='128'/>
+  <os supported='yes'>
+    <loader supported='yes'>
+      <value>/usr/lib/xen/boot/hvmloader</value>
+      <value>/usr/lib/xen/boot/ovmf.bin</value>
+      <enum name='type'>
+        <value>rom</value>
+      </enum>
+      <enum name='readonly'/>
+    </loader>
+  </os>
+  <devices>
+    <disk supported='yes'>
+      <enum name='diskDevice'>
+        <value>disk</value>
+        <value>cdrom</value>
+      </enum>
+      <enum name='bus'>
+        <value>ide</value>
+        <value>scsi</value>
+        <value>xen</value>
+      </enum>
+    </disk>
+    <hostdev supported='yes'>
+      <enum name='mode'>
+        <value>subsystem</value>
+      </enum>
+      <enum name='startupPolicy'>
+        <value>default</value>
+        <value>mandatory</value>
+        <value>requisite</value>
+        <value>optional</value>
+      </enum>
+      <enum name='subsysType'>
+        <value>pci</value>
+      </enum>
+      <enum name='capsType'/>
+      <enum name='pciBackend'>
+        <value>xen</value>
+      </enum>
+    </hostdev>
+  </devices>
+  <features>
+    <gic supported='no'/>
+  </features>
+</domainCapabilities>
diff --git a/tests/domaincapsschemadata/domaincaps-xenpv.xml b/tests/domaincapsschemadata/domaincaps-xenpv.xml
new file mode 100644
index 0000000..22341ba
--- /dev/null
+++ b/tests/domaincapsschemadata/domaincaps-xenpv.xml
@@ -0,0 +1,44 @@
+<domainCapabilities>
+  <path>/usr/bin/qemu-system-x86_64</path>
+  <domain>xen</domain>
+  <machine>xenpv</machine>
+  <arch>x86_64</arch>
+  <vcpu max='512'/>
+  <os supported='yes'>
+    <loader supported='no'/>
+  </os>
+  <devices>
+    <disk supported='yes'>
+      <enum name='diskDevice'>
+        <value>disk</value>
+        <value>cdrom</value>
+      </enum>
+      <enum name='bus'>
+        <value>ide</value>
+        <value>scsi</value>
+        <value>xen</value>
+      </enum>
+    </disk>
+    <hostdev supported='yes'>
+      <enum name='mode'>
+        <value>subsystem</value>
+      </enum>
+      <enum name='startupPolicy'>
+        <value>default</value>
+        <value>mandatory</value>
+        <value>requisite</value>
+        <value>optional</value>
+      </enum>
+      <enum name='subsysType'>
+        <value>pci</value>
+      </enum>
+      <enum name='capsType'/>
+      <enum name='pciBackend'>
+        <value>xen</value>
+      </enum>
+    </hostdev>
+  </devices>
+  <features>
+    <gic supported='no'/>
+  </features>
+</domainCapabilities>
diff --git a/tests/domaincapstest.c b/tests/domaincapstest.c
index b6f6ac8..f8d2026 100644
--- a/tests/domaincapstest.c
+++ b/tests/domaincapstest.c
@@ -137,6 +137,21 @@ fillQemuCaps(virDomainCapsPtr domCaps,
 #endif /* WITH_QEMU */
 
 
+#ifdef WITH_LIBXL
+# include "testutilsxen.h"
+
+static int
+fillXenCaps(virDomainCapsPtr domCaps,
+        void *opaque ATTRIBUTE_UNUSED)
+{
+    if (libxlMakeDomainCapabilities(domCaps) < 0)
+        return -1;
+
+    return 0;
+}
+#endif /* WITH_LIBXL */
+
+
 static virDomainCapsPtr
 buildVirDomainCaps(const char *emulatorbin,
                    const char *machine,
@@ -251,6 +266,24 @@ mymain(void)
     virObjectUnref(cfg);
 #endif /* WITH_QEMU */
 
+#ifdef WITH_LIBXL
+
+# define DO_TEST_LIBXL(Filename, Emulatorbin, Machine, Arch, Type)         \
+    do {                                                                   \
+        struct test_virDomainCapsFormatData data = {.filename = Filename,  \
+            .emulatorbin = Emulatorbin, .machine = Machine, .arch = Arch,  \
+            .type = Type, .fillFunc = fillXenCaps};                        \
+        if (virtTestRun(Filename, test_virDomainCapsFormat, &data) < 0)    \
+            ret = -1;                                                      \
+    } while (0)
+
+    DO_TEST_LIBXL("xenpv", "/usr/bin/qemu-system-x86_64",
+                  "xenpv", VIR_ARCH_X86_64, VIR_DOMAIN_VIRT_XEN);
+    DO_TEST_LIBXL("xenfv", "/usr/bin/qemu-system-x86_64",
+                  "xenfv", VIR_ARCH_X86_64, VIR_DOMAIN_VIRT_XEN);
+
+#endif /* WITH_LIBXL */
+
     return ret;
 }
 
diff --git a/tests/testutilsxen.h b/tests/testutilsxen.h
index c78350d..8b997c3 100644
--- a/tests/testutilsxen.h
+++ b/tests/testutilsxen.h
@@ -2,6 +2,7 @@
 # define _TESTUTILSXEN_H_
 
 # include "capabilities.h"
+# include "libxl/libxl_capabilities.h"
 
 virCapsPtr testXenCapsInit(void);
 
-- 
2.1.4




More information about the libvir-list mailing list