How can I read large data from proc file?
Question
I'm trying to write a kernel module which writes some data to a proc file. I'm trying to write something like 5000 characters but when I say $>cat /proc/myentry I can read only 1000 characters.
int procfile_read(char *buffer, char **buffer_location, off_t offset, int buffer_length, int *eof, void *data){
int ret;
static char my_buffer[4096];
if (offset > 0) {
ret = 0;
} else {
ret = sprintf(my_buffer, LARGE STRING HERE);
}
*buffer_location=my_buffer;
return ret;
}
This is my code. Thanks in advance.
Solution
I had exactly this problem.
One issue in the original post, the if (offset>0)
is used many times in examples of small proc files. The read is called multiple times until we return a 0 to indicate that there is no more data. So the if (offset>0)
means we return (length of the buffer) as 0.
There are 3 ways to return data with this function. Look at the source code comments, line 75 onwards :
For large files (method 2 from comments), I did the following :-
- For each lump of your large data, copy 'buffer_length' of data to 'buffer'.
- Set '*start' (or in your case *buffer_location) to 'buffer'.
- return the amount of data you wrote (typically 'buffer_length')
Finally, all data will be written and you return 0.
This worked for me with several Meg of data.
OTHER TIPS
I am not a kernel expert, but in linux-3.1.6/fs/proc/task_mmu.c
I see some code like
seq_printf(m,
"VmPeak:\t%8lu kB\n"
"VmSize:\t%8lu kB\n"
"VmLck:\t%8lu kB\n"
"VmHWM:\t%8lu kB\n"
"VmRSS:\t%8lu kB\n"
"VmData:\t%8lu kB\n"
"VmStk:\t%8lu kB\n"
so this suggests that you might want to use seq_printf
not sprintf
.... The m
is a
struct seq_file *
pointer.
As a general rule, you'll learn a lot by studying the free software source code which you are extending. In your case, it is the Linux kernel source code