1. What is sysctl?
Consider following points:
- sysclt is an interface for user-space <--> kernel communication.
- It is used to read/write some Kernel variables, from User-Space.
- Each files under /proc/sys directory represents a Kernel variable
- Reading/Writing these files is equivalent to a read/write of the corresponding Kernel variable.
2. What's the problem in using sysctl with 2.6.24+?
A patch was released after 2.6.24, which prohibits Out-of-Kernel modules from using sysctl interface in the normal way. This was apparently done as many broken entries were detected and thus only In-Kernel modules were allowed to use sysctl the conventional way.
3. The way out?
To use sysctl in an Out-of-Kernel module, all you have to do is to set the ctl_name field of ctl_table, of every child in subdir, to 0 (zero). Only the top level ctl_table shall have a ctl_name defined.
EDIT (30th March 2010) : In 2.6.33 onwards, ctl_name field is no longer a member of struct ctl_table. For out-of-tree kernel module, remove the ctl_name from all the concerned ctl_table structure, to get things working.
Example:
If you want following set of files under /proc/sys/net:
/proc/sys/net
|
|----foo---|-----var1
|-----var2
you need to have a config like:
static struct ctl_table child_table[] = {
{
.ctl_name = 0,
.procname = "var1",
.data = &x1,
.maxlen = sizeof(int),
.mode = 0644,
.child = NULL,
.proc_handler = &proc_dointvec},
{
.ctl_name = 0,
.procname = "var2",
.data = &x2,
.maxlen = sizeof(int),
.mode = 0644,
.child = NULL,
.proc_handler = &proc_dointvec},
{ .ctl_name = 0,
.procname = NULL
}
};
static struct ctl_table foo_table[] = {
{
.ctl_name = 0,
.procname = "foo",
.data = NULL,
.maxlen = 0,
.mode = 0555,
.child = child_table},
{
.ctl_name = 0,
.procname = NULL
}
};
static struct ctl_table root_table[] = {
{
.ctl_name = CTL_NET,
.procname = "net",
.data = NULL,
.maxlen = 0,
.mode = 0555,
.child = foo_table},
{
.ctl_name = 0,
.procname = NULL
}
};
Cheers!