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