Let me present my case in question form: is is sufficient to wait until
after a driver's open is called in order to replace a stream head if
necessary (because of a minor change by the open routine), or are there
cases where that's too late?

If it's ever too late (and I believe there are such cases, though I'd
be hard-pressed to think of one right now), then it's not good enough
to deal with a minor change after the fact, it must always be
anticipated if it's possible.  And, I further believe, it's always
possible.

There is only one way I can think of to anticipate a minor change by
a driver open, and that is to pass in a new head every time, and if
the minor passed back is already in use, throw it away and use the
one already in use instead.

A driver should be able to detect if it's about to open an already
open STREAM.

I'm willing to be proven wrong about this, but I would like for you
to test it to make sure.  And it's easy enough to test - on Solaris,
Try opening a non-cloning device a second time without closing it
the first time.  Add a debug statement to the driver open, and print
the queue address passed in.  If it's the same, I'm wrong, but if
it's different, it's at least possible that I'm right.

Where LiS is concerned, I wouldn't doubt that LiS reopens a STREAM
when it should (at least right now, because FIFOs/pipes are working
in this respect); the question is whether or not the driver open
should be called for each concurrent open.  I agree with your original
post that LiS may not be doing that, but I am suggesting that maybe it
should, just not in an obvious way.

-John

David Grothe wrote:
At 09:46 AM 10/8/2003 Wednesday, John A. Boyd Jr. wrote:

There are two obvious ways cloning can be done: one is via the CLONE
major, the other is with the CLONABLE bit set.  I don't remember the
logic now, but I'd specifically determined (a while ago) that every
STREAMS implementation will do one thing for sure when cloning is
possible: pass an unused, available STREAM head to the driver open.
This is to ensure that if the driver open decides to clone a new STREAM,
this right choice will have been made.  I take this as an implicit
requirement, by the way, until someone can prove differently.


The exception is a for a directed re-open of a stream.

The alternative, as I believe Ragnar has speculated, is unworkable.  A
STREAM head once finally open must correspond to a single minor device,
and LiS accomodates that case by finding the head corresponding to
the driver open's returned minor device, if one is found, throwing away
the new head, since it isn't needed.  But the alternative case can't be
so easily accomodated, namely, passing in an open head that is in use
when cloning (i.e., changing the minor device) is possible.


In LiS if a driver in receipt of a non-clone open, maybe even a reopen, changes the minor device number then the executive will either change the stream head structure (if the new minor already exists) or operate the stream with the new minor label (if the new minor did not already exist). LiS simply trusts the driver to make sense of such a situation, and thus does not attempt to prevent it.

The one-to-one correspondence between stream heads and {maj,min} device ids is preserved.

But here's the interesting case: cloning does not have to be explicitly
specified by one of the above obvious methods - it's always possible for
a driver open to change minor device number, whether cloning was
indicated or not, and the effect must be the same as cloning. Because of
that, all STREAMS implementations that I have used assume this
possibility, by always passing a new stream head to a driver open
routine (at least, that's my recollection; someone might want to check
this, but I do remember setting up tests for it on different systems,
none of which I have access to anymore).


It would be fine with LiS if a driver did the following, for instance. Suppose that /dev/foo maps to {245,0} and that the driver open for foo changes the minor to some unique value {245,n} on each call to open; a direct open, not through the clone driver. In LiS this is equivalent to a clone open and will reuse the stream head originally passed in as {245,0}.

By the way, the dev_t * that LiS passes to the driver open points to a local variable in the LiS open routine and not to the sd_dev field of the stream head structure. This gives LiS a chance to evaluate the change before committing it to the stream head structure.

If a STREAMS subsystem doesn't always pass a new head to a driver open,
it opens itself to the possibility of a driver requesting a new minor
device for an already open stream, and changing the minor device of an
open stream is not a good idea; it can compromise not just the STREAMS
subsystem, but the OS as well.


I don't see that it is fatal to do this. Just ill-advised. As long as LiS keeps its stdata structures straight the rest of the OS can't tell.

<I am fairly opinion-less about FIFOs, and so will not comment.>

I would suggest then, that the rule for STREAMS generally, not just LiS,
is that a driver's open should be called if a new head is being passed,
but only if a new head is being passed.  If LiS doesn't now work this
way, it should, in my opinion (I know I've changed the code to do this
in the past, but I haven't checked this for a long time).


Re-opening an existing stream is the exception to this rule.

It's certainly not impossible for non-FIFO STREAMS to be reopened.  It's
also not against the rules for a driver to change not just the minor
number, but the major as well.  It may not be recommended, but it's
certainly possible, and I believe intentionally so.  Changing the major
is even necessary when the CLONE major is used, just to state the
obvious case.  It is only an error when the driver changes the major
to a non-STREAMS major, which can be checked for.


Without looking, I think the qattach routine will catch a non-STREAMS major since it needs to associate the streamtab structure with the created queues. It needs for the major to be a valid STREAMS major in order to pick the correct streamtab structure.

-- Dave




_______________________________________________
Linux-streams mailing list
[EMAIL PROTECTED]
http://gsyc.escet.urjc.es/mailman/listinfo/linux-streams

Reply via email to