Contents
Kernel parameters that are accessible via procfs offer a good interface to expose the kernel internals.
Apart from allowing users to monitor the kernel, it is particularly useful for some features that are configurable at run-time (e.g., CPU frequency scaling).
[Step 1] Declare Your Variable
Let’s assume that you are working on something in the kernel file, say
To make such a variable more identifiable, you may want to name it with the prefix sysctl_
. Let’s assume the variable is an integer named sysctl_my_param
. So you will declare such a variable in
int sysctl_my_param = 0;
[Step 2] Optional: Implement the Handler Function
There is a default handler that handles the read/write operations coming from the procfs.
If you want to do something different (e.g., checking if certain conditions meet and thus updating the parameters is accepted), there is a way to create your own handler and associate it with your kernel parameter.
To create and implement a handler of your own, use the following template (and replace function name with yours):
int my_handler(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { int ret; ret = proc_dointvec(table, write, buffer, lenp, ppos); if (ret) { // update fails } else { // update succeeds } return ret; }
[Step 3] Register in Kernel Table
Next we will have to expose and register our variable and function in the sysctl.
First, declare the variable and, optionally, the function in
extern int sysctl_my_param; extern int my_handler(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos);
Then, we need register the variable.
To do so, find the variable static struct ctl_table kern_table[]
in
static struct ctl_table kern_table[] = { // ... { .procname = "my_param", .data = &sysctl_my_param, .maxlen = sizeof(int), .mode = 0644, .proc_handler = my_handler, }, // ... }
You can give a different name to the field .procname
that will be used to expose this parameter (i.e., our sysctl_my_param
variable) in procfs.
If you choose to use the default handler, then you can replace the last field with this:
.proc_handler = proc_dointvec,
[Step 4] Access It from procfs!
At run-time, your can read the parameter by using the following command:
# option 1 (no sudo required) sysctl kernel.my_param # option 2 sudo cat /proc/sys/kernel/my_param
To assign a new value to the parameter, there are also two ways:
# option 1 sudo sysctl kernel.my_param=1 # option 2 sudo su echo 1 > /proc/sys/kernel/my_param