udev
udev (user /dev) は systemd の Linux カーネルのためのデバイスマネージャです。/dev 内のデバイスノードを管理し、デバイスを追加または削除するときのユーザ空間での操作のすべてを取り扱います。
sys-fs/udev パッケージは、OpenRC init システムを使用する Gentoo システムのためのデフォルトのデバイスマネージャとして、systemd から独立して、利用されます。
udev とは何ですか?
/dev ディレクトリー
多くの Linux ユーザは、/dev/sda1 はカーネルが認識した最初のディスクの最初のパーティションを指す最短の手段だということを知っています。これはとても平易でしょう。
しかし、USB や IEEE 1394、ホットスワップ可能な PCI などのホットプラグ対応デバイスを考えてみてください。最初のデバイスというのはこれらのうちどれのことでしょう? そして、いつまで最初のデバイスといえるのでしょう? 最初のデバイスが消えたとき、他のデバイスは何と名付けられるのでしょうか? それは進行中の処理に影響するでしょうか? 誰かが(たまたま最初のプリンターになっていた)レーザープリンターのプラグを引っこ抜いたというだけの理由で、印刷ジョブが高性能なレーザープリンターからほとんど壊れかけのマトリックスプリンターに突然移ってしまったとしたら、笑ってしまいませんか?
デバイスマネージャに入ってみましょう。( udev や eudev のような)今どきのデバイスマネージャならば必ず:
- ユーザスペースで動作します。
- 動的にデバイスファイルが生成されたり削除されたりします。
- 一貫したデバイス命名を行います。
- ユーザスペースのアプリケーション・プログラム・インターフェイス (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 は udev
USE フラグを、他のパッケージの udev サポートを有効化するものであると認識しています。この USE フラグ値を USE フラグリストに追加すると (すべての Linux プロファイルでデフォルトです)、virtual/udev パッケージを自動でインストールするでしょう:
/etc/portage/make.conf
USE="udev"
USE flags for sys-fs/udev Virtual package to depend on sys-apps/systemd-utils
Emerge
USE フラグを設定したら、システムを更新して変更を反映させましょう:
root #
emerge --ask --changed-use --deep @world
設定
サービス
起動時に udev を始動させるには、 sysinit ランレベルに追加します。root 権限で以下のコマンドを実行すると可能です:
root #
rc-update add udev sysinit
高度な設定
ルール
udev は、uevent (カーネルによって送信されるイベント) から抽出された値と、発見されたデバイスのプロパティに対してマッチする、ルールの集合を提供します。マッチングルールは、デバイスノードを命名して作成し、デバイスのセットアップおよび構成のために設定されたプログラムを実行することができます。
ルール定義は以下の 2 箇所に保存されます:
- /lib/udev/rules.d/ - このディレクトリ内のルールは 特定のパッケージによりインストールされ、一般にユーザが変更すべきではありません;
- /etc/udev/rules.d/ - このフォルダはエンドユーザ固有のルールのためのものです。新しいルールはすべてこのディレクトリに追加すべきです;
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 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 (it does not stop after the first match) to allow a flexible device management approach.
永続的なデバイス名
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
省略可能: 予測可能なネットワークインターフェース名を無効化または上書きする
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:
- Symlink /etc/systemd/network/99-default.link to /dev/null: ln -s /dev/null /etc/systemd/network/99-default.link.
- Create a lower-numbered .link file in /etc/systemd/network which assigns a different name to the interface.
- Pass
net.ifnames=0
on the kernel command line.
使い方
便利なコマンドをいくつか挙げると:
- すべての udev アクティビティを監視します:
root #
udevadm monitor
- 与えられたデバイスファイルについてのすべてのメッセージを表示します:
root #
udevadm info --query=all --name=/dev/DEVICE_FILE
- 与えられた sys path デバイスファイル (udevadm monitor を通じて取得できるかもしれません) についての udev 情報を表示します:
root #
udevadm info --attribute-walk --path=/devices/DEVICE_FILE
- udev ルールファイルの例 - Ethernet デバイスに永続的な名前を割り当てます:
- ファイル
/etc/udev/rules.d/50-ethernet.rules
SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="01:23:45:67:89:ab", NAME="eth0"
- /etc/udev/rules.d/ 内のルールファイルを変更した後は、再起動するか、以下のコマンドで udev に再読み込みさせます:
root #
udevadm control --reload-rules
- 既に追加されているデバイス (接続済みの USB 等) に対しては、再読み込みされたルールは、デバイスを変更する (USB を接続し直す 等) か、udevadm trigger によって udev にカーネルイベントを再度リクエストさせることで反映されます。様々なイベントアクションを発動させることができます。デフォルトでは change イベントアクションが発動します:
root #
udevadm trigger
さらなる情報は udevadm の man page を読んでください。
トラブルシューティング
監視中のメッセージをログとして出力する
udevadm monitor を実行中のすべてのメッセージをログとして出力するには、次の設定ファイルを変更してください:
/etc/conf.d/udev
udev_monitor="YES"
/run/udev/udevmonitor.log に新しいログファイルが作成されるでしょう。
デバッグモード
デバッグモードを有効にすると、詳細なメッセージをログに記録します:
/etc/conf.d/udev
udev_debug="YES"
ロギングの優先順位を設定します:
/etc/udev/udev.conf
udev_log="debug"
ログファイル /run/udev/debug.log が作成されますが、メッセージはこのファイルに出力されないでしょう。最新版の udev はすべてのメッセージを dmesg に出力するでしょう。
デバイスファイル /dev/null と /dev/console が無い
一部の版の udev は、正しく動作するために /dev/null と /dev/console ファイルを必要としますが、自身でこれらを作成することができません。udev のためにこれらのファイルを手動で作成するには、次のコマンドを root 権限で実行してください:
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. 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.