Gentoo Logo
Gentoo Logo Side

Device File System Guide

Content:

1. What is devfs?

The (good?) old days 

Traditional Linux implementations provide their users with an abstract device path, called /dev. Inside this path the user finds device nodes, special files that represent devices inside their system. For instance, /dev/hda represents the first IDE device in their system. By providing device files to the users, they can create programs that interact with hardware as if the hardware was a regular file instead of using special APIs.

The device files are split in two groups, called character devices and block devices. The first group consists of hardware of which read/writes are not buffered. The second group naturally consists of hardware of which read/writes are buffered. Both devices can be read one character at a time, or in blocks. Therefore, the naming might sound confusing and in fact is wrong.

If you take a look at a certain device file, you might find something like this:

Code Listing 1.1: Checking the information of a device file

# ls -l /dev/hda
brw-rw----    1 root     disk       3,   0 Jul  5  2000 /dev/hda

In the previous example we see that /dev/hda is a block device. However, more importantly, it has two special numbers assigned to it: 3, 0. This pair is called the major-minor pair. It is used by the kernel to map a device file to a real device. The major corresponds with a certain device, the minor with a subdevice. Seems confusing? It isn't.

Two examples are /dev/hda4 and /dev/tty5. The first device file corresponds with the fourth partition on the first IDE device. Its major-minor pair is 3, 4. In other words, the minor corresponds with the partition where the major corresponds with the device. The second example has 4, 5 as major-minor pair. In this case, the major corresponds with the terminal driver, while the minor corresponds with the terminal number (in this case, the fifth terminal).

The problems 

If you do a quick check in such a /dev, you'll find out that not only all your devices are listed, but all possible devices that you can imagine. In other words, you have device files for devices you don't have. Managing such a device group is cumbersome to say the least. Imagine having to change the permissions of all device files that have a corresponding device in your system, and leaving the rest of the device files as they are.

When you add new hardware to your system, and this hardware didn't have a device file previously, you would have to create one. Advanced users know that this task can be accomplished with ./MAKEDEV inside the /dev tree, but do you immediately know what device you have to create?

When you have programs interacting with hardware using the device files, you can't have the root partition mounted read only, while there is no further need to have it mounted read-write. And you can't have /dev on a seperate partition, since mount needs /dev to mount partitions.

The solutions 

As you can imagine, the kernel hackers have found quite a number of solutions to the aforementioned problems. However, many of them had other flaws as described in http://www.atnf.csiro.au/people/rgooch/linux/docs/devfs.html#faq-why. We are not going to talk about these implementations, but focus on the one implementation that did make it to the official kernel sources: devfs.

devfs as all-round winner ? 

devfs tackles all listed problems. It only provides the user with existing devices, adds new nodes when new devices are found, and makes it possible to mount the root filesystem read only. And it tackles more problems we haven't discussed previously because they are less interesting for users...

For instance, with devfs, you don't have to worry about major/minor pairs. It is still supported (for backwards compatibility), but isn't needed. This makes it possible for Linux to support even more devices, since there are no limits anymore (numbers always have boundaries :)

Yet devfs does come with it's own problems; for the end users these issues aren't really visible, but for the kernel maintainers the problems are big enough to mark devfs obsolete in favor of udev (which Gentoo supports as well :).

For more information as to why devfs is marked obsolete, please read the udev FAQ and udev versus devfs document.

2. Navigating through the device tree

Directories 

One of the first things you might notice is that devfs uses directories to group devices together. This improves readability, as now all related devices are inside a common directory.

For instance, all IDE-related devices are inside the /dev/ide/ device directory, and SCSI-related devices are inside /dev/scsi/. SCSI and IDE disks are seen in the same way, meaning they both have the same subdirectory structure.

IDE and SCSI disks are controlled by an adapter (on-board or a seperate card), called the host. Every adapter can have several channels. A channel is called a bus. On each channel, you can have several IDs. Such an ID identifies a disk. This ID is called the target. Some SCSI devices can have multiple luns (Logical Unit Numbers), for instance devices that handle multiple media simultaneously (hi-end tapedrives). You mostly have only a single lun, lun0/.

So, whereas /dev/hda4 was used previously, we now have /dev/ide/host0/bus0/target0/lun0/part4. This is far more easy... no, don't argue with me... it is easier... ah whatever! :)

Note: You can also use more Unix-like device file naming for hard disks, such as c0b0t0u0p2. They can be found in /dev/ide/hd, /dev/scsi/hd etc.

To give you an idea on the directories, this is a listing of the directories which I have on my laptop:

Code Listing 2.1: Directories in /dev

cdroms/     cpu/        discs/          floppy/
ide/        input/      loop/           misc/
netlink/    printers/   pts/            pty/
scsi/       sg/         shm/            sound/
sr/         usb/        vc/             vcc/

Backwards compatibility using devfsd 

Using this new scheme sounds fun, but several tools and programs make use of the previous, old scheme. To make sure no system is broken, devfsd is created. This daemon creates symlinks with the old names, pointing to the new device files.

Code Listing 2.2: Created symlinks

$ ls -l /dev/hda4
lr-xr-xr-x    1 root     root           33 Aug 25 12:08 /dev/hda4 -> ide/host0/bus0/target0/lun0/part4

With devfsd, you can also set the permissions, create new device files, define actions etc. All this is described in the next chapter.

3. Administrating the device tree

Restarting devfsd 

When you alter the /etc/devfsd.conf file, and you want the changes to be forced onto the system, you don't have to reboot. Depending on what you want, you can use any of the two following signals:

SIGHUP will have devfsd reread the configuration file, reload the shared objects and generate the REGISTER events for each leaf node in the device tree.

SIGUSR1 will do the same, but won't generate REGISTER events.

To send a signal, simply use kill or killall:

Code Listing 3.1: Sending the SIGHUP signal to devfsd

# kill -s SIGHUP `pidof devfsd`
or
# killall -s SIGHUP devfsd

Removing compatibility symlinks 

Warning: Currently, Gentoo cannot live without the compatibility symlinks.

If you want the compatibility symlinks that clutter up /dev removed from your Gentoo system (Gentoo activates it per default), edit /etc/devfsd.conf and remove the following two lines:

Code Listing 3.2: /etc/devfsd.conf for backwards compatibility

# Comment the following two lines out to remove the symlinks
REGISTER        .*  MKOLDCOMPAT
UNREGISTER      .*  RMOLDCOMPAT

You need to reboot your system for the changes to take affect.

Removing autoload functionality 

When you load a module, devfs will automatically create the device files. If you don't want this behaviour, remove the following line from /etc/devfsd.conf:

Code Listing 3.3: /etc/devfsd.conf, autoload functionality

LOOKUP      .*  MODLOAD

4. Permission Related Items

Set/change permissions using PAM 

Although you can set permissions in /etc/devfsd.conf, you are advised to use PAM (Pluggable Authentification Modules). This is because PAM has the final say on permissions, possibly ignoring the changes you make in /etc/devfsd.conf.

PAM uses the /etc/security/console.perms file for the permissions. The file consists of two parts: the first one describes the groups, and the second one the permissions.

Let's first take a look at the groups part. As an example we view the sound-group:

Code Listing 4.1: Sound group in /etc/security/console.perms

<sound>=/dev/dsp* /dev/audio* /dev/midi* \
    /dev/mixer* /dev/sequencer* \
    /dev/sound/* /dev/snd/* /dev/beep \
    /dev/admm* \
    /dev/adsp* /dev/aload* /dev/amidi* /dev/dmfm* \
    /dev/dmmidi* /dev/sndstat

The syntax is quite easy: you start with a group-name, and end with a list of devices that belong to that group.

Now, groups aren't very useful if you can't do anything with them. So the next part describes how permissions are handled.

Code Listing 4.2: Permissions for sound group in /etc/security/console.perms

<console>  0600 <sound>      0600 root.audio

The first field is the terminal check. On most systems, this is the console-group. PAM will check this field for every login. If the login happens on a device contained in the console-group, PAM will check and possibly change the permissions on some device files.

The second field contains the permissions to which a device file is set upon succesfull login. When a person logs into the system, and the device files are owned by a default owner/group, PAM wil change the ownership to the logged on user, and set the permissions to those in this second field. In this case, 0600 is used (user has read/write access, all others don't).

The third field contains the device-group whose permissions will be changed. In this case, the sound-group (all device files related to sound) will be changed.

The fourth field defines the permissions to which the device file is set after returning to the default state. In other words, if the person who owns all the device files logs out, PAM will set the permissions back to a default state, described by this fourth field.

The fifth field defines the ownership (with group if you want) to which the device attributes are set after returning to the default state. In other words, if the person who owns all the device files logs out, PAM will set the ownership back to a default state, described by this fifth field.

Set/change permissions with devfsd 

If you really want to set permissions using /etc/devfsd.conf, then use the syntax used in the following example:

Code Listing 4.3: Permissions in /etc/devfsd.conf

REGISTER    ^cdroms/.*  PERMISSIONS root.cdrom 0660

The second field is the device group, starting from /dev. It is a regular expression, meaning you can select several device files in one rule.

The fourth field is the ownership of the device file. Unlike with PAM this isn't changed (unless it is mentioned in console.perms since PAM always wins).

The fifth field contains the permissions of the device file.

Manually set permissions and have devfsd save it 

This is the default behaviour for Gentoo: if you chown (CHange OWNer) and chmod (CHange MODe) some device files, devfsd will save the information when you are shutting down the system. This is because the /etc/devfsd.conf file contains the following lines:

Code Listing 4.4: /etc/devfsd.conf for saving permissions

REGISTER        ^pt[sy]/.*   IGNORE
CHANGE          ^pt[sy]/.*   IGNORE
CREATE          ^pt[sy]/.*   IGNORE
DELETE          ^pt[sy]      IGNORE
REGISTER        ^log         IGNORE
CHANGE          ^log         IGNORE
CREATE          ^log         IGNORE
DELETE          ^log         IGNORE
REGISTER        .*           COPY    /lib/dev-state/$devname $devpath
CHANGE          .*           COPY    $devpath /lib/dev-state/$devname
CREATE          .*           COPY    $devpath /lib/dev-state/$devname
DELETE          .*           CFUNCTION GLOBAL unlink
/lib/dev-state/$devname
RESTORE         /lib/dev-state

In other words, changed device files are copied over to /lib/dev-state when shutting down the system, and are copied over to /dev when booting the system.

Another possibility is to mount /lib/dev-state on /dev at boot-time. To do this, you must make sure that devfs is not mounted automatically (meaning you'll have to recompile your kernel) and that /dev/console exists. Then, somewhere at the beginning of the bootscripts of your system, you place:

Code Listing 4.5: Mounting /lib/dev-state on top of /dev

mount --bind /dev /lib/dev-state
mount -t devfs none /dev
devfsd /dev

5. Resources

For more information on devfs, check out the following resources.

The devfsd.conf manpage explains the syntax of the /etc/devfsd.conf file. To view it, type man devfsd.conf.

The devfs FAQ explains everything about devfs. It also contains information about the internal devfs structure and how drivers can support devfs.

On LinuxJournal there is an interesting article on devfs for Management and Administration.

Daniel Robbins has written a set of articles for IBM's DeveloperWorks about Advanced filesystems. Three of them are about devfs:


The contents of this document are licensed under the Creative Commons - Attribution / Share Alike license.
Print
line
Updated September 09, 2004
line
Sven Vermeulen
Author

Seemant Kulleen
Reviewer

line
Summary:  In this document you'll find information on what devfs is really about and how to work with it.
line
The Gentoo Linux Store
line
Copyright 2001-2004 Gentoo Foundation, Inc. Questions, Comments, Corrections? Email [email protected].