ARTICLE

Procfs from the inside
Contributed by Fernando Apesteguia in Misc on 2006-03-20 14:59:21
Page 3 of 5

Implementing procfs

The Linux kernel implements a set of functions to create and manage procfs pseudo-files. These functions are exported by the kernel, so you can use them from a module. (I explain some of them):

  • create_proc_entry:Creates a new file under /proc. Parameters are the name of the file, the mode of the file and the parent directory (if null, /proc is assumed). You can also create symbolic links and directories with proc_symlink and proc_mkdir.
  • remove_proc_entry: Removes a file from the /proc hierarchy.

The creation functions return a pointer to a proc_dir_entry structure. This structure is used to specify the behaviour of the file when a read or write operation is performed. The proc_dir_entry structure is shown below (from /usr/include/linux/proc_fs.h)

struct proc_dir_entry {
unsigned int low_ino;
unsigned short namelen;
const char *name;
mode_t mode;
nlink_t nlink;
uid_t uid;
gid_t gid;
unsigned long size;
struct inode_operations * proc_iops;
struct file_operations * proc_fops;
get_info_t *get_info;
struct module *owner;
struct proc_dir_entry *next, *parent, *subdir;
void *data;
read_proc_t *read_proc;
write_proc_t *write_proc;
atomic_t count; /* use count */
int deleted; /* delete flag */
};

The two last pointers are related to the read and write functions respectively. Let’s assume that we have defined two functions:

static int my_read(char *page, char **start,off_t off, int count,
  int *eof, void *data){
  ...
  ...
}

and

static int my_write(struct file *file,const char *buffer,
unsigned long count,void *data)
{
...
...
}

All we need to do to link this operations to our file is:

my_entry->read_proc=my_read;
my_entry->write_proc=my_write;

What we can do in the body of these functions can be very complex. In the simplier case, if we want to read data from the kernel and make it available for user-land we have to print data in the page structure (with sprintf or whatever else function at your own).

When a user wants to write a data, we first have to read the data from buffer. But watch out! This buffer is in user-land so we need to copy to kernel-land by using copy_from_user function.

Let's see an example. We will create a file in /proc that returns the number of times the file has been read:

*test.c*/

#include  /*Working in kernel mode*/
#include  /*Writing a module*/
#include  /*We use procfs functions*/
static struct proc_dir_entry *my_entry; /*Our file entry*/
/*This is executed when the file is read*/
int
my_read_function (char *page,
char **buffer_location,
off_t offset, int buffer_length, int zero)
{
int len;
static int my_count = 1;
if (offset > 0)
return 0;
len = sprintf (page, "File read %d times\n", my_count);
my_count++;
*buffer_location = page;
return len;
}
/*This function is executed when the module is loaded*/
static int
enter (void)
{
printk (KERN_INFO "Module loaded\n");
my_entry = create_proc_entry ("my_test", 0444, NULL);
if (my_entry == NULL)
{
/*Failed when creating file */
printk (KERN_ALERT "Error while creating file\n");
return -1;
}
/*Set the read function */
my_entry->read_proc = (read_proc_t *)my_read_function;
my_entry->owner = THIS_MODULE;
return 0;
}
/*This is executed when the module is unloaded*/
static void
finish (void)
{
printk (KERN_INFO "Unloading module...\n");
remove_proc_entry ("my_test", NULL);
}
module_init (enter);
module_exit (finish);
To compile this, create a Makefile with these lines:
obj-m += test.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

This program creates a file named my_test that counts the number of reads.

I know this could appear a bit confusing and dark. Writing kernel modules is not as easy as programming a Hello world application with libc and other support libraries. But I hope this will help you to understand the internals of procfs. Reentrancy and concurrency are not trivial problems we have to deal with if we are working in kernel mode. So take it easy. This document is not trying to discover all the knowledge about kernel programming or module writing. This is only an overview about kernel processes needed by procfs to work.



Article Index
Procfs from the inside
OS basics: user-land vs. Kernel-land
Implementing procfs
Some examples on using procfs
Conclusions
 
Discussion(s)
Good information
Written by beparas on 2008-07-04 05:39:48
This is article contains good information.
Thank You
Discuss! Reply!