LinuxQuestions.org
Go Job Hunting at the LQ Job Marketplace
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 05-12-2008, 12:10 PM   #1
jiml8
Senior Member
 
Registered: Sep 2003
Posts: 3,171

Rep: Reputation: 115Reputation: 115
kernel file handles vs userspace file handles.


In a kernel driver I am writing, I have a need to maintain context information pertaining to multiple users who may be simultaneously using the driver.

I have decided that the easiest way to maintain this context information is by tracking the file handles associated with userspace open() or fopen() calls. In fact, I don't really see another way to do it; the file handle information is all I have to reliably go by. However there is a high wall between kernel space and user space, and I am having a lot of trouble figuring out how to get the necessary information across that wall.

Now, these open files are device files, and the basic problem is this. After opening a device file, the userspace applications often have a need to send commands to the driver to configure the device in a specific fashion. Further, this configuration may and usually will vary from userspace application to userspace application AT THE SAME TIME, and when the driver talks to the device for the user, it has to configure it properly for what that user wants to do.

My problem is that the open() and fopen() commands are defined by the system in terms of what they do, and I need a way to relate the file handle that is returned in the userspace application to the file handle the kernel maintains so that when the userspace application sends a command it can also send along the file handle so that the kernel driver knows what user is configuring it.

I cannot use inodes because multiple users might have the same device file open; they would show the same inodes.

I have been writing some test code to traverse the kernel file structure, looking for useful information, but there are a lot of sub-structures and sub-sub-structures under it, and so far I have not found useful information.

Someplace in the kernel, the file handle returned to a userspace application is related to the file structure that is kept in the kernel. This relationship might include the PID of the userspace process; I don't know, but I could deal with that.

Does anyone here know where that information is kept?
 
Old 05-12-2008, 03:25 PM   #2
shishir
Member
 
Registered: Jul 2003
Location: bangalore . india
Distribution: openSUSE 10.3
Posts: 251

Rep: Reputation: 33
I think kernel is not the place where you will find the user FILE struct that you might be looking for, glibc is the place, as the struct FILE that is is typedef'd to _IO_FILE contains the file descriptor, _fileno as a member, that gets returned when fopen calls open() internally.

kernel maintains struct file (lowercase), as I am sure you must have figured out, and each fd has its mapping struct file when open is used.

Last edited by shishir; 05-12-2008 at 03:30 PM.
 
Old 05-13-2008, 05:44 AM   #3
archieval
Member
 
Registered: Apr 2007
Location: Philippines
Distribution: Kubuntu, Ubuntu, CentOS
Posts: 289

Rep: Reputation: 41
My assumptions to your driver is that, for every file handle, there is one corresponding device? or there is only one device, and many applications are accessing it at the same time? If it is the later case, have you consider mutual exclusions? since you said may applications can configure it at the same time? or am I just mistaken this phrase?

Quote:
from userspace application to userspace application AT THE SAME TIME
I think you can use the inode, perform an ioctl with process id as your argument (can be in a struct with other information you need)

Code:
struct pid_t {
 int num;
 /* other info */
}


in app:
pid_t pid;

pid.num  = getpid();
ioctl(fd, IOCTL_KNOW_USER, &pid);


in kernel driver:
my_fops.ioctl = my_ioctl;


my_ioctl(struct.... )
{
     ...

     case IOCTL_KNOW_USER:
          pid_t tmp;
          copy_from_user(&tmp, __user &arg, ...)
     ...
}

sorry I forgot the syntax of copy_from_user. But I hope you get my point.
 
Old 05-13-2008, 06:51 AM   #4
shishir
Member
 
Registered: Jul 2003
Location: bangalore . india
Distribution: openSUSE 10.3
Posts: 251

Rep: Reputation: 33
file->fown_struct in kernel contains the pid information, you might want to get that information back to user space. My only question is ; how does this help you? If I understand the question correctly, it means to say that different processes might have configured the device in different manners, how does the driver know which process should get what services.

So either have a filter in the user-space that knows what it is asking for and then deciding if it should use it (bad idea), or the driver in kernel space should know as to what capabilities/services are being configured for a particular process.

This should be do-able, as you can map just the pid to capabilities.
 
Old 05-13-2008, 09:40 AM   #5
jiml8
Senior Member
 
Registered: Sep 2003
Posts: 3,171

Original Poster
Rep: Reputation: 115Reputation: 115
Quote:
Originally Posted by archieval View Post
My assumptions to your driver is that, for every file handle, there is one corresponding device? or there is only one device, and many applications are accessing it at the same time? If it is the later case, have you consider mutual exclusions? since you said may applications can configure it at the same time? or am I just mistaken this phrase?
One device, many users. No mutual exclusions; this is real-time and on the fly, and the driver has to handle configuration issues to satisfy each user. I have built that capability into it, but am trying to find a way to uniquely identify the users. I can use PID so long as I can also uniquely identify the open() or fopen() with that PID.
 
Old 05-13-2008, 10:00 AM   #6
jiml8
Senior Member
 
Registered: Sep 2003
Posts: 3,171

Original Poster
Rep: Reputation: 115Reputation: 115
Quote:
Originally Posted by shishir View Post
file->fown_struct in kernel contains the pid information, you might want to get that information back to user space. My only question is ; how does this help you? If I understand the question correctly, it means to say that different processes might have configured the device in different manners, how does the driver know which process should get what services.
Well now, that is the problem. I have defined a user_context structure that the driver maintains with all information for this user in it. When the user does a read() for instance, the driver identifies the user, checks the context struct, configures the device, reads the data, and returns it. The issue is that the read() command leads to a pointer to a kernel file structure being passed into the driver's read routine, and somehow I need to extract information from that file structure that lets me identify the user uniquely.

I believe you meant to say that file->f_owner contains PID information (f_owner is type fown_struct), but the member file->f_owner.pid contains a zero when I look at it.

Quote:
So either have a filter in the user-space that knows what it is asking for and then deciding if it should use it (bad idea), or the driver in kernel space should know as to what capabilities/services are being configured for a particular process.

This should be do-able, as you can map just the pid to capabilities.
Well, that is the idea. But when I find a zero for the pid in that member, I find myself at a bit of a loss.

specifically, the line:

printk("<1> PID is %x\n",filp->f_owner.pid);

is returning "PID is 0" when placed at the bottom of the driver's open routine, just ahead of the return statement.
 
Old 05-13-2008, 02:27 PM   #7
shishir
Member
 
Registered: Jul 2003
Location: bangalore . india
Distribution: openSUSE 10.3
Posts: 251

Rep: Reputation: 33
cant you just use "current" macro to get the pid? I mean, the read calls have to be in process context, and current should give you the calling process' PID. This unless I am missing something. Another way to get this info could be to do an fcntl from each process to set owner for that 'struct file'. like so :
Code:
fcntl(filedesc,F_SETOWN, getpid());
I found it to work, you can use the wrapper inline functions to get the pids from the struct pid:
Code:
pid_nr(fi->f_owner.pid)
which returns pid_t. I found this to give me the pid.

I hope this is something that you are looking for.

Last edited by shishir; 05-13-2008 at 02:30 PM.
 
Old 05-13-2008, 06:32 PM   #8
jiml8
Senior Member
 
Registered: Sep 2003
Posts: 3,171

Original Poster
Rep: Reputation: 115Reputation: 115
The current macro got it. That was just what I needed, and I didn't know about it. Thanks.
 
  


Reply


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
Robust NFS file handles traene Programming 2 03-29-2007 06:36 AM
How Fedora linux kernel handles ipsec packets ahm_irf Linux - Networking 1 02-23-2007 12:35 PM
Open file handles - identifying locks KimVette Linux - General 2 09-24-2005 11:50 AM
Not Enough File Handles Jaqflash Mandriva 4 03-08-2005 05:30 PM


All times are GMT -5. The time now is 06:40 AM.

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