Add domain capabilities for PV and HVM domains.
Signed-off-by: Jim Fehlig <jfehlig@suse.com>
#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"
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)
{
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
# include "virobject.h"
# include "capabilities.h"
+# include "domain_capabilities.h"
+# include "virfirmware.h"
# ifndef LIBXL_FIRMWARE_DIR
virCapsPtr
libxlMakeCapabilities(libxl_ctx *ctx);
+int
+libxlMakeDomainCapabilities(virDomainCapsPtr domCaps,
+ virFirmwarePtr *firmwares,
+ size_t nfirmwares);
+
int
libxlDomainGetEmulatorType(const virDomainDef *def);
}
+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 */
.domainMigrateConfirm3Params = libxlDomainMigrateConfirm3Params, /* 1.2.6 */
.nodeGetSecurityModel = libxlNodeGetSecurityModel, /* 1.2.16 */
.domainInterfaceAddresses = libxlDomainInterfaceAddresses, /* 1.3.5 */
+ .connectGetDomainCapabilities = libxlConnectGetDomainCapabilities, /* 1.3.6 */
};
static virConnectDriver libxlConnectDriver = {
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 \
--- /dev/null
+<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>
--- /dev/null
+<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>
#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 {
if (fillQemuCaps(domCaps, data->capsName, data->arch, data->machine,
data->capsOpaque) < 0)
goto cleanup;
+#endif
+ break;
+
+ case CAPS_LIBXL:
+#if WITH_LIBXL
+ if (fillXenCaps(domCaps) < 0)
+ goto cleanup;
#endif
break;
}
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",
#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;
}
# define _TESTUTILSXEN_H_
# include "capabilities.h"
+# include "libxl/libxl_capabilities.h"
virCapsPtr testXenCapsInit(void);