Kernel Korner - udev—Persistent Device Naming in User Space

Whether you're plugging a camera and scanner in to your laptop or adding another SCSI drive to your company server, it's time to end the current mess of major and minor numbers.

As this description shows, the /dev/usb/lp0 device now is assigned to the USB printer with the serial number W09090207101241330 due to this different probing order.

sysfs enables a user to determine which device has been assigned by the kernel to which device file. This is a powerful association that previously had not been easily available. However, a user generally does not care that /dev/usb/lp0 and /dev/usb/lp1 are now reversed and should be changed in a configuration file somewhere. The user simply wants to be able to print to the proper printer, no matter where it is in the USB device tree.

/dev Is Too Big

Not all device files in the /dev directory of most distributions match up to a physical device that is currently connected to the computer. Instead, the /dev directory is created when the operating system is initialized on the machine, populating the /dev directory with all known possible names. On a machine running Red Hat's Fedora release 1, the /dev directory holds more than 18,000 different entries. This many entries soon become unwieldy for users trying to determine exactly what devices currently are present.


Because of the large numbers of device files in the /dev directory, a number of operating systems have moved to having the kernel itself manage the /dev directory, as the kernel always knows exactly what devices are present on the system. It does this by creating a RAM-based filesystem called devfs. Linux also has this option, and it has become popular over time in a number of different distributions, including Gentoo.

For a number of people, devfs solves their immediate needs. However, the Linux-based devfs implementation still has a number of unsolved problems. Most notably, it does not provide the ability to create device nodes with a persistent name.

udev's goals

In light of the previously mentioned problems, the udev Project was started. Its goals are to run in user space; create a dynamic /dev; provide consistent device naming, if wanted; and provide a user-space API to access information about current system devices. For more on how udev compares with devfs, see the on-line Resources section.

The first item, run in user space, is accomplished by harnessing the fact that /sbin/hotplug generates an event for every device added to or removed from the system with sysfs' ability to show all the needed information about all devices.

The second item, create a dynamic /dev, is handled by catching all /sbin/hotplug events, looking up the major and minor number in sysfs for the added device and creating a /dev file with the kernel name the device was assigned. If the device was removed from the system, it is easy to remove the /dev entry for that device.

udev achieved these first two goals back in April 2003 in an extremely tiny 6Kb of compiled code, proving that this scheme of catching hot-plug events and using sysfs was feasible and quite simple to implement. Since that humble beginning in early 2003, udev has achieved all of its goals. It provides users with the ability to name devices in a persistent manner using a flexible rule-based system.

udev's rules are contained in the /etc/udev/udev.rules file and describe any devices the user wants to name in a way that differs from the default kernel name. Here's an example of a udev.rules file:

# if /sbin/scsi_id returns "OEM 0815" device will
# be called disk1
BUS="scsi", PROGRAM="/sbin/scsi_id", \
RESULT="OEM 0815", NAME="disk1"

# USB printer to be called lp_color
BUS="usb", SYSFS_serial="W09090207101241330", \

# SCSI disk with a specific vendor and model number
# is to be called boot
BUS="scsi", SYSFS_vendor="IBM", \
SYSFS_model="ST336", NAME="boot"

# sound card with PCI bus id 00:0b.0 to be called dsp
BUS="pci", ID="00:0b.0", NAME="dsp"

# USB mouse at third port of the second hub to
# be called mouse1
BUS="usb", PLACE="2.3", NAME="mouse1"

# ttyUSB1 should always be called pda with two
# additional symlinks
KERNEL="ttyUSB1", NAME="pda", \
SYMLINK="palmtop handheld"

# multiple USB webcams with symlinks to be called
# webcam0, webcam1, ...
BUS="usb", SYSFS_model="XV3", NAME="video%n", \

A udev rule defines the mapping between a device's attributes and the desired device filename. To do this, a number of keys can be queried from the device to determine a match. If no match is found in the udev.rules file, the default kernel name is used. Below is a list of the different types of keys that udev understands:

  • BUS: matches the bus type of the device; examples of this include PCI, USB or SCSI.

  • KERNEL: matches the name the kernel gives the device.

  • ID: matches the device number on the bus; for example, the PCI bus ID or the USB device ID.

  • PLACE: matches the topological position on bus, such as the physical port a USB device is plugged in to.

  • SYSFS_filename, SYSFS{filename}: allows udev to match any sysfs device attribute, such as label, vendor, USB serial number or SCSI UUID. Up to five different sysfs files can be checked in a single rule, with all of the values being required in order to match the rule.

  • PROGRAM: allows udev to call an external program and check the result. This key is valid if the program returns successfully. The string returned by the program additionally may be matched with the RESULT key.

  • RESULT: matches the returned string of the last PROGRAM call. This key may be used in any rule following a PROGRAM call.

After the different keys, a NAME and optional SYMLINK are specified. The NAME is what udev uses to call the device if the rule matches, and the SYMLINK specifies what, if any, symlinks also are generated. More than one symlink can be specified at once, with spaces between multiple symlinks. Both the NAME and SYMLINK files can contain directories to allow /dev to be simplified.



Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

What about Garrick?

Anonymous's picture

After reading this fine article, I'm still confused about Garrick. Did he respond and is the font I'm seeing already the small one, or did he utterly ignore all requests directed at him? Would be great if somebody could provide some insight. Thanks.

Changing device order and modprobe.d

Anonymous's picture

I think I have been under the misapprehension that it is possible to change device order or allocation using udev rules. I wanted to make dsp dsp1 and dsp1 dsp, but it seems to me that that is impossible without changing the boot order first. Assigning names to devices only identifies them regardless of the boot order. However it is not possible to reassign those devices following startup, it's all locked up in /sys.
Also, how does /etc/modprobe.d fit into the scheme of aliases/device naming in light of udev. How is the modalias file in /sys applied to /etc/modprobe.d.

Writing udev rules is quite easy with...

VilleWitt's picture

I recently needed some custom stuff in /dev on my GNU/Linux Gentoo. Somehow I cam across this wounderfull article about how to actually implement some of all this stuff - and it works, is easy and very customizable.

Most of the problems people tend to smoke about would be solved by reading that document. These problems are
"They should be named with this syste: ...",
"I want a copy of a device node at ...",
"XXX application can't find /dev/YYY - udev is bad!",
udev rocks!

udev ruined Mepis

Anonymous's picture

I had to switch from Mepis to SUSE 10.0 because of problems with udev. As far as I can see it's not ready for prime time. THe fact of the matter is it wrecked a lot of previously good Linux distributions. Try managing an iPod SUffle with udev. It's as good as impossible.

udev and why I will not use the 2.6 kernel

Anonymous's picture

I am a gentoo user with to installations, one based on the 2.4 kernel and the other on the 2.6 kernel. I decided to do a system upgrade over the new year. What a mistake. I no longer have a useable modem, DRI still does not function and I suspect the problem may, in fact, be udev, which I have yet to determine how to correctly set rules for even with the docs currently available. Add to this that I once was able to view movies under linux I am no longer able to do so.

I am willing to admit I just do not have the big picture on this, but at the same time I have misgivings as to why such a system is really necessary. IF it is the default for th 2.6 kernel I can be sure of one thing...I will never use that kernel further.

Nice try, but no cigar.

.I will never use that kernel further.

Bill Savoie's picture

It is not good to smoke Cigars. You are quick to judgement and that makes you closed off to change. The mind is like a parachute, it only functions when it is open. Your attitude is like a child who throws a tantrum. udev is a great improvement and these people work for free. How about a bit more grace. Make peace and love your path..

auto-load drivers a la devfs

Arioch's picture

FAQ says that driver autoloading is not possible with udev and will not be implemented by ydev maintainer.

But i think there still are projects to achieve this.
For example in it is done by tmpfs + modules_lookup script

I wonder, if there is somewhere a list of such a projects?

Program field

phorm's picture

Well, you could try ysing the program field in udev to fire off an event to another program that could do driver lookups?

BUS="scsi", PROGRAM="/sbin/checkdrv", RESULT="somevalue" might be a start?

Trying sysfs with a USB memory stick

Anonymous's picture

Maybe it's more of a sysfs question, but I immediately tried Greg's suggestion with a USB memory stick. I have several of them, and they always appear at another /dev/sdx or /dev/sdx[1-3] device so this is a proper candidate for udev.

But nothing seems to appear in /sys/class/usb. An entry does appear in /sys/block/sda, but there's no identifying information like a serialno there, and there are suddenly 4 subdirs underneath: sda[1-4].

Is my sysfs set up correctly? How do I figure out the right partition (if any) to mount on such a 'pseudo disk' device?

Re: Kernel Korner: Kernel Korner: udev--Persistent Device Naming

Anonymous's picture

Given that the probe function for every registered USB driver will be called when a device is detected on the USB, what prevents the current lp driver from always choosing the same minor number for the same device regardless of location within the USB. Creating lp1 before or without an lp0 would not cause any problems, would it ?

Re: Kernel Korner: Kernel Korner: udev--Persistent Device Naming

Anonymous's picture

what prevents the current lp driver from always choosing the same minor number for the same device regardless of location within the USB

You are proposing that the kernel device driver should maintain a database for the every device it has handled over the time? This sounds like a really bad idea. A lot of devices are very difficult to distinguish from another, e.g. EPSON has the same USB ID's for a lot of printer models and you need to query the printer information with a vendor specific protocol, which surely belongs to userspace.