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
