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