#ifdef CONFIG_SYSFS /* Protects all built-in parameters, modules use their own param_lock */ static DEFINE_MUTEX(param_lock);
/* Use the module's mutex, or if built-in use the built-in mutex */ #ifdef CONFIG_MODULES #define KPARAM_MUTEX(mod) ((mod) ? &(mod)->param_lock : ¶m_lock) #else #define KPARAM_MUTEX(mod) (¶m_lock) #endif
/* This just allows us to keep track of which parameters are kmalloced. */ struct kmalloced_param { struct list_head list; char val[];
}; static LIST_HEAD(kmalloced_params); static DEFINE_SPINLOCK(kmalloced_params_lock);
switch (ret) { case 0: continue; case -ENOENT:
pr_err("%s: Unknown parameter `%s'\n", doing, param); break; case -ENOSPC:
pr_err("%s: `%s' too large for parameter `%s'\n",
doing, val ?: "", param); break; default:
pr_err("%s: `%s' invalid for parameter `%s'\n",
doing, val ?: "", param); break;
}
len = strnlen(val, maxlen + 1); if (len == maxlen + 1) {
pr_err("%s: string parameter too long\n", kp->name); return -ENOSPC;
}
maybe_kfree_parameter(*(char **)kp->arg);
/* * This is a hack. We can't kmalloc() in early boot, and we * don't need to; this mangled commandline is preserved.
*/ if (slab_is_available()) {
*(char **)kp->arg = kmalloc_parameter(len + 1); if (!*(char **)kp->arg) return -ENOMEM;
strcpy(*(char **)kp->arg, val);
} else
*(constchar **)kp->arg = val;
/* Actually could be a bool or an int, for historical reasons. */ int param_set_bool(constchar *val, conststruct kernel_param *kp)
{ /* No equals means "set"... */ if (!val) val = "1";
/* One of =[yYnN01] */ return kstrtobool(val, kp->arg);
}
EXPORT_SYMBOL(param_set_bool);
int param_get_bool(char *buffer, conststruct kernel_param *kp)
{ /* Y and N chosen as being relatively non-coder friendly */ return sprintf(buffer, "%c\n", *(bool *)kp->arg ? 'Y' : 'N');
}
EXPORT_SYMBOL(param_get_bool);
int param_set_bint(constchar *val, conststruct kernel_param *kp)
{ /* Match bool exactly, by re-using it. */ struct kernel_param boolkp = *kp; bool v; int ret;
boolkp.arg = &v;
ret = param_set_bool(val, &boolkp); if (ret == 0)
*(int *)kp->arg = v; return ret;
}
EXPORT_SYMBOL(param_set_bint);
/* * add_sysfs_param - add a parameter to sysfs * @mk: struct module_kobject * @kp: the actual parameter definition to add to sysfs * @name: name of parameter * * Create a kobject if for a (per-module) parameter if mp NULL, and * create file in sysfs. Returns an error on out of memory. Always cleans up * if there's an error.
*/ static __modinit int add_sysfs_param(struct module_kobject *mk, conststruct kernel_param *kp, constchar *name)
{ struct module_param_attrs *new_mp; struct attribute **new_attrs; unsignedint i;
/* We don't bother calling this with invisible parameters. */
BUG_ON(!kp->perm);
if (!mk->mp) { /* First allocation. */
mk->mp = kzalloc(sizeof(*mk->mp), GFP_KERNEL); if (!mk->mp) return -ENOMEM;
mk->mp->grp.name = "parameters"; /* NULL-terminated attribute array. */
mk->mp->grp.attrs = kzalloc(sizeof(mk->mp->grp.attrs[0]),
GFP_KERNEL); /* Caller will cleanup via free_module_param_attrs */ if (!mk->mp->grp.attrs) return -ENOMEM;
}
/* Extra pointer for NULL terminator */
new_attrs = krealloc_array(mk->mp->grp.attrs, mk->mp->num + 1, sizeof(mk->mp->grp.attrs[0]), GFP_KERNEL); if (!new_attrs) return -ENOMEM;
mk->mp->grp.attrs = new_attrs;
/* Tack new one on the end. */
memset(&mk->mp->attrs[mk->mp->num - 1], 0, sizeof(mk->mp->attrs[0]));
sysfs_attr_init(&mk->mp->attrs[mk->mp->num - 1].mattr.attr);
mk->mp->attrs[mk->mp->num - 1].param = kp;
mk->mp->attrs[mk->mp->num - 1].mattr.show = param_attr_show; /* Do not allow runtime DAC changes to make param writable. */ if ((kp->perm & (S_IWUSR | S_IWGRP | S_IWOTH)) != 0)
mk->mp->attrs[mk->mp->num - 1].mattr.store = param_attr_store; else
mk->mp->attrs[mk->mp->num - 1].mattr.store = NULL;
mk->mp->attrs[mk->mp->num - 1].mattr.attr.name = (char *)name;
mk->mp->attrs[mk->mp->num - 1].mattr.attr.mode = kp->perm;
/* Fix up all the pointers, since krealloc can move us */ for (i = 0; i < mk->mp->num; i++)
mk->mp->grp.attrs[i] = &mk->mp->attrs[i].mattr.attr;
mk->mp->grp.attrs[mk->mp->num] = NULL; return 0;
}
/* * module_param_sysfs_setup - setup sysfs support for one module * @mod: module * @kparam: module parameters (array) * @num_params: number of module parameters * * Adds sysfs entries for module parameters under * /sys/module/[mod->name]/parameters/
*/ int module_param_sysfs_setup(struct module *mod, conststruct kernel_param *kparam, unsignedint num_params)
{ int i, err; bool params = false;
for (i = 0; i < num_params; i++) { if (kparam[i].perm == 0) continue;
err = add_sysfs_param(&mod->mkobj, &kparam[i], kparam[i].name); if (err) {
free_module_param_attrs(&mod->mkobj); return err;
}
params = true;
}
if (!params) return 0;
/* Create the param group. */
err = sysfs_create_group(&mod->mkobj.kobj, &mod->mkobj.mp->grp); if (err)
free_module_param_attrs(&mod->mkobj); return err;
}
/* * module_param_sysfs_remove - remove sysfs support for one module * @mod: module * * Remove sysfs entries for module parameters and the corresponding * kobject.
*/ void module_param_sysfs_remove(struct module *mod)
{ if (mod->mkobj.mp) {
sysfs_remove_group(&mod->mkobj.kobj, &mod->mkobj.mp->grp); /* * We are positive that no one is using any param * attrs at this point. Deallocate immediately.
*/
free_module_param_attrs(&mod->mkobj);
}
} #endif
mk = lookup_or_create_module_kobject(name); if (!mk) return;
/* We need to remove old parameters before adding more. */ if (mk->mp)
sysfs_remove_group(&mk->kobj, &mk->mp->grp);
/* These should not fail at boot. */
err = add_sysfs_param(mk, kparam, kparam->name + name_skip);
BUG_ON(err);
err = sysfs_create_group(&mk->kobj, &mk->mp->grp);
BUG_ON(err);
kobject_uevent(&mk->kobj, KOBJ_ADD);
kobject_put(&mk->kobj);
}
/* * param_sysfs_builtin - add sysfs parameters for built-in modules * * Add module_parameters to sysfs for "modules" built into the kernel. * * The "module" name (KBUILD_MODNAME) is stored before a dot, the * "parameter" name is stored behind a dot in kernel_param->name. So, * extract the "module" name for all built-in kernel_param-eters, * and for all who have the same, call kernel_add_sysfs_param.
*/ staticvoid __init param_sysfs_builtin(void)
{ conststruct kernel_param *kp; unsignedint name_len; char modname[MODULE_NAME_LEN];
/* * param_sysfs_init - create "module" kset * * This must be done before the initramfs is unpacked and * request_module() thus becomes possible, because otherwise the * module load would fail in mod_sysfs_init.
*/ staticint __init param_sysfs_init(void)
{
module_kset = kset_create_and_add("module", &module_uevent_ops, NULL); if (!module_kset) {
printk(KERN_WARNING "%s (%d): error creating kset\n",
__FILE__, __LINE__); return -ENOMEM;
}
return 0;
}
subsys_initcall(param_sysfs_init);
/* * param_sysfs_builtin_init - add sysfs version and parameter * attributes for built-in modules
*/ staticint __init param_sysfs_builtin_init(void)
{ if (!module_kset) return -ENOMEM;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.