Connect your devices with udev

From LXF Wiki

Revision as of 18:46, 30 Jan 2009; view current revision
←Older revision | Newer revision→

DEVICE-NAMING SYSTEM: Connect your devices with udev

(Original version written by Neil Bothwick for LXF issue 66.)

Learn how to code a name for your hardware when 'Bob' just won't do.

'Everything is a file' is one of the Unix creeds. It sounds strange at first, but in a way it's true. Of course, we're not suggesting that your hard disk is a file—we all know it's a precision-engineered piece of electromechanical hardware designed to store as much of your valuable data as possible before crashing the heads into the disk and destroying the lot.

However, your hard disk is represented as a file in the Linux filesystem, usually as /dev/hda/. You probably already know this, but any piece of hardware you connect to your computer is represented by a device file in /dev, be it your MP3 player or your webcam.

The /dev directory was originally a standard directory containing device files for every piece of hardware likely to be connected. This usually meant that whenever a driver was installed, the relevant files were created in /dev. This had two really important disadvantages. The first was that as more devices were supported, the number of files in the directory was becoming unmanageable.

It also meant that if you tried to connect a piece of hardware for which there was no device file, you had to create it yourself, first scouring Google for the correct major and minor device number to pass to the mknod command.

As the number of devices supported by Linux increased, especially the huge number of removable devices that could be connected to USB or IEEE1394 (aka Firewire) ports, this became unacceptable. Not only was /dev becoming totally unwieldy, but we were in danger of running out of major and minor device numbers to cover every possible device that could be connected, even though any one computer would only ever see a tiny fraction of them.

The solution was devfs, a system in the Linux kernel that would react to devices being connected or discovered and create their /dev entries automatically. While this improved the situation, there are some issues with devfs that mean its use is now deprecated. The main problem with devfs is that it has a number of bugs, ranging from annoying to serious, some of which cannot be fixed.

Knowing u – a-ha!

Udev is a new alternative developed by Greg Kroah-Hartman that can do all that devfs needs to do but in user space, avoiding the need to keep any code for it inside the kernel. Using the new /sys filesystem from kernel 2.6 and the hotplug system for connecting peripherals, all the device node creation is handled by user space programs. As devfs is not being actively maintained now, udev has become the default choice. If you have installed a recent distribution, you probably already have udev without realising it.

At this point, you may be wondering why all this matters to you. After all, the main differences between devfs and udev seem to lie in the implementation, and how they affect the system from a development point of view. So how does it affect the end user? Well, we've saved one of udev's best advantages until last, and it's a feature that will make a real difference to you.

The feature is called persistent device naming, and it works like this. Devices are normally named in the order in which they are connected. That’s fine if you only have one of each type of device, but this is becoming less common. For example, many devices use the USB storage module to appear as disk drives. These include digital cameras, MP3 players, USB key disks and memory card readers, as well as external disk drives.

If you connect your camera, say, it will often be seen as /dev/sda/. If you then hook up your USB keyring it will appear as /dev/sdb/. But if you connect the keyring first, that will appear as /dev/sda/.

This makes dealing with these devices through fstab entries or automounters more complex than it needs to be. The situation is potentially worse with printers. I have two USB printers: a laser for text documents and an inkjet for printing photographs. One is /dev/lp0 and the other /dev/lp1, but which gets which depends on which is detected first. If one of the printers is turned off when I boot, the devices can be reversed.

Udev fixes this nonsense by enabling you to specify your own device names for each product. Using a simple set of rules, udev will set the device name according to the identification data available from each device. It will also create symlinks, so a device can have more than one name. For example, a DVD-ROM drive could be accessed as any one of /dev/hdc, /dev/cdrom or /dev/dvd. So, how do we write our own udev rules?