On 9/18/18 6:50 PM, Marek Marczykowski-Górecki wrote:
Since this is something between PV and HVM, it makes sense to put
the
setting in place where domain type is specified.
To enable it, use <os><type
machine="xenpvh">...</type></os>. It is
also included in capabilities.xml, for every supported HVM guest type - it
doesn't seems to be any other requirement (besides new enough Xen).
Signed-off-by: Marek Marczykowski-Górecki <marmarek(a)invisiblethingslab.com>
---
Changes in v2 proposed by Jim:
- use new_arch_added var instead of i == nr_guest_archs for clarity
- improve comment
- adjust for now required Xen >= 4.6 (remove part for Xen < 4.5)
---
docs/formatcaps.html.in | 4 ++--
docs/schemas/domaincommon.rng | 1 +
src/libxl/libxl_capabilities.c | 33 ++++++++++++++++++++++++++++++---
src/libxl/libxl_conf.c | 32 +++++++++++++++++++++++++++-----
src/libxl/libxl_driver.c | 6 ++++--
5 files changed, 64 insertions(+), 12 deletions(-)
diff --git a/docs/formatcaps.html.in b/docs/formatcaps.html.in
index 0d9c53d..b8102fd 100644
--- a/docs/formatcaps.html.in
+++ b/docs/formatcaps.html.in
@@ -104,8 +104,8 @@
<dt><code>machine</code></dt><dd>Machine
type, for use in
<a
href="formatdomain.html#attributeOSTypeMachine">machine</a>
attribute of os/type element in domain XML. For example Xen
- supports <code>xenfv</code> for HVM or
<code>xenpv</code> for
- PV.</dd>
+ supports <code>xenfv</code> for HVM,
<code>xenpv</code> for
+ PV, or <code>xenpvh</code> for PVHv2.</dd>
<dt><code>domain</code></dt><dd>The
<code>type</code> attribute of
this element specifies the type of hypervisor required to run the
domain. Use in <a
href="formatdomain.html#attributeDomainType">type</a>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 099a949..820a7c6 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -341,6 +341,7 @@
<choice>
<value>xenpv</value>
<value>xenfv</value>
+ <value>xenpvh</value>
</choice>
</attribute>
</optional>
diff --git a/src/libxl/libxl_capabilities.c b/src/libxl/libxl_capabilities.c
index 18596c7..446fa4c 100644
--- a/src/libxl/libxl_capabilities.c
+++ b/src/libxl/libxl_capabilities.c
@@ -57,6 +57,7 @@ struct guest_arch {
virArch arch;
int bits;
int hvm;
+ int pvh;
int pae;
int nonpae;
int ia64_be;
@@ -439,6 +440,7 @@ libxlCapsInitGuests(libxl_ctx *ctx, virCapsPtr caps)
int hvm = STRPREFIX(&token[subs[1].rm_so], "hvm");
virArch arch;
int pae = 0, nonpae = 0, ia64_be = 0;
+ bool new_arch_added = false;
if (STRPREFIX(&token[subs[2].rm_so], "x86_32")) {
arch = VIR_ARCH_I686;
@@ -475,8 +477,10 @@ libxlCapsInitGuests(libxl_ctx *ctx, virCapsPtr caps)
if (i >= ARRAY_CARDINALITY(guest_archs))
continue;
/* Didn't find a match, so create a new one */
- if (i == nr_guest_archs)
+ if (i == nr_guest_archs) {
nr_guest_archs++;
+ new_arch_added = true;
+ }
guest_archs[i].arch = arch;
guest_archs[i].hvm = hvm;
@@ -491,13 +495,34 @@ libxlCapsInitGuests(libxl_ctx *ctx, virCapsPtr caps)
guest_archs[i].nonpae = nonpae;
if (ia64_be)
guest_archs[i].ia64_be = ia64_be;
+
+ /*
+ * Xen 4.9 introduced support for the PVH guest type, which
+ * requires hardware virtualization support similar to the
+ * HVM guest type. Add a PVH guest type for each new HVM
+ * guest type.
+ */
+ if ((ver_info->xen_version_major > 4 ||
+ (ver_info->xen_version_major == 4 &&
+ ver_info->xen_version_minor >= 9)) &&
+ hvm && new_arch_added) {
In v1 I forgot to mention that libvirt generally frowns upon version checks, but
I don't think we have any other options since pvh is not advertised in Xen's
meager capabilities reporting. Also, I doubt anyone cares. No one is going to
backport pvh enablement to xen < 4.9 and expect to also use libvirt with that.
+ i = nr_guest_archs;
+ /* Ensure we have not exhausted the guest_archs array */
+ if (nr_guest_archs >= ARRAY_CARDINALITY(guest_archs))
+ continue;
+ guest_archs[nr_guest_archs].arch = arch;
+ guest_archs[nr_guest_archs].pvh = 1;
+ nr_guest_archs++;
+ }
}
}
regfree(®ex);
for (i = 0; i < nr_guest_archs; ++i) {
virCapsGuestPtr guest;
- char const *const xen_machines[] = {guest_archs[i].hvm ? "xenfv" :
"xenpv"};
+ char const *const xen_machines[] = {
+ guest_archs[i].hvm ? "xenfv" :
+ (guest_archs[i].pvh ? "xenpvh" : "xenpv")};
virCapsGuestMachinePtr *machines;
if ((machines = virCapabilitiesAllocMachines(xen_machines, 1)) == NULL)
@@ -557,7 +582,9 @@ libxlCapsInitGuests(libxl_ctx *ctx, virCapsPtr caps)
1,
0) == NULL)
return -1;
+ }
+ if (guest_archs[i].hvm || guest_archs[i].pvh) {
if (virCapabilitiesAddGuestFeature(guest,
"hap",
1,
@@ -580,7 +607,7 @@ libxlMakeDomainOSCaps(const char *machine,
os->supported = true;
- if (STREQ(machine, "xenpv"))
+ if (STREQ(machine, "xenpv") || STREQ(machine, "xenpvh"))
return 0;
capsLoader->supported = true;
AFAIK, pvh does not support hostdev passthrough, correct? If that is the case,
libxlMakeDomainDeviceHostdevCaps() will also need adjusted. Can you double check
that all of the capabilities are reported correctly for pvh? FYI on my xen 4.10
setup this patch produces the following domcapabilties
# virsh domcapabilities --machine xenpvh
<domainCapabilities>
<path>/usr/bin/qemu-system-x86_64</path>
<domain>xen</domain>
<machine>xenpvh</machine>
<arch>x86_64</arch>
<vcpu max='512'/>
<iothreads supported='no'/>
<os supported='yes'>
<loader supported='no'/>
</os>
<cpu>
<mode name='host-passthrough' supported='no'/>
<mode name='host-model' supported='no'/>
<mode name='custom' supported='no'/>
</cpu>
<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>usb</value>
<value>pci</value>
</enum>
<enum name='capsType'/>
<enum name='pciBackend'>
<value>xen</value>
</enum>
</hostdev>
</devices>
<features>
<gic supported='no'/>
<vmcoreinfo supported='no'/>
<genid supported='no'/>
<sev supported='no'/>
</features>
</domainCapabilities>
Related observation: The <cpu> caps for machine type xenfv needs to be updated.
It reports host-passthrough mode as unsupported.
diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index f3da0ed..5541a72 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -133,8 +133,11 @@ libxlMakeDomCreateInfo(libxl_ctx *ctx,
libxl_domain_create_info_init(c_info);
- if (def->os.type == VIR_DOMAIN_OSTYPE_HVM) {
- c_info->type = LIBXL_DOMAIN_TYPE_HVM;
+ if (def->os.type == VIR_DOMAIN_OSTYPE_HVM ||
+ (def->os.type == VIR_DOMAIN_OSTYPE_XEN &&
+ STREQ(def->os.machine, "xenpvh"))) {
+ c_info->type = def->os.type == VIR_DOMAIN_OSTYPE_HVM ?
+ LIBXL_DOMAIN_TYPE_HVM : LIBXL_DOMAIN_TYPE_PVH;
Fails to compile on Xen without pvh support
libxl/libxl_conf.c: In function 'libxlMakeDomCreateInfo':
libxl/libxl_conf.c:140:37: error: 'LIBXL_DOMAIN_TYPE_PVH' undeclared (first use
in this function)
switch ((virTristateSwitch)
def->features[VIR_DOMAIN_FEATURE_HAP]) {
case VIR_TRISTATE_SWITCH_OFF:
libxl_defbool_set(&c_info->hap, false);
@@ -276,7 +279,8 @@ libxlMakeDomBuildInfo(virDomainDefPtr def,
virDomainClockDef clock = def->clock;
libxl_ctx *ctx = cfg->ctx;
libxl_domain_build_info *b_info = &d_config->b_info;
- int hvm = def->os.type == VIR_DOMAIN_OSTYPE_HVM;
+ bool hvm = def->os.type == VIR_DOMAIN_OSTYPE_HVM;
+ bool pvh = STREQ(def->os.machine, "xenpvh");
size_t i;
size_t nusbdevice = 0;
@@ -284,6 +288,8 @@ libxlMakeDomBuildInfo(virDomainDefPtr def,
if (hvm)
libxl_domain_build_info_init_type(b_info, LIBXL_DOMAIN_TYPE_HVM);
+ else if (pvh)
+ libxl_domain_build_info_init_type(b_info, LIBXL_DOMAIN_TYPE_PVH);
Another instance here. Looks good otherwise.
Regards,
Jim
else
libxl_domain_build_info_init_type(b_info, LIBXL_DOMAIN_TYPE_PV);
@@ -375,7 +381,7 @@ libxlMakeDomBuildInfo(virDomainDefPtr def,
def->mem.cur_balloon = VIR_ROUND_UP(def->mem.cur_balloon, 1024);
b_info->max_memkb = virDomainDefGetMemoryInitial(def);
b_info->target_memkb = def->mem.cur_balloon;
- if (hvm) {
+ if (hvm || pvh) {
if (caps &&
def->cpu && def->cpu->mode ==
(VIR_CPU_MODE_HOST_PASSTHROUGH)) {
bool hasHwVirt = false;
@@ -647,6 +653,22 @@ libxlMakeDomBuildInfo(virDomainDefPtr def,
return -1;
}
#endif
+ } else if (pvh) {
+ if (VIR_STRDUP(b_info->cmdline, def->os.cmdline) < 0)
+ return -1;
+ if (VIR_STRDUP(b_info->kernel, def->os.kernel) < 0)
+ return -1;
+ if (VIR_STRDUP(b_info->ramdisk, def->os.initrd) < 0)
+ return -1;
+#ifdef LIBXL_HAVE_BUILDINFO_BOOTLOADER
+ if (VIR_STRDUP(b_info->bootloader, def->os.bootloader) < 0)
+ return -1;
+ if (def->os.bootloaderArgs) {
+ if (!(b_info->bootloader_args =
+ virStringSplit(def->os.bootloaderArgs, " \t\n", 0)))
+ return -1;
+ }
+#endif
} else {
/*
* For compatibility with the legacy xen toolstack, default to pygrub
@@ -1230,7 +1252,7 @@ libxlMakeNic(virDomainDefPtr def,
STRNEQ(l_nic->model, "netfront")) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("only model 'netfront' is supported for
"
- "Xen PV domains"));
+ "Xen PV(H) domains"));
return -1;
}
if (VIR_STRDUP(x_nic->model, l_nic->model) < 0)
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index efd47a3..6287cef 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -6398,9 +6398,11 @@ libxlConnectGetDomainCapabilities(virConnectPtr conn,
emulatorbin = "/usr/bin/qemu-system-x86_64";
if (machine) {
- if (STRNEQ(machine, "xenpv") && STRNEQ(machine,
"xenfv")) {
+ if (STRNEQ(machine, "xenpv") &&
+ STRNEQ(machine, "xenpvh") &&
+ STRNEQ(machine, "xenfv")) {
virReportError(VIR_ERR_INVALID_ARG, "%s",
- _("Xen only supports 'xenpv' and 'xenfv'
machines"));
+ _("Xen only supports 'xenpv', 'xenpvh'
and 'xenfv' machines"));
goto cleanup;
}
} else {