From 865406533fe7a163acd5ed299628f1dc8d475803 Mon Sep 17 00:00:00 2001 From: Chunyan Liu Date: Wed, 28 May 2014 14:36:54 +0800 Subject: [PATCH 1/2] xen: pass kernel initrd to qemu xen side patch to support xen HVM direct kernel boot: support 'kernel', 'ramdisk', 'root', 'extra' in HVM config file, parse config file, pass -kernel, -initrd, -append parameters to qemu. It's working with seabios and non-stubdom. Rombios and stubdom cases are currently not supported. [config example] 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/bjz_04_sles11_sp2/disk0.raw,hda,w', ] Signed-off-by: Chunyan Liu --- docs/man/xl.cfg.pod.5 | 50 ++++++++++++++++++++++++---------------- tools/libxl/libxl_dm.c | 15 ++++++++++++ tools/libxl/libxl_types.idl | 3 +++ tools/libxl/xl_cmdimpl.c | 56 +++++++++++++++++++++++++++------------------ 4 files changed, 82 insertions(+), 42 deletions(-) Index: xen-4.4.0-testing/docs/man/xl.cfg.pod.5 =================================================================== --- xen-4.4.0-testing.orig/docs/man/xl.cfg.pod.5 +++ xen-4.4.0-testing/docs/man/xl.cfg.pod.5 @@ -296,6 +296,34 @@ Action to take if the domain crashes. D =back +=head3 Direct Kernel Boot + +Currently, direct kernel boot can be supported by PV guests, and HVM guests +in some configuration. For HVM guests, in case of stubdom-dm and old rombios, +direct kernel boot is not supported. + +=over 4 + +=item B + +Load the specified file as the kernel image. + +=item B + +Load the specified file as the ramdisk. + +=item B + +Append B to the kernel command line (Note: it is guest +specific what meaning this has). + +=item B + +Append B to the kernel command line. (Note: it is guest +specific what meaning this has). + +=back + =head3 Other Options =over 4 @@ -655,20 +683,12 @@ The following options apply only to Para =over 4 -=item B - -Load the specified file as the kernel image. Either B or -B must be specified for PV guests. - -=item B - -Load the specified file as the ramdisk. - =item B Run C to find the kernel image and ramdisk to use. Normally C would be C, which is an emulation of -grub/grub2/syslinux. +grub/grub2/syslinux. Either B or B must be specified +for PV guests. =item B @@ -676,16 +696,6 @@ Append Bs to the arguments to the B 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 - -Append B to the kernel command line (Note: it is guest -specific what meaning this has). - -=item B - -Append B to the kernel command line. Note: it is guest -specific what meaning this has). - =item B Selects whether to expose the host e820 (memory map) to the guest via Index: xen-4.4.0-testing/tools/libxl/libxl_dm.c =================================================================== --- xen-4.4.0-testing.orig/tools/libxl/libxl_dm.c +++ xen-4.4.0-testing/tools/libxl/libxl_dm.c @@ -196,6 +196,12 @@ static char ** libxl__build_device_model int nr_set_cpus = 0; char *s; + if (b_info->u.hvm.kernel) { + LOG(ERROR, "direct kernel boot is not supported by %s", + dm); + return NULL; + } + if (b_info->u.hvm.serial) { flexarray_vappend(dm_args, "-serial", b_info->u.hvm.serial, NULL); } @@ -487,6 +493,15 @@ static char ** libxl__build_device_model if (b_info->type == LIBXL_DOMAIN_TYPE_HVM) { int ioemu_nics = 0; + if (b_info->u.hvm.kernel) + flexarray_vappend(dm_args, "-kernel", b_info->u.hvm.kernel, NULL); + + if (b_info->u.hvm.ramdisk) + flexarray_vappend(dm_args, "-initrd", b_info->u.hvm.ramdisk, NULL); + + if (b_info->u.hvm.cmdline) + flexarray_vappend(dm_args, "-append", b_info->u.hvm.cmdline, NULL); + if (b_info->u.hvm.serial) { flexarray_vappend(dm_args, "-serial", b_info->u.hvm.serial, NULL); } Index: xen-4.4.0-testing/tools/libxl/libxl_types.idl =================================================================== --- xen-4.4.0-testing.orig/tools/libxl/libxl_types.idl +++ xen-4.4.0-testing/tools/libxl/libxl_types.idl @@ -335,6 +335,9 @@ libxl_domain_build_info = Struct("domain ("event_channels", uint32), ("u", KeyedUnion(None, libxl_domain_type, "type", [("hvm", Struct(None, [("firmware", string), + ("kernel", string), + ("cmdline", string), + ("ramdisk", string), ("bios", libxl_bios_type), ("pae", libxl_defbool), ("apic", libxl_defbool), Index: xen-4.4.0-testing/tools/libxl/xl_cmdimpl.c =================================================================== --- xen-4.4.0-testing.orig/tools/libxl/xl_cmdimpl.c +++ xen-4.4.0-testing/tools/libxl/xl_cmdimpl.c @@ -848,6 +848,29 @@ static void parse_top_level_sdl_options( 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_config_data(const char *config_source, const char *config_data, int config_len, @@ -1129,9 +1152,16 @@ static void parse_config_data(const char 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 (!xlu_cfg_get_string (config, "kernel", &buf, 0)) { + if (strstr(buf, "hvmloader")) + fprintf(stderr, "WARNING: ignoring \"kernel\" directive for HVM guest. " + "Use \"firmware_override\" instead if you really want a non-default firmware\n"); + else + b_info->u.hvm.kernel = strdup(buf); + } + + b_info->u.hvm.cmdline = parse_cmdline(config); + xlu_cfg_replace_string (config, "ramdisk", &b_info->u.hvm.ramdisk, 0); xlu_cfg_replace_string (config, "firmware_override", &b_info->u.hvm.firmware, 0); @@ -1183,26 +1213,8 @@ static void parse_config_data(const char 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)) @@ -1230,7 +1242,7 @@ static void parse_config_data(const char exit(1); } - b_info->u.pv.cmdline = cmdline; + b_info->u.pv.cmdline = parse_cmdline(config); xlu_cfg_replace_string (config, "ramdisk", &b_info->u.pv.ramdisk, 0); break; }