Re: FreeBSD devfs support on NetBSD 5.0

On Sat, Jun 20, 2009 at 09:26:47PM -0400, der Mouse wrote:
> >>> (4) Structurally, permissions are (and should be) properties of the
> >>> device driver, not of some intermediate devfs object.
> >> I very strongly disagree with this. For example, I see it as
> >> totally reasonable to have different permissions on the very same
> >> device in /dev and /ftp-chroot/dev and /ntp-chroot/dev
> > That is entirely reasonable; the question is how best to accomplish
> > it.
>
> It can't be accomplished as long as the permissions are a property of
> the device driver, is my point - indeed, it can't be done whenever
> there *is* a "_the_ permissions" for a device driver.
True... but what do we do when the same issue arises for regular
files? The choices are to suck it up, make copies and use additional
tools to keep the copies in sync, or use nullfs and/or some similar
kind of chmodfs overlay that doesn't currently exist.
I guess the next question is this: why should a driver need to have
multiple context-sensitive sets of permissions when no other system
object does? Is there a problem here that couldn't be solved with
ACLs?
I don't have any good examples of chmod in /dev in mind, though. (This
is one reason that I'm myself perfectly prepared to accept static
configuration of device permissions.) All the cases I can think of
either involve tty permission handling (which can and should be
hardwired) or console hardware handled (handled poorly, but handled)
by /etc/ttyaction.
Maybe if we can develop a set of real use cases it'll help clarify
what's actually needed.
Back a *long* time ago when I wrote a replacement MAKEDEV for Linux,
which (as per the Linux intentions of the time) was capable of
regenerating /dev completely on reboot. It had a static config file
that let you give permissions for classes of devices (audio, video,
etc.) and I don't remember anyone ever complaining that this wasn't
general enough. Of course, that was a different world...
> > (I would characterize the underlying problem as "device special files
> > are a hack.")
>
> Possibly. But what's the alternative?
>
> You could move devices out of the filesystem entirely. [...]
Yes, that's a losing proposition.
> And if they're in the filesystem, you inherently have something very
> much like today's device special files. (The binding between a device
> special file and the driver backing it is currently done with two
> usually-small integers, but that's an implementation detail; the
> essential part, for our purposes here, is that there is a filesystem
> object that's somehow bound to the driver.)
There has to be a filesystem object that's bound to the driver, yes.
That's almost tautological if devices appear in the filesystem. It
also turns out to be necessary for those objects to look like device
special files: they need to have types VCHR or VBLK and set st_rdev to
something unique. If you make them regular files like the various
kinds of dynamic or virtual files found in a kernfs or procfs,
application software tends to become quite upset.
However, the traditional model for the way device special files
*work* isn't by any means necessary. Traditionally a device special
file is an on-disk inode that's loaded into a vnode belonging to some
on-disk filesystem instance. This vnode accepts various operations and
through the magic of specfs redirects those operations via [cb]devfs
into device drivers.
One alternative (the one I've been advocating for a while) is to give
the vnode(s) to the driver, which can then accept vnode operations
directly, and attach device driver vnodes into the filesystem
namespace with mount or something like mount.
This is what we (mostly) implemented in VINO twelve years ago:
vfs-level devices export arbitrary vnodes ("vinodes" in VINO parlance)
and there's a big pile of logic that binds them into a magic /dev,
which exists to support these bindings. This logic turned out to do
almoste exactly same thing as the filesystem mount code, just in a
different way; e.g. you don't need directories to serve as mount
points. By the time we realized this there was a lot of duplicate code
with completely different interfaces, so cleaning it up wasn't at all
trivial (especially since it touched namei) and never got done.
IIRC in VINO device permissions are configured by updating entries in
kernfs, but it's been a long time and I'm not sure how accurately I
remember.
Later on I hacked it up properly in a later prototype system, but that
kernel isn't (for a number of reasons) really fit for public viewing.
That's not the only possible alternative approach; another way is to
create more general on-disk binding objects (something like
statically-configured mount points) that go and find the devices and
bind in their vnodes. Another more radical way, probably not suitable
for Unix, would be to stick the *drivers* in /dev and chmod them with
some magic execute-on-open bit that gave you a channel down which you
could speak 9p or equivalent. And I'm sure there are a half-dozen or
more plausible other schemes.
as they say, the good thing about software is that it's infinitely
flexible, and the bad thing about software is that it's infinitely
flexible.
> Given these filesystem objects, I see no a priori reason to restrict
> what you can do with them - that is, no reason why chown, chmod, mv,
> etc, should not Just Work.
Enh. There's a set of things that's hard to do on virtual or transient
filesystem objects. There's another set of things that's already hard
to do on mount points. Meanwhile, the set of things that does and
doesn't work on device special files is already fairly arbitrary. For
example, you can mv them, but you can't cp them... or at least, if you
do the result isn't a copy of the device special file.
I don't see that there's anything absolute here; it's all tradeoffs.
> Those who have used early Eunice, in which / and
> /dev were not real directories but were faked up - actually, very much
> like some of the devfs proposals - will understand how important this
> flexibility can be.
I've often argued that / ought to be faked up, but doing it right
would be ... difficult.
> I still hold that devfs is a solution looking for a problem. The only
> real benefit I've seen anyone cite to a devfs is the lack of need to
> run MAKEDEV when hot-plugging something which wasn't anticipated when
> /dev was built. I would suggest that this can be provided for with a
> userland daemon which listens for device attach/detach events (a new
> kind of kevent, maybe?) and mutates /dev correspondingly. It seems to
> me this would get most of the benefit of the so-far-mostly-mythical
> devfs while avoiding almost all of the prices that have kept it mostly
> mythical so far.
Yes, probably.
> Also, much of the necessary kernel infrastructure (a
> generic framework to generate and handle device attach/detach events,
> for example) is needed either way.
It is much easier to build that framework (and make it reliable) if it
doesn't have to pass to userlevel. That's the catch.
--
David A. Holland
dholland%netbsd.org@localhost