xen side patch to support xen HVM direct kernel boot:
support 'kernel', 'ramdisk', 'cmdline' (and 'root', 'extra' as well
which would be deprecated later) in HVM config file, parse config file,
pass -kernel, -initrd, -append parameters to qemu.
It's working with qemu-xen when using the default BIOS (seabios).
[HVM config example]
name="sles11_sp2"
description="None"
uuid="
5c84adcc-bd59-788a-96d2-
195f9b599cfe"
memory=512
maxmem=512
vcpus=4
on_poweroff="destroy"
on_reboot="restart"
on_crash="destroy"
localtime=0
keymap="en-us"
builder="hvm"
device_model_override="/home/cyliu/git/qemu/x86_64-softmmu/qemu-system-x86_64"
kernel="/mnt/vmlinuz-3.0.13-0.27-default"
ramdisk="/mnt/initrd-3.0.13-0.27-default"
root="/dev/hda2"
extra="console=tty0 console=ttyS0"
disk=[ 'file:/mnt/images/sles11_sp2/disk0.raw,hda,w', ]
vif=[ 'mac=00:16:3e:56:af:69,bridge=br0,type=netfront', ]
stdvga=0
vnc=1
vncunused=1
viridian=0
acpi=1
pae=1
serial="pty"
Signed-off-by: Chunyan Liu <cyliu@suse.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
=back
+=head3 Direct Kernel Boot
+
+Direct kernel boot allows booting directly from a kernel and initrd
+stored in the host physical machine OS, allowing command line arguments
+to be passed directly. PV guest direct kernel boot is supported. HVM
+guest direct kernel boot is supported with limitation (it's supported
+when using qemu-xen and default BIOS 'seabios'; not supported in case of
+stubdom-dm and old rombios.)
+
+=over 4
+
+=item B<kernel="PATHNAME">
+
+Load the specified file as the kernel image.
+
+=item B<ramdisk="PATHNAME">
+
+Load the specified file as the ramdisk.
+
+=item B<root="STRING">
+
+Append B<root="STRING"> to the kernel command line (Note: it is guest
+specific what meaning this has).
+
+=item B<extra="STRING">
+
+Append B<STRING> to the kernel command line. (Note: it is guest
+specific what meaning this has).
+
+=back
+
=head3 Other Options
=over 4
=over 4
-=item B<kernel="PATHNAME">
-
-Load the specified file as the kernel image. Either B<kernel> or
-B<bootloader> must be specified for PV guests.
-
-=item B<ramdisk="PATHNAME">
-
-Load the specified file as the ramdisk.
-
=item B<bootloader="PROGRAM">
Run C<PROGRAM> to find the kernel image and ramdisk to use. Normally
C<PROGRAM> would be C<pygrub>, which is an emulation of
-grub/grub2/syslinux.
+grub/grub2/syslinux. Either B<kernel> or B<bootloader> must be specified
+for PV guests.
=item B<bootloader_args=[ "ARG", "ARG", ...]>
program. Alternatively if the argument is a simple string then it will
be split into words at whitespace (this second option is deprecated).
-=item B<root="STRING">
-
-Append B<root="STRING"> to the kernel command line (Note: it is guest
-specific what meaning this has).
-
-=item B<extra="STRING">
-
-Append B<STRING> to the kernel command line. Note: it is guest
-specific what meaning this has).
-
=item B<e820_host=BOOLEAN>
Selects whether to expose the host e820 (memory map) to the guest via
*/
#define LIBXL_HAVE_DEVICE_PCI_SEIZE 1
+/*
+ * LIBXL_HAVE_BUILDINFO_KERNEL
+ *
+ * If this is defined, then the libxl_domain_build_info structure will
+ * contain 'kernel', 'ramdisk', 'cmdline' fields. 'kernel' is a string
+ * to indicate kernel image location, 'ramdisk' is a string to indicate
+ * ramdisk location, 'cmdline' is a string to indicate the paramters which
+ * would be appended to kernel image.
+ *
+ * Both PV guest and HVM guest can use these fields for direct kernel boot.
+ * But for compatibility reason, u.pv.kernel, u.pv.ramdisk and u.pv.cmdline
+ * still exist.
+ */
+#define LIBXL_HAVE_BUILDINFO_KERNEL 1
+
/* Functions annotated with LIBXL_EXTERNAL_CALLERS_ONLY may not be
* called from within libxl itself. Callers outside libxl, who
* do not #include libxl_internal.h, are fine. */
ARG(bootloader_path);
- if (info->u.pv.kernel)
- ARG(libxl__sprintf(gc, "--kernel=%s", info->u.pv.kernel));
- if (info->u.pv.ramdisk)
- ARG(libxl__sprintf(gc, "--ramdisk=%s", info->u.pv.ramdisk));
- if (info->u.pv.cmdline && *info->u.pv.cmdline != '\0')
- ARG(libxl__sprintf(gc, "--args=%s", info->u.pv.cmdline));
+ if (info->kernel)
+ ARG(libxl__sprintf(gc, "--kernel=%s", info->kernel));
+ if (info->ramdisk)
+ ARG(libxl__sprintf(gc, "--ramdisk=%s", info->ramdisk));
+ if (info->cmdline && *info->cmdline != '\0')
+ ARG(libxl__sprintf(gc, "--args=%s", info->cmdline));
ARG(libxl__sprintf(gc, "--output=%s", bl->outputpath));
ARG("--output-format=simple0");
if (!info->u.pv.bootloader) {
LOG(DEBUG, "no bootloader configured, using user supplied kernel");
- bl->kernel->path = bl->info->u.pv.kernel;
- bl->ramdisk->path = bl->info->u.pv.ramdisk;
- bl->cmdline = bl->info->u.pv.cmdline;
+ bl->kernel->path = bl->info->kernel;
+ bl->ramdisk->path = bl->info->ramdisk;
+ bl->cmdline = bl->info->cmdline;
rc = 0;
goto out_ok;
}
b_info->shadow_memkb = 0;
if (b_info->u.pv.slack_memkb == LIBXL_MEMKB_DEFAULT)
b_info->u.pv.slack_memkb = 0;
+
+ /* For compatibility, fill in b_info->kernel|ramdisk|cmdline
+ * with the value in u.pv, later processing will use
+ * b_info->kernel|ramdisk|cmdline only.
+ * User with old APIs that passes u.pv.kernel|ramdisk|cmdline
+ * is not affected.
+ */
+ if (!b_info->kernel && b_info->u.pv.kernel) {
+ b_info->kernel = b_info->u.pv.kernel;
+ b_info->u.pv.kernel = NULL;
+ }
+ if (!b_info->ramdisk && b_info->u.pv.ramdisk) {
+ b_info->ramdisk = b_info->u.pv.ramdisk;
+ b_info->u.pv.ramdisk = NULL;
+ }
+ if (!b_info->cmdline && b_info->u.pv.cmdline) {
+ b_info->cmdline = b_info->u.pv.cmdline;
+ b_info->u.pv.cmdline = NULL;
+ }
break;
default:
LIBXL__LOG(CTX, LIBXL__LOG_ERROR,
int nr_set_cpus = 0;
char *s;
+ if (b_info->kernel) {
+ LOG(ERROR, "HVM direct kernel boot is not supported by "
+ "qemu-xen-traditional");
+ return NULL;
+ }
+
if (b_info->u.hvm.serial || b_info->u.hvm.serial_list) {
if ( b_info->u.hvm.serial && b_info->u.hvm.serial_list )
{
("iomem", Array(libxl_iomem_range, "num_iomem")),
("claim_mode", libxl_defbool),
("event_channels", uint32),
+ ("kernel", string),
+ ("cmdline", string),
+ ("ramdisk", string),
("u", KeyedUnion(None, libxl_domain_type, "type",
[("hvm", Struct(None, [("firmware", string),
("bios", libxl_bios_type),
xlu_cfg_replace_string (config, "xauthority", &sdl->xauthority, 0);
}
+static char *parse_cmdline(XLU_Config *config)
+{
+ char *cmdline = NULL;
+ const char *root = NULL, *extra = "";
+
+ xlu_cfg_get_string (config, "root", &root, 0);
+ xlu_cfg_get_string (config, "extra", &extra, 0);
+
+ if (root) {
+ if (asprintf(&cmdline, "root=%s %s", root, extra) == -1)
+ cmdline = NULL;
+ } else {
+ cmdline = strdup(extra);
+ }
+
+ if ((root || extra) && !cmdline) {
+ fprintf(stderr, "Failed to allocate memory for cmdline\n");
+ exit(1);
+ }
+
+ return cmdline;
+}
+
static void parse_vcpu_affinity(libxl_domain_build_info *b_info,
XLU_ConfigList *cpus, const char *buf,
int num_cpus, bool is_hard)
if (!xlu_cfg_get_long(config, "max_event_channels", &l, 0))
b_info->event_channels = l;
+ xlu_cfg_replace_string (config, "kernel", &b_info->kernel, 0);
+ xlu_cfg_replace_string (config, "ramdisk", &b_info->ramdisk, 0);
+ b_info->cmdline = parse_cmdline(config);
+
xlu_cfg_get_defbool(config, "driver_domain", &c_info->driver_domain, 0);
switch(b_info->type) {
case LIBXL_DOMAIN_TYPE_HVM:
- if (!xlu_cfg_get_string (config, "kernel", &buf, 0))
- fprintf(stderr, "WARNING: ignoring \"kernel\" directive for HVM guest. "
- "Use \"firmware_override\" instead if you really want a non-default firmware\n");
+ if (!strcmp(libxl_basename(b_info->kernel), "hvmloader")) {
+ fprintf(stderr, "WARNING: you seem to be using \"kernel\" "
+ "directive to override HVM guest firmware. Ignore "
+ "that. Use \"firmware_override\" instead if you "
+ "really want a non-default firmware\n");
+ b_info->kernel = NULL;
+ }
xlu_cfg_replace_string (config, "firmware_override",
&b_info->u.hvm.firmware, 0);
break;
case LIBXL_DOMAIN_TYPE_PV:
{
- char *cmdline = NULL;
- const char *root = NULL, *extra = "";
-
- xlu_cfg_replace_string (config, "kernel", &b_info->u.pv.kernel, 0);
-
- xlu_cfg_get_string (config, "root", &root, 0);
- xlu_cfg_get_string (config, "extra", &extra, 0);
-
- if (root) {
- if (asprintf(&cmdline, "root=%s %s", root, extra) == -1)
- cmdline = NULL;
- } else {
- cmdline = strdup(extra);
- }
-
- if ((root || extra) && !cmdline) {
- fprintf(stderr, "Failed to allocate memory for cmdline\n");
- exit(1);
- }
-
xlu_cfg_replace_string (config, "bootloader", &b_info->u.pv.bootloader, 0);
switch (xlu_cfg_get_list_as_string_list(config, "bootloader_args",
&b_info->u.pv.bootloader_args, 1))
exit(-ERROR_FAIL);
}
- if (!b_info->u.pv.bootloader && !b_info->u.pv.kernel) {
+ if (!b_info->u.pv.bootloader && !b_info->kernel) {
fprintf(stderr, "Neither kernel nor bootloader specified\n");
exit(1);
}
- b_info->u.pv.cmdline = cmdline;
- xlu_cfg_replace_string (config, "ramdisk", &b_info->u.pv.ramdisk, 0);
break;
}
default: