udev
udev (user /dev) は systemd の Linux カーネルのためのデバイスマネージャです。/dev 内のデバイスノードを管理し、デバイスを追加または削除するときのユーザ空間での操作のすべてを取り扱います。
sys-apps/systemd-utils パッケージに含まれる udev は、OpenRC init システムを使用する Gentoo システムのためのデフォルトのデバイスマネージャとして、systemd から独立して利用されます。
udev とは何ですか?
/dev ディレクトリー
多くの Linux ユーザは、/dev/sda1 はカーネルが認識した最初のディスクの最初のパーティションを指す最短の手段だということを知っています。これはとても平易でしょう。
しかし、USB や IEEE 1394、ホットスワップ可能な PCI などのホットプラグ対応デバイスを考えてみてください。最初のデバイスというのはこれらのうちどれのことでしょう? そして、いつまで最初のデバイスといえるのでしょう? 最初のデバイスが消えたとき、他のデバイスは何と名付けられるのでしょうか? それは進行中の処理に影響するでしょうか? 誰かが(たまたま最初のプリンターになっていた)レーザープリンターのプラグを引っこ抜いたというだけの理由で、印刷ジョブが高性能なレーザープリンターからほとんど壊れかけのマトリックスプリンターに突然移ってしまったとしたら、笑ってしまいませんか?
デバイスマネージャに入ってみましょう。今どきのデバイスマネージャならば必ず:
- ユーザスペースで動作します。
- 動的にデバイスファイルが生成されたり削除されたりします。
- 一貫したデバイス命名を行います。
- ユーザスペースのアプリケーション・プログラム・インターフェイス (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 パッケージを自動でインストールするでしょう:
USE="udev"
USE flags for sys-apps/systemd-utils Utilities split out from systemd for OpenRC users
+acl
|
Add support for Access Control Lists |
+kmod
|
Enable kernel module loading via sys-apps/kmod |
+tmpfiles
|
Enable systemd-tmpfiles |
+udev
|
Enable systemd-udev (userspace device manager) |
boot
|
Enable systemd-boot (UEFI boot manager) |
kernel-install
|
Enable kernel-install |
secureboot
|
Automatically sign efi executables using user specified key |
selinux
|
!!internal use only!! Security Enhanced Linux support, this must be set by the selinux profile or breakage will occur |
split-usr
|
Enable behavior to support maintaining /bin, /lib*, /sbin and /usr/sbin separately from /usr/bin and /usr/lib* |
sysusers
|
Enable systemd-sysusers |
test
|
Enable dependencies and/or preparations necessary to run tests (usually controlled by FEATURES=test but can be toggled independently) |
ukify
|
Enable systemd-ukify |
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/ - このフォルダはエンドユーザ固有のルールのためのものです。新しいルールはすべてこのディレクトリに追加すべきです;
これらのディレクトリ内で、複数のルールファイル (接尾辞 .rules を持つもの) が英数字順に走査されます。ルールファイルの中では udev は、uevent にマッチする式、マッチする状態 (その uevent がデバイスが追加または削除されたことによるものか)、および実行するコマンドの組み合わせを探します。
イベントマッチングは、次のような情報に基づいています:
- uevent の SUBSYSTEM (uevent がどのタイプのデバイスに対して発生したか);
- 対処される ACTION (追加 (add)、変更 (change)、または削除 (remove));
- 1 個または複数の属性 (ATTR または ATTRS)。デバイスクラス、ベンダー、またはその他のデバイス情報など;
- カーネルが提供する名前 (KERNEL)。sd* (SCSI/SATA ディスクに対して) または input* (マウスやキーボードなどの入力デバイスに対して) など;
- 1 個または複数の環境設定 (ENV)。複数のルールに渡って情報を送信するために使用されます。
この情報に基づいて、ルールは以下のことを宣言することができます:
- 一部の情報を後々のイベントと共有する必要があるか (環境変数を利用して)
- /dev 内にリンクを作成する必要があるか
- コマンドを実行する必要があるか
Udev はこれをすべてのマッチするルールに対して (最初のマッチ後に止まることなく) 実行し、柔軟なデバイス管理のアプローチを可能にしています。
永続的なデバイス名
カーネルは非同期的にデバイスを検出し、udev はカーネルの sysfs ファイルシステムをミラーリングするため、デバイスは検出された順に番号が振られて名前が付けられます。そのためデフォルトでは udev は永続的なデバイス名を提供しません。しかしながら一部のデバイスクラスでは、これらを提供するための機構があります:
- ストレージデバイスに関しては、udev はデバイスの ID、ラベル、UUID、およびパスに基づいて、追加のシンボリックリンクを作成します。/dev/disk/by-* ディレクトリを参照してください。そのため、例えば /dev/sda などのデバイスファイルを使用する代わりに、ファイル /dev/disk/by-label/SOME_LABEL を使用することができます。
- 入力デバイスに関しては、/dev/input ディレクトリ内で同様のことが行われます。
- カスタムルールを使用することで、ユーザは自身のデバイスファイルを作成することができるようになります。
予測可能なネットワークインターフェースの命名
新しいネットワークインターフェース命名規約は以前のものとは異なっています。netifrc によって使用されるシンボリックリンクは再リンクする必要があるでしょう。追加したいインターフェース名それぞれに対して、リンク先として /etc/init.d/net.lo を使用してください。下のコマンド <interface_name>
の部分はシステムに存在するイーサネットインターフェース名で置き換えてください。ip link コマンドを実行することで、どのインターフェースが存在するか発見することができます:
user $
ip link
存在する各インターフェースに対して /etc/init.d/ ディレクトリ内にシンボリックリンクを作成してください:
root #
ln -s /etc/init.d/net.lo /etc/init.d/net.<interface_name>
すべてのインターフェースに関して必要な設定を /etc/conf.d/net に書いてください。
インターフェースを自動的に開始させるには、対応するスクリプトを default ランレベルに追加してください:
root #
rc-update add net.<interface_name> default
省略可能: 予測可能なネットワークインターフェース名を無効化または上書きする
カーネルによって提供される eth0
または wlan0
などのネットワークデバイス名は通常、/lib/udev/rules.d/80-net-setup-link.rules udev ルールおよび /lib/systemd/network/99-default.link 内の NamePolicy によって、システムブート時に変更されます (dmesg を確認してください)。
この挙動は複数の方法で無効化することができます:
- /etc/systemd/network/99-default.link に /dev/null へのシンボリックリンクを作成してください: ln -s /dev/null /etc/systemd/network/99-default.link。
- /etc/systemd/network 内に、インターフェースに別の名前を割り当てる .link ファイルをより小さい番号を付けて作成してください。
- カーネルコマンドラインに
net.ifnames=0
を渡してください。
参照: https://systemd.io/PREDICTABLE_INTERFACE_NAMES/
使い方
便利なコマンドをいくつか挙げると:
- すべての 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 デバイスに永続的な名前を割り当てます:
SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="01:23:45:67:89:ab", NAME="ethernet0"
- /etc/udev/rules.d/ 内のルールファイルを変更した後は、再起動するか、以下のコマンドで udev に再読み込みさせます:
root #
udevadm control --reload-rules
- 既に追加されているデバイス (接続済みの USB 等) に対しては、再読み込みされたルールは、デバイスを変更する (USB を接続し直す 等) か、udevadm trigger によって udev にカーネルイベントを再度リクエストさせることで反映されます。様々なイベントアクションを発動させることができます。デフォルトでは change イベントアクションが発動します:
root #
udevadm trigger
さらなる情報は udevadm(8) の man page を読んでください。
トラブルシューティング
監視中のメッセージをログとして出力する
udevadm monitor を実行中のすべてのメッセージをログとして出力するには、次の設定ファイルを変更してください:
udev_monitor="YES"
/run/udev/udevmonitor.log に新しいログファイルが作成されるでしょう。
デバッグモード
デバッグモードを有効にすると、詳細なメッセージをログに記録します:
udev_debug="YES"
ロギングの優先順位を設定します:
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 に eth0 が割り当てられるが、eth1 に移動される
マザーボード上にデュアルネットワークカードを持っている場合、ip link が eth0 も eth1 も表示しない状況に陥ることがあるかもしれません。dmesg は、その NIC が eth0 として検出されたが、その後 eth1 に移動したことを示しているかもしれません。ip link を実行する場合も、その NIC は eth1 として表示されるでしょう。これは最初にカーネルによって割り当てられた名前を使用することによって発生します。ユーザは、lan0 や wireless0 のような自由な名前を使用するために、/etc/udev/rules.d/70-my-network.rules のようなカスタムルールを書くか、予測可能なインターフェース名 (udev バージョン 197 からデフォルトで有効化されています) を使用するべきです。
忘れずに、古いバージョンの 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
また、net.ifnames=0
をカーネルコマンドラインに渡していないことも確認してください。この設定は udev の予測可能なインターフェース名の機能を完全に無効化するでしょう。