Help developing a pseudo-device driver ?

Help developing a pseudo-device driver ?

Post by Case van Ri » Thu, 25 Feb 1999 04:00:00



Hi

Given 2 applications that both read/write to a file for output I m
trying to come up with a way to
let the second application use the output of the first as input.
Both these programs *want* filenames for input & output, so I cant just
program A | program B     .. I cant even create a FIFO device and let
the programs use
this for input & output, effectivly doing the same,  because the
programs find out they're
talking to a special file with fstat()  and try to lseek() and ioctl()
on these 'files' .. generatin  a
SIGPIPE or ESPIPE.

So I wanted to make a kernel module for a very simple device .. one that
these applications can
write to or read from ,  but it also implements lseek and ioctl  ..

Let me start by saying .. if there's an easier way to do this, Id love
to hear about it!
but, if there isnt, Ive been trying to do it like this:

open()  has a structure with (struct file*) entries for a 'reader' and a
'writer',  it decides  which 2
 processes are trying to hook up with eachother based on the struct
inode argument to open().
Once it has both a reader and a writer it will accept read() and
write() requests; The first process
to make the request ends up at a  module_interruptible_sleep_on()   loop
which checks for a
complementary request.  The second process makes the complementary
request, finds the other
process waiting, the driver performs the copy from user space buffer to
user space buffer,
wakes up the process that was asleep and returns both with the number of
bytes that was transferred.

the lseek()  and  ioctl()  handlers  just report whats going on at this
point ,  lseek() also adjusts
struct file->f_pos to the desired value.

In theory this should work fine, I think .. but in practice the process
thats supposed to write to this
device does :
open( .. O_WRONLY|O_CREATE, .)
FSTAT(5, ....)     tells it it's talking to a device
mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE,  429467295 , 0)    ???
ioctl(5, TCGETS,  0xbffffb0c )       ??
write(5,   ... , 4096)

 my device recognizes the open and ioctl()  just fine, but never gets
the write. Instead the  process
performing the write gets stuck in an uninterruptable wait .
The first thing I dont understand is the fd parameter to mmap(..)  ..
that doesnt look like a fd  does it ?
Second, the write() .. why doesnt this show up at my driver and where
is  the uninterruptable
wait coming from ? Im assuming this is related to the mmap()
Could I just flat out refuse the mmap() ? its not in my Fops structure
now, but maybe thats not good enough ?

open to any suggestions,
Casey

 
 
 

Help developing a pseudo-device driver ?

Post by Tony Hoyl » Thu, 25 Feb 1999 04:00:00



> Hi

> Given 2 applications that both read/write to a file for output I m
> trying to come up with a way to
> let the second application use the output of the first as input.
> Both these programs *want* filenames for input & output, so I cant just
> program A | program B     .. I cant even create a FIFO device and let
> the programs use
> this for input & output, effectivly doing the same,  because the
> programs find out they're
> talking to a special file with fstat()  and try to lseek() and ioctl()
> on these 'files' .. generatin  a
> SIGPIPE or ESPIPE.

If the feeder app is calling lseek then it really can't be made to work
in
a pipe.  For a pipe to work the data must be strictly sequential, since
there
is no conceptual way to seek within one (pipes do not actually contain
any data).

Either change the two apps so they work without lseek (ioctl should be
OK, but
usually pointless) or chain them with something like (A /tmp/$$; B
/tmp/$$; rm /tmp/$$).

Most apps accept '-' as the filename for the standard input.  Try using
that and
linking them with a normal pipe. (Heck, you could even use /dev/stdin if
you needed to!)

Quote:>lseek() also adjusts struct file->f_pos to the desired value

All you will achieve is creating a pipe which fakes an OK return from an
lseek, but the
resulting data will be meaningless, since it'll be in the wrong order.
Pipes have no
position, they are just links between applications.

Tony

------------------------------------------------------------------------------------
If Bill Gates had a dime for every time a Windows box crashed...
.... Oh, wait a minute, he already does.
------------------------------------------------------------------------------------

------------------------------------------------------------------------------------

 
 
 

Help developing a pseudo-device driver ?

Post by Case van Ri » Sat, 27 Feb 1999 04:00:00




> > Given 2 applications that both read/write to a file for output I m
> > trying to come up with a way to
> > let the second application use the output of the first as input.
> > Both these programs *want* filenames for input & output, so I cant just
> > program A | program B     .. I cant even create a FIFO device and let
> > the programs use
> > this for input & output, effectivly doing the same,  because the
> > programs find out they're
> > talking to a special file with fstat()  and try to lseek() and ioctl()
> > on these 'files' .. generatin  a  SIGPIPE or ESPIPE.

> If the feeder app is calling lseek then it really can't be made to work
> in a pipe.  For a pipe to work the data must be strictly sequential, since
> there is no conceptual way to seek within one (pipes do not actually contain
> any data).

> Either change the two apps so they work without lseek (ioctl should be
> OK, but usually pointless) or chain them with something like (A /tmp/$$; B
> /tmp/$$; rm /tmp/$$).

Im aware of the limitations of a pipe, but this is where the 'device driver magic'
comes in.

This driver is supposed to let a stream decoder (like an mp3 decoder) output to
an encoder (like an mp3 encoder or realaudio encoder which then feeds the output
to a streaming audio server (like icecast or the realaudio server.)  The idea is to
have
high quality (ie high bitrate) source files and generate variable bitrate streams on
demand
without actually generating intermedia files.

The normal decoding/encoding process doesnt require seeks but when a real-audio
client seeks forward or backward I do need the seek capability.  The way Im solving
this is
to let a 3rd process connect to this 'pipe' device, and whenever a seek occurs the
driver writes
a seek command to this 3rd 'controller' device which controls the decoder. (the xaudio
decoder
supports pause, seek, stop, play etc.)

Since I posted the original question I think Ive established that the driver cannot in
fact copy data
from the buffer provided to the write() handler to the buffer provided to the
read() handler  with
get_user() and put_user() since the handler is being called by either the writing
process *or* the
reading process, and cant access both address spaces at the same time. (Is this
correct  or  can
I just have the driver keep track of the respective address spaces ?)

I solved this with a buffer in the driver, so now the driver will copy data handed to
the write() handler, store it in it's queue, and copy it to the reading process in the
read( )  handler.  I think I read in the
kernel programmers guide that I can only allocate PAGE_SIZE bytes in a kernel module ..
can anyone
confirm this ?

Having gotten this far, the next thing Id like to do is add support for  mmap() since
thats what these
applications seem to want. Is there information out there about writing mmap() drivers
? The linux
kernel module programming guide doesnt cover this, and I cant seem to locate the kernel
programmers
guide anymore. Its no longer in the LDP directory on sunsite, and the link provided in
the README
there doesnt seem to exist :-/

Thanks!

Casey

 
 
 

1. STREAMS message from pseudo-device to pseudo-device

Hi everybody,

I have a kernel device driver programming related question for Solaris
2.6.

We have a packet classifier which sits between the IP pseudo-driver
and the network interface driver.

We need to send an unacknowledged message from the IP driver to our
classifier so as to pass on connection setup information. The classifier
is implemented as a pseudo device driver. We have plumbed the classifier
beneath IP, and now need a way to send M_PROTO messages from the IP driver
to the classifier. We have saved up the address of the device write queue
of our classifier in a global variable, but a putnext of a message from IP
onto the classifier's device write queue causes the machine to crash.

(1) In short, is there a way for M_PROTO messages to be transmitted from
IP to our classifier beneath it.

(2) Is there a way to set up a STREAM between two kernel pseudo device
drivers?

Thanks a bunch in advance.

Regards,
ravi

2. Memory Upgrade not working

3. Pseudo-Device Driver in Solaris 2.x

4. lpr-command and parallel-printer communication failed

5. SUMMARY: Is this a job for a pseudo-device driver?

6. How do I launch an X program from csh?

7. Is this a job for a pseudo-device driver?

8. Samba and Win NT 4.0

9. May 23 10:50:05 mwsbit04 pseudo: [ID 129642 kern.info] pseudo-device: devinfo0

10. HELP: configuring tun0 pseudo-device

11. Network Pseudo-device question

12. undefined pseudo-device abcd

13. pseudo-device error in messages