lkml.org 
[lkml]   [2007]   [Apr]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[RFC] [PATCH] Allow overriding module parameters from kernel command_line
    With the move to initramfs and heavily modular configs, which include
    loading storage drivers from early userspace, it's becoming harder
    to provide users with a way of overriding module parameters at boot.

    Currently, users would have to break into the initramfs, edit the
    modprobe options, and then let boot continue. They have a much easier time
    dealing with adding options on the command line from Grub or what have you.

    I hacked out this patch quickly to re-parse saved_command_line[] when we
    load a module in an attempt to rectify this.

    (The specific use-case I was looking at here was HPA commands failing on
    sata_nv controllers, and needing to pass the adma=0 option to the module...
    Users had a hard time testing without an easy way of overriding the module.)

    Clearly this is not entirely optimal, because we're parsing command_line
    after the module params are parsed. This ends of being a policy decision,
    whether the /sbin/modprobe commandline should override the kernel
    command_line, or vice versa.

    Anyway, please comment...

    Cheers,
    Kyle

    diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h
    index c83588c..e8465db 100644
    --- a/include/linux/moduleparam.h
    +++ b/include/linux/moduleparam.h
    @@ -98,7 +98,7 @@ struct kparam_array
    extern int parse_args(const char *name,
    char *args,
    struct kernel_param *params,
    - unsigned num,
    + unsigned num, unsigned strip_module,
    int (*unknown)(char *param, char *val));

    /* All the helper functions */
    diff --git a/init/main.c b/init/main.c
    index a92989e..a3d647f 100644
    --- a/init/main.c
    +++ b/init/main.c
    @@ -478,7 +478,7 @@ void __init parse_early_param(void)

    /* All fall through to do_early_param. */
    strlcpy(tmp_cmdline, boot_command_line, COMMAND_LINE_SIZE);
    - parse_args("early options", tmp_cmdline, NULL, 0, do_early_param);
    + parse_args("early options", tmp_cmdline, NULL, 0, 0, do_early_param);
    done = 1;
    }

    @@ -549,7 +549,7 @@ asmlinkage void __init start_kernel(void)
    printk(KERN_NOTICE "Kernel command line: %s\n", boot_command_line);
    parse_early_param();
    parse_args("Booting kernel", static_command_line, __start___param,
    - __stop___param - __start___param,
    + __stop___param - __start___param, 0,
    &unknown_bootoption);
    if (!irqs_disabled()) {
    printk(KERN_WARNING "start_kernel(): bug: interrupts were "
    diff --git a/kernel/module.c b/kernel/module.c
    index dcdb32b..e576242 100644
    --- a/kernel/module.c
    +++ b/kernel/module.c
    @@ -1914,10 +1914,21 @@ static struct module *load_module(void __user *umod,
    sechdrs[setupindex].sh_addr,
    sechdrs[setupindex].sh_size
    / sizeof(struct kernel_param),
    - NULL);
    + 0, NULL);
    if (err < 0)
    goto arch_cleanup;

    + /* Allow user to override module params from the command line. */
    + err = parse_args(mod->name, saved_command_line,
    + (struct kernel_param *)
    + sechdrs[setupindex].sh_addr,
    + sechdrs[setupindex].sh_size
    + / sizeof(struct kernel_param),
    + 1, NULL);
    + if (err < 0)
    + printk(KERN_WARNING "%s: Ignoring bad module parameters passed on "
    + "kernel command line\n", mod->name);
    +
    err = mod_sysfs_setup(mod,
    (struct kernel_param *)
    sechdrs[setupindex].sh_addr,
    diff --git a/kernel/params.c b/kernel/params.c
    index 1fc4ac7..7c9d3a0 100644
    --- a/kernel/params.c
    +++ b/kernel/params.c
    @@ -50,10 +50,17 @@ static int parse_one(char *param,
    char *val,
    struct kernel_param *params,
    unsigned num_params,
    - int (*handle_unknown)(char *param, char *val))
    + int (*handle_unknown)(char *param, char *val),
    + unsigned strip_module)
    {
    unsigned int i;

    + /* If we're parsing command_line[] for the module,
    + * strip off the module name before looking the param up.
    + */
    + if (strip_module)
    + strsep(&param, ".");
    +
    /* Find parameter */
    for (i = 0; i < num_params; i++) {
    if (parameq(param, params[i].name)) {
    @@ -130,7 +137,7 @@ static char *next_arg(char *args, char **param, char **val)
    int parse_args(const char *name,
    char *args,
    struct kernel_param *params,
    - unsigned num,
    + unsigned num, unsigned strip_module,
    int (*unknown)(char *param, char *val))
    {
    char *param, *val;
    @@ -147,7 +154,7 @@ int parse_args(const char *name,

    args = next_arg(args, &param, &val);
    irq_was_disabled = irqs_disabled();
    - ret = parse_one(param, val, params, num, unknown);
    + ret = parse_one(param, val, params, num, unknown, strip_module);
    if (irq_was_disabled && !irqs_disabled()) {
    printk(KERN_WARNING "parse_args(): option '%s' enabled "
    "irq's!\n", param);
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/
    \
     
     \ /
      Last update: 2007-04-18 18:01    [W:0.031 / U:0.652 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site