Add domain capabilities for PV and HVM domains.
Signed-off-by: Jim Fehlig <jfehlig(a)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