[PATCH] Add --reuse-cmdline
Bernhard Walle
bwalle at suse.de
Thu May 8 16:49:43 EDT 2008
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 <bwalle at suse.de>
---
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,
More information about the kexec
mailing list