is able to run. Possible values are:
<dl>
<dt><code>xen</code></dt>
- <dd>for XEN</dd>
+ <dd>for XEN PV</dd>
<dt><code>linux</code></dt>
<dd>legacy alias for <code>xen</code></dd>
+ <dt><code>xenpvh</code></dt>
+ <dd>for XEN PVH</dd>
+
<dt><code>hvm</code></dt>
<dd>Unmodified operating system</dd>
<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 PVH.</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>
<choice>
<value>xenpv</value>
<value>xenfv</value>
+ <value>xenpvh</value>
</choice>
</attribute>
</optional>
<choice>
<value>xen</value>
<value>linux</value>
+ <value>xenpvh</value>
</choice>
</element>
</define>
])
fi
+ dnl Check if Xen has support for PVH
+ AC_CHECK_DECL(LIBXL_DOMAIN_TYPE_PVH, [AC_DEFINE([HAVE_XEN_PVH], [1], [Define to 1 if Xen has PVH support.])], [], [#include <libxl.h>])
+
AC_SUBST([LIBXL_CFLAGS])
AC_SUBST([LIBXL_LIBS])
])
"xen",
"linux",
"exe",
- "uml")
+ "uml",
+ "xenpvh")
VIR_ENUM_IMPL(virDomainBoot, VIR_DOMAIN_BOOT_LAST,
"fd",
bus);
goto error;
}
- } else if (dom->os.type == VIR_DOMAIN_OSTYPE_XEN) {
+ } else if (dom->os.type == VIR_DOMAIN_OSTYPE_XEN ||
+ dom->os.type == VIR_DOMAIN_OSTYPE_XENPVH) {
if (def->bus != VIR_DOMAIN_INPUT_BUS_XEN) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("unsupported input bus %s"),
} else {
def->bus = VIR_DOMAIN_INPUT_BUS_USB;
}
- } else if (dom->os.type == VIR_DOMAIN_OSTYPE_XEN) {
+ } else if (dom->os.type == VIR_DOMAIN_OSTYPE_XEN ||
+ dom->os.type == VIR_DOMAIN_OSTYPE_XENPVH) {
def->bus = VIR_DOMAIN_INPUT_BUS_XEN;
} else {
if ((dom->virtType == VIR_DOMAIN_VIRT_VZ ||
}
if (def->os.type == VIR_DOMAIN_OSTYPE_XEN ||
+ def->os.type == VIR_DOMAIN_OSTYPE_XENPVH ||
def->os.type == VIR_DOMAIN_OSTYPE_HVM ||
def->os.type == VIR_DOMAIN_OSTYPE_UML) {
xmlNodePtr loader_node;
VIR_DOMAIN_OSTYPE_LINUX,
VIR_DOMAIN_OSTYPE_EXE,
VIR_DOMAIN_OSTYPE_UML,
+ VIR_DOMAIN_OSTYPE_XENPVH,
VIR_DOMAIN_OSTYPE_LAST
} virDomainOSType;
virArch arch;
int bits;
int hvm;
+ int pvh;
int pae;
int nonpae;
int ia64_be;
guest_archs[i].nonpae = nonpae;
if (ia64_be)
guest_archs[i].ia64_be = ia64_be;
+
+ /*
+ * Xen 4.10 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.
+ */
+#ifdef HAVE_XEN_PVH
+ if (hvm && i == nr_guest_archs-1) {
+ /* Ensure we have not exhausted the guest_archs array */
+ if (nr_guest_archs >= ARRAY_CARDINALITY(guest_archs))
+ continue;
+ i = nr_guest_archs;
+ nr_guest_archs++;
+
+ guest_archs[i].arch = arch;
+ guest_archs[i].hvm = 0;
+ guest_archs[i].pvh = 1;
+ }
+#endif
}
}
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)
return -1;
if ((guest = virCapabilitiesAddGuest(caps,
- guest_archs[i].hvm ? VIR_DOMAIN_OSTYPE_HVM : VIR_DOMAIN_OSTYPE_XEN,
+ guest_archs[i].hvm ? VIR_DOMAIN_OSTYPE_HVM :
+ (guest_archs[i].pvh ? VIR_DOMAIN_OSTYPE_XENPVH :
+ VIR_DOMAIN_OSTYPE_XEN),
guest_archs[i].arch,
LIBXL_EXECBIN_DIR "/qemu-system-i386",
(guest_archs[i].hvm ?
1,
0) == NULL)
return -1;
+ }
+ if (guest_archs[i].hvm || guest_archs[i].pvh) {
if (virCapabilitiesAddGuestFeature(guest,
"hap",
1,
os->supported = true;
- if (STREQ(machine, "xenpv"))
+ if (STREQ(machine, "xenpv") || STREQ(machine, "xenpvh"))
return 0;
capsLoader->supported = true;
if (libxlMakeDomainOSCaps(domCaps->machine, os, firmwares, nfirmwares) < 0 ||
libxlMakeDomainDeviceDiskCaps(disk) < 0 ||
libxlMakeDomainDeviceGraphicsCaps(graphics) < 0 ||
- libxlMakeDomainDeviceVideoCaps(video) < 0 ||
+ libxlMakeDomainDeviceVideoCaps(video) < 0)
+ return -1;
+ if (STRNEQ(domCaps->machine, "xenpvh") &&
libxlMakeDomainDeviceHostdevCaps(hostdev) < 0)
return -1;
+
return 0;
}
libxl_domain_create_info_init(c_info);
- if (def->os.type == VIR_DOMAIN_OSTYPE_HVM) {
+ if (def->os.type == VIR_DOMAIN_OSTYPE_HVM ||
+ def->os.type == VIR_DOMAIN_OSTYPE_XENPVH) {
+#ifdef HAVE_XEN_PVH
+ c_info->type = def->os.type == VIR_DOMAIN_OSTYPE_HVM ?
+ LIBXL_DOMAIN_TYPE_HVM : LIBXL_DOMAIN_TYPE_PVH;
+#else
+ if (def->os.type == VIR_DOMAIN_OSTYPE_XENPVH) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("PVH guest os type not supported"));
+ return -1;
+ }
c_info->type = LIBXL_DOMAIN_TYPE_HVM;
+#endif
switch ((virTristateSwitch) def->features[VIR_DOMAIN_FEATURE_HAP]) {
case VIR_TRISTATE_SWITCH_OFF:
libxl_defbool_set(&c_info->hap, false);
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 = def->os.type == VIR_DOMAIN_OSTYPE_XENPVH;
size_t i;
size_t nusbdevice = 0;
libxl_domain_build_info_init(b_info);
- if (hvm)
+ if (hvm) {
libxl_domain_build_info_init_type(b_info, LIBXL_DOMAIN_TYPE_HVM);
- else
+ } else if (pvh) {
+#ifdef HAVE_XEN_PVH
+ libxl_domain_build_info_init_type(b_info, LIBXL_DOMAIN_TYPE_PVH);
+#else
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("PVH guest os type not supported"));
+ return -1;
+#endif
+ } else {
libxl_domain_build_info_init_type(b_info, LIBXL_DOMAIN_TYPE_PV);
+ }
b_info->max_vcpus = virDomainDefGetVcpusMax(def);
if (libxl_cpu_bitmap_alloc(ctx, &b_info->avail_vcpus, b_info->max_vcpus))
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;
VIR_DISPOSE_N(b_info->u.hvm.usbdevice_list, nusbdevice);
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 {
/*
* hvm guest").
*/
if (l_nic->model) {
- if (def->os.type == VIR_DOMAIN_OSTYPE_XEN &&
+ if ((def->os.type == VIR_DOMAIN_OSTYPE_XEN ||
+ def->os.type == VIR_DOMAIN_OSTYPE_XENPVH) &&
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)
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 {