Udev

From Gentoo Wiki
Jump to:navigation Jump to:search
This page is a translated version of the page Udev and the translation is 9% complete.
Outdated translations are marked like this.
Other languages:
Resources
不要混淆 eudev.


udev(user /dev)是systemd的 Linux内核设备管理器。它管理/dev 中的设备节点,并在添加或删除设备时处理所有用户空间操作。

udev from the sys-apps/systemd-utils package is used as the default device manager for Gentoo systems using the OpenRC init system, independently of systemd.

/dev目录

大多数Linux用户都知道 /dev/sda1 只是内核找到的第一个磁盘上的第一个分区的快速方法。这很简单,对吧?

但请考虑USB,IEEE 1394,热插拔PCI等热插拔设备。这些设备的第一个设备是什么?而且持续多久?当第一个设备消失时,其他设备会被命名为什么?这将如何影响正在进行的事务?如果一个打印作业突然从高端激光打印机转移到几乎死机的矩阵打印机,仅仅是因为有人决定拔下激光打印机上的插头(恰好是第一台打印机),这会不会很有趣?

进入设备管理器。一个现代设备管理器(包括 udeveudev)必须:

  • 在用户空间中运行。
  • 动态创建和删除device file
  • 提供一致的设备命名。
  • 提供用户空间应用程序接口(API)。

每当设备结构发生变化时,内核都会发出一个由设备管理器获取的 uevent ,然后设备管理器遵循 /etc/udev/rules.d, /run/udev/rules.d/lib/udev/rules.d 目录中声明的规则,根据uevent中包含的信息,它会找到触发和执行所需操作所需的规则。这些动作可能涉及设备文件的创建或删除,还可能触发将特定固件文件加载到内核内存中。

安装

重要
更新udev时, 从 udev 升级指南 获取信息,以防止系统无法启动。

内核

udev 需要以下内核选项:

内核
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

USE 标记

Portage knows the udev USE flag for enabling support for udev in other packages. Adding this USE flag value to the USE flag list (default in all Linux profiles) will pull in the virtual/udev package automatically:

文件 /etc/portage/make.conf
USE="udev"

Cannot load package information. Is the atom sys-fs/udev correct?

Emerge

设置 USE 标志后更新系统以使更改生效:

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

配置

服务

要在引导时启动 udev,请将其添加到系统初始化运行级别。这可以通过使用 root 权限运行以下命令来完成:

root #rc-update add udev sysinit

高级配置

规则

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 setup and configure the device.

The rule definitions are stored in two locations:

  1. /lib/udev/rules.d/ - Rules in this directory are installed by certain packages, they generally should not be changed by users;
  2. /etc/udev/rules.d/ - This folder is for end-user specified rules. Any new rules should be added in this directory;

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:

  1. Some information needs to be shared with later events (through environment variables)
  2. Links need to be created in /dev
  3. Commands need to be executed

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

Persistent device names

The kernel detects devices asynchronously, udev mirrors the kernel's sysfs filesystem and so the devices 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 enables users to create their own device files.

Predictable network interface naming

The new network interface naming convention is not the same. So the symlinks used by netifrc will need to be re-linked. Use /etc/init.d/net.lo as a link target for whatever interface names need to be added. Be sure to replace <interface_name> in the commands below with the Ethernet interface names present on the system. It is possible to discover which interfaces exist by running the ip link command:

user $ip link

Create a symbolic link for the existing interfaces in the /etc/init.d/ directory:

root #ln -s /etc/init.d/net.lo /etc/init.d/net.<interface_name>

Edit /etc/conf.d/net with any necessary configuration for all interfaces.

Add the script(s) to the default runlevel to have the interface(s) start automatically:

root #rc-update add net.<interface_name> default

Optional: Disable or override predictable network interface naming

Network device names such as eth0 or wlan0 as provided by the kernel are normally changed on system boot (see dmesg) by the /lib/udev/rules.d/80-net-setup-link.rules udev rule and the NamePolicy in /lib/systemd/network/99-default.link.

This behavior may be disabled in several ways:

  1. Symlink /etc/systemd/network/99-default.link to /dev/null: ln -s /dev/null /etc/systemd/network/99-default.link.
  2. Create a lower-numbered .link file in /etc/systemd/network which assigns a different name to the interface.
  3. Pass net.ifnames=0 on the kernel command line.

Usage

Some useful commands are:

  • Monitor all udev activities:
root #udevadm monitor
  • Show all messages about a given device file:
root #udevadm info --query=all --name=/dev/DEVICE_FILE
  • Show udev info about a given sys path device file (might be obtained via udevadm monitor):
root #udevadm info --attribute-walk --path=/devices/DEVICE_FILE
  • Udev rules file example - assign a persistent name to an Ethernet device:
文件 /etc/udev/rules.d/50-ethernet.rules
SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="01:23:45:67:89:ab", NAME="ethernet0"
  • After changing a rules file in /etc/udev/rules.d/, either reboot or make udev reload them with:
root #udevadm control --reload-rules
  • For already added devices (plugged USB, etc.), the reloaded rules take effect either after changing the device (replugging USB, etc.) or by making udev request kernel events again via udevadm trigger. Various event actions can be triggered. By default, the change event action is triggered:
root #udevadm trigger

See the udevadm(8) man page for more information.

Troubleshooting

Log monitor messages

To log all message when udevadm monitor is run, modify the following configuration file:

文件 /etc/conf.d/udev
udev_monitor="YES"

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

Debug mode

Enabling debug mode will output more log messages:

文件 /etc/conf.d/udev
udev_debug="YES"

Set the logging priority:

文件 /etc/udev/udev.conf
udev_log="debug"

The log file /run/udev/debug.log will be created but no messages will be logged to it. The most recent versions of udev will log all messages to dmesg.

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

Some udev versions need the /dev/null and /dev/console files in order to work properly, but cannot create them on their own. To manually create these files for udev run the following commands with root privileges:

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 ip link may show no eth0 or eth1. dmesg may show their NIC detected as eth0, and later moved to eth1. Performing a ip link will also show the NIC as eth1. This is caused by using the kernel assigned names in the first place. Users should write custom rules like /etc/udev/rules.d/70-my-network.rules to use free names like lan0 or wireless0 or use predictable interface names (which have been enabled by default since udev version 197).

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

root #rm /etc/udev/rules.d/70-persistent-net.rules /etc/udev/rules.d/80-net-setup-link.rules /etc/udev/rules.d/80-net-name-slot.rules /etc/systemd/network/99-default.link

Also make sure not to pass net.ifnames=0 on the kernel commandline. This setting would disable the predictable interface names feature of udev altogether.

See also

External resources