Device Filenames and udev

From MythTV Official Wiki
Revision as of 18:02, 8 March 2007 by Srs5694 (Talk | contribs)

Jump to: navigation, search

MythTV often works well with the video devices it finds on your system using whatever default device assignments your distribution creates. Sometimes, though, problems arise. The most serious problem occurs when the association of a device filename (in the /dev directory tree) to a physical device is not consistent. This can happen with USB devices that are attached and detached at will, because of a need to use multiple kernels that are compiled in different ways, because of changes in your hardware configuration, or (so it seems sometimes) because of the phase of the Moon. If you're having problems keeping your video devices consistent, read on.

Note: This wiki entry describes configuring udev to create consistent device file entries. Most modern Linux distributions use udev; however, older distributions don't use udev. If your system doesn't use udev, this wiki entry won't do you any good. In such cases, you may be able to solve the problem by moving device drivers in or out of the kernel proper or by blacklisting them from being loaded automatically and then loading them manually in local startup scripts.

Basics of udev

The udev tool is a user-space filesystem that provides a dynamic mapping of device filenames (typically in /dev) to hardware devices. Developers created udev in order to overcome a number of limitations in previous Linux device file handling schemes, including the one that motivates this entry: inconsistency in device filename mappings to physical devices.

You can find udev configuration files in /etc/udev. The main configuration file is /etc/udev/udev.conf; however, you won't be touching this file. Instead, you'll be creating a new file in /etc/udev/rules.d. This directory holds files, often installed from multiple sources, each of which contains rules that tell udev how to create device files. The files in /etc/udev/rules.d typically take filenames of the form ##-*.rules, where ## is a 2-digit number and * is a name. For instance, on an Ubuntu 6.10 system, the udev rules files include 00-init.rules and 85-alsa.rules for the core rules and rules covering ALSA (audio) devices, respectively. The names of the rules files differ from one distribution to another, and even from one installation to another, depending on what packages you install.

The rules files consist of a series of rules, each of which contains key/value pairs, separated by commas. Each key may be either a matching key, which determines whether or not a rule is to be used, or an assignment key, which tells udev how to create a device file. Matching keys use == or != symbols to separate keys from values, indicating equality or inequality. Assignment keys use =, +=, or := symbols to assign a new value to a key, add a new value to an existing key, or assign a new value to a key while disallowing future changes, respectively. Be careful not to confuse the == and = operators!

As an example, consider the following line, which is taken from the 50-udev.rules file on a Gentoo system:

KERNEL=="video[0-9]*",  NAME="v4l/video%n", SYMLINK+="video%n", GROUP="video"

This line searches for a device that the kernel names video[0-9]* -- that is, video0, video1, and so on. (You can use wildcards, such as [0-9] and *, in much the same way as you can use wildcards when specifying filenames in a Linux shell.) Once found, the rule creates a device file with a name based on the kernel's internal name in the v4l subdirectory of /dev (NAME="v4l/video%n"), creates a symbolic link to this newly-created device file in the main /dev directory (SYMLINK+="video%n"), and assigns group ownership of the device file to the video group (GROUP="video"). Note that details of the default video device file creation differ from one distribution to another, so yours may not exactly match this example.

Many keys aside from these are available. You'll have to use some of these to create unique identifying device filenames; more on that later. Rather than create new device files proper, you'll probably find it convenient to create new symbolic links that point to the device files that are created automatically by udev.

You may want to take a few minutes to examine your existing udev rules files. You might want to try typing grep video /etc/udev/rules.d/* to find all the entries that relate to video devices. On distributions that employ a video account or group, you'll find entries that have nothing to do with video devices except that they're assigned to the video account or group, so you may have to sift through a lot of irrelevant matches. Take note of the sequence (leading 2-digit number) of the file that creates the video devices for future reference.

Obtaining identifying information

To uniquely identify your hardware, you must locate uniquely identifying information. This information could take the form of a device driver (if your devices use different drivers), a bus (PCI or USB, for instance), a model number, a serial number (if your devices have them), or perhaps other things. One good way to look for unique identifying information is to use udevinfo to obtain information on the device:

udevinfo -a -p $(udevinfo -q path -n /dev/video0)

The result will be a rather lengthy list of udev matching key names and their associated values, for both the device you specify (/dev/video0 in this example) and all its parents. Issue this udevinfo command for each of your devices in turn and search for unique key values. You'll probably want to restrict your search for unique key names to the first and second blocks of the udevinfo output, which apply only to the device in question. (An exception might be if your two devices are on different busses, such as PCI and USB.) You can combine two or more identifying keys, if necessary. One common field to use in conjunction with another is the KERNEL key, which holds the kernel's identifying key for the device -- usually video0, video1 or something similar. You may want to use a wildcard to match the KERNEL identifier, since its number can change -- that's the source of the problem!

Tip: Try redirecting the output of udevinfo to a file (by adding > ~/filename.txt to the command). If you redirect each output to a different file, you can load them both into text editors for side-by-side comparison.

Once you've located a uniquely identifying set of characteristics, you can proceed with configuring udev to recognize and act on those features.

Configuring udev

As an example, I've examined the udevinfo output for two video devices, a PcHDTV HD-3000 and a Hauppauge WinTV-PVR-USB2. The udevinfo output for the latter device was rather scant; however, I did find a uniquely identifying feature for the pcHDTV HD-3000, which is sufficient to proceed:

SYSFS{name}=="cx88_0_ video _pcHDTV HD3000 HD"

The SYSFS{name} key is present on the WinTV-PVR-USB2, but it's blank. Using this fact, a new pair of udev rules can be created:

KERNEL=="video[0-9]*", SYSFS{name}=="cx88*", SYMLINK+="video-pcHDTV"
KERNEL=="video[0-9]*", SYSFS{name}=="", SYMLINK+="video-PVR-USB2"

A few comments about these rules are in order:

  • The KERNEL=="video[0-9]*" key is required to keep the rules from matching non-video devices. The first rule might not be a big problem in this respect, but the second could be. You wouldn't want a printer or removable disk to get the video encoding device's filename!
  • The first rule truncates the name returned, using an asterisk (*) to match the remainder of the rule. A simple cut-and-paste doesn't work (presumably the spaces are confusing the system). Wildcards are useful in this case as well as when matching the KERNEL key.
  • The second rule matches a blank name. This happens to work for the PVR-USB2 with the 2.6.20 kernel drivers, but it might not work for other devices. If I were to add another encoder that has a blank name, I might need to add more rules or add the %n variable to the SYMLINK value to number these links.

A second example rule set is based on a system with a single video card, an AVerMedia M150-D. This card uses the Conexant 2388x chip and the 23416 MPEG-2 encoder chip, combined using the "Blackbird" reference design. As such, the card provides two video access files: one for accessing the card as a frame grabber and the second for accessing its MPEG-2 encoder. The design of the drivers is such that the MPEG-2 device file should always be numbered above the framegrabber device file; however, you might still want to provide more intuitive names to the device files or give constant names if you were using this device in conjunction with another. The following configuration does the trick:

KERNEL=="video[0-9]*", DRIVERS=="cx88-blackbird", SYMLINK+="video-M150-MPEG"
KERNEL=="video[0-9]*", DRIVERS=="cx8800", SYMLINK+="video-M150-framegrabber"

These rules look to the second block of output from udevinfo, using the DRIVERS key to differentiate the two devices.

Once you've created new udev rules, you should place them in a new udev rules file. You can include comment lines that begin with hash marks (#), if you like. Give the new file a name that begins with a number greater than the number of the file that creates the original video device files.

Note: Don't try to modify your existing udev rules files. These files are likely to be replaced by your distribution's packaging system when you upgrade your software. You can create rules for creating new links in a separate file, which shouldn't be touched by your distribution's packaging system.

Once this new rule file is in place, the symbolic links should be created the next time you load the relevant device drivers. These new links shouldn't change even if something happens to alter the original device filenames, such as if you add or remove hardware; however, check the Caveats section below for important exceptions! To test your new rule, you can either unload the video device drivers and add them back manually or reboot the computer.

You can use the same procedure to create rules for non-video devices. For instance, if you've got two sound cards to go with two framegrabber video cards, you can use this procedure to create uniquely-named audio device files. You would specify the audio device's filename in the udevinfo command to track down information that uniquely identifies each audio device.

Configuring MythTV

To use the new device files, you'll need to shut down your mythbackend process and use the mythtv-setup utility. You'll then use the Capture Cards option to edit your existing capture card configuration (or create a new one, if you've not yet configured this hardware). Chances are this tool won't be looking for the device files you've created, so you'll need to manually type the filenames in the relevant entry fields. Once this is done, though, mythtv-setup should correctly identify the device and enable you to save your changes.

Caveats

Mucking with your device drivers may require you to shut down the MythTV backend process. You should experiment with this procedure only when you have no recordings scheduled.

The identifying information you locate using this procedure could change if you upgrade your drivers. Likewise, if you add new hardware, you might need to tweak your rules -- perhaps a rule that serves to uniquely distinguish two devices won't uniquely distinguish a third device. The more specific you can make your rules, the less likely you'll have to tweak them when you add hardware. If your udevinfo output includes a serial number, that can be a great way to uniquely identify your hardware, particularly if you've got multiple identical encoders connected to different inputs. On the other hand, if you're too specific, you might have problems if you replace the hardware with a very similar device. For instance, if you use a serial number but the device breaks and you replace it with an identical unit, you'll need to reconfigure udev.

Device drivers occasionally take a few seconds to create device files for a device. I ran into this problem with a Hauppauge WinTV-PVR-USB2; device files didn't appear the moment I typed modprobe pvrusb2. I initially believed my rules weren't working, when in fact I was just being impatient.

Additional information

Additional information on udev can be found at: