xen: pass kernel initrd to qemu

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>
This commit is contained in:
Chunyan Liu authored and Ian Campbell committed 2014-08-26 21:18:51 +01:00
1 parent ceba224970
commit 11dffa2359
7 files changed
+120 -55

No files matched your search

+33 -20
View File
@@ -326,6 +326,37 @@ Action to take if the domain crashes. Default is C<destroy>.
=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
@@ -668,20 +699,12 @@ The following options apply only to Paravirtual guests.
=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", ...]>
@@ -689,16 +712,6 @@ Append B<ARG>s to the arguments to the B<bootloader>
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
+15
View File
@@ -543,6 +543,21 @@ typedef struct libxl__ctx libxl_ctx;
*/
#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. */
+9 -9
View File
@@ -58,12 +58,12 @@ static void make_bootloader_args(libxl__gc *gc, libxl__bootloader_state *bl,
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");
@@ -327,9 +327,9 @@ void libxl__bootloader_run(libxl__egc *egc, libxl__bootloader_state *bl)
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;
}
+19
View File
@@ -354,6 +354,25 @@ int libxl__domain_build_info_setdefault(libxl__gc *gc,
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,
+6
View File
@@ -196,6 +196,12 @@ static char ** libxl__build_device_model_args_old(libxl__gc *gc,
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 )
{
+3
View File
@@ -355,6 +355,9 @@ libxl_domain_build_info = Struct("domain_build_info",[
("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),
+35 -26
View File
@@ -691,6 +691,29 @@ static void parse_top_level_sdl_options(XLU_Config *config,
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)
@@ -970,13 +993,21 @@ static void parse_config_data(const char *config_source,
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);
@@ -1043,26 +1074,6 @@ static void parse_config_data(const char *config_source,
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))
@@ -1085,13 +1096,11 @@ static void parse_config_data(const char *config_source,
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:
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.