Subject: Re: dupfd hack and clonable devices
To: Christos Zoulas <christos@zoulas.com>
From: None <cube@cubidou.net>
List: tech-kern
Date: 11/17/2004 11:42:17
On Tue, Nov 16, 2004 at 03:59:37PM +0000, Christos Zoulas wrote:
> In article <20041116153712.GC11216@gallia.cubidou.net>,
>  <cube@cubidou.net> wrote:
[...]
> >The drawback of this is that it doesn't simply makes a character
> >device clonable, as I have to provide a fileops structure.  There
> >are two ways of doing that: providing my own (as systrace and
> >dmover do), or using vnops (as ptmx does).  The former introduces
> >a lot of complexity, the latter requires the correct device nodes
> >to exist in the file-system.
> >
> >Is my analysis correct?  Is there a simpler way to acheive what
> >I want to do (which, in case it's not clear, is to have a ethfoo
> >device that creates an interface for each open)?
> 
> Actually you don't need to provide device nodes in the second case.
> You only need device nodes if you are planning to access those nodes
> from userland. If the open file descriptor is all you need, then
> you don't need to create them. This is what is done for the master
> side of pty's in ptyfs. You don't get access to /dev/ptc/X,
> but you get a file-descriptor opened that points to it.

I'm not sure if I understand well enough how ptyfs works to completely
grasp your point, but I think I've made progress understanding the
issue.

What makes the difference between ptmx and ptyfs is that ptyfs has an
actual file-system to back it up.  The two methods of getting cloning
devices are actually "work on a new fd" or "work on a new vnode".
The former might be the easiest to implement, and that's more or less
how dupfd works, but it's hackish, since it propagates back to
sys_open where the fd can be actually managed properly.

ptmx is a bit in the middle in that respect, as what it does it
basically re-creating the fd to point to the correct device node.  So
it works by changing the vnode, but using dupfd to have that change
made.

Maybe I'm confused somewhere (and I surely would like to hear about
opinions in that area), but my idea of a cloning _device_ is something
like the following, which I naively implemented last night:  have a
new field in struct cdevsw (and struct bdevsw, too, but at first let's
keep it simple), say 'd_clone'.  In spec_open, that function, if it is
not NULL, would be called.  That way, the device driver can record any
initial state it wants, and present a new face to the caller.  The
easiest way to achieve that is to have d_clone return a new minor
number.  That way the device can create state as needed and index it
with the minor number.  It's up to the device to manage its minor
number addressing scheme.  The rest of the operations, up until close(),
will use the new minor number, so nothing else is required in the
device driver.

Of course, doing only this wasn't enough, because here I don't work on
a new fd, nor I work on a new vnode.  OTOH, it really feels like specfs
is the right place to do the cloning part, at least for devices such as
ethfoo of course, but also audio(4) to get multi-voice handling, and
dmover(4) could work that way instead of using dupfd and its own set of
fileops.

I haven't experimented yet with the ways of creating a new vnode, but
I think it could work.  The price will probably be to have vfs ops for
specfs, and using them to back up the new vnode.  The vnode on which
spec_open initially works on cannot be change since it's linked to the
underlying file-system, and any other use of the vnode will use the
same parameters.

Would the simple idea of providing specfs with vfs ops, and then
backing up the inital vnode and replacing it by a new one with the
correct pointers (and notably the correct dev_t number) in spec_open
be possible?

-- 
Quentin Garnier - cube@cubidou.net - cube@NetBSD.org
"Commala-come-five! / Even when the shadows rise!
To see the world and walk the world / Makes ya glad to be alive."
Susannah's Song, The Dark Tower VI, Stephen King, 2004.