9.4. デバイスの管理

9.4.1. ネットワークデバイス

Udev はデフォルトにおいて、ネットワークデバイスの名前づけを、ファームウェア/BIOS データや物理的特性、つまりバス、スロット、MACアドレスに基づいて取り決めます。 このような命名規則とする目的は、複数のネットワークデバイスの命名を正確に行うためであり、検出した順番に命名することがないようにするためです。 かつての古いバージョンの Linux の場合に、たとえば Intel 製と Realtek 製の 2 つのネットワークカードを持つコンピューターにおいて、 Intel 製が eth0、Realtek 製が eth1 となったとします。 システムを再起動した際には、番号割り振りが逆転することもあります。

新たな命名スキーマでは、ネットワークデバイス名が例えば enp5s0 や wlp3s0 といったものになります。 もしこの命名規則を望まない場合は、従来の命名規則とすることもできます。 またはカスタムスキーマを定義することもできます。

9.4.1.1. カーネルコマンドラインによる持続的命名の回避

従来の命名スキーマ、例えば eth0、eth1 といったものは、カーネルコマンドラインに net.ifnames=0 を加えることで利用できます。 この設定は、イーサネットデバイスをただ一つしか持たないシステムでは適正なものとなります。 一方ノート PC には、たいていは eth0 と wlan0 といった 2 つのイーサネット接続があります。 上に示した方法は、ノート PC に対しても適用できます。 カーネルコマンドラインは GRUB の設定ファイルにて設定できます。 詳しくは「GRUB 設定ファイルの生成」を参照してください。

9.4.1.2. Udev カスタムルールの生成

命名スキーマは udev カスタムルールを生成することによってカスタマイズが可能です。 Udev には初期ルールを生成するスクリプトが含まれています。 このルールを生成するには以下を実行します。

bash /usr/lib/udev/init-net-rules.sh

そして /etc/udev/rules.d/70-persistent-net.rules ファイルを参照し、どういった名前によりネットワークデバイスが定められているかを確認します。

cat /etc/udev/rules.d/70-persistent-net.rules
[注記]

注記

ネットワークカードに対して手動で MAC アドレスを割り当てた場合、あるいは Qemu や Xen のような仮想環境における場合においては、ネットワークルールファイルが生成されないことがあります。 これはアドレスの割り当てが確定されないためです。 こういった場合は本方法を利用することはできません。

このファイルの先頭にはコメントが数行あり、続いてそれぞれの NIC に対する行があります。 NIC ごとの記述では一行めがコメントで、そのハードウェア ID が記されています。 (PCI カードである場合、PCI ベンダとデバイス ID が記述されます。) また(ドライバーが検出できている場合にはカッコ書きで)ドライバー名も示されます。 ハードウェア ID もドライバー名も、インターフェースに対して与えられる名称とは無関係で、単に分かりやすくするために記されているにすぎません。 二行めは udev ルールであり、その NIC を定め、名称を割り当てている記述です。

udev ルールはいくつかのキーワードで構成され、それぞれがカンマで区切られるか、場合によっては空白文字で区切られています。 このキーワードとその内容は以下のようになります。

  • SUBSYSTEM=="net" - ネットワークカードではないデバイスは無視することを指示します。

  • ACTION=="add" - uevent の add イベントではないものは無視することを指示します。 (uevent の "remove" イベントや "change" イベントも発生しますが、これらはネットワークインターフェースの名前を変更するものではありません。)

  • DRIVERS=="?*" - udev に対して VLAN やブリッジサブインターフェース (bridge sub-interfaces) を無視することを指示します。 (サブインターフェースにはドライバーがないためです。) サブインターフェースに名前が割り当てられたとすると、親デバイスの名前と衝突してしまうため、サブインターフェースの名前割り当てはスキップされます。

  • ATTR{address} - このキーワードの値は NIC の MAC アドレスを表します。

  • ATTR{type}=="1" - 特定のワイヤレスドライバーでは複数の仮想インターフェースが生成されますが、そのうちの主となるインターフェースにのみルールが合致するようにします。 二つめ以降のインターフェースに対する処理は、VLAN やブリッジサブインターフェースがスキップされるのと同じくスキップされます。 名前割り当てが行われてしまうと名前衝突を起こすためです。

  • NAME - udev がインターフェースに対して割り当てる名前をキーワードの値として指定します。

NAME に定義される値が重要です。 どのネットワークカードにどんな名前が割り当てられているかをよく確認してください。 そしてネットワーク設定ファイルを生成する際には NAME に定義されている名称を利用してください。

たとえカスタムルールファイルを生成していても、udev は NIC に対して、その物理的特性からいくつかの名前を割り振るかもしれません。 仮にカスタム udev ルールが定めた NIC 名が、他の NIC に割り当てられた別名と同じものに割り当てられた場合、その udev ルールは失敗します。 この問題が発生する場合には、設定ファイル /etc/udev/network/99-default.link を生成して、空の別名割り当てポリシーを設定することで、デフォルトの設定である /usr/lib/udev/network/99-default.link を上書きするようにします。

sed -e '/^AlternativeNamesPolicy/s/=.*$/=/'  \
    -i /usr/lib/udev/network/99-default.link \
     > /etc/udev/network/99-default.link

9.4.2. CD-ROM のシンボリックリンク

後にインストールしていくソフトウェア (例えばメディアプレーヤーなど) では、/dev/cdrom/dev/dvd といったシンボリックリンクを必要とするものがあります。 これらはそれぞれ CD-ROM、DVD-ROM を指し示しています。 こういったシンボリックリンクは /etc/fstab ファイルに設定しておくのが便利です。 Udev が提供するスクリプトファイルで、ルールファイル (rules files) を生成するものがあります。 そのルールファイルは、各デバイスの性能に応じてシンボリックファイルを構成します。 もっともこのスクリプトファイルを利用する際には、二つ存在する動作モードのいずれを用いるかを決めなければなりません。

一つはパス (by-path)モードです。 これは USB デバイスやファームウェアデバイスに対してデフォルトで利用されます。 これによって作り出されるルールは CD や DVD デバイスに対して物理パスが用いられます。 二つめはID (by-id)モードです。 デフォルトで IDE や SCSI デバイスに利用されます。 このモードで作り出されるルールは CD や DVD デバイス自身が持つ識別文字列が用いられます。 パスは udev の path_id スクリプトによって決定します。 一方、識別文字列は ata_id プログラムまたは scsi_id プログラムによってハードウェアから読み出されます。 ata_idscsi_id のいずれであるかは、そのデバイスによって決まります。

二つの方法にはそれぞれに利点があります。 どちらの方法が適切であるかは、デバイスがどのように変更されるかによります。 デバイスに対する物理パス (そのデバイスが接続しているポートやスロット) を変更したい場合、例えば IDE ポートや USB コネクタを切り替えたいような場合、ID (by-id)モードを使うべきです。 一方、デバイスの識別文字列を変えたい場合、つまりデバイスが故障したために、新しいデバイスを同一コネクタに接続しようとする場合は、パス (by-path)モードを使うべきです。

いずれの変更の可能性もあるならば、より変更の可能性の高いケースに従ってモードを選ぶべきです。

[重要]

重要

外部接続のデバイス (例えば USB 接続の CD ドライブなど) はパス (by-path) モードを用いるべきではありません。 そのようなデバイスは接続するたびに外部ポートが新しくなり、物理パスが変わってしまうためです。 こういった外部接続のデバイスを物理パスで認識させ udev ルールを構成した場合は、あらゆるデバイスがこの問題を抱えることになります。 これは CD や DVD ドライブだけに限った話ではありません。

udev スクリプトが利用しているキーの値を確認したい場合は /sys ディレクトリ配下を確認します。 例えば CD-ROM デバイスについては /sys/block/hdd を確認します。 そして以下のようなコマンドを実行します。

udevadm test /sys/block/hdd

出力結果には *_id というプログラム名を示した行がたくさん表示されます。 ID (by-id)モードは ID_SERIAL 値が存在して空でなければこれを利用します。 そうでない時は ID_MODEL と ID_REVISION を利用します。 パス (by-path)モードは ID_PATH の値を利用します。

デフォルトモードが利用状況に合わない場合は、/etc/udev/rules.d/83-cdrom-symlinks.rules ファイルに対して以下のように修正を行います。 mode の部分はby-idby-pathに置き換えます。

sed -e 's/"write_cd_rules"/"write_cd_rules mode"/' \
    -i /etc/udev/rules.d/83-cdrom-symlinks.rules

ここでルールファイルやシンボリックリンクを作成する必要はありません。 この時点ではホストの /dev ディレクトリに対して LFS システムに向けてのバインドマウント (bind-mounted) を行っており、ホスト上にシンボリックリンクが存在していると仮定しているからです。 ルールファイルとシンボリックリンクは LFS システムを初めてブートした時に生成されます。

もっとも CD-ROM デバイスが複数あると、ブート時に生成されるシンボリックリンクが、ホスト利用時に指し示されていたものとは異なる場合が発生します。 デバイスの検出順は予測できないものだからです。 LFS システムを初めて起動した時の割り当ては、たぶん固定的に行われるはずです。 つまりこのことは、ホストシステムと LFS システムの双方で、シンボリックリンクが同じデバイスを指し示すことが必要である場合にのみ問題となります。 これが必要であるなら、生成されている /etc/udev/rules.d/70-persistent-cd.rules ファイルを起動後に調査して (おそらくは編集して) 割り当てられたシンボリックリンクが望むものになっているかどうかを確認してください。

9.4.3. 重複するデバイスの取り扱い方

「デバイスとモジュールの扱いについて」で説明したように、/dev 内に同一機能を有するデバイスがあったとすると、その検出順は本質的にランダムです。 例えば USB 接続のウェブカメラと TV チューナーがあったとして、/dev/video0 がウェブカメラを、また /dev/video1 がチューナーをそれぞれ参照していたとしても、システム起動後はその順が変わることがあります。 サウンドカードやネットワークカードを除いた他のハードウェアであれば、udev ルールを適切に記述することで、固定的なシンボリックリンクを作り出すことができます。 ネットワークカードについては、別途 「全般的なネットワークの設定」にて説明しています。 またサウンドカードの設定方法は BLFS にて説明しています。

利用しているデバイスに上の問題の可能性がある場合 (お使いの Linux ディストリビューションではそのような問題がなかったとしても) /sys/class ディレクトリや /sys/block ディレクトリ配下にある対応ディレクトリを探してください。 ビデオデバイスであれば /sys/class/video4linux/videoX といったディレクトリです。 そしてそのデバイスを一意に特定する識別情報を確認してください。 (通常はベンダー名、プロダクトID、シリアル番号などです。)

udevadm info -a -p /sys/class/video4linux/video0

シンボリックリンクを生成するルールを作ります。

cat > /etc/udev/rules.d/83-duplicate_devs.rules << "EOF"

# Persistent symlinks for webcam and tuner
KERNEL=="video*", ATTRS{idProduct}=="1910", ATTRS{idVendor}=="0d81", SYMLINK+="webcam"
KERNEL=="video*", ATTRS{device}=="0x036f",  ATTRS{vendor}=="0x109e", SYMLINK+="tvtuner"

EOF

こうしたとしても /dev/video0/dev/video1 はチューナーとウェブカメラのいずれかをランダムに指し示すことに変わりありません。 (したがって直接このデバイス名を使ってはなりません。) しかしシンボリックリンク /dev/tvtuner/dev/webcam は常に正しいデバイスを指し示すようになります。