Add domain capabilities for PV and HVM domains.
Signed-off-by: Jim Fehlig <jfehlig(a)suse.com>
---
src/libxl/libxl_capabilities.c | 140 +++++++++++++++++++++++++++++
src/libxl/libxl_capabilities.h | 7 ++
src/libxl/libxl_driver.c | 74 +++++++++++++++
tests/Makefile.am | 5 ++
tests/domaincapsschemadata/libxl-xenfv.xml | 68 ++++++++++++++
tests/domaincapsschemadata/libxl-xenpv.xml | 58 ++++++++++++
tests/domaincapstest.c | 61 +++++++++++++
tests/testutilsxen.h | 1 +
8 files changed, 414 insertions(+)
diff --git a/src/libxl/libxl_capabilities.c b/src/libxl/libxl_capabilities.c
index aef2c2d..45f0988 100644
--- a/src/libxl/libxl_capabilities.c
+++ b/src/libxl/libxl_capabilities.c
@@ -30,8 +30,10 @@
#include "virerror.h"
#include "virfile.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"
@@ -396,6 +398,109 @@ libxlCapsInitGuests(libxl_ctx *ctx, virCapsPtr caps)
return 0;
}
+static int
+libxlMakeDomainOSCaps(const char *machine,
+ virDomainCapsOSPtr os,
+ virFirmwarePtr *firmwares,
+ size_t nfirmwares)
+{
+ virDomainCapsLoaderPtr capsLoader = &os->loader;
+ size_t i;
+
+ os->supported = true;
+
+ if (STREQ(machine, "xenpv"))
+ return 0;
+
+ capsLoader->supported = true;
+ if (VIR_ALLOC_N(capsLoader->values.values, nfirmwares) < 0)
+ return -1;
+
+ for (i = 0; i < nfirmwares; i++) {
+ if (VIR_STRDUP(capsLoader->values.values[capsLoader->values.nvalues],
+ firmwares[i]->name) < 0)
+ return -1;
+ capsLoader->values.nvalues++;
+ }
+
+ VIR_DOMAIN_CAPS_ENUM_SET(capsLoader->type,
+ VIR_DOMAIN_LOADER_TYPE_ROM,
+ VIR_DOMAIN_LOADER_TYPE_PFLASH);
+ VIR_DOMAIN_CAPS_ENUM_SET(capsLoader->readonly,
+ VIR_TRISTATE_BOOL_YES);
+
+ return 0;
+}
+
+static int
+libxlMakeDomainDeviceDiskCaps(virDomainCapsDeviceDiskPtr dev)
+{
+ dev->supported = true;
+
+ VIR_DOMAIN_CAPS_ENUM_SET(dev->diskDevice,
+ VIR_DOMAIN_DISK_DEVICE_DISK,
+ VIR_DOMAIN_DISK_DEVICE_CDROM);
+
+ VIR_DOMAIN_CAPS_ENUM_SET(dev->bus,
+ VIR_DOMAIN_DISK_BUS_IDE,
+ VIR_DOMAIN_DISK_BUS_SCSI,
+ VIR_DOMAIN_DISK_BUS_XEN);
+
+ return 0;
+}
+
+static int
+libxlMakeDomainDeviceGraphicsCaps(virDomainCapsDeviceGraphicsPtr dev)
+{
+ dev->supported = true;
+
+ VIR_DOMAIN_CAPS_ENUM_SET(dev->type,
+ VIR_DOMAIN_GRAPHICS_TYPE_SDL,
+ VIR_DOMAIN_GRAPHICS_TYPE_VNC,
+ VIR_DOMAIN_GRAPHICS_TYPE_SPICE);
+
+ return 0;
+}
+
+static int
+libxlMakeDomainDeviceVideoCaps(virDomainCapsDeviceVideoPtr dev)
+{
+ dev->supported = true;
+
+ VIR_DOMAIN_CAPS_ENUM_SET(dev->modelType,
+ VIR_DOMAIN_VIDEO_TYPE_VGA,
+ VIR_DOMAIN_VIDEO_TYPE_CIRRUS,
+ VIR_DOMAIN_VIDEO_TYPE_XEN);
+
+ return 0;
+}
+
+static int
+libxlMakeDomainDeviceHostdevCaps(virDomainCapsDeviceHostdevPtr dev)
+{
+ dev->supported = true;
+ /* VIR_DOMAIN_HOSTDEV_MODE_CAPABILITIES is for containers only */
+ VIR_DOMAIN_CAPS_ENUM_SET(dev->mode,
+ VIR_DOMAIN_HOSTDEV_MODE_SUBSYS);
+
+ VIR_DOMAIN_CAPS_ENUM_SET(dev->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(dev->subsysType,
+ VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI);
+
+ /* No virDomainHostdevCapsType for libxl */
+ virDomainCapsEnumClear(&dev->capsType);
+
+ virDomainCapsEnumClear(&dev->pciBackend);
+ VIR_DOMAIN_CAPS_ENUM_SET(dev->pciBackend,
+ VIR_DOMAIN_HOSTDEV_PCI_BACKEND_XEN);
+ return 0;
+}
+
virCapsPtr
libxlMakeCapabilities(libxl_ctx *ctx)
{
@@ -424,6 +529,41 @@ 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,
+ virFirmwarePtr *firmwares,
+ size_t nfirmwares)
+{
+ virDomainCapsOSPtr os = &domCaps->os;
+ virDomainCapsDeviceDiskPtr disk = &domCaps->disk;
+ virDomainCapsDeviceGraphicsPtr graphics = &domCaps->graphics;
+ virDomainCapsDeviceVideoPtr video = &domCaps->video;
+ 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, firmwares, nfirmwares) < 0 ||
+ libxlMakeDomainDeviceDiskCaps(disk) < 0 ||
+ libxlMakeDomainDeviceGraphicsCaps(graphics) < 0 ||
+ libxlMakeDomainDeviceVideoCaps(video) < 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..992b780 100644
--- a/src/libxl/libxl_capabilities.h
+++ b/src/libxl/libxl_capabilities.h
@@ -27,6 +27,8 @@
# include "virobject.h"
# include "capabilities.h"
+# include "domain_capabilities.h"
+# include "virfirmware.h"
# ifndef LIBXL_FIRMWARE_DIR
@@ -45,6 +47,11 @@ virCapsPtr
libxlMakeCapabilities(libxl_ctx *ctx);
int
+libxlMakeDomainCapabilities(virDomainCapsPtr domCaps,
+ virFirmwarePtr *firmwares,
+ size_t nfirmwares);
+
+int
libxlDomainGetEmulatorType(const virDomainDef *def);
#endif /* LIBXL_CAPABILITIES_H */
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index afc5ac3..82b8b83 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -5562,6 +5562,79 @@ libxlDomainInterfaceAddresses(virDomainPtr dom,
}
+static char *
+libxlConnectGetDomainCapabilities(virConnectPtr conn,
+ const char *emulatorbin,
+ const char *arch_str,
+ const char *machine,
+ const char *virttype_str,
+ unsigned int flags)
+{
+ libxlDriverPrivatePtr driver = conn->privateData;
+ libxlDriverConfigPtr cfg;
+ 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;
+
+ cfg = libxlDriverConfigGet(driver);
+
+ 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, cfg->firmwares,
+ cfg->nfirmwares) < 0)
+ goto cleanup;
+
+ ret = virDomainCapsFormat(domCaps);
+
+ cleanup:
+ virObjectUnref(domCaps);
+ virObjectUnref(cfg);
+ return ret;
+}
+
+
static virHypervisorDriver libxlHypervisorDriver = {
.name = LIBXL_DRIVER_NAME,
.connectOpen = libxlConnectOpen, /* 0.9.0 */
@@ -5663,6 +5736,7 @@ static virHypervisorDriver libxlHypervisorDriver = {
.domainMigrateConfirm3Params = libxlDomainMigrateConfirm3Params, /* 1.2.6 */
.nodeGetSecurityModel = libxlNodeGetSecurityModel, /* 1.2.16 */
.domainInterfaceAddresses = libxlDomainInterfaceAddresses, /* 1.3.5 */
+ .connectGetDomainCapabilities = libxlConnectGetDomainCapabilities, /* 1.3.5 */
};
static virConnectDriver libxlConnectDriver = {
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 839af26..480f034 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -930,6 +930,11 @@ domaincapstest_SOURCES += testutilsqemu.c testutilsqemu.h
domaincapstest_LDADD += $(qemu_LDADDS) $(GNULIB_LIBS)
endif WITH_QEMU
+if WITH_LIBXL
+domaincapstest_SOURCES += testutilsxen.c testutilsxen.h
+domaincapstest_LDADD += ../src/libvirt_driver_libxl_impl.la
+endif WITH_LIBXL
+
if WITH_LIBVIRTD
libvirtdconftest_SOURCES = \
libvirtdconftest.c testutils.h testutils.c \
diff --git a/tests/domaincapsschemadata/libxl-xenfv.xml
b/tests/domaincapsschemadata/libxl-xenfv.xml
new file mode 100644
index 0000000..9436ef8
--- /dev/null
+++ b/tests/domaincapsschemadata/libxl-xenfv.xml
@@ -0,0 +1,68 @@
+<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>
+ <value>pflash</value>
+ </enum>
+ <enum name='readonly'>
+ <value>yes</value>
+ </enum>
+ </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>
+ <graphics supported='yes'>
+ <enum name='type'>
+ <value>sdl</value>
+ <value>vnc</value>
+ <value>spice</value>
+ </enum>
+ </graphics>
+ <video supported='yes'>
+ <enum name='modelType'>
+ <value>vga</value>
+ <value>cirrus</value>
+ <value>xen</value>
+ </enum>
+ </video>
+ <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/libxl-xenpv.xml
b/tests/domaincapsschemadata/libxl-xenpv.xml
new file mode 100644
index 0000000..ab00a28
--- /dev/null
+++ b/tests/domaincapsschemadata/libxl-xenpv.xml
@@ -0,0 +1,58 @@
+<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>
+ <graphics supported='yes'>
+ <enum name='type'>
+ <value>sdl</value>
+ <value>vnc</value>
+ <value>spice</value>
+ </enum>
+ </graphics>
+ <video supported='yes'>
+ <enum name='modelType'>
+ <value>vga</value>
+ <value>cirrus</value>
+ <value>xen</value>
+ </enum>
+ </video>
+ <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 83ce0e5..9fb2c97 100644
--- a/tests/domaincapstest.c
+++ b/tests/domaincapstest.c
@@ -162,10 +162,41 @@ fillQemuCaps(virDomainCapsPtr domCaps,
#endif /* WITH_QEMU */
+#ifdef WITH_LIBXL
+# include "testutilsxen.h"
+
+static int
+fillXenCaps(virDomainCapsPtr domCaps)
+{
+ virFirmwarePtr *firmwares;
+ int ret = -1;
+
+ if (VIR_ALLOC_N(firmwares, 2) < 0)
+ return ret;
+
+ if (VIR_ALLOC(firmwares[0]) < 0 || VIR_ALLOC(firmwares[1]) < 0)
+ goto cleanup;
+ if (VIR_STRDUP(firmwares[0]->name, "/usr/lib/xen/boot/hvmloader") < 0
||
+ VIR_STRDUP(firmwares[1]->name, "/usr/lib/xen/boot/ovmf.bin") <
0)
+ goto cleanup;
+
+ if (libxlMakeDomainCapabilities(domCaps, firmwares, 2) < 0)
+ goto cleanup;
+
+ ret = 0;
+
+ cleanup:
+ virFirmwareFreeList(firmwares, 2);
+ return ret;
+}
+#endif /* WITH_LIBXL */
+
+
enum testCapsType {
CAPS_NONE,
CAPS_ALL,
CAPS_QEMU,
+ CAPS_LIBXL,
};
struct testData {
@@ -213,6 +244,13 @@ test_virDomainCapsFormat(const void *opaque)
goto cleanup;
#endif
break;
+
+ case CAPS_LIBXL:
+#if WITH_LIBXL
+ if (fillXenCaps(domCaps) < 0)
+ goto cleanup;
+#endif
+ break;
}
if (!(domCapsXML = virDomainCapsFormat(domCaps)))
@@ -280,6 +318,20 @@ mymain(void)
VIR_FREE(name); \
} while (0)
+#define DO_TEST_LIBXL(Name, Emulator, Machine, Arch, Type) \
+ do { \
+ struct testData data = { \
+ .name = Name, \
+ .emulator = Emulator, \
+ .machine = Machine, \
+ .arch = Arch, \
+ .type = Type, \
+ .capsType = CAPS_LIBXL, \
+ }; \
+ if (virTestRun(Name, test_virDomainCapsFormat, &data) < 0) \
+ ret = -1; \
+ } while (0)
+
DO_TEST("basic", "/bin/emulatorbin",
"my-machine-type",
"x86_64", VIR_DOMAIN_VIRT_UML, CAPS_NONE);
DO_TEST("full", "/bin/emulatorbin", "my-machine-type",
@@ -313,6 +365,15 @@ mymain(void)
#endif /* WITH_QEMU */
+#if WITH_LIBXL
+
+ DO_TEST_LIBXL("libxl-xenpv", "/usr/bin/qemu-system-x86_64",
+ "xenpv", "x86_64", VIR_DOMAIN_VIRT_XEN);
+ DO_TEST_LIBXL("libxl-xenfv", "/usr/bin/qemu-system-x86_64",
+ "xenfv", "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.8.4