linux/kernel/params.c
<<
>>
Prefs
   1/* Helpers for initial module or kernel cmdline parsing
   2   Copyright (C) 2001 Rusty Russell.
   3
   4    This program is free software; you can redistribute it and/or modify
   5    it under the terms of the GNU General Public License as published by
   6    the Free Software Foundation; either version 2 of the License, or
   7    (at your option) any later version.
   8
   9    This program is distributed in the hope that it will be useful,
  10    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12    GNU General Public License for more details.
  13
  14    You should have received a copy of the GNU General Public License
  15    along with this program; if not, write to the Free Software
  16    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  17*/
  18#include <linux/moduleparam.h>
  19#include <linux/kernel.h>
  20#include <linux/string.h>
  21#include <linux/errno.h>
  22#include <linux/module.h>
  23#include <linux/device.h>
  24#include <linux/err.h>
  25#include <linux/slab.h>
  26#include <linux/ctype.h>
  27
  28#if 0
  29#define DEBUGP printk
  30#else
  31#define DEBUGP(fmt, a...)
  32#endif
  33
  34/* Protects all parameters, and incidentally kmalloced_param list. */
  35static DEFINE_MUTEX(param_lock);
  36
  37/* This just allows us to keep track of which parameters are kmalloced. */
  38struct kmalloced_param {
  39        struct list_head list;
  40        char val[];
  41};
  42static LIST_HEAD(kmalloced_params);
  43
  44static void *kmalloc_parameter(unsigned int size)
  45{
  46        struct kmalloced_param *p;
  47
  48        p = kmalloc(sizeof(*p) + size, GFP_KERNEL);
  49        if (!p)
  50                return NULL;
  51
  52        list_add(&p->list, &kmalloced_params);
  53        return p->val;
  54}
  55
  56/* Does nothing if parameter wasn't kmalloced above. */
  57static void maybe_kfree_parameter(void *param)
  58{
  59        struct kmalloced_param *p;
  60
  61        list_for_each_entry(p, &kmalloced_params, list) {
  62                if (p->val == param) {
  63                        list_del(&p->list);
  64                        kfree(p);
  65                        break;
  66                }
  67        }
  68}
  69
  70static inline char dash2underscore(char c)
  71{
  72        if (c == '-')
  73                return '_';
  74        return c;
  75}
  76
  77static inline int parameq(const char *input, const char *paramname)
  78{
  79        unsigned int i;
  80        for (i = 0; dash2underscore(input[i]) == paramname[i]; i++)
  81                if (input[i] == '\0')
  82                        return 1;
  83        return 0;
  84}
  85
  86static int parse_one(char *param,
  87                     char *val,
  88                     const struct kernel_param *params,
  89                     unsigned num_params,
  90                     int (*handle_unknown)(char *param, char *val))
  91{
  92        unsigned int i;
  93        int err;
  94
  95        /* Find parameter */
  96        for (i = 0; i < num_params; i++) {
  97                if (parameq(param, params[i].name)) {
  98                        /* Noone handled NULL, so do it here. */
  99                        if (!val && params[i].ops->set != param_set_bool)
 100                                return -EINVAL;
 101                        DEBUGP("They are equal!  Calling %p\n",
 102                               params[i].ops->set);
 103                        mutex_lock(&param_lock);
 104                        err = params[i].ops->set(val, &params[i]);
 105                        mutex_unlock(&param_lock);
 106                        return err;
 107                }
 108        }
 109
 110        if (handle_unknown) {
 111                DEBUGP("Unknown argument: calling %p\n", handle_unknown);
 112                return handle_unknown(param, val);
 113        }
 114
 115        DEBUGP("Unknown argument `%s'\n", param);
 116        return -ENOENT;
 117}
 118
 119/* You can use " around spaces, but can't escape ". */
 120/* Hyphens and underscores equivalent in parameter names. */
 121static char *next_arg(char *args, char **param, char **val)
 122{
 123        unsigned int i, equals = 0;
 124        int in_quote = 0, quoted = 0;
 125        char *next;
 126
 127        if (*args == '"') {
 128                args++;
 129                in_quote = 1;
 130                quoted = 1;
 131        }
 132
 133        for (i = 0; args[i]; i++) {
 134                if (isspace(args[i]) && !in_quote)
 135                        break;
 136                if (equals == 0) {
 137                        if (args[i] == '=')
 138                                equals = i;
 139                }
 140                if (args[i] == '"')
 141                        in_quote = !in_quote;
 142        }
 143
 144        *param = args;
 145        if (!equals)
 146                *val = NULL;
 147        else {
 148                args[equals] = '\0';
 149                *val = args + equals + 1;
 150
 151                /* Don't include quotes in value. */
 152                if (**val == '"') {
 153                        (*val)++;
 154                        if (args[i-1] == '"')
 155                                args[i-1] = '\0';
 156                }
 157                if (quoted && args[i-1] == '"')
 158                        args[i-1] = '\0';
 159        }
 160
 161        if (args[i]) {
 162                args[i] = '\0';
 163                next = args + i + 1;
 164        } else
 165                next = args + i;
 166
 167        /* Chew up trailing spaces. */
 168        return skip_spaces(next);
 169}
 170
 171/* Args looks like "foo=bar,bar2 baz=fuz wiz". */
 172int parse_args(const char *name,
 173               char *args,
 174               const struct kernel_param *params,
 175               unsigned num,
 176               int (*unknown)(char *param, char *val))
 177{
 178        char *param, *val;
 179
 180        DEBUGP("Parsing ARGS: %s\n", args);
 181
 182        /* Chew leading spaces */
 183        args = skip_spaces(args);
 184
 185        while (*args) {
 186                int ret;
 187                int irq_was_disabled;
 188
 189                args = next_arg(args, &param, &val);
 190                irq_was_disabled = irqs_disabled();
 191                ret = parse_one(param, val, params, num, unknown);
 192                if (irq_was_disabled && !irqs_disabled()) {
 193                        printk(KERN_WARNING "parse_args(): option '%s' enabled "
 194                                        "irq's!\n", param);
 195                }
 196                switch (ret) {
 197                case -ENOENT:
 198                        printk(KERN_ERR "%s: Unknown parameter `%s'\n",
 199                               name, param);
 200                        return ret;
 201                case -ENOSPC:
 202                        printk(KERN_ERR
 203                               "%s: `%s' too large for parameter `%s'\n",
 204                               name, val ?: "", param);
 205                        return ret;
 206                case 0:
 207                        break;
 208                default:
 209                        printk(KERN_ERR
 210                               "%s: `%s' invalid for parameter `%s'\n",
 211                               name, val ?: "", param);
 212                        return ret;
 213                }
 214        }
 215
 216        /* All parsed OK. */
 217        return 0;
 218}
 219
 220/* Lazy bastard, eh? */
 221#define STANDARD_PARAM_DEF(name, type, format, tmptype, strtolfn)       \
 222        int param_set_##name(const char *val, const struct kernel_param *kp) \
 223        {                                                               \
 224                tmptype l;                                              \
 225                int ret;                                                \
 226                                                                        \
 227                ret = strtolfn(val, 0, &l);                             \
 228                if (ret == -EINVAL || ((type)l != l))                   \
 229                        return -EINVAL;                                 \
 230                *((type *)kp->arg) = l;                                 \
 231                return 0;                                               \
 232        }                                                               \
 233        int param_get_##name(char *buffer, const struct kernel_param *kp) \
 234        {                                                               \
 235                return sprintf(buffer, format, *((type *)kp->arg));     \
 236        }                                                               \
 237        struct kernel_param_ops param_ops_##name = {                    \
 238                .set = param_set_##name,                                \
 239                .get = param_get_##name,                                \
 240        };                                                              \
 241        EXPORT_SYMBOL(param_set_##name);                                \
 242        EXPORT_SYMBOL(param_get_##name);                                \
 243        EXPORT_SYMBOL(param_ops_##name)
 244
 245
 246STANDARD_PARAM_DEF(byte, unsigned char, "%c", unsigned long, strict_strtoul);
 247STANDARD_PARAM_DEF(short, short, "%hi", long, strict_strtol);
 248STANDARD_PARAM_DEF(ushort, unsigned short, "%hu", unsigned long, strict_strtoul);
 249STANDARD_PARAM_DEF(int, int, "%i", long, strict_strtol);
 250STANDARD_PARAM_DEF(uint, unsigned int, "%u", unsigned long, strict_strtoul);
 251STANDARD_PARAM_DEF(long, long, "%li", long, strict_strtol);
 252STANDARD_PARAM_DEF(ulong, unsigned long, "%lu", unsigned long, strict_strtoul);
 253
 254int param_set_charp(const char *val, const struct kernel_param *kp)
 255{
 256        if (strlen(val) > 1024) {
 257                printk(KERN_ERR "%s: string parameter too long\n",
 258                       kp->name);
 259                return -ENOSPC;
 260        }
 261
 262        maybe_kfree_parameter(*(char **)kp->arg);
 263
 264        /* This is a hack.  We can't kmalloc in early boot, and we
 265         * don't need to; this mangled commandline is preserved. */
 266        if (slab_is_available()) {
 267                *(char **)kp->arg = kmalloc_parameter(strlen(val)+1);
 268                if (!*(char **)kp->arg)
 269                        return -ENOMEM;
 270                strcpy(*(char **)kp->arg, val);
 271        } else
 272                *(const char **)kp->arg = val;
 273
 274        return 0;
 275}
 276EXPORT_SYMBOL(param_set_charp);
 277
 278int param_get_charp(char *buffer, const struct kernel_param *kp)
 279{
 280        return sprintf(buffer, "%s", *((char **)kp->arg));
 281}
 282EXPORT_SYMBOL(param_get_charp);
 283
 284static void param_free_charp(void *arg)
 285{
 286        maybe_kfree_parameter(*((char **)arg));
 287}
 288
 289struct kernel_param_ops param_ops_charp = {
 290        .set = param_set_charp,
 291        .get = param_get_charp,
 292        .free = param_free_charp,
 293};
 294EXPORT_SYMBOL(param_ops_charp);
 295
 296/* Actually could be a bool or an int, for historical reasons. */
 297int param_set_bool(const char *val, const struct kernel_param *kp)
 298{
 299        bool v;
 300
 301        /* No equals means "set"... */
 302        if (!val) val = "1";
 303
 304        /* One of =[yYnN01] */
 305        switch (val[0]) {
 306        case 'y': case 'Y': case '1':
 307                v = true;
 308                break;
 309        case 'n': case 'N': case '0':
 310                v = false;
 311                break;
 312        default:
 313                return -EINVAL;
 314        }
 315
 316        if (kp->flags & KPARAM_ISBOOL)
 317                *(bool *)kp->arg = v;
 318        else
 319                *(int *)kp->arg = v;
 320        return 0;
 321}
 322EXPORT_SYMBOL(param_set_bool);
 323
 324int param_get_bool(char *buffer, const struct kernel_param *kp)
 325{
 326        bool val;
 327        if (kp->flags & KPARAM_ISBOOL)
 328                val = *(bool *)kp->arg;
 329        else
 330                val = *(int *)kp->arg;
 331
 332        /* Y and N chosen as being relatively non-coder friendly */
 333        return sprintf(buffer, "%c", val ? 'Y' : 'N');
 334}
 335EXPORT_SYMBOL(param_get_bool);
 336
 337struct kernel_param_ops param_ops_bool = {
 338        .set = param_set_bool,
 339        .get = param_get_bool,
 340};
 341EXPORT_SYMBOL(param_ops_bool);
 342
 343/* This one must be bool. */
 344int param_set_invbool(const char *val, const struct kernel_param *kp)
 345{
 346        int ret;
 347        bool boolval;
 348        struct kernel_param dummy;
 349
 350        dummy.arg = &boolval;
 351        dummy.flags = KPARAM_ISBOOL;
 352        ret = param_set_bool(val, &dummy);
 353        if (ret == 0)
 354                *(bool *)kp->arg = !boolval;
 355        return ret;
 356}
 357EXPORT_SYMBOL(param_set_invbool);
 358
 359int param_get_invbool(char *buffer, const struct kernel_param *kp)
 360{
 361        return sprintf(buffer, "%c", (*(bool *)kp->arg) ? 'N' : 'Y');
 362}
 363EXPORT_SYMBOL(param_get_invbool);
 364
 365struct kernel_param_ops param_ops_invbool = {
 366        .set = param_set_invbool,
 367        .get = param_get_invbool,
 368};
 369EXPORT_SYMBOL(param_ops_invbool);
 370
 371/* We break the rule and mangle the string. */
 372static int param_array(const char *name,
 373                       const char *val,
 374                       unsigned int min, unsigned int max,
 375                       void *elem, int elemsize,
 376                       int (*set)(const char *, const struct kernel_param *kp),
 377                       u16 flags,
 378                       unsigned int *num)
 379{
 380        int ret;
 381        struct kernel_param kp;
 382        char save;
 383
 384        /* Get the name right for errors. */
 385        kp.name = name;
 386        kp.arg = elem;
 387        kp.flags = flags;
 388
 389        *num = 0;
 390        /* We expect a comma-separated list of values. */
 391        do {
 392                int len;
 393
 394                if (*num == max) {
 395                        printk(KERN_ERR "%s: can only take %i arguments\n",
 396                               name, max);
 397                        return -EINVAL;
 398                }
 399                len = strcspn(val, ",");
 400
 401                /* nul-terminate and parse */
 402                save = val[len];
 403                ((char *)val)[len] = '\0';
 404                BUG_ON(!mutex_is_locked(&param_lock));
 405                ret = set(val, &kp);
 406
 407                if (ret != 0)
 408                        return ret;
 409                kp.arg += elemsize;
 410                val += len+1;
 411                (*num)++;
 412        } while (save == ',');
 413
 414        if (*num < min) {
 415                printk(KERN_ERR "%s: needs at least %i arguments\n",
 416                       name, min);
 417                return -EINVAL;
 418        }
 419        return 0;
 420}
 421
 422static int param_array_set(const char *val, const struct kernel_param *kp)
 423{
 424        const struct kparam_array *arr = kp->arr;
 425        unsigned int temp_num;
 426
 427        return param_array(kp->name, val, 1, arr->max, arr->elem,
 428                           arr->elemsize, arr->ops->set, kp->flags,
 429                           arr->num ?: &temp_num);
 430}
 431
 432static int param_array_get(char *buffer, const struct kernel_param *kp)
 433{
 434        int i, off, ret;
 435        const struct kparam_array *arr = kp->arr;
 436        struct kernel_param p;
 437
 438        p = *kp;
 439        for (i = off = 0; i < (arr->num ? *arr->num : arr->max); i++) {
 440                if (i)
 441                        buffer[off++] = ',';
 442                p.arg = arr->elem + arr->elemsize * i;
 443                BUG_ON(!mutex_is_locked(&param_lock));
 444                ret = arr->ops->get(buffer + off, &p);
 445                if (ret < 0)
 446                        return ret;
 447                off += ret;
 448        }
 449        buffer[off] = '\0';
 450        return off;
 451}
 452
 453static void param_array_free(void *arg)
 454{
 455        unsigned int i;
 456        const struct kparam_array *arr = arg;
 457
 458        if (arr->ops->free)
 459                for (i = 0; i < (arr->num ? *arr->num : arr->max); i++)
 460                        arr->ops->free(arr->elem + arr->elemsize * i);
 461}
 462
 463struct kernel_param_ops param_array_ops = {
 464        .set = param_array_set,
 465        .get = param_array_get,
 466        .free = param_array_free,
 467};
 468EXPORT_SYMBOL(param_array_ops);
 469
 470int param_set_copystring(const char *val, const struct kernel_param *kp)
 471{
 472        const struct kparam_string *kps = kp->str;
 473
 474        if (strlen(val)+1 > kps->maxlen) {
 475                printk(KERN_ERR "%s: string doesn't fit in %u chars.\n",
 476                       kp->name, kps->maxlen-1);
 477                return -ENOSPC;
 478        }
 479        strcpy(kps->string, val);
 480        return 0;
 481}
 482EXPORT_SYMBOL(param_set_copystring);
 483
 484int param_get_string(char *buffer, const struct kernel_param *kp)
 485{
 486        const struct kparam_string *kps = kp->str;
 487        return strlcpy(buffer, kps->string, kps->maxlen);
 488}
 489EXPORT_SYMBOL(param_get_string);
 490
 491struct kernel_param_ops param_ops_string = {
 492        .set = param_set_copystring,
 493        .get = param_get_string,
 494};
 495EXPORT_SYMBOL(param_ops_string);
 496
 497/* sysfs output in /sys/modules/XYZ/parameters/ */
 498#define to_module_attr(n) container_of(n, struct module_attribute, attr)
 499#define to_module_kobject(n) container_of(n, struct module_kobject, kobj)
 500
 501extern struct kernel_param __start___param[], __stop___param[];
 502
 503struct param_attribute
 504{
 505        struct module_attribute mattr;
 506        const struct kernel_param *param;
 507};
 508
 509struct module_param_attrs
 510{
 511        unsigned int num;
 512        struct attribute_group grp;
 513        struct param_attribute attrs[0];
 514};
 515
 516#ifdef CONFIG_SYSFS
 517#define to_param_attr(n) container_of(n, struct param_attribute, mattr)
 518
 519static ssize_t param_attr_show(struct module_attribute *mattr,
 520                               struct module *mod, char *buf)
 521{
 522        int count;
 523        struct param_attribute *attribute = to_param_attr(mattr);
 524
 525        if (!attribute->param->ops->get)
 526                return -EPERM;
 527
 528        mutex_lock(&param_lock);
 529        count = attribute->param->ops->get(buf, attribute->param);
 530        mutex_unlock(&param_lock);
 531        if (count > 0) {
 532                strcat(buf, "\n");
 533                ++count;
 534        }
 535        return count;
 536}
 537
 538/* sysfs always hands a nul-terminated string in buf.  We rely on that. */
 539static ssize_t param_attr_store(struct module_attribute *mattr,
 540                                struct module *owner,
 541                                const char *buf, size_t len)
 542{
 543        int err;
 544        struct param_attribute *attribute = to_param_attr(mattr);
 545
 546        if (!attribute->param->ops->set)
 547                return -EPERM;
 548
 549        mutex_lock(&param_lock);
 550        err = attribute->param->ops->set(buf, attribute->param);
 551        mutex_unlock(&param_lock);
 552        if (!err)
 553                return len;
 554        return err;
 555}
 556#endif
 557
 558#ifdef CONFIG_MODULES
 559#define __modinit
 560#else
 561#define __modinit __init
 562#endif
 563
 564#ifdef CONFIG_SYSFS
 565void __kernel_param_lock(void)
 566{
 567        mutex_lock(&param_lock);
 568}
 569EXPORT_SYMBOL(__kernel_param_lock);
 570
 571void __kernel_param_unlock(void)
 572{
 573        mutex_unlock(&param_lock);
 574}
 575EXPORT_SYMBOL(__kernel_param_unlock);
 576
 577/*
 578 * add_sysfs_param - add a parameter to sysfs
 579 * @mk: struct module_kobject
 580 * @kparam: the actual parameter definition to add to sysfs
 581 * @name: name of parameter
 582 *
 583 * Create a kobject if for a (per-module) parameter if mp NULL, and
 584 * create file in sysfs.  Returns an error on out of memory.  Always cleans up
 585 * if there's an error.
 586 */
 587static __modinit int add_sysfs_param(struct module_kobject *mk,
 588                                     const struct kernel_param *kp,
 589                                     const char *name)
 590{
 591        struct module_param_attrs *new;
 592        struct attribute **attrs;
 593        int err, num;
 594
 595        /* We don't bother calling this with invisible parameters. */
 596        BUG_ON(!kp->perm);
 597
 598        if (!mk->mp) {
 599                num = 0;
 600                attrs = NULL;
 601        } else {
 602                num = mk->mp->num;
 603                attrs = mk->mp->grp.attrs;
 604        }
 605
 606        /* Enlarge. */
 607        new = krealloc(mk->mp,
 608                       sizeof(*mk->mp) + sizeof(mk->mp->attrs[0]) * (num+1),
 609                       GFP_KERNEL);
 610        if (!new) {
 611                kfree(mk->mp);
 612                err = -ENOMEM;
 613                goto fail;
 614        }
 615        attrs = krealloc(attrs, sizeof(new->grp.attrs[0])*(num+2), GFP_KERNEL);
 616        if (!attrs) {
 617                err = -ENOMEM;
 618                goto fail_free_new;
 619        }
 620
 621        /* Sysfs wants everything zeroed. */
 622        memset(new, 0, sizeof(*new));
 623        memset(&new->attrs[num], 0, sizeof(new->attrs[num]));
 624        memset(&attrs[num], 0, sizeof(attrs[num]));
 625        new->grp.name = "parameters";
 626        new->grp.attrs = attrs;
 627
 628        /* Tack new one on the end. */
 629        sysfs_attr_init(&new->attrs[num].mattr.attr);
 630        new->attrs[num].param = kp;
 631        new->attrs[num].mattr.show = param_attr_show;
 632        new->attrs[num].mattr.store = param_attr_store;
 633        new->attrs[num].mattr.attr.name = (char *)name;
 634        new->attrs[num].mattr.attr.mode = kp->perm;
 635        new->num = num+1;
 636
 637        /* Fix up all the pointers, since krealloc can move us */
 638        for (num = 0; num < new->num; num++)
 639                new->grp.attrs[num] = &new->attrs[num].mattr.attr;
 640        new->grp.attrs[num] = NULL;
 641
 642        mk->mp = new;
 643        return 0;
 644
 645fail_free_new:
 646        kfree(new);
 647fail:
 648        mk->mp = NULL;
 649        return err;
 650}
 651
 652#ifdef CONFIG_MODULES
 653static void free_module_param_attrs(struct module_kobject *mk)
 654{
 655        kfree(mk->mp->grp.attrs);
 656        kfree(mk->mp);
 657        mk->mp = NULL;
 658}
 659
 660/*
 661 * module_param_sysfs_setup - setup sysfs support for one module
 662 * @mod: module
 663 * @kparam: module parameters (array)
 664 * @num_params: number of module parameters
 665 *
 666 * Adds sysfs entries for module parameters under
 667 * /sys/module/[mod->name]/parameters/
 668 */
 669int module_param_sysfs_setup(struct module *mod,
 670                             const struct kernel_param *kparam,
 671                             unsigned int num_params)
 672{
 673        int i, err;
 674        bool params = false;
 675
 676        for (i = 0; i < num_params; i++) {
 677                if (kparam[i].perm == 0)
 678                        continue;
 679                err = add_sysfs_param(&mod->mkobj, &kparam[i], kparam[i].name);
 680                if (err)
 681                        return err;
 682                params = true;
 683        }
 684
 685        if (!params)
 686                return 0;
 687
 688        /* Create the param group. */
 689        err = sysfs_create_group(&mod->mkobj.kobj, &mod->mkobj.mp->grp);
 690        if (err)
 691                free_module_param_attrs(&mod->mkobj);
 692        return err;
 693}
 694
 695/*
 696 * module_param_sysfs_remove - remove sysfs support for one module
 697 * @mod: module
 698 *
 699 * Remove sysfs entries for module parameters and the corresponding
 700 * kobject.
 701 */
 702void module_param_sysfs_remove(struct module *mod)
 703{
 704        if (mod->mkobj.mp) {
 705                sysfs_remove_group(&mod->mkobj.kobj, &mod->mkobj.mp->grp);
 706                /* We are positive that no one is using any param
 707                 * attrs at this point.  Deallocate immediately. */
 708                free_module_param_attrs(&mod->mkobj);
 709        }
 710}
 711#endif
 712
 713void destroy_params(const struct kernel_param *params, unsigned num)
 714{
 715        unsigned int i;
 716
 717        for (i = 0; i < num; i++)
 718                if (params[i].ops->free)
 719                        params[i].ops->free(params[i].arg);
 720}
 721
 722static struct module_kobject * __init locate_module_kobject(const char *name)
 723{
 724        struct module_kobject *mk;
 725        struct kobject *kobj;
 726        int err;
 727
 728        kobj = kset_find_obj(module_kset, name);
 729        if (kobj) {
 730                mk = to_module_kobject(kobj);
 731        } else {
 732                mk = kzalloc(sizeof(struct module_kobject), GFP_KERNEL);
 733                BUG_ON(!mk);
 734
 735                mk->mod = THIS_MODULE;
 736                mk->kobj.kset = module_kset;
 737                err = kobject_init_and_add(&mk->kobj, &module_ktype, NULL,
 738                                           "%s", name);
 739                if (err) {
 740                        kobject_put(&mk->kobj);
 741                        printk(KERN_ERR
 742                                "Module '%s' failed add to sysfs, error number %d\n",
 743                                name, err);
 744                        printk(KERN_ERR
 745                                "The system will be unstable now.\n");
 746                        return NULL;
 747                }
 748
 749                /* So that we hold reference in both cases. */
 750                kobject_get(&mk->kobj);
 751        }
 752
 753        return mk;
 754}
 755
 756static void __init kernel_add_sysfs_param(const char *name,
 757                                          struct kernel_param *kparam,
 758                                          unsigned int name_skip)
 759{
 760        struct module_kobject *mk;
 761        int err;
 762
 763        mk = locate_module_kobject(name);
 764        if (!mk)
 765                return;
 766
 767        /* We need to remove old parameters before adding more. */
 768        if (mk->mp)
 769                sysfs_remove_group(&mk->kobj, &mk->mp->grp);
 770
 771        /* These should not fail at boot. */
 772        err = add_sysfs_param(mk, kparam, kparam->name + name_skip);
 773        BUG_ON(err);
 774        err = sysfs_create_group(&mk->kobj, &mk->mp->grp);
 775        BUG_ON(err);
 776        kobject_uevent(&mk->kobj, KOBJ_ADD);
 777        kobject_put(&mk->kobj);
 778}
 779
 780/*
 781 * param_sysfs_builtin - add contents in /sys/parameters for built-in modules
 782 *
 783 * Add module_parameters to sysfs for "modules" built into the kernel.
 784 *
 785 * The "module" name (KBUILD_MODNAME) is stored before a dot, the
 786 * "parameter" name is stored behind a dot in kernel_param->name. So,
 787 * extract the "module" name for all built-in kernel_param-eters,
 788 * and for all who have the same, call kernel_add_sysfs_param.
 789 */
 790static void __init param_sysfs_builtin(void)
 791{
 792        struct kernel_param *kp;
 793        unsigned int name_len;
 794        char modname[MODULE_NAME_LEN];
 795
 796        for (kp = __start___param; kp < __stop___param; kp++) {
 797                char *dot;
 798
 799                if (kp->perm == 0)
 800                        continue;
 801
 802                dot = strchr(kp->name, '.');
 803                if (!dot) {
 804                        /* This happens for core_param() */
 805                        strcpy(modname, "kernel");
 806                        name_len = 0;
 807                } else {
 808                        name_len = dot - kp->name + 1;
 809                        strlcpy(modname, kp->name, name_len);
 810                }
 811                kernel_add_sysfs_param(modname, kp, name_len);
 812        }
 813}
 814
 815ssize_t __modver_version_show(struct module_attribute *mattr,
 816                              struct module *mod, char *buf)
 817{
 818        struct module_version_attribute *vattr =
 819                container_of(mattr, struct module_version_attribute, mattr);
 820
 821        return sprintf(buf, "%s\n", vattr->version);
 822}
 823
 824extern struct module_version_attribute __start___modver[], __stop___modver[];
 825
 826static void __init version_sysfs_builtin(void)
 827{
 828        const struct module_version_attribute *vattr;
 829        struct module_kobject *mk;
 830        int err;
 831
 832        for (vattr = __start___modver; vattr < __stop___modver; vattr++) {
 833                mk = locate_module_kobject(vattr->module_name);
 834                if (mk) {
 835                        err = sysfs_create_file(&mk->kobj, &vattr->mattr.attr);
 836                        kobject_uevent(&mk->kobj, KOBJ_ADD);
 837                        kobject_put(&mk->kobj);
 838                }
 839        }
 840}
 841
 842/* module-related sysfs stuff */
 843
 844static ssize_t module_attr_show(struct kobject *kobj,
 845                                struct attribute *attr,
 846                                char *buf)
 847{
 848        struct module_attribute *attribute;
 849        struct module_kobject *mk;
 850        int ret;
 851
 852        attribute = to_module_attr(attr);
 853        mk = to_module_kobject(kobj);
 854
 855        if (!attribute->show)
 856                return -EIO;
 857
 858        ret = attribute->show(attribute, mk->mod, buf);
 859
 860        return ret;
 861}
 862
 863static ssize_t module_attr_store(struct kobject *kobj,
 864                                struct attribute *attr,
 865                                const char *buf, size_t len)
 866{
 867        struct module_attribute *attribute;
 868        struct module_kobject *mk;
 869        int ret;
 870
 871        attribute = to_module_attr(attr);
 872        mk = to_module_kobject(kobj);
 873
 874        if (!attribute->store)
 875                return -EIO;
 876
 877        ret = attribute->store(attribute, mk->mod, buf, len);
 878
 879        return ret;
 880}
 881
 882static const struct sysfs_ops module_sysfs_ops = {
 883        .show = module_attr_show,
 884        .store = module_attr_store,
 885};
 886
 887static int uevent_filter(struct kset *kset, struct kobject *kobj)
 888{
 889        struct kobj_type *ktype = get_ktype(kobj);
 890
 891        if (ktype == &module_ktype)
 892                return 1;
 893        return 0;
 894}
 895
 896static const struct kset_uevent_ops module_uevent_ops = {
 897        .filter = uevent_filter,
 898};
 899
 900struct kset *module_kset;
 901int module_sysfs_initialized;
 902
 903struct kobj_type module_ktype = {
 904        .sysfs_ops =    &module_sysfs_ops,
 905};
 906
 907/*
 908 * param_sysfs_init - wrapper for built-in params support
 909 */
 910static int __init param_sysfs_init(void)
 911{
 912        module_kset = kset_create_and_add("module", &module_uevent_ops, NULL);
 913        if (!module_kset) {
 914                printk(KERN_WARNING "%s (%d): error creating kset\n",
 915                        __FILE__, __LINE__);
 916                return -ENOMEM;
 917        }
 918        module_sysfs_initialized = 1;
 919
 920        version_sysfs_builtin();
 921        param_sysfs_builtin();
 922
 923        return 0;
 924}
 925subsys_initcall(param_sysfs_init);
 926
 927#endif /* CONFIG_SYSFS */
 928