Hi,

v2 changes:
- Fixed ARM's multiline KEXEC_ALL_OPTIONS #define
- Removed opterr=0 from main()'s getopts_long() scan, and handle 
  unknown options in main() (as it now knows about all allowed opts).  
  Previously it relied on the file_type->load()er parsing & complaining
  about unknown options; if the loader didn't parse them, no complaint.

Tested on x86, ppc and compile-tested on my new crisv32-axis-linux-gnu
crosscompiler :-)


Cheers,


Matt


---
The argument parsing is currently a bit broken as main()'s getopt_long()
knows nothing about either the architecture-specific options or, even
more specifically, the architecture-and-loader-specific options.

This patch introduces new #defines for all architectures,
KEXEC_ALL_OPTIONS and KEXEC_ALL_OPT_STR.  These contain all possible
options for a given build, and the getopt_long() passes in main() and
arch_process_options() will now recognise arch- and loader-specific
options; these will not be re-ordered in argv[], there is no confusion
over which argv[] entry is the kernel filename, and using '--opt=foo' and
'--opt foo' both work.

All architectures have command line options (and #define OPT_BLAHs)
consolidated into their include/arch/option.h files.  x86_64 builds
parts of i386/ as well, so now both share a single option.h file (with
a symlink).

Signed-off-by: Matt Evans <[email protected]>
---
 kexec/arch/alpha/include/arch/options.h  |    9 +++++
 kexec/arch/arm/include/arch/options.h    |   29 +++++++++++++++++
 kexec/arch/arm/kexec-zImage-arm.c        |    3 +-
 kexec/arch/cris/include/arch/options.h   |   32 ++++++++++++++++--
 kexec/arch/cris/kexec-elf-cris.c         |    4 +-
 kexec/arch/i386/include/arch/options.h   |   51 ++++++++++++++++++++++++++++++
 kexec/arch/i386/kexec-beoboot-x86.c      |    3 +-
 kexec/arch/i386/kexec-bzImage.c          |    6 +--
 kexec/arch/i386/kexec-elf-x86.c          |    7 +---
 kexec/arch/i386/kexec-multiboot-x86.c    |    5 +--
 kexec/arch/i386/kexec-x86.c              |    4 +-
 kexec/arch/ia64/include/arch/options.h   |   33 ++++++++++++++++++-
 kexec/arch/ia64/kexec-elf-ia64.c         |    7 +---
 kexec/arch/mips/include/arch/options.h   |   27 +++++++++++++++-
 kexec/arch/mips/kexec-elf-mips.c         |    3 +-
 kexec/arch/ppc/include/arch/options.h    |   34 ++++++++++++++++++++
 kexec/arch/ppc/kexec-dol-ppc.c           |    4 +-
 kexec/arch/ppc/kexec-elf-ppc.c           |    7 +---
 kexec/arch/ppc/kexec-uImage-ppc.c        |    6 +--
 kexec/arch/ppc64/include/arch/options.h  |   37 ++++++++++++++++++++-
 kexec/arch/ppc64/kexec-elf-ppc64.c       |   12 ++++---
 kexec/arch/ppc64/kexec-ppc64.c           |   12 +++----
 kexec/arch/s390/include/arch/options.h   |   28 ++++++++++++++++-
 kexec/arch/s390/kexec-image.c            |    4 +--
 kexec/arch/sh/include/arch/options.h     |   26 +++++++++++++--
 kexec/arch/sh/kexec-sh.c                 |    7 +++-
 kexec/arch/x86_64/include/arch/options.h |   23 +-------------
 kexec/arch/x86_64/kexec-elf-x86_64.c     |    7 +---
 kexec/arch/x86_64/kexec-x86_64.c         |    4 +-
 kexec/kexec.c                            |    6 ++--
 30 files changed, 341 insertions(+), 99 deletions(-)
 mode change 100644 => 120000 kexec/arch/x86_64/include/arch/options.h

diff --git a/kexec/arch/alpha/include/arch/options.h 
b/kexec/arch/alpha/include/arch/options.h
index 11557a4..a012c8a 100644
--- a/kexec/arch/alpha/include/arch/options.h
+++ b/kexec/arch/alpha/include/arch/options.h
@@ -3,9 +3,18 @@
 
 #define OPT_ARCH_MAX   (OPT_MAX+0)
 
+/* Options relevant to the architecture (excluding loader-specific ones),
+ * in this case none:
+ */
 #define KEXEC_ARCH_OPTIONS \
        KEXEC_OPTIONS \
 
 #define KEXEC_ARCH_OPT_STR KEXEC_OPT_STR ""
 
+/* See the other architectures for details of these; Alpha has no
+ * loader-specific options yet.
+ */
+#define KEXEC_ALL_OPTIONS KEXEC_ARCH_OPTIONS
+#define KEXEC_ALL_OPT_STR KEXEC_ARCH_OPT_STR
+
 #endif /* KEXEC_ARCH_ALPHA_OPTIONS_H */
diff --git a/kexec/arch/arm/include/arch/options.h 
b/kexec/arch/arm/include/arch/options.h
index 248230b..d89c91f 100644
--- a/kexec/arch/arm/include/arch/options.h
+++ b/kexec/arch/arm/include/arch/options.h
@@ -3,9 +3,38 @@
 
 #define OPT_ARCH_MAX   (OPT_MAX+0)
 
+#define OPT_APPEND     'a'
+#define OPT_RAMDISK    'r'
+
+/* Options relevant to the architecture (excluding loader-specific ones),
+ * in this case none:
+ */
 #define KEXEC_ARCH_OPTIONS \
        KEXEC_OPTIONS \
 
 #define KEXEC_ARCH_OPT_STR KEXEC_OPT_STR ""
 
+/* The following two #defines list ALL of the options added by all of the
+ * architecture's loaders.
+ * o   main() uses this complete list to scan for its options, ignoring
+ *     arch-specific/loader-specific ones.
+ * o   Then, arch_process_options() uses this complete list to scan for its
+ *     options, ignoring general/loader-specific ones.
+ * o   Then, the file_type[n].load re-scans for options, using
+ *     KEXEC_ARCH_OPTIONS plus its loader-specific options subset.
+ *     Any unrecognised options cause an error here.
+ *
+ * This is done so that main()'s/arch_process_options()'s getopt_long() calls
+ * don't choose a kernel filename from random arguments to options they don't
+ * recognise -- as they now recognise (if not act upon) all possible options.
+ */
+#define KEXEC_ALL_OPTIONS                              \
+       KEXEC_ARCH_OPTIONS                              \
+       { "command-line",       1, 0, OPT_APPEND },     \
+       { "append",             1, 0, OPT_APPEND },     \
+       { "initrd",             1, 0, OPT_RAMDISK },    \
+       { "ramdisk",            1, 0, OPT_RAMDISK },
+
+#define KEXEC_ALL_OPT_STR KEXEC_ARCH_OPT_STR "a:r:"
+
 #endif /* KEXEC_ARCH_ARM_OPTIONS_H */
diff --git a/kexec/arch/arm/kexec-zImage-arm.c 
b/kexec/arch/arm/kexec-zImage-arm.c
index 1a446d9..e060f6e 100644
--- a/kexec/arch/arm/kexec-zImage-arm.c
+++ b/kexec/arch/arm/kexec-zImage-arm.c
@@ -219,8 +219,7 @@ int zImage_arm_load(int argc, char **argv, const char *buf, 
off_t len,
        off_t ramdisk_length;
        off_t ramdisk_offset;
        int opt;
-#define OPT_APPEND     'a'
-#define OPT_RAMDISK    'r'
+       /* See options.h -- add any more there, too. */
        static const struct option options[] = {
                KEXEC_ARCH_OPTIONS
                { "command-line",       1, 0, OPT_APPEND },
diff --git a/kexec/arch/cris/include/arch/options.h 
b/kexec/arch/cris/include/arch/options.h
index bc5f706..1c1a029 100644
--- a/kexec/arch/cris/include/arch/options.h
+++ b/kexec/arch/cris/include/arch/options.h
@@ -1,11 +1,35 @@
-#ifndef KEXEC_ARCH_MIPS_OPTIONS_H
-#define KEXEC_ARCH_MIPS_OPTIONS_H
+#ifndef KEXEC_ARCH_CRIS_OPTIONS_H
+#define KEXEC_ARCH_CRIS_OPTIONS_H
 
-#define OPT_ARCH_MAX   (OPT_MAX+0)
+#define OPT_ARCH_MAX   (OPT_MAX+0)
+#define OPT_APPEND     (OPT_ARCH_MAX+0)
 
+/* Options relevant to the architecture (excluding loader-specific ones),
+ * in this case none:
+ */
 #define KEXEC_ARCH_OPTIONS \
        KEXEC_OPTIONS \
 
 #define KEXEC_ARCH_OPT_STR KEXEC_OPT_STR ""
 
-#endif /* KEXEC_ARCH_MIPS_OPTIONS_H */
+/* The following two #defines list ALL of the options added by all of the
+ * architecture's loaders.
+ * o   main() uses this complete list to scan for its options, ignoring
+ *     arch-specific/loader-specific ones.
+ * o   Then, arch_process_options() uses this complete list to scan for its
+ *     options, ignoring general/loader-specific ones.
+ * o   Then, the file_type[n].load re-scans for options, using
+ *     KEXEC_ARCH_OPTIONS plus its loader-specific options subset.
+ *     Any unrecognised options cause an error here.
+ *
+ * This is done so that main()'s/arch_process_options()'s getopt_long() calls
+ * don't choose a kernel filename from random arguments to options they don't
+ * recognise -- as they now recognise (if not act upon) all possible options.
+ */
+#define KEXEC_ALL_OPTIONS \
+       KEXEC_ARCH_OPTIONS \
+       {"append", 1, 0, OPT_APPEND},
+
+#define KEXEC_ALL_OPT_STR KEXEC_ARCH_OPT_STR
+
+#endif /* KEXEC_ARCH_CRIS_OPTIONS_H */
diff --git a/kexec/arch/cris/kexec-elf-cris.c b/kexec/arch/cris/kexec-elf-cris.c
index 4b56a20..b48b7b3 100644
--- a/kexec/arch/cris/kexec-elf-cris.c
+++ b/kexec/arch/cris/kexec-elf-cris.c
@@ -40,8 +40,6 @@
 #include <arch/options.h>
 #include "kexec-cris.h"
 
-#define OPT_APPEND      (OPT_ARCH_MAX+0)
-
 int elf_cris_probe(const char *buf, off_t len)
 {
        struct mem_ehdr ehdr;
@@ -89,8 +87,10 @@ int elf_cris_load(int argc, char **argv, const char *buf, 
off_t len,
                unsigned int regs[16];
        } cris_regframe;
 
+       /* See options.h -- add any more there, too. */
        static const struct option options[] = {
                KEXEC_ARCH_OPTIONS
+               {"append", 1, 0, OPT_APPEND},
                { 0, 0, 0, 0 },
        };
 
diff --git a/kexec/arch/i386/include/arch/options.h 
b/kexec/arch/i386/include/arch/options.h
index 0695f37..990527c 100644
--- a/kexec/arch/i386/include/arch/options.h
+++ b/kexec/arch/i386/include/arch/options.h
@@ -1,6 +1,15 @@
 #ifndef KEXEC_ARCH_I386_OPTIONS_H
 #define KEXEC_ARCH_I386_OPTIONS_H
 
+/*
+ *************************************************************************
+ * NOTE NOTE NOTE
+ * This file is included for i386 builds *and* x86_64 builds (which build
+ * both x86_64 and i386 loaders).
+ * It contains the combined set of options used by i386 and x86_64.
+ *************************************************************************
+ */
+
 #define OPT_RESET_VGA      (OPT_MAX+0)
 #define OPT_SERIAL         (OPT_MAX+1)
 #define OPT_SERIAL_BAUD    (OPT_MAX+2)
@@ -10,6 +19,18 @@
 #define OPT_ELF64_CORE     (OPT_MAX+6)
 #define OPT_ARCH_MAX       (OPT_MAX+7)
 
+#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)
+#define OPT_CL                 (OPT_ARCH_MAX+6)
+#define OPT_MOD                (OPT_ARCH_MAX+7)
+#define OPT_VGA                (OPT_ARCH_MAX+8)
+#define OPT_REAL_MODE          (OPT_ARCH_MAX+9)
+
+/* Options relevant to the architecture (excluding loader-specific ones): */
 #define KEXEC_ARCH_OPTIONS \
        KEXEC_OPTIONS \
        { "reset-vga",      0, 0, OPT_RESET_VGA }, \
@@ -22,5 +43,35 @@
 
 #define KEXEC_ARCH_OPT_STR KEXEC_OPT_STR ""
 
+/* The following two #defines list ALL of the options added by all of the
+ * architecture's loaders.
+ * o   main() uses this complete list to scan for its options, ignoring
+ *     arch-specific/loader-specific ones.
+ * o   Then, arch_process_options() uses this complete list to scan for its
+ *     options, ignoring general/loader-specific ones.
+ * o   Then, the file_type[n].load re-scans for options, using
+ *     KEXEC_ARCH_OPTIONS plus its loader-specific options subset.
+ *     Any unrecognised options cause an error here.
+ *
+ * This is done so that main()'s/arch_process_options()'s getopt_long() calls
+ * don't choose a kernel filename from random arguments to options they don't
+ * recognise -- as they now recognise (if not act upon) all possible options.
+ */
+#define KEXEC_ALL_OPTIONS \
+       KEXEC_ARCH_OPTIONS \
+       { "command-line",       1, NULL, OPT_APPEND },          \
+       { "append",             1, NULL, OPT_APPEND },          \
+       { "reuse-cmdline",      0, NULL, OPT_REUSE_CMDLINE },   \
+       { "initrd",             1, NULL, OPT_RAMDISK },         \
+       { "ramdisk",            1, NULL, OPT_RAMDISK },         \
+       { "args-elf",           0, NULL, OPT_ARGS_ELF },        \
+       { "args-linux",         0, NULL, OPT_ARGS_LINUX },      \
+       { "args-none",          0, NULL, OPT_ARGS_NONE },       \
+       { "debug",              0, NULL, OPT_DEBUG },           \
+       { "module",             1, 0, OPT_MOD },                \
+       { "real-mode",          0, NULL, OPT_REAL_MODE },
+
+#define KEXEC_ALL_OPT_STR KEXEC_ARCH_OPT_STR
+
 #endif /* KEXEC_ARCH_I386_OPTIONS_H */
 
diff --git a/kexec/arch/i386/kexec-beoboot-x86.c 
b/kexec/arch/i386/kexec-beoboot-x86.c
index 27c5a2c..6d459ae 100644
--- a/kexec/arch/i386/kexec-beoboot-x86.c
+++ b/kexec/arch/i386/kexec-beoboot-x86.c
@@ -84,7 +84,8 @@ int beoboot_load(int argc, char **argv, const char *buf, 
off_t UNUSED(len),
        int debug, real_mode_entry;
        int opt;
        int result;
-#define OPT_REAL_MODE  (OPT_ARCH_MAX+0)
+
+       /* See options.h -- add any more there, too. */
        static const struct option options[] = {
                KEXEC_ARCH_OPTIONS
                { "debug",              0, 0, OPT_DEBUG },
diff --git a/kexec/arch/i386/kexec-bzImage.c b/kexec/arch/i386/kexec-bzImage.c
index 53a50b3..ae18689 100644
--- a/kexec/arch/i386/kexec-bzImage.c
+++ b/kexec/arch/i386/kexec-bzImage.c
@@ -341,10 +341,8 @@ int bzImage_load(int argc, char **argv, const char *buf, 
off_t len,
        int debug, real_mode_entry;
        int opt;
        int result;
-#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)
+
+       /* See options.h -- add any more there, too. */
        static const struct option options[] = {
                KEXEC_ARCH_OPTIONS
                { "debug",              0, 0, OPT_DEBUG },
diff --git a/kexec/arch/i386/kexec-elf-x86.c b/kexec/arch/i386/kexec-elf-x86.c
index 2cb9d11..2e9cf9a 100644
--- a/kexec/arch/i386/kexec-elf-x86.c
+++ b/kexec/arch/i386/kexec-elf-x86.c
@@ -99,13 +99,8 @@ int elf_x86_load(int argc, char **argv, const char *buf, 
off_t len,
 #define ARG_STYLE_LINUX 1
 #define ARG_STYLE_NONE  2
        int opt;
-#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)
 
+       /* See options.h -- add any more there, too. */
        static const struct option options[] = {
                KEXEC_ARCH_OPTIONS
                { "command-line",       1, NULL, OPT_APPEND },
diff --git a/kexec/arch/i386/kexec-multiboot-x86.c 
b/kexec/arch/i386/kexec-multiboot-x86.c
index 970de2a..23dab7b 100644
--- a/kexec/arch/i386/kexec-multiboot-x86.c
+++ b/kexec/arch/i386/kexec-multiboot-x86.c
@@ -157,10 +157,7 @@ int multiboot_x86_load(int argc, char **argv, const char 
*buf, off_t len,
        uint32_t u;
        int opt;
        int modules, mod_command_line_space;
-#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)
+       /* See options.h -- add any more there, too. */
        static const struct option options[] = {
                KEXEC_ARCH_OPTIONS
                { "command-line",               1, 0, OPT_CL },
diff --git a/kexec/arch/i386/kexec-x86.c b/kexec/arch/i386/kexec-x86.c
index d33a14b..5c701aa 100644
--- a/kexec/arch/i386/kexec-x86.c
+++ b/kexec/arch/i386/kexec-x86.c
@@ -69,10 +69,10 @@ struct arch_options_t arch_options = {
 int arch_process_options(int argc, char **argv)
 {
        static const struct option options[] = {
-               KEXEC_ARCH_OPTIONS
+               KEXEC_ALL_OPTIONS
                { 0,                    0, NULL, 0 },
        };
-       static const char short_options[] = KEXEC_ARCH_OPT_STR;
+       static const char short_options[] = KEXEC_ALL_OPT_STR;
        int opt;
        unsigned long value;
        char *end;
diff --git a/kexec/arch/ia64/include/arch/options.h 
b/kexec/arch/ia64/include/arch/options.h
index 3053576..e8754ad 100644
--- a/kexec/arch/ia64/include/arch/options.h
+++ b/kexec/arch/ia64/include/arch/options.h
@@ -1,11 +1,42 @@
 #ifndef KEXEC_ARCH_IA64_OPTIONS_H
 #define KEXEC_ARCH_IA64_OPTIONS_H
 
-#define OPT_ARCH_MAX   (OPT_MAX+0)
+#define OPT_ARCH_MAX   (OPT_MAX+0)
+#define OPT_APPEND     (OPT_ARCH_MAX+0)
+#define OPT_RAMDISK    (OPT_ARCH_MAX+1)
+#define OPT_NOIO       (OPT_ARCH_MAX+2)
+#define OPT_VMM                (OPT_ARCH_MAX+3)
 
+/* Options relevant to the architecture (excluding loader-specific ones),
+ * in this case none:
+ */
 #define KEXEC_ARCH_OPTIONS \
        KEXEC_OPTIONS \
 
 #define KEXEC_ARCH_OPT_STR KEXEC_OPT_STR ""
 
+/* The following two #defines list ALL of the options added by all of the
+ * architecture's loaders.
+ * o   main() uses this complete list to scan for its options, ignoring
+ *     arch-specific/loader-specific ones.
+ * o   Then, arch_process_options() uses this complete list to scan for its
+ *     options, ignoring general/loader-specific ones.
+ * o   Then, the file_type[n].load re-scans for options, using
+ *     KEXEC_ARCH_OPTIONS plus its loader-specific options subset.
+ *     Any unrecognised options cause an error here.
+ *
+ * This is done so that main()'s/arch_process_options()'s getopt_long() calls
+ * don't choose a kernel filename from random arguments to options they don't
+ * recognise -- as they now recognise (if not act upon) all possible options.
+ */
+#define KEXEC_ALL_OPTIONS                      \
+       KEXEC_ARCH_OPTIONS                      \
+       {"command-line", 1, 0, OPT_APPEND},     \
+       {"append",       1, 0, OPT_APPEND},     \
+       {"initrd",       1, 0, OPT_RAMDISK},    \
+       {"noio",         0, 0, OPT_NOIO},       \
+       {"vmm",          1, 0, OPT_VMM},        \
+
+#define KEXEC_ALL_OPT_STR KEXEC_OPT_STR
+
 #endif /* KEXEC_ARCH_IA64_OPTIONS_H */
diff --git a/kexec/arch/ia64/kexec-elf-ia64.c b/kexec/arch/ia64/kexec-elf-ia64.c
index 3bb5a4d..8da061e 100644
--- a/kexec/arch/ia64/kexec-elf-ia64.c
+++ b/kexec/arch/ia64/kexec-elf-ia64.c
@@ -45,11 +45,6 @@
 #include "crashdump-ia64.h"
 #include <arch/options.h>
 
-#define OPT_APPEND     (OPT_ARCH_MAX+0)
-#define OPT_RAMDISK    (OPT_ARCH_MAX+1)
-#define OPT_NOIO       (OPT_ARCH_MAX+2)
-#define OPT_VMM                (OPT_ARCH_MAX+3)
-
 static const int probe_debug = 0;
 extern unsigned long saved_efi_memmap_size;
 
@@ -136,6 +131,8 @@ int elf_ia64_load(int argc, char **argv, const char *buf, 
off_t len,
        int result;
        int opt;
        char *efi_memmap_buf, *boot_param;
+
+       /* See options.h -- add any more there, too. */
        static const struct option options[] = {
                KEXEC_ARCH_OPTIONS
                {"command-line", 1, 0, OPT_APPEND},
diff --git a/kexec/arch/mips/include/arch/options.h 
b/kexec/arch/mips/include/arch/options.h
index bc5f706..07b4f63 100644
--- a/kexec/arch/mips/include/arch/options.h
+++ b/kexec/arch/mips/include/arch/options.h
@@ -1,11 +1,36 @@
 #ifndef KEXEC_ARCH_MIPS_OPTIONS_H
 #define KEXEC_ARCH_MIPS_OPTIONS_H
 
-#define OPT_ARCH_MAX   (OPT_MAX+0)
+#define OPT_ARCH_MAX   (OPT_MAX+0)
+#define OPT_APPEND     (OPT_ARCH_MAX+0)
 
+/* Options relevant to the architecture (excluding loader-specific ones),
+ * in this case none:
+ */
 #define KEXEC_ARCH_OPTIONS \
        KEXEC_OPTIONS \
 
 #define KEXEC_ARCH_OPT_STR KEXEC_OPT_STR ""
 
+/* The following two #defines list ALL of the options added by all of the
+ * architecture's loaders.
+ * o   main() uses this complete list to scan for its options, ignoring
+ *     arch-specific/loader-specific ones.
+ * o   Then, arch_process_options() uses this complete list to scan for its
+ *     options, ignoring general/loader-specific ones.
+ * o   Then, the file_type[n].load re-scans for options, using
+ *     KEXEC_ARCH_OPTIONS plus its loader-specific options subset.
+ *     Any unrecognised options cause an error here.
+ *
+ * This is done so that main()'s/arch_process_options()'s getopt_long() calls
+ * don't choose a kernel filename from random arguments to options they don't
+ * recognise -- as they now recognise (if not act upon) all possible options.
+ */
+#define KEXEC_ALL_OPTIONS                      \
+       KEXEC_ARCH_OPTIONS                      \
+       {"command-line", 1, 0, OPT_APPEND},     \
+       {"append",       1, 0, OPT_APPEND},
+
+#define KEXEC_ALL_OPT_STR KEXEC_ARCH_OPT_STR
+
 #endif /* KEXEC_ARCH_MIPS_OPTIONS_H */
diff --git a/kexec/arch/mips/kexec-elf-mips.c b/kexec/arch/mips/kexec-elf-mips.c
index ce6bf0c..a9c865e 100644
--- a/kexec/arch/mips/kexec-elf-mips.c
+++ b/kexec/arch/mips/kexec-elf-mips.c
@@ -35,7 +35,6 @@ static const int probe_debug = 0;
 #define BOOTLOADER         "kexec"
 #define MAX_COMMAND_LINE   256
 #define UPSZ(X) ((sizeof(X) + 3) & ~3)
-#define OPT_APPEND     (OPT_ARCH_MAX+0)
 static char cmdline_buf[256] = "kexec ";
 
 int elf_mips_probe(const char *buf, off_t len)
@@ -82,6 +81,8 @@ int elf_mips_load(int argc, char **argv, const char *buf, 
off_t len,
        unsigned long cmdline_addr;
        size_t i;
        unsigned long bss_start = 0, bss_size = 0;
+
+       /* See options.h if adding any more options. */
        static const struct option options[] = {
                KEXEC_ARCH_OPTIONS
                {"command-line", 1, 0, OPT_APPEND},
diff --git a/kexec/arch/ppc/include/arch/options.h 
b/kexec/arch/ppc/include/arch/options.h
index df14db5..f646ccc 100644
--- a/kexec/arch/ppc/include/arch/options.h
+++ b/kexec/arch/ppc/include/arch/options.h
@@ -3,9 +3,43 @@
 
 #define OPT_ARCH_MAX   (OPT_MAX+0)
 
+/* All 'local' loader options: */
+#define OPT_APPEND      (OPT_ARCH_MAX+0)
+#define OPT_GAMECUBE    (OPT_ARCH_MAX+1)
+#define OPT_DTB         (OPT_ARCH_MAX+2)
+#define OPT_NODES       (OPT_ARCH_MAX+3)
+
+/* Options relevant to the architecture (excluding loader-specific ones),
+ * in this case none:
+ */
 #define KEXEC_ARCH_OPTIONS \
        KEXEC_OPTIONS \
 
 #define KEXEC_ARCH_OPT_STR KEXEC_OPT_STR ""
 
+/* The following two #defines list ALL of the options added by all of the
+ * architecture's loaders.
+ * o   main() uses this complete list to scan for its options, ignoring
+ *     arch-specific/loader-specific ones.
+ * o   Then, arch_process_options() uses this complete list to scan for its
+ *     options, ignoring general/loader-specific ones.
+ * o   Then, the file_type[n].load re-scans for options, using
+ *     KEXEC_ARCH_OPTIONS plus its loader-specific options subset.
+ *     Any unrecognised options cause an error here.
+ *
+ * This is done so that main()'s/arch_process_options()'s getopt_long() calls
+ * don't choose a kernel filename from random arguments to options they don't
+ * recognise -- as they now recognise (if not act upon) all possible options.
+ */
+#define KEXEC_ALL_OPTIONS \
+       KEXEC_ARCH_OPTIONS \
+       {"command-line", 1, 0, OPT_APPEND},\
+       {"append",       1, 0, OPT_APPEND},\
+       {"gamecube",     1, 0, OPT_GAMECUBE},\
+       {"dtb",     1, 0, OPT_DTB},\
+       {"reuse-node",     1, 0, OPT_NODES},\
+       {"debug",        0, 0, OPT_DEBUG},
+
+#define KEXEC_ALL_OPT_STR KEXEC_OPT_STR
+
 #endif /* KEXEC_ARCH_PPC_OPTIONS_H */
diff --git a/kexec/arch/ppc/kexec-dol-ppc.c b/kexec/arch/ppc/kexec-dol-ppc.c
index 83c122a..8de5293 100644
--- a/kexec/arch/ppc/kexec-dol-ppc.c
+++ b/kexec/arch/ppc/kexec-dol-ppc.c
@@ -335,8 +335,8 @@ int dol_ppc_load(int argc, char **argv, const char *buf, 
off_t UNUSED(len),
        unsigned long lowest_start;
        int i, j, k;
        int opt;
-#define OPT_APPEND      (OPT_ARCH_MAX+0)
 
+       /* See options.h -- add any more there, too. */
         static const struct option options[] = {
                 KEXEC_ARCH_OPTIONS
                 {"debug",        0, 0, OPT_DEBUG},
@@ -344,7 +344,7 @@ int dol_ppc_load(int argc, char **argv, const char *buf, 
off_t UNUSED(len),
                 {"append",       1, 0, OPT_APPEND},
                 {0, 0, 0, 0},
         };
-       static const char short_options[] = KEXEC_ARCH_OPT_STR "d";
+       static const char short_options[] = KEXEC_ARCH_OPT_STR;
 
        /*
         * Parse the command line arguments
diff --git a/kexec/arch/ppc/kexec-elf-ppc.c b/kexec/arch/ppc/kexec-elf-ppc.c
index a54a5d5..cb2c07a 100644
--- a/kexec/arch/ppc/kexec-elf-ppc.c
+++ b/kexec/arch/ppc/kexec-elf-ppc.c
@@ -113,10 +113,7 @@ static void gamecube_hack_addresses(struct mem_ehdr *ehdr)
        }
 }
 
-#define OPT_APPEND     (OPT_ARCH_MAX+0)
-#define OPT_GAMECUBE   (OPT_ARCH_MAX+1)
-#define OPT_DTB                (OPT_ARCH_MAX+2)
-#define OPT_NODES      (OPT_ARCH_MAX+3)
+/* See options.h -- add any more there, too. */
 static const struct option options[] = {
        KEXEC_ARCH_OPTIONS
        {"command-line", 1, 0, OPT_APPEND},
@@ -126,7 +123,7 @@ static const struct option options[] = {
        {"reuse-node",     1, 0, OPT_NODES},
        {0, 0, 0, 0},
 };
-static const char short_options[] = KEXEC_ARCH_OPT_STR "d";
+static const char short_options[] = KEXEC_ARCH_OPT_STR;
 
 void elf_ppc_usage(void)
 {
diff --git a/kexec/arch/ppc/kexec-uImage-ppc.c 
b/kexec/arch/ppc/kexec-uImage-ppc.c
index 0a655a3..45cde2f 100644
--- a/kexec/arch/ppc/kexec-uImage-ppc.c
+++ b/kexec/arch/ppc/kexec-uImage-ppc.c
@@ -14,9 +14,7 @@
 #include "fixup_dtb.h"
 #include <kexec-uImage.h>
 
-#define OPT_APPEND      (OPT_ARCH_MAX+0)
-#define OPT_DTB         (OPT_ARCH_MAX+1)
-#define OPT_NODES       (OPT_ARCH_MAX+2)
+/* See options.h -- add any more there, too. */
 static const struct option options[] = {
        KEXEC_ARCH_OPTIONS
        {"command-line",        1, 0, OPT_APPEND},
@@ -25,7 +23,7 @@ static const struct option options[] = {
        {"reuse-node",  1, 0, OPT_NODES},
        {0, 0, 0, 0},
 };
-static const char short_options[] = KEXEC_ARCH_OPT_STR "d";
+static const char short_options[] = KEXEC_ARCH_OPT_STR;
 
 void uImage_ppc_usage(void)
 {
diff --git a/kexec/arch/ppc64/include/arch/options.h 
b/kexec/arch/ppc64/include/arch/options.h
index 973cd4f..8f11c83 100644
--- a/kexec/arch/ppc64/include/arch/options.h
+++ b/kexec/arch/ppc64/include/arch/options.h
@@ -1,13 +1,46 @@
 #ifndef KEXEC_ARCH_PPC64_OPTIONS_H
 #define KEXEC_ARCH_PPC64_OPTIONS_H
 
-#define OPT_ARCH_MAX   (OPT_MAX+0)
-#define OPT_ELF64_CORE  (OPT_MAX+1)
+#define OPT_ELF64_CORE         (OPT_MAX+0)
+#define OPT_ARCH_MAX           (OPT_MAX+1)
 
+/* All 'local' loader options: */
+#define OPT_APPEND             (OPT_ARCH_MAX+0)
+#define OPT_RAMDISK            (OPT_ARCH_MAX+1)
+#define OPT_DEVICETREEBLOB     (OPT_ARCH_MAX+2)
+#define OPT_ARGS_IGNORE                (OPT_ARCH_MAX+3)
+
+/* Options relevant to the architecture (excluding loader-specific ones): */
 #define KEXEC_ARCH_OPTIONS \
        KEXEC_OPTIONS \
        { "elf64-core-headers", 0, 0, OPT_ELF64_CORE }, \
 
 #define KEXEC_ARCH_OPT_STR KEXEC_OPT_STR ""
 
+/* The following two #defines list ALL of the options added by all of the
+ * architecture's loaders.
+ * o   main() uses this complete list to scan for its options, ignoring
+ *     arch-specific/loader-specific ones.
+ * o   Then, arch_process_options() uses this complete list to scan for its
+ *     options, ignoring general/loader-specific ones.
+ * o   Then, the file_type[n].load re-scans for options, using
+ *     KEXEC_ARCH_OPTIONS plus its loader-specific options subset.
+ *     Any unrecognised options cause an error here.
+ *
+ * This is done so that main()'s/arch_process_options()'s getopt_long() calls
+ * don't choose a kernel filename from random arguments to options they don't
+ * recognise -- as they now recognise (if not act upon) all possible options.
+ */
+#define KEXEC_ALL_OPTIONS \
+       KEXEC_ARCH_OPTIONS                              \
+       { "command-line",       1, NULL, OPT_APPEND },  \
+       { "append",             1, NULL, OPT_APPEND },  \
+       { "ramdisk",            1, NULL, OPT_RAMDISK }, \
+       { "initrd",             1, NULL, OPT_RAMDISK },         \
+       { "devicetreeblob",     1, NULL, OPT_DEVICETREEBLOB },  \
+       { "args-linux",         0, NULL, OPT_ARGS_IGNORE },
+
+#define KEXEC_ALL_OPT_STR KEXEC_OPT_STR
+
+
 #endif /* KEXEC_ARCH_PPC64_OPTIONS_H */
diff --git a/kexec/arch/ppc64/kexec-elf-ppc64.c 
b/kexec/arch/ppc64/kexec-elf-ppc64.c
index d65a5d5..ab6da7c 100644
--- a/kexec/arch/ppc64/kexec-elf-ppc64.c
+++ b/kexec/arch/ppc64/kexec-elf-ppc64.c
@@ -93,11 +93,7 @@ int elf_ppc64_load(int argc, char **argv, const char *buf, 
off_t len,
        uint32_t my_run_at_load;
        unsigned int slave_code[256/sizeof (unsigned int)], master_entry;
 
-#define OPT_APPEND     (OPT_ARCH_MAX+0)
-#define OPT_RAMDISK     (OPT_ARCH_MAX+1)
-#define OPT_DEVICETREEBLOB     (OPT_ARCH_MAX+2)
-#define OPT_ARGS_IGNORE                (OPT_ARCH_MAX+3)
-
+       /* See options.h -- add any more there, too. */
        static const struct option options[] = {
                KEXEC_ARCH_OPTIONS
                { "command-line",       1, NULL, OPT_APPEND },
@@ -347,5 +343,11 @@ int elf_ppc64_load(int argc, char **argv, const char *buf, 
off_t len,
 
 void elf_ppc64_usage(void)
 {
+       fprintf(stderr, "     --command-line=<Command line> command line to 
append.\n");
+       fprintf(stderr, "     --append=<Command line> same as 
--command-line.\n");
+       fprintf(stderr, "     --ramdisk=<filename> Initial RAM disk.\n");
+       fprintf(stderr, "     --initrd=<filename> same as --ramdisk.\n");
+       fprintf(stderr, "     --devicetreeblob=<filename> Specify device tree 
blob file.\n");
+
        fprintf(stderr, "elf support is still broken\n");
 }
diff --git a/kexec/arch/ppc64/kexec-ppc64.c b/kexec/arch/ppc64/kexec-ppc64.c
index f9dc65b..48ea421 100644
--- a/kexec/arch/ppc64/kexec-ppc64.c
+++ b/kexec/arch/ppc64/kexec-ppc64.c
@@ -735,11 +735,6 @@ int file_types = sizeof(file_type) / sizeof(file_type[0]);
 
 void arch_usage(void)
 {
-       fprintf(stderr, "     --command-line=<Command line> command line to 
append.\n");
-       fprintf(stderr, "     --append=<Command line> same as 
--command-line.\n");
-       fprintf(stderr, "     --ramdisk=<filename> Initial RAM disk.\n");
-       fprintf(stderr, "     --initrd=<filename> same as --ramdisk.\n");
-       fprintf(stderr, "     --devicetreeblob=<filename> Specify device tree 
blob file.\n");
        fprintf(stderr, "     --elf64-core-headers Prepare core headers in 
ELF64 format\n");
 }
 
@@ -749,11 +744,14 @@ struct arch_options_t arch_options = {
 
 int arch_process_options(int argc, char **argv)
 {
+       /* We look for all options so getopt_long doesn't start reordering
+        * argv[] before file_type[n].load() gets a look in.
+        */
        static const struct option options[] = {
-               KEXEC_ARCH_OPTIONS
+               KEXEC_ALL_OPTIONS
                { 0, 0, NULL, 0 },
        };
-       static const char short_options[] = KEXEC_ARCH_OPT_STR;
+       static const char short_options[] = KEXEC_ALL_OPT_STR;
        int opt;
 
        opterr = 0; /* Don't complain about unrecognized options here */
diff --git a/kexec/arch/s390/include/arch/options.h 
b/kexec/arch/s390/include/arch/options.h
index 2979617..b57539f 100644
--- a/kexec/arch/s390/include/arch/options.h
+++ b/kexec/arch/s390/include/arch/options.h
@@ -1,11 +1,37 @@
 #ifndef KEXEC_ARCH_S390_OPTIONS_H
 #define KEXEC_ARCH_S390_OPTIONS_H
 
-#define OPT_ARCH_MAX   (OPT_MAX+0)
+#define OPT_ARCH_MAX   (OPT_MAX+0)
+#define OPT_APPEND     OPT_MAX+0
+#define OPT_RAMDISK    OPT_MAX+1
 
+/* Options relevant to the architecture (excluding loader-specific ones),
+ * in this case none:
+ */
 #define KEXEC_ARCH_OPTIONS \
        KEXEC_OPTIONS \
 
 #define KEXEC_ARCH_OPT_STR KEXEC_OPT_STR ""
 
+/* The following two #defines list ALL of the options added by all of the
+ * architecture's loaders.
+ * o   main() uses this complete list to scan for its options, ignoring
+ *     arch-specific/loader-specific ones.
+ * o   Then, arch_process_options() uses this complete list to scan for its
+ *     options, ignoring general/loader-specific ones.
+ * o   Then, the file_type[n].load re-scans for options, using
+ *     KEXEC_ARCH_OPTIONS plus its loader-specific options subset.
+ *     Any unrecognised options cause an error here.
+ *
+ * This is done so that main()'s/arch_process_options()'s getopt_long() calls
+ * don't choose a kernel filename from random arguments to options they don't
+ * recognise -- as they now recognise (if not act upon) all possible options.
+ */
+#define KEXEC_ALL_OPTIONS                              \
+       KEXEC_ARCH_OPTIONS                              \
+       {"command-line",     1, 0, OPT_APPEND},         \
+       {"initrd",           1, 0, OPT_RAMDISK},
+
+#define KEXEC_ALL_OPT_STR KEXEC_ARCH_OPT_STR
+
 #endif /* KEXEC_ARCH_S390_OPTIONS_H */
diff --git a/kexec/arch/s390/kexec-image.c b/kexec/arch/s390/kexec-image.c
index 13e550d..7ef8e29 100644
--- a/kexec/arch/s390/kexec-image.c
+++ b/kexec/arch/s390/kexec-image.c
@@ -19,9 +19,7 @@
 #include <getopt.h>
 #include "../../kexec.h"
 #include "kexec-s390.h"
-
-#define OPT_APPEND     OPT_MAX+0
-#define OPT_RAMDISK    OPT_MAX+1
+#include <arch/options.h>
 
 int
 image_s390_load(int argc, char **argv, const char *kernel_buf,
diff --git a/kexec/arch/sh/include/arch/options.h 
b/kexec/arch/sh/include/arch/options.h
index e02960d..4bdd6a3 100644
--- a/kexec/arch/sh/include/arch/options.h
+++ b/kexec/arch/sh/include/arch/options.h
@@ -7,16 +7,36 @@
 #define OPT_NBSD_HOWTO   (OPT_ARCH_MAX+3)
 #define OPT_NBSD_MROOT   (OPT_ARCH_MAX+4)
 
-
+/* Options relevant to the architecture (excluding loader-specific ones): */
 #define KEXEC_ARCH_OPTIONS \
        KEXEC_OPTIONS \
         {"command-line",   1, 0, OPT_APPEND}, \
         {"append",         1, 0, OPT_APPEND}, \
         {"empty-zero",     1, 0, OPT_APPEND}, \
         {"howto",          1, 0, OPT_NBSD_HOWTO}, \
-        {"miniroot",       1, 0, OPT_NBSD_MROOT}, \
-
+        {"miniroot",       1, 0, OPT_NBSD_MROOT},
+/* These options seem to be loader-specific rather than cris-specific, so
+ * ought to be moved to KEXEC_ALL_OPTIONS below and parsed in the relevant 
+ * loader, e.g. kexec-netbsd-sh.c
+ */
 
 #define KEXEC_ARCH_OPT_STR KEXEC_OPT_STR ""
 
+/* The following two #defines list ALL of the options added by all of the
+ * architecture's loaders.
+ * o   main() uses this complete list to scan for its options, ignoring
+ *     arch-specific/loader-specific ones.
+ * o   Then, arch_process_options() uses this complete list to scan for its
+ *     options, ignoring general/loader-specific ones.
+ * o   Then, the file_type[n].load re-scans for options, using
+ *     KEXEC_ARCH_OPTIONS plus its loader-specific options subset.
+ *     Any unrecognised options cause an error here.
+ *
+ * This is done so that main()'s/arch_process_options()'s getopt_long() calls
+ * don't choose a kernel filename from random arguments to options they don't
+ * recognise -- as they now recognise (if not act upon) all possible options.
+ */
+#define KEXEC_ALL_OPTIONS KEXEC_ARCH_OPTIONS
+#define KEXEC_ALL_OPT_STR KEXEC_ARCH_OPT_STR
+
 #endif /* KEXEC_ARCH_SH_OPTIONS_H */
diff --git a/kexec/arch/sh/kexec-sh.c b/kexec/arch/sh/kexec-sh.c
index 1ad3d38..4b21ee8 100644
--- a/kexec/arch/sh/kexec-sh.c
+++ b/kexec/arch/sh/kexec-sh.c
@@ -97,8 +97,13 @@ void arch_usage(void)
 
 int arch_process_options(int argc, char **argv)
 {
+       /* The common options amongst loaders (e.g. --append) should be read
+        * here, and the loader-specific options (e.g. NetBSD stuff) should
+        * then be re-parsed in the loader.
+        * (e.g. in kexec-netbsd-sh.c, for example.)
+        */
        static const struct option options[] = {
-               KEXEC_ARCH_OPTIONS
+               KEXEC_ALL_OPTIONS
                { 0,                    0, NULL, 0 },
        };
        static const char short_options[] = KEXEC_ARCH_OPT_STR;
diff --git a/kexec/arch/x86_64/include/arch/options.h 
b/kexec/arch/x86_64/include/arch/options.h
deleted file mode 100644
index 75065b9..0000000
--- a/kexec/arch/x86_64/include/arch/options.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef KEXEC_ARCH_X86_64_OPTIONS_H
-#define KEXEC_ARCH_X86_64_OPTIONS_H
-
-#define OPT_RESET_VGA      (OPT_MAX+0)
-#define OPT_SERIAL         (OPT_MAX+1)
-#define OPT_SERIAL_BAUD    (OPT_MAX+2)
-#define OPT_CONSOLE_VGA    (OPT_MAX+3)
-#define OPT_CONSOLE_SERIAL (OPT_MAX+4)
-#define OPT_ARCH_MAX       (OPT_MAX+5)
-
-#define KEXEC_ARCH_OPTIONS \
-       KEXEC_OPTIONS \
-       { "reset-vga",      0, 0, OPT_RESET_VGA }, \
-       { "serial",         1, 0, OPT_SERIAL }, \
-       { "serial-baud",    1, 0, OPT_SERIAL_BAUD }, \
-       { "console-vga",    0, 0, OPT_CONSOLE_VGA }, \
-       { "console-serial", 0, 0, OPT_CONSOLE_SERIAL }, \
-
-#define KEXEC_ARCH_OPT_STR KEXEC_OPT_STR ""
-
-#endif /* KEXEC_ARCH_X86_64_OPTIONS_H */
-
diff --git a/kexec/arch/x86_64/include/arch/options.h 
b/kexec/arch/x86_64/include/arch/options.h
new file mode 120000
index 0000000..047b0f9
--- /dev/null
+++ b/kexec/arch/x86_64/include/arch/options.h
@@ -0,0 +1 @@
+../../../i386/include/arch/options.h
\ No newline at end of file
diff --git a/kexec/arch/x86_64/kexec-elf-x86_64.c 
b/kexec/arch/x86_64/kexec-elf-x86_64.c
index 20c7d77..a8204bc 100644
--- a/kexec/arch/x86_64/kexec-elf-x86_64.c
+++ b/kexec/arch/x86_64/kexec-elf-x86_64.c
@@ -98,13 +98,8 @@ int elf_x86_64_load(int argc, char **argv, const char *buf, 
off_t len,
 #define ARG_STYLE_LINUX 1
 #define ARG_STYLE_NONE  2
        int opt;
-#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)
 
+       /* See options.h and add any new options there too! */
        static const struct option options[] = {
                KEXEC_ARCH_OPTIONS
                { "command-line",       1, NULL, OPT_APPEND },
diff --git a/kexec/arch/x86_64/kexec-x86_64.c b/kexec/arch/x86_64/kexec-x86_64.c
index 49bfd36..a4f2d10 100644
--- a/kexec/arch/x86_64/kexec-x86_64.c
+++ b/kexec/arch/x86_64/kexec-x86_64.c
@@ -74,10 +74,10 @@ static struct {
 int arch_process_options(int argc, char **argv)
 {
        static const struct option options[] = {
-               KEXEC_ARCH_OPTIONS
+               KEXEC_ALL_OPTIONS
                { 0,                    0, NULL, 0 },
        };
-       static const char short_options[] = KEXEC_ARCH_OPT_STR;
+       static const char short_options[] = KEXEC_ALL_OPT_STR;
        int opt;
        unsigned long value;
        char *end;
diff --git a/kexec/kexec.c b/kexec/kexec.c
index e9a13a7..2d8258f 100644
--- a/kexec/kexec.c
+++ b/kexec/kexec.c
@@ -1062,17 +1062,17 @@ int main(int argc, char *argv[])
        int result = 0;
        int fileind;
        static const struct option options[] = {
-               KEXEC_ARCH_OPTIONS
+               KEXEC_ALL_OPTIONS
                { 0, 0, 0, 0},
        };
-       static const char short_options[] = KEXEC_OPT_STR;
+       static const char short_options[] = KEXEC_ALL_OPT_STR;
 
        arch_init();
 
-       opterr = 0; /* Don't complain about unrecognized options here */
        while ((opt = getopt_long(argc, argv, short_options,
                                  options, 0)) != -1) {
                switch(opt) {
+               case '?':
                case OPT_HELP:
                        usage();
                        return 0;
-- 
1.6.3.3


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

Reply via email to