Click to See Complete Forum and Search --> : open from the kernel
kseeker
10-13-2003, 04:24 PM
The basic question is whether I can call open(2) from inside the kernel or if there is a more appropriate solution.
The background is that I inherited a software architecture where one kernel module that registers as a device driver relies on sending data to another built in device driver. It does this by insisting that a 3rd component open the target driver from user space and then calling that driver's write routine directly.
I would like to do something cleaner but it is not clear to me what that is. Can I simply call open myself or is there some other standard way to open a device file from inside the kernel?
bwkaz
10-13-2003, 07:32 PM
This is more of a programming question. Moved there. :)
But anyway, I don't believe you should ever call functions like open() from inside the kernel. There should be a way around it for you, but I'm not really getting the picture of how these kernel modules interact, so I can't come up with one offhand.
I think part of the problem may be terminology. You don't "open a device driver". You "open a device node" (or "open a device file"), and the driver (or kernel module) handles the open() call. The driver/module also handles read() and write() (it does this by registering callbacks with the VFS layer; these callbacks get run when the corresponding system call is invoked).
And you don't really "register as a device driver" -- all modules are device drivers, pretty much. You can register the existence of a device file/device node, which is the call that you use to give VFS the addresses of the callbacks for open(), read(), write(), and a couple others. And there are functions you use to register yourself as a module, I think.
I think a bit more info about these various modules (what they do, basically) might be helpful too.
kseeker
10-14-2003, 09:56 AM
Thanks for the move and the response, and sorry for the sloppy terminology. I'll try to clarify here...
Driver A (home grown) handles a set of device files and funnels the output (writes) on those nodes to Driver B (standard Linux driver) which writes them to a physical link. Input from that (dedicated) link is passed up from Driver B to Driver A which in turn passes the info back through the file system to the apps that opened the nodes handled by A. Basically, Driver A is a mux/demux channeling the apps I/O over a single physical link.
Again, Driver A insists that some application opens a particular one of the device nodes handled by driver B before any of the device nodes for Driver A are allowed to be opened. Also, the means by which Driver A sends data to Driver B is via the same write callback that B has registered with the VFS in a tty_driver structure that it has also exported so that Driver A can dig into it. Yuck.
Still hoping there is a better way, any help is appreciated.
bwkaz
10-14-2003, 08:17 PM
OK, I think I get the picture now. Thanks. :)
You might be able to call whatever function gets registered with VFS to handle open(). That ought to return a file handle, at least.
Unfortunately, I don't know how to get around it if that function is declared static in module B. Because if it is, the C language won't let you call it directly, you have to get a pointer to it from module B itself (the tty_driver struct that you're talking about), then call it through that pointer. Like you said, yuck.
Most device nodes that I've seen are set up this way, which probably does not bode well. It might be worth looking into anyway, though.
Is module A something like ESD or aRts basically? Might it work to move it to userspace instead, and handle the multiplexing there?
kseeker
10-14-2003, 09:44 PM
Thanks for your followup.
I have considered calling the Driver B open function directly since I already have a pointer to the tty_driver struct in Driver A. I am a little concerned that it may be opening a can of worms because I will have to set up the arguments correctly. I may have little other choice.
You ask exactly the right question about whether I can simply move Driver A into user space. I have asked that myself and am waiting for an answer (from colleagues). I have been told that there are other kernel components that use Driver A which it why it is in the kernel to begin with. My first step is to confirm/deny that point and then go from there.
Thanks again.
bwkaz
10-14-2003, 10:38 PM
It might be possible to split it up, too. Have one piece in userspace that handles the mux/demuxing, and another piece in kernel space that handles "everything else".
Dunno if that would work in your case, though -- it depends on the rest of the code.
kseeker
10-14-2003, 10:43 PM
an interesting thought... thank you.