xref: /openbmc/linux/kernel/params.c (revision b68e31d0)
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 	int ret;
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 	ret = kobject_register(&mk->kobj);
559 	BUG_ON(ret < 0);
560 
561 	/* no need to keep the kobject if no parameter is exported */
562 	if (!param_sysfs_setup(mk, kparam, num_params, name_skip)) {
563 		kobject_unregister(&mk->kobj);
564 		kfree(mk);
565 	}
566 }
567 
568 /*
569  * param_sysfs_builtin - add contents in /sys/parameters for built-in modules
570  *
571  * Add module_parameters to sysfs for "modules" built into the kernel.
572  *
573  * The "module" name (KBUILD_MODNAME) is stored before a dot, the
574  * "parameter" name is stored behind a dot in kernel_param->name. So,
575  * extract the "module" name for all built-in kernel_param-eters,
576  * and for all who have the same, call kernel_param_sysfs_setup.
577  */
578 static void __init param_sysfs_builtin(void)
579 {
580 	struct kernel_param *kp, *kp_begin = NULL;
581 	unsigned int i, name_len, count = 0;
582 	char modname[MAX_KBUILD_MODNAME + 1] = "";
583 
584 	for (i=0; i < __stop___param - __start___param; i++) {
585 		char *dot;
586 
587 		kp = &__start___param[i];
588 
589 		/* We do not handle args without periods. */
590 		dot = memchr(kp->name, '.', MAX_KBUILD_MODNAME);
591 		if (!dot) {
592 			DEBUGP("couldn't find period in %s\n", kp->name);
593 			continue;
594 		}
595 		name_len = dot - kp->name;
596 
597  		/* new kbuild_modname? */
598 		if (strlen(modname) != name_len
599 		    || strncmp(modname, kp->name, name_len) != 0) {
600 			/* add a new kobject for previous kernel_params. */
601 			if (count)
602 				kernel_param_sysfs_setup(modname,
603 							 kp_begin,
604 							 count,
605 							 strlen(modname)+1);
606 
607 			strncpy(modname, kp->name, name_len);
608 			modname[name_len] = '\0';
609 			count = 0;
610 			kp_begin = kp;
611 		}
612 		count++;
613 	}
614 
615 	/* last kernel_params need to be registered as well */
616 	if (count)
617 		kernel_param_sysfs_setup(modname, kp_begin, count,
618 					 strlen(modname)+1);
619 }
620 
621 
622 /* module-related sysfs stuff */
623 #ifdef CONFIG_SYSFS
624 
625 #define to_module_attr(n) container_of(n, struct module_attribute, attr);
626 #define to_module_kobject(n) container_of(n, struct module_kobject, kobj);
627 
628 static ssize_t module_attr_show(struct kobject *kobj,
629 				struct attribute *attr,
630 				char *buf)
631 {
632 	struct module_attribute *attribute;
633 	struct module_kobject *mk;
634 	int ret;
635 
636 	attribute = to_module_attr(attr);
637 	mk = to_module_kobject(kobj);
638 
639 	if (!attribute->show)
640 		return -EIO;
641 
642 	ret = attribute->show(attribute, mk->mod, buf);
643 
644 	return ret;
645 }
646 
647 static ssize_t module_attr_store(struct kobject *kobj,
648 				struct attribute *attr,
649 				const char *buf, size_t len)
650 {
651 	struct module_attribute *attribute;
652 	struct module_kobject *mk;
653 	int ret;
654 
655 	attribute = to_module_attr(attr);
656 	mk = to_module_kobject(kobj);
657 
658 	if (!attribute->store)
659 		return -EIO;
660 
661 	ret = attribute->store(attribute, mk->mod, buf, len);
662 
663 	return ret;
664 }
665 
666 static struct sysfs_ops module_sysfs_ops = {
667 	.show = module_attr_show,
668 	.store = module_attr_store,
669 };
670 
671 #else
672 static struct sysfs_ops module_sysfs_ops = {
673 	.show = NULL,
674 	.store = NULL,
675 };
676 #endif
677 
678 static struct kobj_type module_ktype = {
679 	.sysfs_ops =	&module_sysfs_ops,
680 };
681 
682 decl_subsys(module, &module_ktype, NULL);
683 
684 /*
685  * param_sysfs_init - wrapper for built-in params support
686  */
687 static int __init param_sysfs_init(void)
688 {
689 	int ret;
690 
691 	ret = subsystem_register(&module_subsys);
692 	if (ret < 0) {
693 		printk(KERN_WARNING "%s (%d): subsystem_register error: %d\n",
694 			__FILE__, __LINE__, ret);
695 		return ret;
696 	}
697 
698 	param_sysfs_builtin();
699 
700 	return 0;
701 }
702 subsys_initcall(param_sysfs_init);
703 
704 EXPORT_SYMBOL(param_set_byte);
705 EXPORT_SYMBOL(param_get_byte);
706 EXPORT_SYMBOL(param_set_short);
707 EXPORT_SYMBOL(param_get_short);
708 EXPORT_SYMBOL(param_set_ushort);
709 EXPORT_SYMBOL(param_get_ushort);
710 EXPORT_SYMBOL(param_set_int);
711 EXPORT_SYMBOL(param_get_int);
712 EXPORT_SYMBOL(param_set_uint);
713 EXPORT_SYMBOL(param_get_uint);
714 EXPORT_SYMBOL(param_set_long);
715 EXPORT_SYMBOL(param_get_long);
716 EXPORT_SYMBOL(param_set_ulong);
717 EXPORT_SYMBOL(param_get_ulong);
718 EXPORT_SYMBOL(param_set_charp);
719 EXPORT_SYMBOL(param_get_charp);
720 EXPORT_SYMBOL(param_set_bool);
721 EXPORT_SYMBOL(param_get_bool);
722 EXPORT_SYMBOL(param_set_invbool);
723 EXPORT_SYMBOL(param_get_invbool);
724 EXPORT_SYMBOL(param_array_set);
725 EXPORT_SYMBOL(param_array_get);
726 EXPORT_SYMBOL(param_set_copystring);
727 EXPORT_SYMBOL(param_get_string);
728