Where does the actual write happens when writing to a proc file?
Linux - KernelThis forum is for all discussion relating to the Linux kernel.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Where does the actual write happens when writing to a proc file?
Hi everyone,
I wanted to create a proc file in my driver which will be updated every time a certain event happens. I have read about this http://linux.die.net/lkmpg/x769.html
Here is the code in that site:
Code:
/**
* procfs2.c - create a "file" in /proc
*
*/
#include <linux/module.h> /* Specifically, a module */
#include <linux/kernel.h> /* We're doing kernel work */
#include <linux/proc_fs.h> /* Necessary because we use the proc fs */
#include <asm/uaccess.h> /* for copy_from_user */
#define PROCFS_MAX_SIZE 1024
#define PROCFS_NAME "buffer1k"
/**
* This structure hold information about the /proc file
*
*/
static struct proc_dir_entry *Our_Proc_File;
/**
* The buffer used to store character for this module
*
*/
static char procfs_buffer[PROCFS_MAX_SIZE];
/**
* The size of the buffer
*
*/
static unsigned long procfs_buffer_size = 0;
/**
* This function is called then the /proc file is read
*
*/
int
procfile_read(char *buffer,
char **buffer_location,
off_t offset, int buffer_length, int *eof, void *data)
{
int ret;
printk(KERN_INFO "procfile_read (/proc/%s) called\n", PROCFS_NAME);
if (offset > 0) {
/* we have finished to read, return 0 */
ret = 0;
} else {
/* fill the buffer, return the buffer size */
memcpy(buffer, procfs_buffer, procfs_buffer_size);
ret = procfs_buffer_size;
}
return ret;
}
/**
* This function is called with the /proc file is written
*
*/
int procfile_write(struct file *file, const char *buffer, unsigned long count,
void *data)
{
/* get buffer size */
procfs_buffer_size = count;
if (procfs_buffer_size > PROCFS_MAX_SIZE ) {
procfs_buffer_size = PROCFS_MAX_SIZE;
}
/* write data to the buffer */
if ( copy_from_user(procfs_buffer, buffer, procfs_buffer_size) ) {
return -EFAULT;
}
return procfs_buffer_size;
}
/**
*This function is called when the module is loaded
*
*/
int init_module()
{
/* create the /proc file */
Our_Proc_File = create_proc_entry(PROCFS_NAME, 0644, NULL);
if (Our_Proc_File == NULL) {
remove_proc_entry(PROCFS_NAME, &proc_root);
printk(KERN_ALERT "Error: Could not initialize /proc/%s\n",
PROCFS_NAME);
return -ENOMEM;
}
Our_Proc_File->read_proc = procfile_read;
Our_Proc_File->write_proc = procfile_write;
Our_Proc_File->owner = THIS_MODULE;
Our_Proc_File->mode = S_IFREG | S_IRUGO;
Our_Proc_File->uid = 0;
Our_Proc_File->gid = 0;
Our_Proc_File->size = 37;
printk(KERN_INFO "/proc/%s created\n", PROCFS_NAME);
return 0; /* everything is ok */
}
/**
*This function is called when the module is unloaded
*
*/
void cleanup_module()
{
remove_proc_entry(PROCFS_NAME, &proc_root);
printk(KERN_INFO "/proc/%s removed\n", PROCFS_NAME);
}
It looks simple but I cannot see the point where the actual write happens. The internal buffer used, procfs_buffer, is where the data from user space buffer is copied. I'm not sure if I am missing anything but procfs_buffer is not used anywhere aside from that. I was expecting a transfer from procfs_buffer to another address probably a member of the proc_dir_entry but there isn't any.
Regards,
archieval
Last edited by archieval; 11-19-2010 at 02:45 AM.
Reason: writing into a file in kernel space is bad
This may be less details than you like..it's a high-level overview of how proc works:
There is no actual file there, or write happening. What that snippet of code does is hook to /proc/<foo>, and whenever a user 'writes'(using echo, a pipe, or some other mechanism), that code executes procfile_write(), which is passed directly what the user wrote. The reverse happens if a user reads(cat, less, etc) that /proc/<foo> entry, the kernel calls procfile_read(), and returns whatever value that function returns.
Hopefully that makes sense...the summary is that there is no actual reading/writing. When you think of the file as being read or written to, it's really the respective read/write function being called and storing/returning a value.
This is very similar to writing a kernel module that utilizes /dev/<foo>, you define a read/write function that corresponds to userspace reading or writing to /dev, and you communicate with userspace using the same method the code snippet above uses.
Ok, now I think I get it a bit. The proc file above can only be modified by a user space application. After you create it initially, it has no value, so reading from it, will transfer empty content of procfs_buffer to the user space buffer. When no user space program writes to it, it will never have any value. When a program writes into it, it is stored in procfs_buffer, then will be used when a program reads it. Why the hell am I thinking too complicated when it was actually too simple! So the purpose of this whole code is for storage of data only. I should have gone read the previous topic before that, which changes the content of the proc file internally. And I should have not thought of a proc file as a "regular text file", but something more like a "device" (with the /proc/myfile as device file). And the code above is a device driver that will communicate with the "storage device" to store or read data from it. A "device driver" for no actual device!
So to integrate it to my actual device driver that updates something when an event happens, I would only need the read part since the procfs_buffer will be updated internally.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.