diff mbox

[RFC,V5,1/3] xen: pass kernel initrd to qemu

Message ID 1404714875-24362-2-git-send-email-cyliu@suse.com
State New
Headers show

Commit Message

Chunyan Liu July 7, 2014, 6:34 a.m. UTC
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>
---
Changes:
  - update b_info->u.pv.kernel compatibility work:
    turn b_info->u.pv.kernel to b_info->kernel in 
    libxl__domain_build_info_setdefault, handle b_info->kernel
    in later processing.
  - include LIBXL_HAVE_BUILDINFO_KERNEL only instead of each
    for kernel, ramdisk and cmdline.
  - update examples in commit message

 docs/man/xl.cfg.pod.5          | 53 ++++++++++++++++++++++--------------
 tools/libxl/libxl.h            | 15 +++++++++++
 tools/libxl/libxl_bootloader.c | 18 ++++++-------
 tools/libxl/libxl_create.c     | 19 +++++++++++++
 tools/libxl/libxl_dm.c         | 15 +++++++++++
 tools/libxl/libxl_types.idl    |  3 +++
 tools/libxl/xl_cmdimpl.c       | 61 ++++++++++++++++++++++++------------------
 7 files changed, 129 insertions(+), 55 deletions(-)

Comments

Ian Campbell July 10, 2014, 2:48 p.m. UTC | #1
On Mon, 2014-07-07 at 14:34 +0800, Chunyan Liu wrote:
> 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>
Stefano Stabellini Nov. 27, 2014, 6:14 p.m. UTC | #2
On Mon, 7 Jul 2014, Chunyan Liu wrote:
> diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c
> index addacdb..4f1cbd2 100644
> --- a/tools/libxl/libxl_dm.c
> +++ b/tools/libxl/libxl_dm.c
> @@ -479,6 +485,15 @@ static char ** libxl__build_device_model_args_new(libxl__gc *gc,
>      if (b_info->type == LIBXL_DOMAIN_TYPE_HVM) {
>          int ioemu_nics = 0;
>  
> +        if (b_info->kernel)
> +            flexarray_vappend(dm_args, "-kernel", b_info->kernel, NULL);
> +
> +        if (b_info->ramdisk)
> +            flexarray_vappend(dm_args, "-initrd", b_info->ramdisk, NULL);
> +
> +        if (b_info->cmdline)
> +            flexarray_vappend(dm_args, "-append", b_info->cmdline, NULL);
> +
>          if (b_info->u.hvm.serial) {
>              flexarray_vappend(dm_args, "-serial", b_info->u.hvm.serial, NULL);
>          }

This chunk of the patch was never applied to xen-unstable (commit
11dffa2359e8a2629490c14c029c7c7c777b3e47), see
http://marc.info/?l=qemu-devel&m=140471493425353&w=2.
The feature is broken at the moment.
Chunyan Liu Nov. 28, 2014, 6:03 a.m. UTC | #3
>>> On 11/28/2014 at 02:14 AM, in message
<alpine.DEB.2.02.1411271809430.14135@kaball.uk.xensource.com>, Stefano
Stabellini <stefano.stabellini@eu.citrix.com> wrote: 
> On Mon, 7 Jul 2014, Chunyan Liu wrote: 
> > diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c 
> > index addacdb..4f1cbd2 100644 
> > --- a/tools/libxl/libxl_dm.c 
> > +++ b/tools/libxl/libxl_dm.c 
> > @@ -479,6 +485,15 @@ static char **  
> libxl__build_device_model_args_new(libxl__gc *gc, 
> >      if (b_info->type == LIBXL_DOMAIN_TYPE_HVM) { 
> >          int ioemu_nics = 0; 
> >   
> > +        if (b_info->kernel) 
> > +            flexarray_vappend(dm_args, "-kernel", b_info->kernel, NULL); 
> > + 
> > +        if (b_info->ramdisk) 
> > +            flexarray_vappend(dm_args, "-initrd", b_info->ramdisk, NULL); 
> > + 
> > +        if (b_info->cmdline) 
> > +            flexarray_vappend(dm_args, "-append", b_info->cmdline, NULL); 
> > + 
> >          if (b_info->u.hvm.serial) { 
> >              flexarray_vappend(dm_args, "-serial", b_info->u.hvm.serial,  
> NULL); 
> >          } 
>  
> This chunk of the patch was never applied to xen-unstable (commit 
> 11dffa2359e8a2629490c14c029c7c7c777b3e47), see 
> http://marc.info/?l=qemu-devel&m=140471493425353&w=2. 
> The feature is broken at the moment. 
>  

Thanks very much. Didn't notice that. Resend the missing part of patch.

>
diff mbox

Patch

diff --git a/docs/man/xl.cfg.pod.5 b/docs/man/xl.cfg.pod.5
index ff9ea77..c4a6589 100644
--- a/docs/man/xl.cfg.pod.5
+++ b/docs/man/xl.cfg.pod.5
@@ -304,6 +304,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
@@ -646,20 +677,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", ...]>
 
@@ -667,16 +690,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
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 459557d..3a1be8d 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -530,6 +530,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. */
diff --git a/tools/libxl/libxl_bootloader.c b/tools/libxl/libxl_bootloader.c
index c3ec782..79947d4 100644
--- a/tools/libxl/libxl_bootloader.c
+++ b/tools/libxl/libxl_bootloader.c
@@ -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;
     }
diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index 0686f96..d5c3b7d 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -339,6 +339,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,
diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c
index addacdb..4f1cbd2 100644
--- a/tools/libxl/libxl_dm.c
+++ b/tools/libxl/libxl_dm.c
@@ -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) {
             flexarray_vappend(dm_args, "-serial", b_info->u.hvm.serial, NULL);
         }
@@ -479,6 +485,15 @@  static char ** libxl__build_device_model_args_new(libxl__gc *gc,
     if (b_info->type == LIBXL_DOMAIN_TYPE_HVM) {
         int ioemu_nics = 0;
 
+        if (b_info->kernel)
+            flexarray_vappend(dm_args, "-kernel", b_info->kernel, NULL);
+
+        if (b_info->ramdisk)
+            flexarray_vappend(dm_args, "-initrd", b_info->ramdisk, NULL);
+
+        if (b_info->cmdline)
+            flexarray_vappend(dm_args, "-append", b_info->cmdline, NULL);
+
         if (b_info->u.hvm.serial) {
             flexarray_vappend(dm_args, "-serial", b_info->u.hvm.serial, NULL);
         }
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index de25f42..e02abff 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -340,6 +340,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),
diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index 68df548..d4cd50b 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -690,6 +690,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_config_data(const char *config_source,
                               const char *config_data,
                               int config_len,
@@ -928,13 +951,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);
@@ -1001,26 +1032,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))
@@ -1043,13 +1054,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: