Add domain capabilities for PV and HVM domains. Signed-off-by: Jim Fehlig <jfehlig@xxxxxxxx> --- V3: - Change introduction of connectGetDomainCapabilities to 1.3.6 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..c12c1cf 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.6 */ }; static virConnectDriver libxlConnectDriver = { diff --git a/tests/Makefile.am b/tests/Makefile.am index 18ffab6..4a1e0f3 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.1.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list