This patch adds an option "--reuse-cmdline" for people that are lazy in typing
--append="$(cat /proc/cmdline)". The advantage of "--reuse-cmdline" is also that
it strips off BOOT_IMAGE (since it may not be correct any more) from lilo and
other boot loaders, and, more important, the crashkernel option in case a
panic kernel is loaded.

If you like the option I can also add it for really all architectures. Tested 
only
with x86-bzImage both the kexec and kdump case.


Signed-off-by: Bernhard Walle <[EMAIL PROTECTED]>

---
 kexec/arch/i386/kexec-bzImage.c       |   12 +++-
 kexec/arch/i386/kexec-elf-x86.c       |   16 ++++--
 kexec/arch/i386/kexec-multiboot-x86.c |   12 +++-
 kexec/arch/x86_64/kexec-elf-x86_64.c  |   16 ++++--
 kexec/kexec.8                         |   18 +++++++
 kexec/kexec.c                         |   85 +++++++++++++++++++++++++++++-----
 kexec/kexec.h                         |    1 
 7 files changed, 132 insertions(+), 28 deletions(-)

--- a/kexec/arch/i386/kexec-bzImage.c
+++ b/kexec/arch/i386/kexec-bzImage.c
@@ -89,6 +89,7 @@ void bzImage_usage(void)
                "    --real-mode           Use the kernels real mode entry 
point.\n"
                "    --command-line=STRING Set the kernel command line to 
STRING.\n"
                "    --append=STRING       Set the kernel command line to 
STRING.\n"
+               "    --reuse-cmdline       Use kernel command line from running 
system.\n"
                "    --initrd=FILE         Use FILE as the kernel's initial 
ramdisk.\n"
                "    --ramdisk=FILE        Use FILE as the kernel's initial 
ramdisk.\n"
                );
@@ -335,14 +336,16 @@ int bzImage_load(int argc, char **argv,
        int debug, real_mode_entry;
        int opt;
        int result;
-#define OPT_APPEND     (OPT_ARCH_MAX+0)
-#define OPT_RAMDISK    (OPT_ARCH_MAX+1)
-#define OPT_REAL_MODE  (OPT_ARCH_MAX+2)
+#define OPT_APPEND             (OPT_ARCH_MAX+0)
+#define OPT_REUSE_CMDLINE      (OPT_ARCH_MAX+1)
+#define OPT_RAMDISK            (OPT_ARCH_MAX+2)
+#define OPT_REAL_MODE          (OPT_ARCH_MAX+3)
        static const struct option options[] = {
                KEXEC_ARCH_OPTIONS
                { "debug",              0, 0, OPT_DEBUG },
                { "command-line",       1, 0, OPT_APPEND },
                { "append",             1, 0, OPT_APPEND },
+               { "reuse-cmdline",      1, 0, OPT_REUSE_CMDLINE },
                { "initrd",             1, 0, OPT_RAMDISK },
                { "ramdisk",            1, 0, OPT_RAMDISK },
                { "real-mode",          0, 0, OPT_REAL_MODE },
@@ -374,6 +377,9 @@ int bzImage_load(int argc, char **argv,
                case OPT_APPEND:
                        command_line = optarg;
                        break;
+               case OPT_REUSE_CMDLINE:
+                       command_line = get_command_line();
+                       break;
                case OPT_RAMDISK:
                        ramdisk = optarg;
                        break;
--- a/kexec/arch/i386/kexec-elf-x86.c
+++ b/kexec/arch/i386/kexec-elf-x86.c
@@ -73,6 +73,7 @@ void elf_x86_usage(void)
 {
        printf( "    --command-line=STRING Set the kernel command line to 
STRING\n"
                "    --append=STRING       Set the kernel command line to 
STRING\n"
+               "    --reuse-cmdline       Use kernel command line from running 
system.\n"
                "    --initrd=FILE         Use FILE as the kernel's initial 
ramdisk.\n"
                "    --ramdisk=FILE        Use FILE as the kernel's initial 
ramdisk.\n"
                "    --args-linux          Pass linux kernel style options\n"
@@ -97,16 +98,18 @@ int elf_x86_load(int argc, char **argv,
 #define ARG_STYLE_LINUX 1
 #define ARG_STYLE_NONE  2
        int opt;
-#define OPT_APPEND     (OPT_ARCH_MAX+0)
-#define OPT_RAMDISK    (OPT_ARCH_MAX+1)
-#define OPT_ARGS_ELF    (OPT_ARCH_MAX+2)
-#define OPT_ARGS_LINUX  (OPT_ARCH_MAX+3)
-#define OPT_ARGS_NONE   (OPT_ARCH_MAX+4)
+#define OPT_APPEND             (OPT_ARCH_MAX+0)
+#define OPT_REUSE_CMDLINE      (OPT_ARCH_MAX+1)
+#define OPT_RAMDISK            (OPT_ARCH_MAX+2)
+#define OPT_ARGS_ELF           (OPT_ARCH_MAX+3)
+#define OPT_ARGS_LINUX         (OPT_ARCH_MAX+4)
+#define OPT_ARGS_NONE          (OPT_ARCH_MAX+5)
 
        static const struct option options[] = {
                KEXEC_ARCH_OPTIONS
                { "command-line",       1, NULL, OPT_APPEND },
                { "append",             1, NULL, OPT_APPEND },
+               { "reuse-cmdline",      1, NULL, OPT_REUSE_CMDLINE },
                { "initrd",             1, NULL, OPT_RAMDISK },
                { "ramdisk",            1, NULL, OPT_RAMDISK },
                { "args-elf",           0, NULL, OPT_ARGS_ELF },
@@ -138,6 +141,9 @@ int elf_x86_load(int argc, char **argv,
                case OPT_APPEND:
                        command_line = optarg;
                        break;
+               case OPT_REUSE_CMDLINE:
+                       command_line = get_command_line();
+                       break;
                case OPT_RAMDISK:
                        ramdisk = optarg;
                        break;
--- a/kexec/arch/i386/kexec-multiboot-x86.c
+++ b/kexec/arch/i386/kexec-multiboot-x86.c
@@ -129,6 +129,7 @@ void multiboot_x86_usage(void)
 /* Multiboot-specific options */
 {
        printf("    --command-line=STRING        Set the kernel command line to 
STRING.\n");
+       printf("    --reuse-cmdline              Use kernel command line from 
running system.\n");
        printf("    --module=\"MOD arg1 arg2...\"  Load module MOD with 
command-line \"arg1...\"\n");
        printf("                                 (can be used multiple 
times).\n");
 }
@@ -155,13 +156,15 @@ int multiboot_x86_load(int argc, char **
        int i;
        int opt;
        int modules, mod_command_line_space;
-#define OPT_CL         (OPT_ARCH_MAX+0)
-#define OPT_MOD        (OPT_ARCH_MAX+1)
-#define OPT_VGA        (OPT_ARCH_MAX+2)
+#define OPT_CL                 (OPT_ARCH_MAX+0)
+#define OPT_REUSE_CMDLINE      (OPT_ARCH_MAX+1)
+#define OPT_MOD                (OPT_ARCH_MAX+2)
+#define OPT_VGA                (OPT_ARCH_MAX+3)
        static const struct option options[] = {
                KEXEC_ARCH_OPTIONS
                { "command-line",               1, 0, OPT_CL },
                { "append",                     1, 0, OPT_CL },
+               { "reuse-cmdline",              1, 0, OPT_REUSE_CMDLINE },
                { "module",                     1, 0, OPT_MOD },
                { 0,                            0, 0, 0 },
        };
@@ -194,6 +197,9 @@ int multiboot_x86_load(int argc, char **
                case OPT_CL:
                        command_line = optarg;
                        break;
+               case OPT_REUSE_CMDLINE:
+                       command_line = get_command_line();
+                       break;
                case OPT_MOD:
                        modules++;
                        mod_command_line_space += strlen(optarg) + 1;
--- a/kexec/arch/x86_64/kexec-elf-x86_64.c
+++ b/kexec/arch/x86_64/kexec-elf-x86_64.c
@@ -73,6 +73,7 @@ void elf_x86_64_usage(void)
 {
        printf( "    --command-line=STRING Set the kernel command line to 
STRING\n"
                "    --append=STRING       Set the kernel command line to 
STRING\n"
+               "    --reuse-cmdline       Use kernel command line from running 
system.\n"
                "    --initrd=FILE         Use FILE as the kernel's initial 
ramdisk.\n"
                "    --ramdisk=FILE        Use FILE as the kernel's initial 
ramdisk.\n"
                "    --args-linux          Pass linux kernel style options\n"
@@ -96,16 +97,18 @@ int elf_x86_64_load(int argc, char **arg
 #define ARG_STYLE_LINUX 1
 #define ARG_STYLE_NONE  2
        int opt;
-#define OPT_APPEND     (OPT_ARCH_MAX+0)
-#define OPT_RAMDISK    (OPT_ARCH_MAX+1)
-#define OPT_ARGS_ELF    (OPT_ARCH_MAX+2)
-#define OPT_ARGS_LINUX  (OPT_ARCH_MAX+3)
-#define OPT_ARGS_NONE   (OPT_ARCH_MAX+4)
+#define OPT_APPEND             (OPT_ARCH_MAX+0)
+#define OPT_REUSE_CMDLINE      (OPT_ARCH_MAX+1)
+#define OPT_RAMDISK            (OPT_ARCH_MAX+2)
+#define OPT_ARGS_ELF           (OPT_ARCH_MAX+3)
+#define OPT_ARGS_LINUX         (OPT_ARCH_MAX+4)
+#define OPT_ARGS_NONE          (OPT_ARCH_MAX+5)
 
        static const struct option options[] = {
                KEXEC_ARCH_OPTIONS
                { "command-line",       1, NULL, OPT_APPEND },
                { "append",             1, NULL, OPT_APPEND },
+               { "reuse-cmdline",      1, NULL, OPT_REUSE_CMDLINE },
                { "initrd",             1, NULL, OPT_RAMDISK },
                { "ramdisk",            1, NULL, OPT_RAMDISK },
                { "args-elf",           0, NULL, OPT_ARGS_ELF },
@@ -138,6 +141,9 @@ int elf_x86_64_load(int argc, char **arg
                case OPT_APPEND:
                        command_line = optarg;
                        break;
+               case OPT_REUSE_CMDLINE:
+                       command_line = get_command_line();
+                       break;
                case OPT_RAMDISK:
                        ramdisk = optarg;
                        break;
--- a/kexec/kexec.8
+++ b/kexec/kexec.8
@@ -186,6 +186,15 @@ to the kernel command line.
 Set the kernel command line to
 .IR string .
 .TP
+.BI \-\-reuse-cmdline
+Use the command line from the running system. When a panic kernel is loaded, it
+strips the
+.I
+crashkernel
+parameter automatically. The
+.I BOOT_IMAGE
+parameter is also stripped.
+.TP
 .BI \-\-initrd= file
 Use
 .I file
@@ -204,6 +213,15 @@ as the kernel's initial ramdisk.
 Set the kernel command line to
 .IR string .
 .TP
+.BI \-\-reuse-cmdline
+Use the command line from the running system. When a panic kernel is loaded, it
+strips the
+.I
+crashkernel
+parameter automatically. The
+.I BOOT_IMAGE
+parameter is also stripped.
+.TP
 .BI \-\-module= "mod arg1 arg2 ..."
 Load module
 .I mod
--- a/kexec/kexec.c
+++ b/kexec/kexec.c
@@ -31,6 +31,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <getopt.h>
+#include <ctype.h>
 
 #include "config.h"
 
@@ -46,6 +47,7 @@
 
 unsigned long long mem_min = 0;
 unsigned long long mem_max = ULONG_MAX;
+unsigned long kexec_flags = 0;
 
 void die(char *fmt, ...)
 {
@@ -792,26 +794,86 @@ static int kexec_loaded(void)
        return ret;
 }
 
+/*
+ * Remove parameter from a kernel command line. Helper function by 
get_command_line().
+ */
+static void remove_parameter(char *line, const char *param_name)
+{
+       char *start, *end;
+
+       start = strstr(line, param_name);
+
+       /* parameter not found */
+       if (!start)
+               return;
+
+       /*
+        * check if that's really the start of a parameter and not in
+        * the middle of the word
+        */
+       if (start != line && !isspace(*(start-1)))
+               return;
+
+       end = strstr(start, " ");
+       if (!end)
+               *start = 0;
+       else {
+               memmove(start, end+1, strlen(end));
+               *(end + strlen(end)) = 0;
+       }
+}
+
+/*
+ * Returns the contents of the current command line to be used with
+ * --reuse-cmdline option.  The function gets called from architecture specific
+ * code. If we load a panic kernel, that function will strip the
+ * "crashkernel=" option because it does not make sense that the crashkernel
+ * reserves memory for a crashkernel (well, it would not boot since the
+ * amount is exactly the same as the crashkernel has overall memory). Also,
+ * remove the BOOT_IMAGE from lilo (and others) since that doesn't make
+ * sense here any more. The kernel could be different even if we reuse the
+ * commandline.
+ *
+ * The function returns dynamically allocated memory.
+ */
+char *get_command_line(void)
+{
+       FILE *fp;
+       size_t len;
+       char *line = NULL;
+
+       fp = fopen("/proc/cmdline", "r");
+       if (!fp)
+               die("Could not read /proc/cmdline.");
+       getline(&line, &len, fp);
+       fclose(fp);
+
+       if (line) {
+               /* strip newline */
+               *(line + strlen(line) - 1) = 0;
+
+               remove_parameter(line, "crashkernel");
+               if (kexec_flags & KEXEC_ON_CRASH)
+                       remove_parameter(line, "BOOT_IMAGE");
+       } else
+               line = strdup("");
+
+       return line;
+}
+
 /* check we retained the initrd */
 void check_reuse_initrd(void)
 {
-       FILE * fp;
-       char * line = NULL;
-       size_t len = 0;
-       ssize_t read;
+       char *line = get_command_line();
 
-       fp = fopen("/proc/cmdline", "r");
-       if (fp == NULL)
-               die("unable to open /proc/cmdline\n");
-       read = getline(&line, &len, fp);
        if (strstr(line, "retain_initrd") == NULL)
                die("unrecoverable error: current boot didn't "
                    "retain the initrd for reuse.\n");
-       if (line)
-               free(line);
-       fclose(fp);
+
+       free(line);
 }
 
+
 int main(int argc, char *argv[])
 {
        int do_load = 1;
@@ -821,7 +883,6 @@ int main(int argc, char *argv[])
        int do_ifdown = 0;
        int do_unload = 0;
        int do_reuse_initrd = 0;
-       unsigned long kexec_flags = 0;
        char *type = 0;
        char *endptr;
        int opt;
--- a/kexec/kexec.h
+++ b/kexec/kexec.h
@@ -220,6 +220,7 @@ int arch_process_options(int argc, char
 int arch_compat_trampoline(struct kexec_info *info);
 void arch_update_purgatory(struct kexec_info *info);
 int is_crashkernel_mem_reserved(void);
+char *get_command_line(void);
 
 int kexec_iomem_for_each_line(char *match,
                              int (*callback)(void *data,

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

Reply via email to