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 27 #if 0 28 #define DEBUGP printk 29 #else 30 #define DEBUGP(fmt, a...) 31 #endif 32 33 static struct kobj_type module_ktype; 34 35 static inline char dash2underscore(char c) 36 { 37 if (c == '-') 38 return '_'; 39 return c; 40 } 41 42 static inline int parameq(const char *input, const char *paramname) 43 { 44 unsigned int i; 45 for (i = 0; dash2underscore(input[i]) == paramname[i]; i++) 46 if (input[i] == '\0') 47 return 1; 48 return 0; 49 } 50 51 static int parse_one(char *param, 52 char *val, 53 struct kernel_param *params, 54 unsigned num_params, 55 int (*handle_unknown)(char *param, char *val)) 56 { 57 unsigned int i; 58 59 /* Find parameter */ 60 for (i = 0; i < num_params; i++) { 61 if (parameq(param, params[i].name)) { 62 DEBUGP("They are equal! Calling %p\n", 63 params[i].set); 64 return params[i].set(val, ¶ms[i]); 65 } 66 } 67 68 if (handle_unknown) { 69 DEBUGP("Unknown argument: calling %p\n", handle_unknown); 70 return handle_unknown(param, val); 71 } 72 73 DEBUGP("Unknown argument `%s'\n", param); 74 return -ENOENT; 75 } 76 77 /* You can use " around spaces, but can't escape ". */ 78 /* Hyphens and underscores equivalent in parameter names. */ 79 static char *next_arg(char *args, char **param, char **val) 80 { 81 unsigned int i, equals = 0; 82 int in_quote = 0, quoted = 0; 83 char *next; 84 85 if (*args == '"') { 86 args++; 87 in_quote = 1; 88 quoted = 1; 89 } 90 91 for (i = 0; args[i]; i++) { 92 if (args[i] == ' ' && !in_quote) 93 break; 94 if (equals == 0) { 95 if (args[i] == '=') 96 equals = i; 97 } 98 if (args[i] == '"') 99 in_quote = !in_quote; 100 } 101 102 *param = args; 103 if (!equals) 104 *val = NULL; 105 else { 106 args[equals] = '\0'; 107 *val = args + equals + 1; 108 109 /* Don't include quotes in value. */ 110 if (**val == '"') { 111 (*val)++; 112 if (args[i-1] == '"') 113 args[i-1] = '\0'; 114 } 115 if (quoted && args[i-1] == '"') 116 args[i-1] = '\0'; 117 } 118 119 if (args[i]) { 120 args[i] = '\0'; 121 next = args + i + 1; 122 } else 123 next = args + i; 124 125 /* Chew up trailing spaces. */ 126 while (*next == ' ') 127 next++; 128 return next; 129 } 130 131 /* Args looks like "foo=bar,bar2 baz=fuz wiz". */ 132 int parse_args(const char *name, 133 char *args, 134 struct kernel_param *params, 135 unsigned num, 136 int (*unknown)(char *param, char *val)) 137 { 138 char *param, *val; 139 140 DEBUGP("Parsing ARGS: %s\n", args); 141 142 /* Chew leading spaces */ 143 while (*args == ' ') 144 args++; 145 146 while (*args) { 147 int ret; 148 int irq_was_disabled; 149 150 args = next_arg(args, ¶m, &val); 151 irq_was_disabled = irqs_disabled(); 152 ret = parse_one(param, val, params, num, unknown); 153 if (irq_was_disabled && !irqs_disabled()) { 154 printk(KERN_WARNING "parse_args(): option '%s' enabled " 155 "irq's!\n", param); 156 } 157 switch (ret) { 158 case -ENOENT: 159 printk(KERN_ERR "%s: Unknown parameter `%s'\n", 160 name, param); 161 return ret; 162 case -ENOSPC: 163 printk(KERN_ERR 164 "%s: `%s' too large for parameter `%s'\n", 165 name, val ?: "", param); 166 return ret; 167 case 0: 168 break; 169 default: 170 printk(KERN_ERR 171 "%s: `%s' invalid for parameter `%s'\n", 172 name, val ?: "", param); 173 return ret; 174 } 175 } 176 177 /* All parsed OK. */ 178 return 0; 179 } 180 181 /* Lazy bastard, eh? */ 182 #define STANDARD_PARAM_DEF(name, type, format, tmptype, strtolfn) \ 183 int param_set_##name(const char *val, struct kernel_param *kp) \ 184 { \ 185 char *endp; \ 186 tmptype l; \ 187 \ 188 if (!val) return -EINVAL; \ 189 l = strtolfn(val, &endp, 0); \ 190 if (endp == val || ((type)l != l)) \ 191 return -EINVAL; \ 192 *((type *)kp->arg) = l; \ 193 return 0; \ 194 } \ 195 int param_get_##name(char *buffer, struct kernel_param *kp) \ 196 { \ 197 return sprintf(buffer, format, *((type *)kp->arg)); \ 198 } 199 200 STANDARD_PARAM_DEF(byte, unsigned char, "%c", unsigned long, simple_strtoul); 201 STANDARD_PARAM_DEF(short, short, "%hi", long, simple_strtol); 202 STANDARD_PARAM_DEF(ushort, unsigned short, "%hu", unsigned long, simple_strtoul); 203 STANDARD_PARAM_DEF(int, int, "%i", long, simple_strtol); 204 STANDARD_PARAM_DEF(uint, unsigned int, "%u", unsigned long, simple_strtoul); 205 STANDARD_PARAM_DEF(long, long, "%li", long, simple_strtol); 206 STANDARD_PARAM_DEF(ulong, unsigned long, "%lu", unsigned long, simple_strtoul); 207 208 int param_set_charp(const char *val, struct kernel_param *kp) 209 { 210 if (!val) { 211 printk(KERN_ERR "%s: string parameter expected\n", 212 kp->name); 213 return -EINVAL; 214 } 215 216 if (strlen(val) > 1024) { 217 printk(KERN_ERR "%s: string parameter too long\n", 218 kp->name); 219 return -ENOSPC; 220 } 221 222 *(char **)kp->arg = (char *)val; 223 return 0; 224 } 225 226 int param_get_charp(char *buffer, struct kernel_param *kp) 227 { 228 return sprintf(buffer, "%s", *((char **)kp->arg)); 229 } 230 231 int param_set_bool(const char *val, struct kernel_param *kp) 232 { 233 /* No equals means "set"... */ 234 if (!val) val = "1"; 235 236 /* One of =[yYnN01] */ 237 switch (val[0]) { 238 case 'y': case 'Y': case '1': 239 *(int *)kp->arg = 1; 240 return 0; 241 case 'n': case 'N': case '0': 242 *(int *)kp->arg = 0; 243 return 0; 244 } 245 return -EINVAL; 246 } 247 248 int param_get_bool(char *buffer, struct kernel_param *kp) 249 { 250 /* Y and N chosen as being relatively non-coder friendly */ 251 return sprintf(buffer, "%c", (*(int *)kp->arg) ? 'Y' : 'N'); 252 } 253 254 int param_set_invbool(const char *val, struct kernel_param *kp) 255 { 256 int boolval, ret; 257 struct kernel_param dummy = { .arg = &boolval }; 258 259 ret = param_set_bool(val, &dummy); 260 if (ret == 0) 261 *(int *)kp->arg = !boolval; 262 return ret; 263 } 264 265 int param_get_invbool(char *buffer, struct kernel_param *kp) 266 { 267 int val; 268 struct kernel_param dummy = { .arg = &val }; 269 270 val = !*(int *)kp->arg; 271 return param_get_bool(buffer, &dummy); 272 } 273 274 /* We cheat here and temporarily mangle the string. */ 275 static int param_array(const char *name, 276 const char *val, 277 unsigned int min, unsigned int max, 278 void *elem, int elemsize, 279 int (*set)(const char *, struct kernel_param *kp), 280 int *num) 281 { 282 int ret; 283 struct kernel_param kp; 284 char save; 285 286 /* Get the name right for errors. */ 287 kp.name = name; 288 kp.arg = elem; 289 290 /* No equals sign? */ 291 if (!val) { 292 printk(KERN_ERR "%s: expects arguments\n", name); 293 return -EINVAL; 294 } 295 296 *num = 0; 297 /* We expect a comma-separated list of values. */ 298 do { 299 int len; 300 301 if (*num == max) { 302 printk(KERN_ERR "%s: can only take %i arguments\n", 303 name, max); 304 return -EINVAL; 305 } 306 len = strcspn(val, ","); 307 308 /* nul-terminate and parse */ 309 save = val[len]; 310 ((char *)val)[len] = '\0'; 311 ret = set(val, &kp); 312 313 if (ret != 0) 314 return ret; 315 kp.arg += elemsize; 316 val += len+1; 317 (*num)++; 318 } while (save == ','); 319 320 if (*num < min) { 321 printk(KERN_ERR "%s: needs at least %i arguments\n", 322 name, min); 323 return -EINVAL; 324 } 325 return 0; 326 } 327 328 int param_array_set(const char *val, struct kernel_param *kp) 329 { 330 struct kparam_array *arr = kp->arg; 331 unsigned int temp_num; 332 333 return param_array(kp->name, val, 1, arr->max, arr->elem, 334 arr->elemsize, arr->set, arr->num ?: &temp_num); 335 } 336 337 int param_array_get(char *buffer, struct kernel_param *kp) 338 { 339 int i, off, ret; 340 struct kparam_array *arr = kp->arg; 341 struct kernel_param p; 342 343 p = *kp; 344 for (i = off = 0; i < (arr->num ? *arr->num : arr->max); i++) { 345 if (i) 346 buffer[off++] = ','; 347 p.arg = arr->elem + arr->elemsize * i; 348 ret = arr->get(buffer + off, &p); 349 if (ret < 0) 350 return ret; 351 off += ret; 352 } 353 buffer[off] = '\0'; 354 return off; 355 } 356 357 int param_set_copystring(const char *val, struct kernel_param *kp) 358 { 359 struct kparam_string *kps = kp->arg; 360 361 if (strlen(val)+1 > kps->maxlen) { 362 printk(KERN_ERR "%s: string doesn't fit in %u chars.\n", 363 kp->name, kps->maxlen-1); 364 return -ENOSPC; 365 } 366 strcpy(kps->string, val); 367 return 0; 368 } 369 370 int param_get_string(char *buffer, struct kernel_param *kp) 371 { 372 struct kparam_string *kps = kp->arg; 373 return strlcpy(buffer, kps->string, kps->maxlen); 374 } 375 376 /* sysfs output in /sys/modules/XYZ/parameters/ */ 377 378 extern struct kernel_param __start___param[], __stop___param[]; 379 380 #define MAX_KBUILD_MODNAME KOBJ_NAME_LEN 381 382 struct param_attribute 383 { 384 struct module_attribute mattr; 385 struct kernel_param *param; 386 }; 387 388 struct module_param_attrs 389 { 390 struct attribute_group grp; 391 struct param_attribute attrs[0]; 392 }; 393 394 #define to_param_attr(n) container_of(n, struct param_attribute, mattr); 395 396 static ssize_t param_attr_show(struct module_attribute *mattr, 397 struct module *mod, char *buf) 398 { 399 int count; 400 struct param_attribute *attribute = to_param_attr(mattr); 401 402 if (!attribute->param->get) 403 return -EPERM; 404 405 count = attribute->param->get(buf, attribute->param); 406 if (count > 0) { 407 strcat(buf, "\n"); 408 ++count; 409 } 410 return count; 411 } 412 413 /* sysfs always hands a nul-terminated string in buf. We rely on that. */ 414 static ssize_t param_attr_store(struct module_attribute *mattr, 415 struct module *owner, 416 const char *buf, size_t len) 417 { 418 int err; 419 struct param_attribute *attribute = to_param_attr(mattr); 420 421 if (!attribute->param->set) 422 return -EPERM; 423 424 err = attribute->param->set(buf, attribute->param); 425 if (!err) 426 return len; 427 return err; 428 } 429 430 #ifdef CONFIG_MODULES 431 #define __modinit 432 #else 433 #define __modinit __init 434 #endif 435 436 /* 437 * param_sysfs_setup - setup sysfs support for one module or KBUILD_MODNAME 438 * @mk: struct module_kobject (contains parent kobject) 439 * @kparam: array of struct kernel_param, the actual parameter definitions 440 * @num_params: number of entries in array 441 * @name_skip: offset where the parameter name start in kparam[].name. Needed for built-in "modules" 442 * 443 * Create a kobject for a (per-module) group of parameters, and create files 444 * in sysfs. A pointer to the param_kobject is returned on success, 445 * NULL if there's no parameter to export, or other ERR_PTR(err). 446 */ 447 static __modinit struct module_param_attrs * 448 param_sysfs_setup(struct module_kobject *mk, 449 struct kernel_param *kparam, 450 unsigned int num_params, 451 unsigned int name_skip) 452 { 453 struct module_param_attrs *mp; 454 unsigned int valid_attrs = 0; 455 unsigned int i, size[2]; 456 struct param_attribute *pattr; 457 struct attribute **gattr; 458 int err; 459 460 for (i=0; i<num_params; i++) { 461 if (kparam[i].perm) 462 valid_attrs++; 463 } 464 465 if (!valid_attrs) 466 return NULL; 467 468 size[0] = ALIGN(sizeof(*mp) + 469 valid_attrs * sizeof(mp->attrs[0]), 470 sizeof(mp->grp.attrs[0])); 471 size[1] = (valid_attrs + 1) * sizeof(mp->grp.attrs[0]); 472 473 mp = kmalloc(size[0] + size[1], GFP_KERNEL); 474 if (!mp) 475 return ERR_PTR(-ENOMEM); 476 477 mp->grp.name = "parameters"; 478 mp->grp.attrs = (void *)mp + size[0]; 479 480 pattr = &mp->attrs[0]; 481 gattr = &mp->grp.attrs[0]; 482 for (i = 0; i < num_params; i++) { 483 struct kernel_param *kp = &kparam[i]; 484 if (kp->perm) { 485 pattr->param = kp; 486 pattr->mattr.show = param_attr_show; 487 pattr->mattr.store = param_attr_store; 488 pattr->mattr.attr.name = (char *)&kp->name[name_skip]; 489 pattr->mattr.attr.owner = mk->mod; 490 pattr->mattr.attr.mode = kp->perm; 491 *(gattr++) = &(pattr++)->mattr.attr; 492 } 493 } 494 *gattr = NULL; 495 496 if ((err = sysfs_create_group(&mk->kobj, &mp->grp))) { 497 kfree(mp); 498 return ERR_PTR(err); 499 } 500 return mp; 501 } 502 503 504 #ifdef CONFIG_MODULES 505 506 /* 507 * module_param_sysfs_setup - setup sysfs support for one module 508 * @mod: module 509 * @kparam: module parameters (array) 510 * @num_params: number of module parameters 511 * 512 * Adds sysfs entries for module parameters, and creates a link from 513 * /sys/module/[mod->name]/parameters to /sys/parameters/[mod->name]/ 514 */ 515 int module_param_sysfs_setup(struct module *mod, 516 struct kernel_param *kparam, 517 unsigned int num_params) 518 { 519 struct module_param_attrs *mp; 520 521 mp = param_sysfs_setup(&mod->mkobj, kparam, num_params, 0); 522 if (IS_ERR(mp)) 523 return PTR_ERR(mp); 524 525 mod->param_attrs = mp; 526 return 0; 527 } 528 529 /* 530 * module_param_sysfs_remove - remove sysfs support for one module 531 * @mod: module 532 * 533 * Remove sysfs entries for module parameters and the corresponding 534 * kobject. 535 */ 536 void module_param_sysfs_remove(struct module *mod) 537 { 538 if (mod->param_attrs) { 539 sysfs_remove_group(&mod->mkobj.kobj, 540 &mod->param_attrs->grp); 541 /* We are positive that no one is using any param 542 * attrs at this point. Deallocate immediately. */ 543 kfree(mod->param_attrs); 544 mod->param_attrs = NULL; 545 } 546 } 547 #endif 548 549 /* 550 * kernel_param_sysfs_setup - wrapper for built-in params support 551 */ 552 static void __init kernel_param_sysfs_setup(const char *name, 553 struct kernel_param *kparam, 554 unsigned int num_params, 555 unsigned int name_skip) 556 { 557 struct module_kobject *mk; 558 int ret; 559 560 mk = kzalloc(sizeof(struct module_kobject), GFP_KERNEL); 561 BUG_ON(!mk); 562 563 mk->mod = THIS_MODULE; 564 kobj_set_kset_s(mk, module_subsys); 565 kobject_set_name(&mk->kobj, name); 566 kobject_init(&mk->kobj); 567 ret = kobject_add(&mk->kobj); 568 BUG_ON(ret < 0); 569 param_sysfs_setup(mk, kparam, num_params, name_skip); 570 kobject_uevent(&mk->kobj, KOBJ_ADD); 571 } 572 573 /* 574 * param_sysfs_builtin - add contents in /sys/parameters for built-in modules 575 * 576 * Add module_parameters to sysfs for "modules" built into the kernel. 577 * 578 * The "module" name (KBUILD_MODNAME) is stored before a dot, the 579 * "parameter" name is stored behind a dot in kernel_param->name. So, 580 * extract the "module" name for all built-in kernel_param-eters, 581 * and for all who have the same, call kernel_param_sysfs_setup. 582 */ 583 static void __init param_sysfs_builtin(void) 584 { 585 struct kernel_param *kp, *kp_begin = NULL; 586 unsigned int i, name_len, count = 0; 587 char modname[MAX_KBUILD_MODNAME + 1] = ""; 588 589 for (i=0; i < __stop___param - __start___param; i++) { 590 char *dot; 591 592 kp = &__start___param[i]; 593 594 /* We do not handle args without periods. */ 595 dot = memchr(kp->name, '.', MAX_KBUILD_MODNAME); 596 if (!dot) { 597 DEBUGP("couldn't find period in %s\n", kp->name); 598 continue; 599 } 600 name_len = dot - kp->name; 601 602 /* new kbuild_modname? */ 603 if (strlen(modname) != name_len 604 || strncmp(modname, kp->name, name_len) != 0) { 605 /* add a new kobject for previous kernel_params. */ 606 if (count) 607 kernel_param_sysfs_setup(modname, 608 kp_begin, 609 count, 610 strlen(modname)+1); 611 612 strncpy(modname, kp->name, name_len); 613 modname[name_len] = '\0'; 614 count = 0; 615 kp_begin = kp; 616 } 617 count++; 618 } 619 620 /* last kernel_params need to be registered as well */ 621 if (count) 622 kernel_param_sysfs_setup(modname, kp_begin, count, 623 strlen(modname)+1); 624 } 625 626 627 /* module-related sysfs stuff */ 628 #ifdef CONFIG_SYSFS 629 630 #define to_module_attr(n) container_of(n, struct module_attribute, attr); 631 #define to_module_kobject(n) container_of(n, struct module_kobject, kobj); 632 633 static ssize_t module_attr_show(struct kobject *kobj, 634 struct attribute *attr, 635 char *buf) 636 { 637 struct module_attribute *attribute; 638 struct module_kobject *mk; 639 int ret; 640 641 attribute = to_module_attr(attr); 642 mk = to_module_kobject(kobj); 643 644 if (!attribute->show) 645 return -EIO; 646 647 ret = attribute->show(attribute, mk->mod, buf); 648 649 return ret; 650 } 651 652 static ssize_t module_attr_store(struct kobject *kobj, 653 struct attribute *attr, 654 const char *buf, size_t len) 655 { 656 struct module_attribute *attribute; 657 struct module_kobject *mk; 658 int ret; 659 660 attribute = to_module_attr(attr); 661 mk = to_module_kobject(kobj); 662 663 if (!attribute->store) 664 return -EIO; 665 666 ret = attribute->store(attribute, mk->mod, buf, len); 667 668 return ret; 669 } 670 671 static struct sysfs_ops module_sysfs_ops = { 672 .show = module_attr_show, 673 .store = module_attr_store, 674 }; 675 676 static int uevent_filter(struct kset *kset, struct kobject *kobj) 677 { 678 struct kobj_type *ktype = get_ktype(kobj); 679 680 if (ktype == &module_ktype) 681 return 1; 682 return 0; 683 } 684 685 static struct kset_uevent_ops module_uevent_ops = { 686 .filter = uevent_filter, 687 }; 688 689 #else 690 static struct sysfs_ops module_sysfs_ops = { 691 .show = NULL, 692 .store = NULL, 693 }; 694 #endif 695 696 static struct kobj_type module_ktype = { 697 .sysfs_ops = &module_sysfs_ops, 698 }; 699 700 decl_subsys(module, &module_ktype, &module_uevent_ops); 701 702 /* 703 * param_sysfs_init - wrapper for built-in params support 704 */ 705 static int __init param_sysfs_init(void) 706 { 707 int ret; 708 709 ret = subsystem_register(&module_subsys); 710 if (ret < 0) { 711 printk(KERN_WARNING "%s (%d): subsystem_register error: %d\n", 712 __FILE__, __LINE__, ret); 713 return ret; 714 } 715 716 param_sysfs_builtin(); 717 718 return 0; 719 } 720 subsys_initcall(param_sysfs_init); 721 722 EXPORT_SYMBOL(param_set_byte); 723 EXPORT_SYMBOL(param_get_byte); 724 EXPORT_SYMBOL(param_set_short); 725 EXPORT_SYMBOL(param_get_short); 726 EXPORT_SYMBOL(param_set_ushort); 727 EXPORT_SYMBOL(param_get_ushort); 728 EXPORT_SYMBOL(param_set_int); 729 EXPORT_SYMBOL(param_get_int); 730 EXPORT_SYMBOL(param_set_uint); 731 EXPORT_SYMBOL(param_get_uint); 732 EXPORT_SYMBOL(param_set_long); 733 EXPORT_SYMBOL(param_get_long); 734 EXPORT_SYMBOL(param_set_ulong); 735 EXPORT_SYMBOL(param_get_ulong); 736 EXPORT_SYMBOL(param_set_charp); 737 EXPORT_SYMBOL(param_get_charp); 738 EXPORT_SYMBOL(param_set_bool); 739 EXPORT_SYMBOL(param_get_bool); 740 EXPORT_SYMBOL(param_set_invbool); 741 EXPORT_SYMBOL(param_get_invbool); 742 EXPORT_SYMBOL(param_array_set); 743 EXPORT_SYMBOL(param_array_get); 744 EXPORT_SYMBOL(param_set_copystring); 745 EXPORT_SYMBOL(param_get_string); 746