LinuxQuestions.org
Review your favorite Linux distribution.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Software > Linux - Kernel
User Name
Password
Linux - Kernel This forum is for all discussion relating to the Linux kernel.

Notices

Reply
 
Search this Thread
Old 11-19-2010, 12:59 AM   #1
archieval
Member
 
Registered: Apr 2007
Location: Philippines
Distribution: Kubuntu, Ubuntu, CentOS
Posts: 289

Rep: Reputation: 41
Question 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
 
Old 11-19-2010, 08:20 AM   #2
module0000
Member
 
Registered: Feb 2010
Location: USA
Distribution: RHEL
Posts: 36

Rep: Reputation: 15
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.
 
Old 11-19-2010, 02:58 PM   #3
nini09
Member
 
Registered: Apr 2009
Posts: 978

Rep: Reputation: 67
You need modify procfile_write function to write new value to local variable in driver module after you get new value from user space.
 
Old 11-19-2010, 07:05 PM   #4
archieval
Member
 
Registered: Apr 2007
Location: Philippines
Distribution: Kubuntu, Ubuntu, CentOS
Posts: 289

Original Poster
Rep: Reputation: 41
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.

Thanks everyone!

Regards,
archieval
 
Old 11-21-2010, 11:43 PM   #5
AwesomeMachine
Senior Member
 
Registered: Jan 2005
Location: USA and Italy
Distribution: Debian jessie/sid; OpenSuSE; Fedora
Posts: 1,591

Rep: Reputation: 162Reputation: 162
/proc is a virtual filesystem. It's just values within the kernel or links to device files.
 
  


Reply

Tags
edit, file, proc, write


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] How do you write to a proc file from a user program? beaglebird Programming 3 11-02-2009 01:13 AM
bash: renaming file extension based on actual file type alekone Linux - General 9 12-28-2008 09:12 AM
writing a structure to the a entry in /proc linuxdoniv Programming 2 03-20-2008 07:05 AM
Why can't a universal progarm write drivers based on the actual hardware it sees? SoccerballTux Linux - Software 3 06-09-2005 09:59 AM
writing to proc module dmaxj Linux - General 5 07-02-2003 09:44 AM


All times are GMT -5. The time now is 09:45 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration