mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 10:40:03 +01:00
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:
1 parent
ceba224970
commit
11dffa2359
7 files changed
+120
-55
No files matched your search
+33
-20
@@ -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
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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
@@ -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:
|
||||
|
||||