udev

From Gentoo Wiki
Jump to: navigation, search
Other languages:English 100% • ‎español 100% • ‎français 100% • ‎русский 100%

External resources

udev is the device manager for the Linux kernel. Primarily, it manages device nodes in /dev and handles all user space actions when adding/removing devices. Also have a look at eudev, a fork of udev.

What is udev?

The /dev directory

When Linux-users talk about the hardware on their system in the vicinity of people who believe Linux is some sort of virus or brand of coffee, the use of "slash dev slash foo" will return a strange look for sure. But for the fortunate user (and that includes you) using /dev/sda1 is just a fast way of explaining that we are talking about the primary master SATA, first partition. Or aren't we?

We all know what a device file is. Some even know why device files have special numbers when we take a closer look at them when we issue ls -l in /dev. But what we always take for granted is that the primary SATA disk is referred to as /dev/sda. You might not see it this way, but this is a flaw by design.

Think about hotpluggable devices like USB, IEEE1394, hot-swappable PCI, ... What is the first device? And for how long? What will the other devices be named when the first one disappears? How will that affect ongoing transactions? Wouldn't it be fun that a printing job is suddenly moved from your supernew laserprinter to your almost-dead matrix printer because your mom decided to pull the plug of the laserprinter which happened to be the first printer?

Enter udev. The goals of the udev project are both interesting and needed:

  • Runs in userspace
  • Dynamically creates/removes device files
  • Provides consistent naming
  • Provides a user-space API

Every time a change happens within the device structure, the kernel emits a uevent which gets picked up by udev. udev then follows the rules as declared in the /etc/udev/rules.d, /run/udev/rules.d and /lib/udev/rules.d directories. Based on the information contained within the uevent, it finds the rule or rules it needs to trigger and performs the required actions. These actions can be creating or deleting device files, but can also trigger the loading of particular firmware files into the kernel memory.

Installation

Note
If you're updating, check the upgrade subpage.

Kernel

You need to activate the following kernel options:

Kernel configuration

General setup  --->
    [*] Configure standard kernel features (expert users)  --->
        [ ] Enable deprecated sysfs features to support old userspace tools
        [*] Enable signalfd() system call
Enable the block layer  --->
    [*] Block layer SG support v4
Networking support  --->
    Networking options  --->
        <*> Unix domain sockets
Device Drivers  --->
    Generic Driver Options  --->
        ()  path to uevent helper
        [*] Maintain a devtmpfs filesystem to mount at /dev
    < > ATA/ATAPI/MFM/RLL support (DEPRECATED)  --->
File systems  --->
    [*] Inotify support for userspace
    Pseudo filesystems --->
        [*] /proc file system support
        [*] sysfs file system support

Software

Portage knows the global USE flag udev for enabling support for udev in other packages. Enabling this USE flag (default in all linux profiles) will pull in sys-fs/udev automatically:

File/etc/portage/make.conf

USE="... udev ..."

The USE flags of udev are:


→ Information about USE flags
USE flag Default Recommended Description
acl Yes Adds support for Access Control Lists
doc No Adds extra documentation (API, Javadoc, etc). It is recommended to enable per package instead of globally
firmware-loader Yes Enable userspace firmware loader (DEPRECATED, replaced by in-kernel loader in 3.8+)
gudev Yes Build the gobject interface library
introspection Yes Adds support for GObject based introspection
kmod Yes Enable kernel module loading/unloading support using sys-apps/kmod
openrc Yes Install the OpenRC init scripts
selinux No No  !!internal use only!! Security Enhanced Linux support, this must be set by the selinux profile or breakage will occur
static-libs No No Build static libraries

After setting this you want to update your system so the changes take effect:

root # emerge --ask --changed-use --deep @world

Configuration

Service

To start udev at boot time, add it your sysinit runlevel:

root # rc-update add udev sysinit

Advanced Configuration

Rules

udev provides a set of rules that match against exported values of uevents (events sent by the kernel) and properties of the discovered device. A matching rule will possibly name and create a device node and run configured programs to set-up and configure the device.

The rule definitions are stored in /lib/udev/rules.d (installed by packages) and /etc/udev/rules.d (for end-user specified rules). In these directories, multiple rule files (with suffix .rules) are traversed in alphanumerical order. Inside the rules files, udev will find expressions that might match a uevent together with the state to match (is the uevent because a device is added or removed) and the command to execute.

The event matching is based on information such as:

  • the SUBSYSTEM of the uevent (for which type of device is the uevent fired)
  • the ACTION that is taken (add, change or remove)
  • one or more attributes (through ATTR or ATTRS), such as the device class, vendor or other device information
  • the kernel-provided name (through KERNEL), such as sd* (for SCSI/SATA disks) or input* (for input devices such as mice and keyboards)
  • one or more environment settings (through ENV), used to send information between multiple rules

Based on this information, the rule can then state if

  • some information needs to be shared with later events (through environment variables)
  • links need to be created in /dev
  • commands need to be executed

Udev does this for every rule that matches (so it does not stop after the first match) to allow a flexible device management approach.

Persistent device names

The kernel detects devices asynchronous, udev mirrors the kernel's sysfs filesystem and so the device are named and numbered in order of detection. So by default udev provides no persistent device names. However there are mechanisms for some device classes to provide these:

  • udev creates for storage devices additional symlinks based on the device's id, label, uuid and path. See the /dev/disk/by-* directory. So instead of using e.g. the device file /dev/sda use the file /dev/disk/by-label/SOME_LABEL.
  • The same for input devices in the /dev/input directory.
  • Using custom rules you can create your own device files.

Usage

Some useful commands are:

  • Show all messages about a given device file:
root # udevadm info --query=all --name=/dev/DEVICE_FILE
  • Monitor udev activities:
root # udevadm monitor

See the udevadm man page for more information.

Troubleshooting

Log monitor messages

Log all message you see, when you run udevadm monitor:

File/etc/conf.d/udev

udev_monitor="YES"

It will create the new log file /run/udev/udevmonitor.log.

Debug mode

Enable debug mode to get more log messages:

File/etc/conf.d/udev

udev_debug="YES"

It will create the new log file /run/udev/udevdebug.log.

Missing device files /dev/null and /dev/console

Some udev versions need these files and can't create them on their own. So you have to create them:

root # mkdir test
root #
mount --bind / test
root #
cd test/dev
root #
mknod -m 660 console c 5 1
root #
mknod -m 660 null c 1 3
root #
cd ../..
root #
umount test
root #
rmdir test

NIC assigned eth0, but is moved to eth1

Those having dual network cards on their motherboards may run into a situation where ifconfig may show no eth0 or eth1. dmesg may show their NIC detected as eth0, and later moved to eth1. Performing a "ifconfig -a" will also show the NIC as eth1. This is caused by using the kernel assigned names in the first place. You should write your own rules like /etc/udev/rules.d/70-my-network.rules to use free names like lan0 or wireless0 or use the predictable interface names which are enabled by the default since version 197.

Remember to also remove old files from old versions of udev:

root # rm /etc/udev/rules.d/70-persistent-net.rules