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/