Translation(s): English - Français - Italiano - Русский


FileSystem


udev is a FileSystem replacement for DevFS on the Linux 2.6 kernel series.

udev runs in user space (as opposed to devfs which was executed in kernel space). udev allows for dynamic updating of /dev, much like its predecessor sysfs. Sysfs was considered to be useful for development, existing only in Linux 2.5, and was supplemented by udev in 2.6.

udev allows for rules that specify what device name is given to a specific device, regardless of which port is plugged into. For example, a rule to always mount a hard drive with manufacturer "iRiver" and device code "ABC" as /dev/iriver is possible. This consistent naming of devices guarantees that scripts dependent on a specific device's existence will not be broken.

Overview

The udev system is composed of some kernel services and the udevd daemon. The kernel informs the udevd daemon when certain events happen. The udevd daemon is configured to respond to some events with actions. The event information comes from the kernel - the actions happen in userspace. Is the event information coming from the kernel configurable? The responses to the events are configurable in "rules".

The udevd daemon, like other daemons, starts on boot because of an init script: /etc/rcS.d/udev. Its config file is in /etc/udev/udev.conf. The rules files (which amount to more configuration for udevd) are taken from /etc/udev/rules.d. Files in there are parsed in alpha order, as long as the name ends with ".rules". When the config file or rules files are changed, then the udevd daemon should be restarted (or, as mentioned further down this page, you can use the udevadm program).

Many of the files in /etc/udev/rules.d are links to files elsewhere. I'm guessing that's so that when the rules files are edited, the editor backups aren't left lying around where they might be used in the next restart of the udevd daemon. Also, since the links can have different names from the original files, then they can be ordered without having to worry about what names they have (as with the init scripts).

udev was created to respond to hotplug type of events. Much documentation refers to creating devices in response to new devices that have appeared. But, udev is more general; it can run arbitrary userspace commands in response to a new device appearing - or to whatever events it receives from the kernel.

The times when udevd is active are:

  1. at startup, it parses all the config files and rule files and builds a rules database in memory.
  2. When an event happens, it checks its rule database and performs the appropriate actions.

Rules

Rules for rules:

  1. rules are all on one line (lines can be broken with \ just before newline)
  2. rules consist of "matches" and "actions"
  3. matches and actions are "key" "operator" "value" triplets
  4. matches have == or != for operator
  5. actions have = (assignment) for operator
  6. matches check one or more attributes of the event to see if the action will be applied
  7. actions specify what will happen
  8. example match: BUS=="usb"

  9. example action: NAME="mydev"

  10. example rule:

    KERNEL=="sd*[0-9]|dasd*[0-9]", ENV{ID_SERIAL}=="?*", \
            SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}-part%n"
  11. all matching rules will fire
  12. earlier rules have precedence over later rules - so put your customizations early in the rules.d file list
  13. actions like key="value" override
  14. actions like key+="value" add to the actions that are executed, eg SYMLINK+="foo" means "in addition to any other symlinks you were going to make for this event, also make one called foo"

Rule sets

Rules for rule sets:

  1. All the rules are in one big rule space, although they are divided into several files.
  2. The only organization in the rule space is the ability to set labels, and then to skip a bunch of rules during "match this event to rules" time by jumping forward with a GOTO action.

  3. there is one other rule type called a label: eg LABEL="persistent_storage_end" These are used by regular rules that have "GOTO" actions, eg:

    ACTION!="add", GOTO="persistent_storage_end"
    Note that in this rule, the term ACTION is an attribute of an event and is being used as a condition for deciding if the GOTO action will be triggered.
  4. It is polite to keep GOTOs to jump within a file (or you will have to worry about reordering the files)
  5. Don't jump backwards to a label (didn't try it, but imagine it might end in an infinite loop? Maybe the udev code checks for that - but if it's going to be ignored (at best) why bother?)
  6. You can set variables in ENV space in earlier rules and refer to them with later rules
  7. The facility for dynamic rule creation exists (example: see z45_persistent-net-generator.rules)

Blacklisting

KernelModuleBlacklisting

Persistent Device name

In this example, we want to make sure your 3G card get a persistent name.

1. Plug the "card" (or device)

2. run the following command, on the proper device;

$ udevadm info --name=/dev/ttyS1 --attribute-walk

note that on very old systems one might have to use udevinfo instead:
$ udevinfo -a -p $(udevinfo -q path -n /dev/ttyS1)

udevadm starts with the device specified by the devpath and then walks up the chain of parent devices. It prints for every device found, all possible attributes in the udev rules key format. A rule to match, can be composed by the attributes of the device and the attributes from one single parent device.

  looking at device '/class/tty/ttyS1':
    KERNEL=="ttyS1"
    SUBSYSTEM=="tty"
    DRIVER==""
    ATTR{dev}=="4:65"

  looking at parent device '/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/0.0':
    KERNELS=="0.0"
    SUBSYSTEMS=="pcmcia"
    DRIVERS=="serial_cs"
    ATTRS{modalias}=="pcmcia:m00A4c1AAFf02fn00pfn00pa32607776pbD9E73B13pcAF9C4D7Fpd00000000"
    ATTRS{prod_id3}=="NRM6831"
    ATTRS{prod_id2}=="Merlin UMTS Modem"
    ATTRS{prod_id1}=="Novatel Wireless"
    ATTRS{card_id}=="0x1aaf"
    ATTRS{manf_id}=="0x00a4"
    ATTRS{func_id}=="0x02"
    ATTRS{pm_state}=="on"
    ATTRS{function}=="0x00"

  looking at parent device '/devices/pci0000:00/0000:00:1e.0/0000:15:00.0':
    KERNELS=="0000:15:00.0"
    SUBSYSTEMS=="pci"
    DRIVERS=="yenta_cardbus"
    ATTRS{msi_bus}=="1"
    ATTRS{broken_parity_status}=="0"
    ATTRS{enable}=="2"
    ATTRS{numa_node}=="0"
    ATTRS{modalias}=="pci:v00001180d00000476sv000017AAsd000020C6bc06sc07i00"
    ATTRS{local_cpus}=="00000003"
    ATTRS{irq}=="16"
    ATTRS{class}=="0x060700"
    ATTRS{subsystem_device}=="0x20c6"
    ATTRS{subsystem_vendor}=="0x17aa"
    ATTRS{device}=="0x0476"
    ATTRS{vendor}=="0x1180"

  looking at parent device '/devices/pci0000:00/0000:00:1e.0':
    KERNELS=="0000:00:1e.0"
    SUBSYSTEMS=="pci"
    DRIVERS==""
    ATTRS{msi_bus}=="1"
    ATTRS{broken_parity_status}=="0"
    ATTRS{enable}=="1"
    ATTRS{numa_node}=="0"
    ATTRS{modalias}=="pci:v00008086d00002448sv00000000sd00000000bc06sc04i01"
    ATTRS{local_cpus}=="00000003"
    ATTRS{irq}=="0"
    ATTRS{class}=="0x060401"
    ATTRS{subsystem_device}=="0x0000"
    ATTRS{subsystem_vendor}=="0x0000"
    ATTRS{device}=="0x2448"
    ATTRS{vendor}=="0x8086"

  looking at parent device '/devices/pci0000:00':
    KERNELS=="pci0000:00"
    SUBSYSTEMS==""
    DRIVERS==""
    ATTRS{uevent}==""

3. Create a file in /etc/udev/rules.d, typically named z21_persistent-local.rules.

ATTRS{prod_id2}=="Merlin UMTS Modem", ATTRS{prod_id1}=="Novatel Wireless", SYMLINK+="MerlinUMTS"
## Alternatively we could use :
# ATTRS{card_id}=="0x1aaf", ATTRS{manf_id}=="0x00a4", SYMLINK+="MerlinUMTS"

4. Force re-running the scripts (or reboot ;)

udevadm control --reload-rules
udevadm test -a -p  $(udevadm info -q path -n /dev/ttyS1)

a more detailed example by semu5 on comp.os.linux.questions. There is also a Writing udev rules.

References


CategorySystemAdministration | ?CategoryLocalResourcesManagement | CategoryBootProcess