udev

From Gentoo Wiki
Jump to:navigation Jump to:search
This page is a translated version of the page Udev and the translation is 96% complete.
これと混同しないでください: eudev.


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 パッケージを自動でインストールするでしょう:

ファイル /etc/portage/make.conf
USE="udev"

USE flags for sys-apps/systemd-utils Utilities split out from systemd for OpenRC users

acl Add support for Access Control Lists
boot Enable systemd-boot (UEFI boot manager)
kernel-install Enable kernel-install
kmod Enable kernel module loading via sys-apps/kmod
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)
tmpfiles Enable systemd-tmpfiles
udev Enable systemd-udev (userspace device manager)
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 箇所に保存されます:

  1. /lib/udev/rules.d/ - このディレクトリ内のルールは 特定のパッケージによりインストールされ、一般にユーザが変更すべきではありません;
  2. /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)。複数のルールに渡って情報を送信するために使用されます。

この情報に基づいて、ルールは以下のことを宣言することができます:

  1. 一部の情報を後々のイベントと共有する必要があるか (環境変数を利用して)
  2. /dev 内にリンクを作成する必要があるか
  3. コマンドを実行する必要があるか

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 を確認してください)。

この挙動は複数の方法で無効化することができます:

  1. /etc/systemd/network/99-default.link/dev/null へのシンボリックリンクを作成してください: ln -s /dev/null /etc/systemd/network/99-default.link
  2. /etc/systemd/network 内に、インターフェースに別の名前を割り当てる .link ファイルをより小さい番号を付けて作成してください。
  3. カーネルコマンドラインに 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 デバイスに一貫性のある名前を割り当てます:
ファイル /etc/udev/rules.d/50-ethernet.rules
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 を実行中のすべてのメッセージをログとして出力するには、次の設定ファイルを変更してください:

ファイル /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 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.

関連項目

外部資料