The Bullet Points: Linux 2.4 - Part Deux
Every so often, something happens that is so breathtaking, so absolutely amazing, that it changes the world. Linux 2.4 still isn't one of those things. Linus' rapid-release plan didn't actually rapidly produce a new kernel, not at the rate many developers (myself included) expected. This article is an addendum to “The Bullet Points” (January 2000) and a followup to “Linux 2.4 Spotlight: ISA Plug-and-Play” (February 2000). For a more complete rundown of Linux 2.4, see “Linux 2.4 Scorecard” and “Wonderful World of Linux 2.4”, available on Linux Today (www.linuxtoday.com).
Linux 2.2 took just over a month during its “pre-” stage, ditto with 2.0. While the 2.4 kernel is in the final development cycle, this pre-series has been extended several months and it's still difficult to predict how long it will take for the official release. The 2.2 kernel had some “brown bag” problems that I'm sure Linus would not be interested in repeating. According to the recent 2.4 bug list, there were 12 very important bugs that need fixing in the current pre-releases, 26 less important ones, several more minor minor ones, lots of things to merge and verify and other similar things. This list grows smaller daily, but it's still a big list.
Alan Cox's recent work on the “ac” series of kernels has helped to stabilize the code, but a number of items remain on the “must fix” list. I expect 2.4 to be released in a couple of months. The actual date of release, however will be entirely up to Linus.
And now, in no particular order, more of the new features of Linux 2.4.
Nearly every variant of UNIX accesses block and character devices through a common model: special device files in the /dev directory. Unfortunately, different UNIX variants name these devices in drastically different ways. BSD variations, for instance, refer to hard disks as /dev/wd* instead of /dev/hd*. (The characters “wd” stand for Western Digital, the manufacturer of IDE hard disks.) Unlike Linux, some UNIX variants use the /dev directory for network devices, too (e.g., eth0).
Although the naming of devices is different across UNIX variants, the method of how these devices communicate with the kernel is generally the same. Under Linux 2.2, special files (device nodes) for each accessible device are placed in the /dev directory. The device nodes are just two values, a major and minor number. The major number generally correspond to a driver or subsystem in the Linux kernel. The minor numbers generally corresponds to a sub-function or sub-device (e.g., a specific partition on a hard disk). Communication is actually done with these numbers. The names of the device nodes are standardized, but could be called anything an administrator wanted. (All Linux distributions today use the same standard naming scheme provided as a document with the kernel.)
There are several shortcomings of the 2.2 /dev model. First off, it uses a finite numeric name-space. Inevitably, we run out of numbers naming new devices in the standard. Second, modern devices (such as USB) don't lay well against a major/minor arrangement. Even complicated partitioning schemes reveal limitations in the current infrastructure. As it's impossible to know in advance which devices a user will install on their system, distributions create hundreds (sometimes more than a thousand) of device nodes in the /dev directory. Only a handful are used on a given machine; the rest remain to satisfy all possible configurations of all compatible hardware devices. It's a bit crazy, when you think about it. To better meet the demands of a more plug-and-play world, Linux 2.4 introduces the Device Filesystem (DevFS): in an elegant reworking of /dev, only configured devices are listed.
DevFS is a kernel-based file system. Like /proc, DevFS is seen in the filesystem tree (as /dev) but never gets “synced” to a physical device; /dev stays in RAM. Whenever a driver is loaded into the kernel and the device is detected, appropriate entries are added to the /dev tree.
Besides cleaning out the file system tree, DevFS will be faster, too. Here's how it works. Communication is direct; when you open() a file, you are communicating directly with the driver. Under 2.2, when a normal device node is open()ed, the kernel looks up the major device number in a table and calls a function. The actual driver then works out the specific device using the minor number. DevFS removes a layer of indirection. Now programs talk to drivers, not nodes.
With the introduction of DevFS and deprecation of device nodes, Linus has decided 2.2 device nodes are too limiting and going the way of the dodo. Nearly all DevFS node names are different than their major/minor counterparts, usually very different. Device classes are now categorized in subdirectories (structurally similar to /proc/scsi/*). For compatibility with 2.2 systems, administrators may still use old-style nodes (with the devfsd d<\#230>mon), but they are deprecated.
Unfortunately, there are some problems with DevFS as well. The permissions are more difficult to manage in the new system. Device permissions are allocated by the drivers, rather than by nodes in the file system. Changes to permissions can be made, but they are forgotten each time the module is loaded (or on reboot). Drivers (part of the kernel) name themselves, hence controlling the naming conventions and /dev layout, hence setting policy which is considered a bad thing. You can move (or rename) DevFS files after boot, or change their permissions, but you start with the kernel's policy. (Scripts are available to record the state of /dev at shutdown.) Presently, it's not clear which routines the distributions will use, or if they will even use DevFS. DevFS is still “experimental”, after all, though that may change before release.
While setting policy in the kernel is considered a bad thing, the many wins of the DevFS model have convinced Linus that the new way is the right way. Work is being done to make DevFS more “friendly” to administrators stung by its downsides—some of this is likely to make its way into the kernel before Linux 2.4 officially ships.