[LWN Logo]

To:	linux-kernel@vger.rutgers.edu
Subject: Re: devfs - the missing link
Date:	Sat, 20 May 2000 03:13:27 -0600
From:	James <james@amethyst.nurealm.net>

I read through Neil Brown's reflections on the devfs, picked up by the Linux
Weekly News.  I have some thoughts to share, somewhat naive, as I haven't
been following the devfs debate very closely.

One of the things that stood out for me was Neil's description of a "3 1/2"
level hierarchy, where the "half" level attempts to address "sub-components"
of a device: partitions on a hard disc, or rewind behavior on a tape drive,
for example.  For the devfs itself, what I remembered as an important
advantage was the devfs attempting to address the sometimes intractable
number of these sub-components, as, for instance, the possibly large number
of drive partitions in a disc array.  Also, even for devices which might not
be strictly "sub-components", all the tty*, say, I notice that there can be
a large number of devices, all  similar, most of which aren't active.

So I'm thinking, how much of the motivation for the devfs is traceable to an
awkwardly addressed "degree of freedom" (designating sub-components) in the
"device as file" unix model?  What solution might I like to see if "how to
designate sub-components" was the only thing I wanted to change?

Neil points out that /dev/ devices are not really physical devices, but are
a kind of virtual device, a "layer of interpretation", implying an
organization and transformation of data, as in, perhaps, an encrypting loop
device filesystem.  I would say that these device "sub-components" are the
"published interfaces" to the underlying device hardware.

What I look for in the nature of usability is a simple classification of
these published interfaces.  Any protocol for enumerating or designating the
underlying device hardware is, in and of itself, of no useful consequence.
So, in practical terms, I don't need to see device entries for hardware, I
need to see device entries for device drivers, those specific software
modules which make active each interface.  Now, I don't think there are too
many of those, and there are only a few, really, that I use in any
particular system.

Since, practically, there's a one to one relationship between driver modules
(whether or not they're compiled into the kernel or loaded separately) and
active device entries, those connected to working hardware, it seems
to me that the _device_driver_ itself should be responsible for knowing
everything about: how many device interfaces to create for that class of
interface, which and how many functional interfaces to create for
multi-personality hardware, which permissions to apply to each interface,
what ownership to apply to each interface, what specialized character to
establish for the interface, and such other needful configuration.  For that
matter, the device driver might as well: scan the system for hardware,
create the appropriate device entries, and configure the device interface,
as well as configure the hardware itself, whether or not this is done
automagically or under direction of a configuration file in /etc/.

Now (here's the part where I beat my drum a bit), my reason for preferring
an approach not quite like the devfs is the sometimes chaotic way that
configuration data is specified.  Configuration data is sometimes: 1)
hardcoded at compile time 2) held in an environment variable 3) placed on
the command line 4) made a directory entry in a symlink farm 5) held in a
directory entry 6) made dependent upon the file name 7) held in a file in
the parent directory 8) in a file in /usr/lib/ 9) in a file in /etc/
10) held in hardware 11) held in the kernel.  Diversity is a wonderfully
artistic, but uniformity is easier to administer.  I don't like when:
hardcoded data is wrong for my system, an environment variable is ignored, a
directory file is used as a program's configuration file, an automagical
configuration process guesses wrong, or a package's configuration files are
scattered all over the filesystem. 

With respect to the devfs, I'm concerned that what appear to be functional
issues are actually ambiguities, or disagreements, about where configuration
data is stored or should be stored.  For example, some dynamic device
configuration info is kept in /etc/modules.conf (irq, port), but after that,
there is no uniform convention for deciding how to configure a device.

Some device hardware must be configured prior to activating a device
interface, with, for instance isapnp and /etc/isapnp.conf.  Some device
hardware must be configured after activating the device interface, as with
hdparm.  There is an /etc/fdprm for setfdprm, but no /etc/serialprm or
/etc/hdprm for setserial or hdparm, which use command line parameters.  A
hardrive's partition info is held within the hard drive itself, in the
partition table, and copied to the kernel.  There is no
/etc/hd/<partition_table>.  Hard drives even have multiple layers of
abstraction.  First, hard drives have a device entry, which can be activated
manually with insmod or automatically by kmod, possibly using
/etc/modules.conf or the command line.  Second, hard drives may have a mount
point, which is not itself any longer a device.  This mount point is
activated with mount, and can use either the command line or /etc/fstab.
Networking interfaces don't even get device entries - they just have context
specific interface names.  There is no /dev/eth0/1, not even a device entry
for an ethernet card, except for sometimes, as with the Myricom Myrinet
board.  Network interfaces are activated with ifconfig which uses command
line parameters.  There is no /etc/if.conf.  More network interface
configuration is done automagically with policy based routing in the Linux
kernel.  A little more network interface tweaking can be done manually with
route, which uses command line parameters, or automatically with routed
which also looks into /etc/gateways.

Some system resources are activated automatically, some manually.  Some
hardware subsystems have device files, some do not.  Some device drivers
have /etc/ configuration files, some use command line parameters.  Some use
both.  Some don't want either.  It all seems pretty ad hoc, but I also think
there's a pattern of common usage in there... somewhere.

So, suggestions for a devfs device tree (I think this means I like the
original devfs naming scheme best):

1) Only populate the top level of the device tree with the device interfaces
created by actual device driver modules, those "sub-component gateways".  So
at the top level there exists only, say, a /dev/scsi/ or /dev/eide/
directory, rather than a long list of hard disc device files.  Of course,
use subdirectories as appropriate: /dev/scsi/hdpartition/,
/dev/scsi/cdfiletype/.  All that matters is how the interface appears, not
what or where the underlying hardware is.

2) Conceptually, retain the major:minor organization, interpreting it
strictly as "interface class:instance of class".  Device special files would
be created by the devfs under the top level interface directories which
describe the nature of the interface.  The device special files are each
similar instances of the parent interface.

3) Put the configuration data, all of it, including initial file
permissions, in regular files in /etc/.  Have a policy for localizing device
special file configuration data.  (Symlink farms are a bad idea.)

Longer term: Develop a uniform interface handling policy.  Develop a common
approach to the class of activation/configuration commands: hdparm, isapnp,
*set*, *tune*,  *config, mount, insmod, and such.

Should configuring hardware interfaces require iterating each of maybe six
different configuration commands, then iterating each command with a
different set of command line parameters?  Should configuration data be
specified using a dozen different schemes just because it can be done?
Seems kind of silly.

What about device interfaces?  Why should some hardware have user level device
interfaces while some hardware interfaces are protected, kernel level only?

Should all hardware have a user level interface, even though such interfaces
are not absolutely essential?  or should user level interfaces be
deprecated?  Should "losetup -e blackice /dev/loop0 /dev/eth0:0", or
something like it, be possible? allowable?

I'd like to see the concept of user level device interfaces be extended.
It's a powerful abstraction.


James Feeney


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/