Add domain capabilities for PV and HVM domains. Signed-off-by: Jim Fehlig <jfehlig@xxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list