create Linux kernel proc entry – some good-to-know tricky stuffs

It costs me 2 days to make a kernel module written few years ago back to work again. However, there is nothing fancy within the module except adding a new proc entry under /proc/sys/net/ipv4, which I would never know is the nightmare. There are a lot of posts introducing how to add a entry under /proc, like this one (http://www.rt-embedded.com/blog/archives/creating-and-using-proc-files/). And this post is intending to make it clear and to avoid wasting time thinking about why ‘this does not work’ (kernel oops!). No complicate details into the kernel but the focusing on the topic~

1. create_proc_entry()

This is the kernel function used to create a proc entry. The complete signature of this function (include/linux/proc_fs.h)

extern struct proc_dir_entry *create_proc_entry(const char *name, umode_t mode,
						struct proc_dir_entry *parent);

2. create_proc_entry(“whatever”, 0644, NULL);

This (should) always work! What we are doing is to create a new proc entry – ‘/proc/whatever’.

3. create_proc_entry(“sys/net/ipv4/whatever”, 0644, NULL);

It used to work before. BUT it does NOT work anymore! I am not sure the exact kernel version which started to prevent us from doing this. Kernel Oops (stack dump) will be generated then saying the kernel is not happy.

4. create_proc_entry(“whatever”, 0644, parent);

The ‘parent’ should be the proc_dir_entry pointing to the proc dir, like “/proc/sys/net/ipv4”. The common way to get of this parent proc dir is to use the kernel file structure and inode. For instance:

struct file *fp = filp_open(MODULE_PATH_DIR, O_RDONLY, 0);
parent = PDE(fp->f_dentry->d_inode);
filp_close(fp, NULL);
if (parent == NULL)
{
        printk(KERN_INFO “Get proc dir entry [%s] failure\n”, MODULE_PATH_DIR);
        return -1;
}
mod_entry = create_proc_entry(MODULE_FILE_NAME, 0644, parent);

However, as you might guess, it used to work before BUT it does NOT work anymore. Again I am not sure since when. When kernel Oops happens, you should know what is going on.

5. So what is the point here?

The point here is if you want to create a proc entry, consider to put it right under /proc instead of deep into the subdir of /proc, like the one mentioned above – /proc/sys/net/ipv4. I assume (have not gone thru the code to verify it) that the kernel does not allow to create any proc entry under the subdir of /proc for either security or management reasons. Instead, each subdir of /proc is viewed like an independent component, which needs specific system calls to add a new entry. Check the link here (https://lkml.org/lkml/2008/6/8/116). For /proc/sys, register_sysctl_table() is used to do that. Put it in anther way, put the new proc entry right under /proc is always straightforward.

6. proc_create()

This is the latest way to add a new proc entry, which means create_proc_entry is deprecated now. There is a good example from stackoverflow (http://stackoverflow.com/questions/8516021/proc-create-example-for-kernel-module). However, like you will see, the ‘parent’ is still NULL. Then I suppose this new function does not break my assumption above.

About daveti

Interested in kernel hacking, compilers, machine learning and guitars.
This entry was posted in OS, Programming and tagged , , . Bookmark the permalink.

1 Response to create Linux kernel proc entry – some good-to-know tricky stuffs

  1. hippogo says:

    hi, dave, this is hippo. enjoy your blog.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.