「Udev」の版間の差分

提供: ArchWiki
ナビゲーションに移動 検索に移動
(TranslationStatus)
 
(6人の利用者による、間の31版が非表示)
1行目: 1行目:
 
{{Lowercase title}}
 
{{Lowercase title}}
 
[[Category:ハードウェア検出とトラブルシューティング]]
 
[[Category:ハードウェア検出とトラブルシューティング]]
[[cs:Udev]]
 
 
[[de:Udev]]
 
[[de:Udev]]
 
[[en:Udev]]
 
[[en:Udev]]
[[es:Udev]]
 
 
[[fr:Udev]]
 
[[fr:Udev]]
[[it:Udev]]
 
 
[[ru:Udev]]
 
[[ru:Udev]]
 
[[zh-hans:Udev]]
 
[[zh-hans:Udev]]
[[zh-hant:Udev]]
 
 
{{Related articles start}}
 
{{Related articles start}}
 
{{Related|udisks}}
 
{{Related|udisks}}
 
{{Related articles end}}
 
{{Related articles end}}
  +
''udev'' は、オペレーティングシステムの管理者がユーザー空間のイベントハンドラを登録できるようにする、ユーザー空間のシステムです。''udev'' のデーモンによって捕捉されたイベントは主に、周辺機器関連の物理イベントに応答して (Linux) カーネルによって生成されたものです。そのため、''udev'' の主な使用目的は、(カーネルモジュールやデバイスファームウェアのロードなど) カーネルに制御が戻るようなアクションを含む、周辺機器の検出やホットプラグです。また、周辺機器の検出においては、デバイス (ファイル) のパーミッションを調整して非 root ユーザーや非 root グループからアクセス可能にするなども行われます。
[[Wikipedia:ja:Udev|Wikipedia の記事]]より:
 
:''"udev とは、Linuxカーネル 用のデバイス管理ツールである。主に {{ic|/dev}} ディレクトリ以下のデバイスノードを管理するために利用する。以前 {{ic|/dev}} ディレクトリの管理を担っていた devfs と、ホットスワップやファームウェアのロードなどユーザー空間におけるデバイスのアクション全てを担っていた hotplug の後継ツールである。"''
 
   
{{ic|udev}} は {{ic|hotplug}} と {{ic|hwdetect}} 両方の機能を置き換えます。
+
''udev''、''devfsd'' と ''hotplug'' の後継として、{{ic|/dev}} ディレクトリ内のデバイスノードの追加、シンボリックリンクの作成、名称変更などの管理も行います。''udev'' は ''hotplug''''hwdetect'' 両方の機能を置き換えます。
   
Udev は並列処理を利用てカーネルモジュールをロードるため順番モジュールをロードするのと比べ良いパフォーマンスが得られます。従ってモジュールは非同期読み込まます。この方法欠点とし、起動た時 udev はいつ同じ順番はモジュールをロードしせん。マシンに複数のブロックデバイスがる場合、デバイスノードの名称がランダムに変化する可能性があります。例えば、マシンに2つハードドライブが接続されている場合、ランダムで {{ic|/dev/sda}} {{ic|/dev/sdb}} かもしれません。これについては下で詳しく説明しています
+
''udev''、別々のイベントを同時に (並列に) 処理し。それより、古いシステムよりも高いパフォーマンスが得られる可能性があります。しかし、カーネルモジュールのロード順がブート毎同じであることが保証さないなどの理由により、この機構はシステム管理を複雑化させてしまう可能性はらん。マシンに複数のブロックデバイスが搭載されている場合、再起動するとデバイスノードの名称が変化してしまう場合があります。例えば、マシンに 2 ハードドライブが存在する場合、{{ic|/dev/sda}} は次回の起動時に {{ic|/dev/sdb}} ってしまうかもしれません。これに関する詳細記を見ください。
   
 
== インストール ==
 
== インストール ==
   
現在 Udev{{Pkg|systemd}} に含まれているため Arch Linuxデフォルトでインストールされています。詳しくは {{man|8|systemd-udevd.service}} [[man ページ]]を見てさい。
+
''udev''[[systemd]] の一部なのデフォルトでインストールされます。詳は {{man|8|systemd-udevd.service}} を見てください。
 
AUR には独立したフォークが存在します: [[eudev]]。
 
   
 
== udev ルールについて ==
 
== udev ルールについて ==
   
Udev ルールは管理者によって書かれます。{{ic|/etc/udev/rules.d/}} を見下さい、ファイル{{ic|.rules}} で終わる必要がありま。様々なパッケージに udev ルールが含まれており {{ic|/usr/lib/udev/rules.d/}} に保存されます。同じ名前のファイルが {{ic|/usr/lib}} と {{ic|/etc}} に存在する場合、{{ic|/etc}} 内のファイルが優先されます。
+
管理者が書いた ''udev'' ルールは {{ic|/etc/udev/rules.d/}} 内に配置することになっおりそのファイル名は ''.rules'' で終わらなければなりません。様々なパッケージに同梱されている ''udev'' ルール {{ic|/usr/lib/udev/rules.d/}} に格納されています。もし {{ic|/usr/lib}} と {{ic|/etc}} に同じ名前のファイルがあった場合、{{ic|/etc}} にあるファイルが優先されます。
   
  +
''udev'' ルールについて学ぶには、{{man|7|udev}} マニュアルを参照してください。また、[http://www.reactivated.net/writing_udev_rules.html Writing udev rules] も参照してください。このガイドには、実践的な例 ([http://www.reactivated.net/writing_udev_rules.html#example-printer Writing udev rules - Examples]) がいくつか挙げられています。
=== udev ルールを記述する ===
 
   
  +
=== udev ルールの例 ===
{{Warning|リムーバルドライブをマウントするのに、udev ルールから {{ic|mount}} を呼ばないで下さい。FUSE ファイルシステムの場合、{{ic|Transport endpoint not connected}} エラーが起こります。代わりに自動マウントを適切に処理する [[udisks]] を使って下さい。}}
 
   
  +
以下は、ウェブカメラが接続された時に {{ic|/dev/video-cam}} シンボリックリンクを作成するルールの例です。
* udev ルールの書き方を学ぶには [http://www.reactivated.net/writing_udev_rules.html Writing udev rules] を見て下さい。
 
* udev ルールのサンプルを見るには [https://soosck.wordpress.com/2011/01/19/improved-udev-rule-arch-linux/ Improved Udev Rule For Arch Linux] を見て下さい。
 
   
以下はウェブカメラ接続されたときにシンボリックリンク {{ic|/dev/video-cam1}} を作るルールの例です。まず、カメラが接続されたデバイス {{ic|/dev/video2}} にロードされていることを見つけたとします。のルールを書く理由は次のブート時にデバイスが {{ic|/dev/video0}} などの名表示され可能性あるからです。
+
ここで、カメラは既に接続されていて、{{ic|/dev/video2}} というデバイス名でロードされているとします。そして、以下 udev ルールを書く理由はのブート時にデバイスファイル別の名前 (例えば {{ic|/dev/video0}} など) になってしまうかもしれないからです (なで、{{ic|/dev/video-cam}} という固定のファイル名で参照できようにしようというの目的です)
   
  +
{{hc|1=$ udevadm info --attribute-walk --path=$(udevadm info --query=path --name=/dev/video2)|2=
{{hc|# udevadm info -a -p $(udevadm info -q path -n /dev/video2)|<nowiki>Udevadm info starts with the device specified by the devpath and then walks up the chain of parent devices. It prints for every device found, all possible attributes in the udev rules key format. A rule to match, can be composed by the attributes of the device and the attributes from one single parent device.
 
  +
Udevadm info starts with the device specified by the devpath and then walks up the chain of parent devices.
  +
It prints for every device found, all possible attributes in the udev rules key format.
  +
A rule to match, can be composed by the attributes of the device and the attributes from one single parent device.
   
looking at device '/devices/pci0000:00/0000:00:04.1/usb3/3-2/3-2:1.0/video4linux/video2':
+
looking at device '/devices/pci0000:00/0000:00:04.1/usb3/3-2/3-2:1.0/video4linux/video2':
KERNEL=="video2"
+
KERNEL=="video2"
SUBSYSTEM=="video4linux"
+
SUBSYSTEM=="video4linux"
...
+
...
looking at parent device '/devices/pci0000:00/0000:00:04.1/usb3/3-2/3-2:1.0':
+
looking at parent device '/devices/pci0000:00/0000:00:04.1/usb3/3-2/3-2:1.0':
KERNELS=="3-2:1.0"
+
KERNELS=="3-2:1.0"
SUBSYSTEMS=="usb"
+
SUBSYSTEMS=="usb"
...
+
...
looking at parent device '/devices/pci0000:00/0000:00:04.1/usb3/3-2':
+
looking at parent device '/devices/pci0000:00/0000:00:04.1/usb3/3-2':
KERNELS=="3-2"
+
KERNELS=="3-2"
SUBSYSTEMS=="usb"
+
SUBSYSTEMS=="usb"
  +
ATTRS{idVendor}=="05a9"
...
 
ATTRS{idVendor}=="05a9"
+
ATTRS{manufacturer}=="OmniVision Technologies, Inc."
  +
ATTRS{removable}=="unknown"
...
 
ATTRS{manufacturer}=="OmniVision Technologies, Inc."
+
ATTRS{idProduct}=="4519"
ATTRS{removable}=="unknown"
+
ATTRS{bDeviceClass}=="00"
ATTRS{idProduct}=="4519"
+
ATTRS{product}=="USB Camera"
  +
...
ATTRS{bDeviceClass}=="00"
 
  +
}}
ATTRS{product}=="USB Camera"
 
...
 
</nowiki>}}
 
   
video4linux デバイスから {{ic|<nowiki>KERNEL=="video2"</nowiki>}} と {{ic|<nowiki>SUBSYSTEM=="video4linux"</nowiki>}} 使いますして usb parent {{ic|<nowiki>SUBSYSTEMS=="usb"</nowiki>}}, {{ic|<nowiki>ATTRS{idVendor}=="05a9"</nowiki>}}, {{ic|<nowiki>ATTRS{idProduct}=="4519"</nowiki>}} から製造者・製品 ID を使ってウェブカメラをマッチさせます。
+
対象のウェブカメラを識別するために、''video4linux'' デバイスから {{ic|1=KERNEL=="video2"}} と {{ic|1=SUBSYSTEM=="video4linux"}} という条件式が使用されていますれより 2 階層上を見ると、USB 親デバイス {{ic|1=SUBSYSTEMS=="usb"}} からはベンダー ID {{ic|1=ATTRS{idVendor}=="05a9"}} とプロダクト ID {{ic|1=ATTRS{idProduct}=="4519"}} を使ってウェブカメラをマッチさせています。
   
  +
以上から、以下のようにこのデバイスにマッチするルールを作成することができます:
{{hc|/etc/udev/rules.d/83-webcam.rules|<nowiki>
 
KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", SUBSYSTEMS=="usb", \
 
ATTRS{idVendor}=="05a9", ATTRS{idProduct}=="4519", SYMLINK+="video-cam1"
 
</nowiki>}}
 
   
  +
{{hc|/etc/udev/rules.d/83-webcam.rules|2=
上の例では {{ic|<nowiki>SYMLINK+="video-cam1"</nowiki>}} を使ってシンボリックリンクを作成していますが {{ic|<nowiki>OWNER="john"</nowiki>}} や {{ic|<nowiki>GROUP="video"</nowiki>}} を使ってユーザーやグループを設定したり {{ic|<nowiki>MODE="0660"</nowiki>}} を使ってパーミッションを設定することも簡単にできます。
 
  +
KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", SUBSYSTEMS=="usb", ATTRS{idVendor}=="05a9", ATTRS{idProduct}=="4519", SYMLINK+="video-cam"}}
   
  +
ここで、{{ic|1=SYMLINK+="video-cam"}} を使ってシンボリックリンクを作成していますが、{{ic|1=OWNER="john"}} でデバイスの所有者を、{{ic|1=GROUP="video"}} でデバイスの所有グループを設定することもできますし、{{ic|1=MODE="0660"}} でパーミッションも設定できます。
ただし、デバイスが取り除かれた時に何かを実行するルールを書く時は、デバイスの属性にアクセス出来ないことに注意してください。この場合、プリセットのデバイス環境変数を使う必要があります。これらの環境変数を監視するには、デバイスを抜いた時に次のコマンドを実行してください:
 
# udevadm monitor --environment --udev
 
   
  +
デバイスが取り除かれた時に何かを行うルールを記述したい場合は、デバイスの属性にはアクセスできないことに注意してください (とっくにデバイスは取り除かれているからです)。この場合、事前に定義されたデバイスの[[環境変数]]を使う必要があります。そのような環境変数を監視するには、デバイスが取り除かれた状態で以下のコマンドを実行してください:
このコマンドの出力の中に、ID_VENDOR_ID や ID_MODEL_ID などの、前に使っていた属性 "idVendor" と "idProduct" に一致する値があるはずです。デバイスの環境変数を使うルールは以下のようになります:
 
{{hc|/etc/udev/rules.d/83-webcam-removed.rules|<nowiki>
 
ACTION=="remove", SUBSYSTEM=="usb", ENV{ID_VENDOR_ID}=="05a9", ENV{ID_MODEL_ID}=="4519", RUN+="/path/to/your/script"
 
</nowiki>}}
 
   
  +
$ udevadm monitor --property --udev
=== デバイスの属性を一覧する ===
 
ルールを書くときに使えるデバイスの属性全てのリストを表示するには、次のコマンドを実行してください:
 
# udevadm info -a -n [device name]
 
   
  +
このコマンドでは、{{ic|ID_VENDOR_ID}} と {{ic|ID_MODEL_ID}} というような値のペアが出力されます。これらは、上記の属性 {{ic|idVendor}} と {{ic|idProduct}} に対応します。デバイスの属性の代わりにデバイスの環境変数を使うルールは以下のようになります:
{{ic|[device name]}} は {{ic|/dev/sda}} や {{ic|/dev/ttyUSB0}} などシステム上のデバイスに置き換えてください。
 
   
  +
{{hc|/etc/udev/rules.d/83-webcam-removed.rules|2=ACTION=="remove", SUBSYSTEM=="usb", ENV{ID_VENDOR_ID}=="05a9", ENV{ID_MODEL_ID}=="4519", RUN+="''/path/to/your/script''"}}
デバイスの名前がわからない場合は特定のシステムパスの全ての属性をリストアップすることもできます:
 
   
  +
=== デバイスの属性を一覧表示する ===
# udevadm info -a -p /sys/class/backlight/acpi_video0
 
  +
  +
ルールを書く際に使用できるデバイスの属性のリストを全て一覧表示するには、以下のコマンドを実行してください:
  +
  +
$ udevadm info --attribute-walk --name=''device_name''
  +
  +
{{ic|''device_name''}} の部分は、システムに存在しているデバイス ({{ic|/dev/sda}}、{{ic|/dev/ttyUSB0}} など) に置き換えてください。
  +
  +
デバイス名が分からない場合は、特定のシステムパスの全属性をリストアップすることもできます:
  +
  +
$ udevadm info --attribute-walk --path=/sys/class/backlight/acpi_video0
  +
  +
デバイスを絞り込むには、まずデバイスのクラスを調べて、以下のコマンドを実行してください:
  +
  +
$ ls /dev/''class''/by-id
  +
  +
{{ic|--name}} 引数には、単にデバイスのシンボリックリンクを使うこともできますし、シンボリックリンクの指す実際のアイルを使うこともできます。例えば:
  +
  +
$ udevadm info --attribute-walk --name=/dev/input/by-id/usb-foostan_Corne-event-kbd
  +
  +
下位デバイスを持たない裸のUSBデバイスのパスを取得するには、 USB デバイスのフルパスを使用する必要があります。''udevadm'' のモニターモードを開始し、対象の USB デバイスを接続すれば、デバイスへのパスを得ることができます:
  +
  +
{{hc|1=$ udevadm monitor|2=
  +
...
  +
KERNEL[26652.638931] add /devices/pci0000:00/0000:00:01.2/0000:02:00.0/0000:03:05.0/0000:05:00.0/usb1/1-3 (usb)
  +
KERNEL[26652.639153] add /devices/pci0000:00/0000:00:01.2/0000:02:00.0/0000:03:05.0/0000:05:00.0/usb1/1-3/1-3:1.0 (usb)
  +
...
  +
}}
  +
  +
一番深いパスを選択し、{{ic|''--attribute-walk''}} を使えば、親デバイスの全属性を出力することができます:
  +
  +
$ udevadm info --attribute-walk --path=''/devices/pci0000:00/0000:00:01.2/0000:02:00.0/0000:03:05.0/0000:05:00.0/usb1/1-3/1-3:1.0''
   
 
=== ロードする前にルールをテストする ===
 
=== ロードする前にルールをテストする ===
  +
# udevadm test $(udevadm info -q path -n [device name]) 2>&1
 
  +
# udevadm test $(udevadm info --query=path --name=''device_name'') 2>&1
このコマンドは新しいルールの全てのアクションを実行はしませんが、既存のデバイスのシンボリックリンクのルールは処理します。ロードできないときに役に立つかもしれません。また、テストしたい udev ルールのデバイスのパスを直接指定することも可能です:
 
  +
  +
このコマンドは、ルールの全てのアクションを実行しませんが、既存のデバイスに対するシンボリックリンクのルールは処理します。ルールをロードできない場合に役立つかもしれません。また、テストしたい ''udev'' ルールのデバイスへのパスを直接指定することも可能です:
  +
 
# udevadm test /sys/class/backlight/acpi_video0/
 
# udevadm test /sys/class/backlight/acpi_video0/
   
 
=== 新しいルールをロードする ===
 
=== 新しいルールをロードする ===
Udev はルールファイルの変更を自動で検知するため、変更をすぐ反映させるのに udev の再起動は必要ありません。しかしながら、既に存在するデバイスでルールの自動再始動は行われません。USB デバイスなどの、ホットプラグ可能なデバイスはおそらく、新しいルールを適用するために再接続したり、少なくとも ohci-hcd と ehci-hcd カーネルモジュールをアンロード・再ロードして全ての USB ドライバーを再ロードする必要があります。
 
   
  +
''udev'' はルールファイルの変更を自動的に検出するので、''udev'' を再起動せずとも変更は即座に有効になります。しかし、既に存在するデバイスに対しては、ルールが自動的に再トリガーされません。USB デバイスなどのホットプラグ可能なデバイスは、新しいルールを有効にするために再接続するか、少なくともカーネルモジュール ohci-hcd と ehci-hcd を再ロードして全ての USB ドライバを再読み込みする必要があります。
自動的にルールがリロードされない場合:
 
  +
  +
ルールが自動的に再読み込みされない場合は、以下を実行してください:
  +
 
# udevadm control --reload
 
# udevadm control --reload
   
udev に手動で強制的にルを適用させるには:
+
手動でルールを強制的にトリガるには:
  +
 
# udevadm trigger
 
# udevadm trigger
   
108行目: 130行目:
 
[[Udisks]] を見て下さい。
 
[[Udisks]] を見て下さい。
   
  +
== ヒントとテクニック ==
== Tips and tricks ==
 
   
  +
=== ルールの中でドライブをマウントする ===
=== ファームウェアプログラマや USB 仮想 comm デバイスにアクセス ===
 
   
  +
リムーバブルディスクをマウントする際に ''udev'' ルールから {{ic|mount}} コマンドを実行しないでください。これは以下の 2 つの理由により賢明ではありません:
以下のルールセットは ("users" グループに入っている) 通常のユーザーが AVR マイクロコントローラの [http://www.ladyada.net/make/usbtinyisp/ USBtinyISP] USB プログラマと一般的な (SiLabs [http://www.silabs.com/products/interface/usbtouart CP2102]) USB を UART アダブター, [http://www.atmel.com/tools/AVRDRAGON.aspx?tab=overview Atmel AVR Dragon] プログラマ, [http://www.atmel.com/tools/AVRISPMKII.aspx Atmel AVR ISP mkII] にアクセスできるようにします。必要に応じてパーミッションは調整してください。2012年10月31日確認。
 
  +
# デフォルトで systemd は、分離された "mount 名前空間" 内で {{ic|systemd-udevd.service}} を実行します ({{man|7|namespaces}} を参照)。つまり、この名前空間外からはデバイスが不可視になります。
  +
# この問題を解決するために ({{ic|PrivateMounts}} と {{ic|MountFlags}} の行をコメントアウトして) サービスのパラメータを変更したとしても、''udev'' から起動されたプロセスは数秒後に終了させられてしまうという問題があります。[[NTFS-3G]] などの FUSE ファイルシステムにおいては、''mount'' はファイルシステムを管理するためにユーザー空間のプロセスを起動します。このプロセスが終了されると、そのファイルシステムにアクセスしようとした時に {{ic|Transport endpoint not connected}} ({{ic|通信端点が接続されていません}}) というエラーが発生します。
   
  +
うまく行く方法もいくつかあります:
{{hc|/etc/udev/rules.d/50-embedded_devices.rules|2=<nowiki>
 
# USBtinyISP Programmer rules
 
SUBSYSTEMS=="usb", ATTRS{idVendor}=="1781", ATTRS{idProduct}=="0c9f", GROUP="users", MODE="0666"
 
SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="0479", GROUP="users", MODE="0666"
 
# USBasp Programmer rules http://www.fischl.de/usbasp/
 
SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="05dc", GROUP="users", MODE="0666"
 
   
  +
* Udev ルールからカスタムの systemd サービスを起動する。カスタムの systemd サービスでは、長時間動作させるプロセス (FUSE など) を開始するスクリプトを開始するなどができます。USB ディスクを自動的に {{ic|/media}} 内にマウントする簡単な例は [https://github.com/Ferk/udev-media-automount udev-media-automount] です。似たようなアイディアは[http://jasonwryan.com/blog/2014/01/20/udev/ このブログ記事]でも説明されています。
# Mdfly.com Generic (SiLabs CP2102) 3.3v/5v USB VComm adapter
 
  +
* Udev ルールで {{ic|mount}} の代わりに {{ic|systemd-mount}} を使う。これは、[https://github.com/systemd/systemd/issues/11982#issuecomment-472529566 systemd の開発者達によって推奨されている方法です]。例えば、以下の udev ルールは USB ディスクを {{ic|/media}} 内にマウントします:
SUBSYSTEMS=="usb", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", GROUP="users", MODE="0666"
 
  +
:{{bc|1=
  +
ACTION=="add", SUBSYSTEMS=="usb", SUBSYSTEM=="block", ENV{ID_FS_USAGE}=="filesystem", RUN{program}+="/usr/bin/systemd-mount --no-block --automount=yes --collect $devnode /media"
  +
}}
  +
* [[udisks]] や [[udiskie]] といったパッケージを使う。このようなパッケージは非常に強力ですが、セットアップが難しいです。また、これらのパッケージは一部のファイルシステムの所有者を、アクティブなセッションを現在持っている非特権ユーザーに設定するので、シングルユーザーのセッションで使用されることを意図しています。
   
  +
=== 通常ユーザーにデバイスの使用を許可する ===
#Atmel AVR Dragon (dragon_isp) rules
 
SUBSYSTEM=="usb", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2107", GROUP="users", MODE="0666"
 
   
  +
[[カーネル]]ドライバがデバイスを初期化する際に、デフォルト状態ではデバイスノードは {{ic|root:root}} によって所有され、パーミッションは {{ic|600}} に設定されます。[https://github.com/torvalds/linux/blob/v5.19/drivers/base/devtmpfs.c#L11-L13] よって、ドライバがこのデフォルトを変更するか、ユーザー空間の udev ルールがパーミッションを変更しない限り、通常ユーザーはデバイスにアクセスできません。
#Atmel AVR JTAGICEMKII rules
 
SUBSYSTEM=="usb", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2103", GROUP="users", MODE="0666"
 
   
  +
Udev 値 {{ic|OWNER}}、{{ic|GROUP}}、{{ic|MODE}} を使って、アクセス権を付与することができます。しかし、全てのユーザーがデバイスを利用できるようにし、なおかつデバイスファイルのモードを過度に寛容にしないようにするのは困難です。Ubuntu では、{{ic|plugdev}} というグループを作成して、このグループにデバイスが追加されます。しかし、このアプローチは systemd の開発者達によって推奨されていない [https://bugzilla.redhat.com/show_bug.cgi?id=815093] だけでなく、Arch の udev ルールに追加されたときにはバグとみなされました ({{Bug|35602}})。歴史的に採用されていたもう一つのアプローチは、デバイスのカテゴリ毎に対応する別々のグループを使用するというものです ([[ユーザーとグループ#systemd 以前のグループ]] で説明されています)。
#Atmel Corp. AVR ISP mkII
 
SUBSYSTEM=="usb", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2104", GROUP="users", MODE="0666"
 
   
  +
Systemd システムにおける最近の推奨されるアプローチは、{{ic|MODE}} を {{ic|660}} に設定してグループがデバイスを使用できるようにし、{{ic|uaccess}} という {{ic|TAG}} を付けることです [https://github.com/systemd/systemd/blob/main/rules.d/70-uaccess.rules.in]。この特殊なタグにより、udev は[https://github.com/systemd/systemd/blob/main/src/udev/udev-builtin-uaccess.c 動的なユーザー ACL] をデバイスノードに適用するようになり、{{man|8|systemd-logind}} と連携してログイン中のユーザーがデバイスにアクセスできるようにします。以下は、このアプローチを実装する udev ルールの例です:
#Atmel Copr. JTAGICE3
 
SUBSYSTEM=="usb", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2140", GROUP="users", MODE="0666"
 
</nowiki>}}
 
   
  +
{{hc|/etc/udev/rules.d/71-device-name.rules|2=
=== USB 挿入で実行 ===
 
  +
SUBSYSTEMS=="usb", ATTRS{idVendor}=="''vendor_id''", ATTRS{idProduct}=="''product_id''", MODE="0660", TAG+="uaccess"
  +
}}
   
  +
=== HDMI ケーブルの抜き差し時に実行する ===
[[Udisks]] または [http://igurublog.wordpress.com/downloads/script-devmon/ devmon ラッパースクリプト] を参照してください。
 
   
  +
以下の内容でルール {{ic|/etc/udev/rules.d/95-hdmi-plug.rules}} を作成してください:
=== VGA ケーブル接続時に実行 ===
 
   
  +
ACTION=="change", SUBSYSTEM=="drm", ENV{DISPLAY}=":0", ENV{XAUTHORITY}="/home/''username''/.Xauthority", RUN+="''/path/to/script.sh''"
VGA モニターケーブルが接続されたときに {{Pkg|arandr}} を起動するには以下の内容の {{ic|/etc/udev/rules.d/95-monitor-hotplug.rules}} ルールを作成します:
 
  +
  +
{{Note|このルールが X サーバの開始前にトリガーされると、意図したとおりに動作しない場合があります。[[#X サーバーが存在しない場合に RUN ルールの X プログラムがハングする]] 章を参照してください。}}
  +
  +
=== VGA ケーブルの接続時に実行する ===
  +
  +
VGA モニターのケーブルが接続された時に {{Pkg|arandr}} を実行するには、以下の内容でルール {{ic|/etc/udev/rules.d/95-monitor-hotplug.rules}} を作成してください:
   
 
KERNEL=="card0", SUBSYSTEM=="drm", ENV{DISPLAY}=":0", ENV{XAUTHORITY}="/home/''username''/.Xauthority", RUN+="/usr/bin/arandr"
 
KERNEL=="card0", SUBSYSTEM=="drm", ENV{DISPLAY}=":0", ENV{XAUTHORITY}="/home/''username''/.Xauthority", RUN+="/usr/bin/arandr"
   
ディスプレイマネージャによっては {{ic|.Xauthority}} ユーザーのホームディレクトリに保存されないことがあります。場合 {{ic|<nowiki>ENV{XAUTHORITY}</nowiki>}} を修正する必要があります。例えば [[GDM]] なら以下のようになります:
+
一部のディスプレイマネージャは {{ic|.Xauthority}} ユーザーのホームディレクトリに保存ます。で、{{ic|ENV{XAUTHORITY} }} の値は適宜変更する必要があります。例として、[[GNOME Display Manager]] の場合は以下のようになります:
   
 
{{hc|$ printenv XAUTHORITY|/run/user/1000/gdm/Xauthority}}
 
{{hc|$ printenv XAUTHORITY|/run/user/1000/gdm/Xauthority}}
   
  +
{{Note|このルールが X サーバの開始前にトリガーされると、意図したとおりに動作しない場合があります。[[#X サーバーが存在しない場合に RUN ルールの X プログラムがハングする]] 章を参照してください。}}
=== 新しい eSATA ドライブの検知 ===
 
   
  +
=== 新しい eSATA を検知する ===
eSATA ドライブを挿入しても検知されない場合、いくつか試せることがあります。eSATA を挿入したまま再起動してください。もしくは次を実行してください:
 
   
  +
eSATA ドライブが挿入された時に検出されない場合、問題を解決できるかもしれない方法がいくつかあります。1つ目は、eSATA が挿入されている状態で再起動することです。あるいは、以下のコマンドを試してみることもできます:
# echo 0 0 0 | tee /sys/class/scsi_host/host*/scan
 
   
  +
# echo 0 0 0 > /sys/class/scsi_host/host*/scan
または (AUR から) {{AUR|scsiadd}} をインストールして次を実行してください:
 
  +
  +
あるいは、{{AUR|scsiadd}} を[[インストール]]し、以下を実行してみることもできます:
   
 
# scsiadd -s
 
# scsiadd -s
   
うまくけば、あなたのドライブが {{ic|/dev}} にあります。ドライブがない場合、を実行しながら上のコマンドを試して何が起こっているのか確認してください:
+
うまくけば、ドライブが {{ic|/dev}} 出現します。出現しない場合以下のコマンドを実行し、出力されるログを見ながら上のコマンドをもう一度試してください:
   
 
# udevadm monitor
 
# udevadm monitor
   
=== 内部 SATA ポートを eSATA とる ===
+
=== 内部 SATA ポートを eSATA として認識させる ===
   
eSATA ベイや他の eSATA アダタを接続するとシステムはディスクを内部 SATA ドライブとして認識します。[[GNOME]] や [[KDE]] はその度に root パスワードを尋ねることになります。以下の udev ルールは指定した SATA ポートを外部 eSATA ポートとして表示させます。これUSB ドライブと同じように通常の GNOME ユーザーで eSATA ドライブを root パスワーなしでポートに接続することができるようになります。
+
eSATA ベイや他の eSATA アダタを接続するとシステムはこのディスクを内部 SATA ドライブとして認識します。[[GNOME]] や [[KDE]] 毎回 root パスワードが要求されます。以下のルールは指定した SATA ポートを外部 eSATA ポートとしてマークします。これによりGNOME 通常ユーザーでも root のパスワード無しで eSATA ドライブを USBライブのようにポートに接続できるようになります。
   
{{hc|/etc/udev/rules.d/10-esata.rules|2=<nowiki>
+
{{hc|/etc/udev/rules.d/10-esata.rules|<nowiki>
 
DEVPATH=="/devices/pci0000:00/0000:00:1f.2/host4/*", ENV{UDISKS_SYSTEM}="0"
 
DEVPATH=="/devices/pci0000:00/0000:00:1f.2/host4/*", ENV{UDISKS_SYSTEM}="0"
 
</nowiki>}}
 
</nowiki>}}
   
  +
{{Note|The {{ic|DEVPATH}} can be found after connection the eSATA drive with the following commands (replace {{ic|sdb}} accordingly):
{{Note|eSATA ドライブを接続した後、以下のコマンドを使うことで DEVPATH がわかります ({{ic|sdb}} は適宜置き換えてください):
 
   
# udevadm info -q path -n /dev/sdb
+
{{hc|<nowiki>$ udevadm info --query=path /dev/sdb</nowiki>|
/devices/pci0000:00/0000:00:1f.2/host4/target4:0:0/4:0:0:0/block/sdb
+
/devices/pci0000:00/0000:00:1f.2/host4/target4:0:0/4:0:0:0/block/sdb
  +
}}
   
# find /sys/devices/ -name sdb
+
{{hc|$ find /sys/devices/ -name sdb|
/sys/devices/pci0000:00/0000:00:1f.2/host4/target4:0:0/4:0:0:0/block/sdb
+
/sys/devices/pci0000:00/0000:00:1f.2/host4/target4:0:0/4:0:0:0/block/sdb
  +
}}
 
}}
 
}}
   
=== 固定デバイス名設定 ===
+
=== 固定デバイス名設定する ===
   
udev は全てのモジュールを非同期ロードするので、初期化される順番は異なってしまいます。この結果デバイスがランダム変わる可能性があります。udev ルールを追加すれば固定デバイス名を使ます:
+
''udev'' は全てのモジュールを非同期ロードするので、モジュールは毎回異なる順番で初期化される可能性があります。これにより、デバイス名がランダム変わってしまいます。''udev'' ルールを用いることで、固定デバイス名を使用することができます
* ブロックデバイスは[[永続的なブロックデバイスの命名]]を見さい。
+
ブロックデバイスに関して [[永続的なブロックデバイスの命名]] も、ネットワークデバイスに関しては [[ネットワーク設定#インターフェイス名の変更]] も参照しください。
* ネットワークデバイスは[[ネットワーク設定#デバイス名]]を見て下さい。
 
   
==== iscsi デバイス ====
+
==== ビデオデバイス ====
   
  +
ウェブカメラのセットアップに関しては [[ウェブカメラ設定]] を参照してください。
scsi_id からの出力をテストしてください:
 
   
  +
複数のウェブカメラを使用すると、それぞれのビデオデバイスはブート時に {{ic|/dev/video*}} としてランダムに割り当てられます。推奨される解決策は、[[#udev ルールの例]] 章にあるような ''udev'' ルールを使ってシンボリックリンクを作成することです:
# /usr/lib/udev/scsi_id --whitelisted --replace-whitespace --device=/dev/sdb
 
3600601607db11e0013ab5a8e371ce111
 
   
{{hc|/etc/udev/rules.d/75-iscsi.rules|2=<nowiki>
+
{{hc|/etc/udev/rules.d/83-webcam.rules|2=
#The iscsi device rules.
 
#This will create an iscsi device for each of the targets.
 
KERNEL=="sd*", SUBSYSTEM=="block", \
 
PROGRAM="/usr/lib/udev/scsi_id --whitelisted --replace-whitespace /dev/$name", \ RESULT=="3600601607db11e0013ab5a8e371ce111", \
 
NAME="isda"</nowiki>}}
 
 
==== ビデオドライバー ====
 
 
ウェブカメラをセットアップするなら、まず[[ウェブカメラ設定]]を参照してください。
 
 
複数のウェブカメラを使うと、例えば {{pkg|motion}} (video4linux デバイスやウェブカメラから画像を取得するソフトウェアモーション検知プログラム) を使う場合、起動時にビデオデバイスはランダムで {{ic|/dev/video0..n}} と割り当てられます。推奨される方法は udev ルールを使って ([[#udev ルールを記述する|udev ルールの記述]]にある例のようにして) シンボリックリンクを作成する方法です。
 
 
{{hc|/etc/udev/rules.d/83-webcam.rules|<nowiki>
 
 
KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", SUBSYSTEMS=="usb", ATTRS{idVendor}=="05a9", ATTRS{idProduct}=="4519", SYMLINK+="video-cam1"
 
KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", SUBSYSTEMS=="usb", ATTRS{idVendor}=="05a9", ATTRS{idProduct}=="4519", SYMLINK+="video-cam1"
 
KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", SUBSYSTEMS=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="08f6", SYMLINK+="video-cam2"
 
KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", SUBSYSTEMS=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="08f6", SYMLINK+="video-cam2"
  +
}}
KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", SUBSYSTEMS=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="0840", SYMLINK+="video-cam3"
 
</nowiki>}}
 
   
{{Note|{{ic|/dev/video*}} 以外の名前を使と {{ic|v4l1compat.so}} {{ic|v4l2convert.so}} のプリロードが破壊されます。}}
+
{{Note|{{ic|/dev/video*}} 以外の名前を使用すると {{ic|v4l1compat.so}} のプリロードに失敗します ({{ic|v4l2convert.so}} のプリロードにも失敗する可能性あります)。}}
   
==== プリンタ ====
+
==== プリンタ ====
   
複数のプリンタを使ってい場合起動時にランダムで {{ic|/dev/lp[0-9]}} のデバイスが割り当てられ、[[CUPS]] の設定などを破壊てしまいます。
+
複数のプリンタを使用すそれぞれのプリンタはブート時に {{ic|/dev/lp[0-9]}} としてランダムに割り当てられます。これにより、[[CUPS]] の設定などが機能なくなります。
   
[[永続的なブロックバイスの命名]]と同じように {{ic|/dev/lp/by-id}} と {{ic|/dev/lp/by-path}} のにシンボリックリンクを作成する以下のルールを作成することが可能です:
+
ィレクトリ {{ic|/dev/lp/by-id}} と {{ic|/dev/lp/by-path}} 内に[[永続的なブロックデバイス命名]]規則似たシンボリックリンクを作成する以下のルールを作成することができます:
   
{{hc|/etc/udev/rules.d/60-persistent-printer.rules|<nowiki>
+
{{hc|/etc/udev/rules.d/60-persistent-printer.rules|2=
 
ACTION=="remove", GOTO="persistent_printer_end"
 
ACTION=="remove", GOTO="persistent_printer_end"
  +
# これは必須では無いはずです
 
# This should not be necessary
 
 
#KERNEL!="lp*", GOTO="persistent_printer_end"
 
#KERNEL!="lp*", GOTO="persistent_printer_end"
   
236行目: 249行目:
 
ENV{ID_PATH}=="?*", SYMLINK+="lp/by-path/$env{ID_PATH}"
 
ENV{ID_PATH}=="?*", SYMLINK+="lp/by-path/$env{ID_PATH}"
   
LABEL="persistent_printer_end"
+
LABEL="persistent_printer_end"}}
</nowiki>}}
 
   
  +
=== ディスクをシリアル番号で識別する ===
=== HAL の実行 ===
 
   
  +
特定のディスクデバイス {{ic|/dev/sd''X''}} に対して何らかのアクションを実行する際、{{ic|udevadm info /dev/sd''X''}} コマンドで出力されるユニークかつ永続的なシリアル番号 {{ic|ID_SERIAL_SHORT}} を使ってデバイスを指定するには、以下のようなルールを使うことができます。以下はその例です:
(Flash DRM コンテンツなど) プログラムによってはいまだ HAL が必要なものがあります。Hal は {{AUR|hal}} と {{AUR|hal-info}} からインストールできます。
 
   
  +
{{hc|/etc/udev/rules.d/69-disk.rules|2=ACTION=="add", KERNEL=="sd[a-z]", ENV{ID_SERIAL_SHORT}=="''serial_number''", RUN+="/path/to/script /dev/%k"}}
Systemd を使う: 以下の systemd のコマンドで hal サービスを起動・停止できます:
 
   
  +
=== USB デバイスでサスペンドから復帰させる ===
HAL を起動する:
 
{{ic|# systemctl start hal.service}}
 
   
  +
udev ルールを用いることで、マウスやキーボードといった USB デバイスの[[復帰トリガー]]を有効化して、そのデバイスを使ってシステムをスリープから復帰させることができます。
HAL を停止する:
 
{{ic|# systemctl stop hal.service}}
 
   
  +
{{Note|デフォルトでは、全ての USB のホストコントローラで復帰 (トリガー) が有効化されています。デバイスの状態は {{ic|cat /proc/acpi/wakeup}} を使って確認できます。復帰が有効化されている場合以下のルールは必要ありませんが、他のアクション (復帰機能の無効化など) を実行するためのテンプレートとして使用できます。}}
または、以下のスクリプトを使うこともできます:
 
{{bc|<nowiki>
 
#!/bin/bash
 
   
  +
まず、対象の USB デバイスのベンダー ID とプロダクト ID を調べてください。これらの ID は udev ルール内でデバイスを識別するために使用します。例えば:
## written by Mark Lee <bluerider>
 
## using information from <https://wiki.archlinux.org/index.php/Chromium#Google_Play_.26_Flash>
 
   
  +
{{hc|$ lsusb {{!}} grep Logitech|Bus 007 Device 002: ID '''046d''':'''c52b''' Logitech, Inc. Unifying Receiver
## Start and stop Hal service on command for Google Play Movie service
 
  +
}}
   
  +
次に、以下のコマンドを使ってデバイスの接続先を調べてください:
function main () { ## run the main insertion function
 
clear-cache; ## remove adobe cache
 
start-hal; ## start the hal daemon
 
read -p "Press 'enter' to stop hal"; ## pause the command line with a read line
 
stop-hal; ## stop the hal daemon
 
}
 
   
  +
{{hc|$ grep ''c52b'' /sys/bus/usb/devices/*/idProduct|/sys/bus/usb/devices/'''1-1.1.1.4/'''idProduct:c52b
function clear-cache () { ## remove adobe cache
 
  +
}}
cd ~/.adobe/Flash_Player; ## go to Flash player user directory
 
rm -rf NativeCache AssetCache APSPrivateData2; ## remove cache
 
}
 
   
  +
最後に、USB デバイス自体と、USB デバイスの接続先である USB コントローラの {{ic|power/wakeup}} 属性をデバイスの接続時に変更するルールを作成してください:
function start-hal () { ## start the hal daemon
 
sudo systemctl start hal.service && ( ## systemd : start hal daemon
 
echo "Started hal service..."
 
) || (
 
echo "Failed to start hal service!")
 
}
 
   
  +
{{hc|/etc/udev/rules.d/50-wake-on-device.rules|2=
function stop-hal () { ## stop the hal daemon
 
  +
ACTION=="add", SUBSYSTEM=="usb", DRIVERS=="usb", ATTRS{idVendor}=="'''046d'''", ATTRS{idProduct}=="'''c52b'''", ATTR{power/wakeup}="enabled", ATTR{driver/'''1-1.1.1.4'''/power/wakeup}="enabled"
sudo systemctl stop hal.service && ( ## systemd : stop hal daemon
 
  +
}}
echo "Stopped hal service..."
 
) || (
 
echo "Failed to stop hal service!"
 
)
 
}
 
   
  +
=== イベントをトリガーする ===
main; ## run the main insertion function
 
</nowiki>}}
 
   
  +
''udev'' イベントをトリガーすると便利である場合があります。例えば、リモートマシン上の USB デバイスの切断をシミュレートしたい場合などです。そのような場合は {{ic|udevadm trigger}} を使ってください:
=== USB デバイスでサスペンドから復帰 ===
 
   
  +
# udevadm trigger --verbose --type=subsystems --action=remove --subsystem-match=usb --attr-match="idVendor=abcd"
最初に、あなたのデバイスの製造者・製品 ID を見つけて下さい、例えば:
 
   
  +
このコマンドは、ベンダー ID が {{ic|abcd}} の全 USB デバイスに対して USB リモートイベントをトリガーします。
{{hc|<nowiki># lsusb | grep Logitech</nowiki>|Bus 007 Device 002: ID 046d:c52b Logitech, Inc. Unifying Receiver}}
 
   
  +
=== Udev ルールからデスクトップ通知をトリガーする ===
デバイスと接続している USB コントローラの {{ic|power/wakeup}} 属性を変更してください、ここでは {{ic|driver/usb7/power/wakeup}} になります。以下のルールを使って下さい:
 
   
  +
{{ic|notify-send}} を呼び出す外部スクリプトを ''udev'' から実行してデスクトップに通知を表示させるのは、[https://bbs.archlinux.org/viewtopic.php?id=212364 場合によっては困難です]。以下の例では、{{ic|notify-send}} を ''udev'' ルールから正しく実行するために、どのファイルにどのコマンドや環境変数を記述すべきかを説明しています。
{{hc|/etc/udev/rules.d/50-wake-on-device.rules|<nowiki>
 
ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c52b", ATTR{power/wakeup}="enabled", ATTR{driver/usb7/power/wakeup}="enabled"
 
</nowiki>}}
 
   
  +
{{Note|この例では多くの変数がハードコードされています。なので、この例を理解したあとは、これらをよりポータブルにする (例えば、ユーザー名ではなく $USER を使うなど) ことを検討してください。}}
{{Note|{{ic|/proc/acpi/wakeup}} で USB コントローラが有効にされていることも確認してください。}}
 
  +
  +
1) 以下の ''udev'' は、ノート PC の電源状態によって画面の輝度が変更された際に通知音を再生しデスクトップ通知を送信するスクリプトを実行します。以下のファイルを作成してください:
  +
  +
{{hc|/etc/udev/rules.d/99-backlight_notification.rules|2=
  +
# バッテリー駆動に切り替わったときのルール
  +
ACTION=="change", SUBSYSTEM=="power_supply", ATTR{type}=="Mains", ATTR{online}=="0", ENV{DISPLAY}=":0", ENV{XAUTHORITY}="/home/USERNAME/.Xauthority" RUN+="/usr/bin/su USERNAME_TO_RUN_SCRIPT_AS -c /usr/local/bin/brightness_notification.sh"
  +
# AC 電源に切り替わったときのルール
  +
ACTION=="change", SUBSYSTEM=="power_supply", ATTR{type}=="Mains", ATTR{online}=="1", ENV{DISPLAY}=":0", ENV{XAUTHORITY}="/home/USERNAME/.Xauthority" RUN+="/usr/bin/su USERNAME_TO_RUN_SCRIPT_AS -c /usr/local/bin/brightness_notification.sh"
  +
}}
  +
  +
* {{ic|USERNAME_TO_RUN_SCRIPT_AS}} と {{ic|USERNAME}} は、通知が表示されるグラフィカルセッションのユーザーのショートネームに変更してください。
  +
* スクリプトは {{ic|/usr/bin/su}} で実行する必要があります。そうすることで、(root としてではなく) 通知が表示されるグラフィカルセッションのユーザーとしてプロセスを実行します。
  +
  +
2) ''udev'' のトリガー時に実行する実行可能スクリプトの内容:
  +
  +
{{hc|/usr/local/bin/brightness_notification.sh|2=
  +
#!/bin/sh
  +
  +
export XAUTHORITY=/home/USERNAME_TO_RUN_SCRIPT_AS/.Xauthority
  +
export DISPLAY=:0
  +
export DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/UID_OF_USER_TO_RUN_SCRIPT_AS/bus"
  +
  +
/usr/bin/sudo -u USERNAME_TO_RUN_SCRIPT_AS /usr/bin/paplay --server=/run/user/UID_OF_USER_TO_RUN_SCRIPT_AS/pulse/native /home/USERNAME/.i3/sounds/Click1.wav > /dev/null 2>&1
  +
  +
/usr/bin/notify-send --icon=/usr/share/icons/gnome/256x256/status/battery-full-charging.png 'Changing Power States' --expire-time=4000
  +
}}
  +
  +
* {{ic|USERNAME_TO_RUN_SCRIPT_AS}}、{{ic|UID_OF_USER_TO_RUN_SCRIPT_AS}}、{{ic|USERNAME}} は、通知が表示されるグラフィカルセッションのユーザーのショートネームや UID に置き換える必要があります。
  +
* {{ic|/usr/bin/sudo}} は、pulseaudio で音声を再生するために必要です。
  +
* 通知が表示されるグラフィカルセッションのユーザーに対して、3つの環境変数 ({{ic|XAUTHORITY}}、{{ic|DISPLAY}}、{{ic|DBUS_SESSION_BUS_ADDRESS}}) を定義し export する必要があります。
  +
  +
{{Tip|ユーザーのディスプレイ環境変数を取得し、{{ic|IMPORT}} キーで ''udev'' ルールに変数を export する方法については {{AUR|xpub}} を参照してください。}}
  +
  +
3) 作成した ''udev'' ルールを (再) ロードし、ノート PC から電源アダプタを抜いてテストしてください。
  +
  +
{{Note|上記のルールが X サーバーの開始前にトリガーされてしまうと、意図したとおりに動作しない場合があります。[[#X サーバーが存在しない場合に RUN ルールの X プログラムがハングする]] 章を参照してください。}}
  +
  +
=== 長時間稼働するプロセスを生成する ===
  +
  +
udev からプログラムを開始するとそのデバイス以降のイベントがブロックされ、また、udev ルール内で生成されたタスクはイベント処理の完了後に終了されます。長時間稼働するプロセスを udev から生成する必要がある場合は、{{Pkg|at}} を使うか (使用例: {{ic|your_command {{!}} at now}} または {{ic|batch}})、[https://blog.fraggod.net/2012/06/16/proper-ish-way-to-start-long-running-systemd-service-on-udev-event-device-hotplug.html udev ルールから直接トリガーできる] [[systemd]] ユニットを作成してください。
   
 
== トラブルシューティング ==
 
== トラブルシューティング ==
   
=== モジュールブラックリスト ===
+
=== モジュールブラックリストに追加する ===
   
、udev が間違って誤ったモジュールをロードすることがあります。これ止めさせために、モジュールをブラックリストに入れることができます。ブラックリストれば、udev は二度そのモジュールをロードしません。[[カーネルモジュール#ブラックリスト]]を見て下さい。起動時と hotplug のイベント (例: USB フラッシュドライブを入) 両方です。
+
なケースですが''udev'' が間違って誤ったモジュールをロードしてしまうことがあります。間違ったモジュールロードしないようにするに、モジュールを[[ブラックリスト]]追加することができます。ブラックリストに追加起動時にも、ホットプラグイベントが発生したとき (USB フラッシュドライブをときなど) にも、''udev'' はそのモジュールをロードしなくなります。
   
 
=== デバッグ出力 ===
 
=== デバッグ出力 ===
   
ハードウェアのデバッグ情報を取得したいときは、{{ic|1=udev.log-priority=debug}} [[カーネルパラメータ]]を使ってください。もしくは、以下設定:
+
ハードウェアの[[一般的なトラブルシューティング|デバッグ]]情報を表示するには、{{ic|1=udev.log-priority=debug}} [[カーネルパラメータ]]を使ってください。あるいは、以下設定を行うこともできます:
   
 
{{hc|/etc/udev/udev.conf|2=udev_log="debug"}}
 
{{hc|/etc/udev/udev.conf|2=udev_log="debug"}}
   
上記設定ファイルを {{ic|FILES}} に追加することで initramfs に組み込むこともできます:
+
このオプションは、mkinitcpio の {{ic|FILES}} 配列この設定ファイルを追加することでinitramfs に組み込むことも可能です:
   
 
{{hc|/etc/mkinitcpio.conf|2=FILES="... /etc/udev/udev.conf"}}
 
{{hc|/etc/mkinitcpio.conf|2=FILES="... /etc/udev/udev.conf"}}
   
設定後は initramfs を再生成してください:
+
{{ic|mkinitcpio.conf}} を変更した後は、[[initramfs を再生成する|initramfs を再生成]]してください
 
# mkinitcpio -p linux
 
   
 
=== 起動時に udevd が止まる ===
 
=== 起動時に udevd が止まる ===
   
LDAP に移行したり LDAP を使っているシステムを更新した後 udevd が起動時 "Starting UDev Daemon" というメッセージを出したときに止まることがあります。これは通常 udevd が LDAP にある名前を検索しようとして、ネットワークがまだ立ち上がっておらず、失敗していることが原因です。解決方法は全てのシステムグループの名前をローカルで存在させることです。
+
LDAP に移行したり LDAP を使っているシステムを更新した後 ''udevd'' が起動時 "Starting UDev Daemon" というメッセージを出したときに止まることがあります。これは通常 ''udevd'' が LDAP にある名前を検索しようとして、ネットワークがまだ立ち上がっておらず、失敗していることが原因です。解決方法は全てのシステムグループの名前をローカルで存在させることです。
   
udev ルールで記述されているグループ名とシステム上にるグループ名を抽出してください:
+
''udev'' ルールで参照されているグループ名とシステム上に実際に存在しているグループ名を抽出してください:
   
# fgrep -r GROUP /etc/udev/rules.d/ /usr/lib/udev/rules.d | perl -nle '/GROUP\s*=\s*"(.*?)"/ && print $1;' | sort | uniq > udev_groups
+
# grep -Fr GROUP /etc/udev/rules.d/ /usr/lib/udev/rules.d/ | sed 's:.*GROUP="\([-a-z_]\{1,\}\)".*:\1:' | sort -u >udev_groups
# cut -f1 -d: /etc/gshadow /etc/group | sort | uniq > present_groups
+
# cut -d: -f1 /etc/gshadow /etc/group | sort -u >present_groups
   
 
違いを確認するために、side-by-side の diff を実行してください:
 
違いを確認するために、side-by-side の diff を実行してください:
349行目: 376行目:
 
...
 
...
   
この場合、何らかの理由で pcscd グループがシステム上に存在しません。欠けているグループを追加してください:
+
この場合、何らかの理由で pcscd グループがシステム上に存在していないことがわかり[[ユーザーとグループ#グループ一覧|欠けているグループを追加してください]]。また、LDAP よりも前にローカルのリソースを参照するように設定してください。{{ic|/etc/nsswitch.conf}} には以下の行が含まれている必要があります:
 
# groupadd pcscd
 
 
また、LDAP に頼る前にローカルリソースが検索されるようにしてください。{{ic|/etc/nsswitch.conf}} に次の行を含める必要があります:
 
   
 
group: files ldap
 
group: files ldap
   
  +
=== リムーバブルデバイスとして扱われなくてはならないデバイスがそう扱われない ===
=== ハードウェアの既知の問題 ===
 
   
  +
問題のリムーバブルデバイスに対してカスタムの ''udev'' ルールを作成する必要があります。デバイスの不変な情報 (そのデバイスを識別するために利用できる情報) としては、{{ic|ID_SERIAL}} や {{ic|ID_SERIAL_SHORT}} が使えます (以下の {{ic|/dev/sdb}} の部分は必要に応じて変更してください):
==== BusLogic デバイスが壊れて起動中にフリーズする ====
 
   
  +
$ udevadm info /dev/sdb | grep ID_SERIAL
これはカーネルのバグでありまだ修正されていません。
 
   
  +
次に、デバイスが自動マウントされるようにするために {{ic|1=UDISKS_AUTO="1"}} を、デバイスを "リムーバブル" として指定するために {{ic|1=UDISKS_SYSTEM="0"}} を設定します。詳細は {{man|8|udisks}} を見てください。
==== リムーバルとして扱われなくてはならないデバイスがそう扱われない ====
 
   
  +
{{hc|/etc/udev/rules.d/99-removable.rules|2=
{{ic|UDISKS_SYSTEM_INTERNAL<nowiki>=</nowiki>0}} を設定するカスタム udev ルールを作成してください。詳しくは、udisks の man ページを見て下さい。
 
  +
ENV{ID_SERIAL_SHORT}=="''serial_number''", ENV{UDISKS_AUTO}="1", ENV{UDISKS_SYSTEM}="0"
  +
}}
   
  +
{{ic|udevadm control --reload}} を実行して ''udev'' ルールを再読み込みするのを忘れないでください。次回デバイスを挿入すると、外部ドライブとして扱われます。
=== 自動ロードの既知の問題 ===
 
   
==== モジュールが自動でロードされないサウンドの問題 ====
+
=== 一部のモジュールが自動でロードされず、サウンドの問題が発生する ===
   
{{ic|/etc/modprobe.d/sound.conf}} の古いエントリによって問題こる場合があります。このファイルを手入れして、それから再度試してさい。
+
一部のユーザーは、この問題は {{ic|/etc/modprobe.d/sound.conf}} の古いエントリが原因であるとを突き止めていようです。このファイルの古いエントリクリーンアップして、問題が発生ないか確かめください。
   
{{Note|{{ic|1=udev>=171}} から、デフォルトで OSS エミュレーションモジュール ({{ic|snd_seq_oss}}, {{ic|snd_pcm_oss}}, {{ic|snd_mixer_oss}}) は自動ロードされなくなりました。}}
+
{{Note|{{ic|1=udev>=171}} から、デフォルトで OSS エミュレーションモジュール ({{ic|snd_seq_oss}}{{ic|snd_pcm_oss}}{{ic|snd_mixer_oss}}) は自動的にロードされなくなりました。}}
   
  +
=== IDE CD/DVD ドライブのサポート ===
=== カスタムカーネルの既知の問題 ===
 
   
  +
''udev'' はバージョン 170 から、{{ic|ide_cd_mod}} モジュールによって従来の IDE ドライブとしてロードされデバイスファイルが {{ic|/dev/hd*}} となる CD-ROM/DVD-ROM をサポートしなくなりました。このようなドライブはハードウェアに直接アクセスするツール ([[光学ディスクドライブ#リッピング|cdparanoia]] など) によって依然として利用可能ですが、より高いレイヤーのユーザー空間のプログラム (KDE など) からは不可視です。
==== Udev が全く起動しない ====
 
   
  +
ide_cd_mod モジュールが他のモジュール (sr_mod など) よりも優先されてロードされる原因は、何らかの理由により [[initramfs]] 内で piix モジュールがロードされてしまっているなどが考えられます。その場合は、{{ic|/etc/mkinitcpio.conf}} で piix モジュールを ata_piix モジュールに置き換えると問題が解決します。
あなたのカーネルバージョンが 2.6.32 以上であることを確認してください。それ以前のカーネルでは udev が自動ロードをするのに必要な uevent をサポートしていません。
 
   
=== IDE CD/DVD ドライブサポ ===
+
=== 光学ドライブのグルプ ID が "disk" に設定される ===
   
  +
光学ドライブのグループ ID が {{ic|disk}} に設定されるが、{{ic|optical}} に設定されるようにしたい場合は、カスタムの ''udev'' ルールを作成することで可能です:
バージョン 170 から、udev は CD-ROM/DVD-ROM ドライブをサポートしておらず、伝統的な IDE ドライブとして {{ic|ide_cd_mod}} モジュールを使ってロードされ {{ic|/dev/hd*}} として表示します。cdparanoia など、ハードウェアに直接アクセスするツールでは問題なくドライブを使えますが、KDE などのより高い次元のユーザースペースのプログラムにはドライブが見えなくなります。
 
 
sr_mod など他のモジュールよりも先に ide_cd_mod モジュールがロードされる理由は、何らかの理由で initramfs で piix モジュールをロードしているなどが考えられます。その場合、{{ic|/etc/mkinitcpio.conf}} で piix を ata_piix に置き換えることができます。
 
 
=== オプティカルドライブのグループ ID が "disk" に設定される ===
 
 
オプティカルドライブのグループ ID が {{ic|disk}} に設定されていて、それを {{ic|optical}} に設定したい場合、カスタム udev ルールを作成する必要があります:
 
   
 
{{hc|/etc/udev/rules.d|2=<nowiki>
 
{{hc|/etc/udev/rules.d|2=<nowiki>
397行目: 416行目:
 
# permissions for SCSI CD devices
 
# permissions for SCSI CD devices
 
SUBSYSTEMS=="scsi", KERNEL=="s[rg][0-9]*", ATTRS{type}=="5", GROUP="optical"</nowiki>}}
 
SUBSYSTEMS=="scsi", KERNEL=="s[rg][0-9]*", ATTRS{type}=="5", GROUP="optical"</nowiki>}}
  +
  +
=== X サーバーが存在しない場合に RUN ルールの X プログラムがハングする ===
  +
  +
''xrandr'' や他の X ベースのプログラムが X サーバに接続する際に失敗すると、TCP 接続にフォールバックします。しかし、[https://github.com/systemd/systemd/blob/main/units/systemd-udevd.service.in#L43 systemd-udev サービスの設定ファイル]で {{ic|IPAddressDeny}} が設定されているため、ハングしてしまいます。最終的には、プログラムは kill され、イベントの処理が再開されます。
  +
  +
対象のルールが drm デバイスに対するものであり、X サーバが開始されるとハングによってイベントの処理が終わってしまう場合、{{ic|failed to authenticate magic}} エラーで 3D アクセラレーションが機能しなくなってしまう可能性があります。
   
 
== 参照 ==
 
== 参照 ==
   
  +
* {{man|7|udev}}
* [https://www.kernel.org/pub/linux/utils/kernel/hotplug/udev/udev.html Udev ホームページ]
 
* [http://www.linux.com/news/hardware/peripherals/180950-udev An Introduction to Udev]
+
* [https://opensource.com/article/18/11/udev An Introduction to udev]
* [http://vger.kernel.org/vger-lists.html#linux-hotplug Udev mailing list information]
+
* [http://vger.kernel.org/vger-lists.html#linux-hotplug Udev メーリングリストの情報]
 
* [http://jasonwryan.com/blog/2014/01/20/udev/ Scripting with udev]
 
* [http://jasonwryan.com/blog/2014/01/20/udev/ Scripting with udev]
* [http://www.reactivated.net/writing_udev_rules.html Writing udev rules]
+
* [http://www.reactivated.net/writing_udev_rules.html Writing udev rules] (日本語訳: [https://www.gentoo.gr.jp/transdocs/udevrules/udevrules.html udevルールの書き方])
* [http://www.linuxfromscratch.org/lfs/view/6.1/chapter07/udev.html Device and Module Handling on an LFS System]
+
* [https://www.linuxfromscratch.org/lfs/view/stable/chapter09/udev.html LFS 環境のデバイスとモジュールの扱いについて]
  +
* [https://github.com/Ventto/xpub Udev ルールからの GUI の実行とディスプレイ変数へのアクセス]
  +
* [https://doc.opensuse.org/documentation/leap/reference/html/book-reference/cha-udev.html openSUSE の udev ドキュメント]
  +
  +
{{TranslationStatus|udev|2023-12-28|786632}}

2023年12月28日 (木) 12:52時点における最新版

関連記事

udev は、オペレーティングシステムの管理者がユーザー空間のイベントハンドラを登録できるようにする、ユーザー空間のシステムです。udev のデーモンによって捕捉されたイベントは主に、周辺機器関連の物理イベントに応答して (Linux) カーネルによって生成されたものです。そのため、udev の主な使用目的は、(カーネルモジュールやデバイスファームウェアのロードなど) カーネルに制御が戻るようなアクションを含む、周辺機器の検出やホットプラグです。また、周辺機器の検出においては、デバイス (ファイル) のパーミッションを調整して非 root ユーザーや非 root グループからアクセス可能にするなども行われます。

udev は、devfsdhotplug の後継として、/dev ディレクトリ内のデバイスノードの追加、シンボリックリンクの作成、名称変更などの管理も行います。udevhotplughwdetect の両方の機能を置き換えます。

udev は、別々のイベントを同時に (並列に) 処理します。それにより、古いシステムよりも高いパフォーマンスが得られる可能性があります。しかし、カーネルモジュールのロード順がブート毎に同じであることが保証されないなどの理由により、この機構はシステムの管理を複雑化させてしまう可能性もはらんでいます。マシンに複数のブロックデバイスが搭載されている場合、再起動するとデバイスノードの名称が変化してしまう場合があります。例えば、マシンに 2 つのハードドライブが存在する場合、/dev/sda は次回の起動時に /dev/sdb となってしまうかもしれません。これに関する詳細は、下記を見てください。

目次

インストール

udevsystemd の一部なので、デフォルトでインストールされます。詳細は systemd-udevd.service(8) を見てください。

udev ルールについて

管理者が書いた udev ルールは /etc/udev/rules.d/ 内に配置することになっており、そのファイル名は .rules で終わらなければなりません。様々なパッケージに同梱されている udev ルールは /usr/lib/udev/rules.d/ に格納されています。もし /usr/lib/etc に同じ名前のファイルがあった場合、/etc にあるファイルが優先されます。

udev ルールについて学ぶには、udev(7) マニュアルを参照してください。また、Writing udev rules も参照してください。このガイドには、実践的な例 (Writing udev rules - Examples) がいくつか挙げられています。

udev ルールの例

以下は、ウェブカメラが接続された時に /dev/video-cam シンボリックリンクを作成するルールの例です。

ここで、カメラは既に接続されていて、/dev/video2 というデバイス名でロードされているとします。そして、以下の udev ルールを書く理由は、次回のブート時にデバイスファイルが別の名前 (例えば /dev/video0 など) になってしまうかもしれないからです (なので、/dev/video-cam という固定のファイル名で参照できるようにしようというのが目的です)。

$ udevadm info --attribute-walk --path=$(udevadm info --query=path --name=/dev/video2)
Udevadm info starts with the device specified by the devpath and then walks up the chain of parent devices.
It prints for every device found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device and the attributes from one single parent device.

looking at device '/devices/pci0000:00/0000:00:04.1/usb3/3-2/3-2:1.0/video4linux/video2':
  KERNEL=="video2"
  SUBSYSTEM=="video4linux"
   ...
looking at parent device '/devices/pci0000:00/0000:00:04.1/usb3/3-2/3-2:1.0':
  KERNELS=="3-2:1.0"
  SUBSYSTEMS=="usb"
  ...
looking at parent device '/devices/pci0000:00/0000:00:04.1/usb3/3-2':
  KERNELS=="3-2"
  SUBSYSTEMS=="usb"
  ATTRS{idVendor}=="05a9"
  ATTRS{manufacturer}=="OmniVision Technologies, Inc."
  ATTRS{removable}=="unknown"
  ATTRS{idProduct}=="4519"
  ATTRS{bDeviceClass}=="00"
  ATTRS{product}=="USB Camera"
  ...

対象のウェブカメラを識別するために、video4linux デバイスからは KERNEL=="video2"SUBSYSTEM=="video4linux" という条件式が使用されています。それより 2 階層上を見ると、USB 親デバイス SUBSYSTEMS=="usb" からはベンダー ID ATTRS{idVendor}=="05a9" とプロダクト ID ATTRS{idProduct}=="4519" を使ってウェブカメラをマッチさせています。

以上から、以下のようにこのデバイスにマッチするルールを作成することができます:

/etc/udev/rules.d/83-webcam.rules
KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", SUBSYSTEMS=="usb", ATTRS{idVendor}=="05a9", ATTRS{idProduct}=="4519", SYMLINK+="video-cam"

ここで、SYMLINK+="video-cam" を使ってシンボリックリンクを作成していますが、OWNER="john" でデバイスの所有者を、GROUP="video" でデバイスの所有グループを設定することもできますし、MODE="0660" でパーミッションも設定できます。

デバイスが取り除かれた時に何かを行うルールを記述したい場合は、デバイスの属性にはアクセスできないことに注意してください (とっくにデバイスは取り除かれているからです)。この場合、事前に定義されたデバイスの環境変数を使う必要があります。そのような環境変数を監視するには、デバイスが取り除かれた状態で以下のコマンドを実行してください:

$ udevadm monitor --property --udev

このコマンドでは、ID_VENDOR_IDID_MODEL_ID というような値のペアが出力されます。これらは、上記の属性 idVendoridProduct に対応します。デバイスの属性の代わりにデバイスの環境変数を使うルールは以下のようになります:

/etc/udev/rules.d/83-webcam-removed.rules
ACTION=="remove", SUBSYSTEM=="usb", ENV{ID_VENDOR_ID}=="05a9", ENV{ID_MODEL_ID}=="4519", RUN+="/path/to/your/script"

デバイスの属性を一覧表示する

ルールを書く際に使用できるデバイスの属性のリストを全て一覧表示するには、以下のコマンドを実行してください:

$ udevadm info --attribute-walk --name=device_name

device_name の部分は、システムに存在しているデバイス (/dev/sda/dev/ttyUSB0 など) に置き換えてください。

デバイス名が分からない場合は、特定のシステムパスの全属性をリストアップすることもできます:

$ udevadm info --attribute-walk --path=/sys/class/backlight/acpi_video0

デバイスを絞り込むには、まずデバイスのクラスを調べて、以下のコマンドを実行してください:

$ ls /dev/class/by-id

--name 引数には、単にデバイスのシンボリックリンクを使うこともできますし、シンボリックリンクの指す実際のアイルを使うこともできます。例えば:

$ udevadm info --attribute-walk --name=/dev/input/by-id/usb-foostan_Corne-event-kbd

下位デバイスを持たない裸のUSBデバイスのパスを取得するには、 USB デバイスのフルパスを使用する必要があります。udevadm のモニターモードを開始し、対象の USB デバイスを接続すれば、デバイスへのパスを得ることができます:

$ udevadm monitor
...
KERNEL[26652.638931] add      /devices/pci0000:00/0000:00:01.2/0000:02:00.0/0000:03:05.0/0000:05:00.0/usb1/1-3 (usb)
KERNEL[26652.639153] add      /devices/pci0000:00/0000:00:01.2/0000:02:00.0/0000:03:05.0/0000:05:00.0/usb1/1-3/1-3:1.0 (usb)
...

一番深いパスを選択し、--attribute-walk を使えば、親デバイスの全属性を出力することができます:

$ udevadm info --attribute-walk --path=/devices/pci0000:00/0000:00:01.2/0000:02:00.0/0000:03:05.0/0000:05:00.0/usb1/1-3/1-3:1.0

ロードする前にルールをテストする

# udevadm test $(udevadm info --query=path --name=device_name) 2>&1

このコマンドは、ルールの全てのアクションを実行しませんが、既存のデバイスに対するシンボリックリンクのルールは処理します。ルールをロードできない場合に役立つかもしれません。また、テストしたい udev ルールのデバイスへのパスを直接指定することも可能です:

# udevadm test /sys/class/backlight/acpi_video0/

新しいルールをロードする

udev はルールファイルの変更を自動的に検出するので、udev を再起動せずとも変更は即座に有効になります。しかし、既に存在するデバイスに対しては、ルールが自動的に再トリガーされません。USB デバイスなどのホットプラグ可能なデバイスは、新しいルールを有効にするために再接続するか、少なくともカーネルモジュール ohci-hcd と ehci-hcd を再ロードして全ての USB ドライバを再読み込みする必要があります。

ルールが自動的に再読み込みされない場合は、以下を実行してください:

# udevadm control --reload

手動でルールを強制的にトリガーするには:

# udevadm trigger

Udisks

Udisks を見て下さい。

ヒントとテクニック

ルールの中でドライブをマウントする

リムーバブルディスクをマウントする際に udev ルールから mount コマンドを実行しないでください。これは以下の 2 つの理由により賢明ではありません:

  1. デフォルトで systemd は、分離された "mount 名前空間" 内で systemd-udevd.service を実行します (namespaces(7) を参照)。つまり、この名前空間外からはデバイスが不可視になります。
  2. この問題を解決するために (PrivateMountsMountFlags の行をコメントアウトして) サービスのパラメータを変更したとしても、udev から起動されたプロセスは数秒後に終了させられてしまうという問題があります。NTFS-3G などの FUSE ファイルシステムにおいては、mount はファイルシステムを管理するためにユーザー空間のプロセスを起動します。このプロセスが終了されると、そのファイルシステムにアクセスしようとした時に Transport endpoint not connected (通信端点が接続されていません) というエラーが発生します。

うまく行く方法もいくつかあります:

  • Udev ルールからカスタムの systemd サービスを起動する。カスタムの systemd サービスでは、長時間動作させるプロセス (FUSE など) を開始するスクリプトを開始するなどができます。USB ディスクを自動的に /media 内にマウントする簡単な例は udev-media-automount です。似たようなアイディアはこのブログ記事でも説明されています。
  • Udev ルールで mount の代わりに systemd-mount を使う。これは、systemd の開発者達によって推奨されている方法です。例えば、以下の udev ルールは USB ディスクを /media 内にマウントします:
ACTION=="add", SUBSYSTEMS=="usb", SUBSYSTEM=="block", ENV{ID_FS_USAGE}=="filesystem", RUN{program}+="/usr/bin/systemd-mount --no-block --automount=yes --collect $devnode /media"
  • udisksudiskie といったパッケージを使う。このようなパッケージは非常に強力ですが、セットアップが難しいです。また、これらのパッケージは一部のファイルシステムの所有者を、アクティブなセッションを現在持っている非特権ユーザーに設定するので、シングルユーザーのセッションで使用されることを意図しています。

通常ユーザーにデバイスの使用を許可する

カーネルドライバがデバイスを初期化する際に、デフォルト状態ではデバイスノードは root:root によって所有され、パーミッションは 600 に設定されます。[1] よって、ドライバがこのデフォルトを変更するか、ユーザー空間の udev ルールがパーミッションを変更しない限り、通常ユーザーはデバイスにアクセスできません。

Udev 値 OWNERGROUPMODE を使って、アクセス権を付与することができます。しかし、全てのユーザーがデバイスを利用できるようにし、なおかつデバイスファイルのモードを過度に寛容にしないようにするのは困難です。Ubuntu では、plugdev というグループを作成して、このグループにデバイスが追加されます。しかし、このアプローチは systemd の開発者達によって推奨されていない [2] だけでなく、Arch の udev ルールに追加されたときにはバグとみなされました (FS#35602)。歴史的に採用されていたもう一つのアプローチは、デバイスのカテゴリ毎に対応する別々のグループを使用するというものです (ユーザーとグループ#systemd 以前のグループ で説明されています)。

Systemd システムにおける最近の推奨されるアプローチは、MODE660 に設定してグループがデバイスを使用できるようにし、uaccess という TAG を付けることです [3]。この特殊なタグにより、udev は動的なユーザー ACL をデバイスノードに適用するようになり、systemd-logind(8) と連携してログイン中のユーザーがデバイスにアクセスできるようにします。以下は、このアプローチを実装する udev ルールの例です:

/etc/udev/rules.d/71-device-name.rules
SUBSYSTEMS=="usb", ATTRS{idVendor}=="vendor_id", ATTRS{idProduct}=="product_id", MODE="0660", TAG+="uaccess"

HDMI ケーブルの抜き差し時に実行する

以下の内容でルール /etc/udev/rules.d/95-hdmi-plug.rules を作成してください:

ACTION=="change", SUBSYSTEM=="drm", ENV{DISPLAY}=":0", ENV{XAUTHORITY}="/home/username/.Xauthority", RUN+="/path/to/script.sh"
ノート: このルールが X サーバの開始前にトリガーされると、意図したとおりに動作しない場合があります。#X サーバーが存在しない場合に RUN ルールの X プログラムがハングする 章を参照してください。

VGA ケーブルの接続時に実行する

VGA モニターのケーブルが接続された時に arandr を実行するには、以下の内容でルール /etc/udev/rules.d/95-monitor-hotplug.rules を作成してください:

KERNEL=="card0", SUBSYSTEM=="drm", ENV{DISPLAY}=":0", ENV{XAUTHORITY}="/home/username/.Xauthority", RUN+="/usr/bin/arandr"

一部のディスプレイマネージャは .Xauthority をユーザーのホームディレクトリ外に保存します。なので、ENV{XAUTHORITY} の値は適宜変更する必要があります。例として、GNOME Display Manager の場合は以下のようになります:

$ printenv XAUTHORITY
/run/user/1000/gdm/Xauthority
ノート: このルールが X サーバの開始前にトリガーされると、意図したとおりに動作しない場合があります。#X サーバーが存在しない場合に RUN ルールの X プログラムがハングする 章を参照してください。

新しい eSATA を検知する

eSATA ドライブが挿入された時に検出されない場合、問題を解決できるかもしれない方法がいくつかあります。1つ目は、eSATA が挿入されている状態で再起動することです。あるいは、以下のコマンドを試してみることもできます:

# echo 0 0 0 > /sys/class/scsi_host/host*/scan

あるいは、scsiaddAURインストールし、以下を実行してみることもできます:

# scsiadd -s

うまく行けば、ドライブが /dev 内に出現します。出現しない場合は、以下のコマンドを実行し、出力されるログを見ながら上記のコマンドをもう一度試してください:

# udevadm monitor

内部 SATA ポートを eSATA として認識させる

eSATA ベイや他の eSATA アダプタを接続すると、システムはこのディスクを内部 SATA ドライブとして認識します。GNOMEKDE では毎回 root のパスワードが要求されます。以下のルールは、指定した SATA ポートを外部 eSATA ポートとしてマークします。これにより、GNOME の通常ユーザーでも root のパスワード無しで eSATA ドライブを USB ドライブのようにポートに接続できるようになります。

/etc/udev/rules.d/10-esata.rules
DEVPATH=="/devices/pci0000:00/0000:00:1f.2/host4/*", ENV{UDISKS_SYSTEM}="0"
ノート: The DEVPATH can be found after connection the eSATA drive with the following commands (replace sdb accordingly):
$ udevadm info --query=path /dev/sdb
/devices/pci0000:00/0000:00:1f.2/host4/target4:0:0/4:0:0:0/block/sdb
$ find /sys/devices/ -name sdb
/sys/devices/pci0000:00/0000:00:1f.2/host4/target4:0:0/4:0:0:0/block/sdb

固定デバイス名を設定する

udev は全てのモジュールを非同期でロードするので、モジュールは毎回異なる順番で初期化される可能性があります。これにより、デバイス名がランダムに変わってしまいます。udev ルールを用いることで、固定デバイス名を使用することができます。 ブロックデバイスに関しては 永続的なブロックデバイスの命名 も、ネットワークデバイスに関しては ネットワーク設定#インターフェイス名の変更 も参照してください。

ビデオデバイス

ウェブカメラのセットアップに関しては ウェブカメラ設定 を参照してください。

複数のウェブカメラを使用すると、それぞれのビデオデバイスはブート時に /dev/video* としてランダムに割り当てられます。推奨される解決策は、#udev ルールの例 章にあるような udev ルールを使ってシンボリックリンクを作成することです:

/etc/udev/rules.d/83-webcam.rules
KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", SUBSYSTEMS=="usb", ATTRS{idVendor}=="05a9", ATTRS{idProduct}=="4519", SYMLINK+="video-cam1"
KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", SUBSYSTEMS=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="08f6", SYMLINK+="video-cam2"
ノート: /dev/video* 以外の名前を使用すると v4l1compat.so のプリロードに失敗します (v4l2convert.so のプリロードにも失敗する可能性があります)。

プリンタ

複数のプリンタを使用すると、それぞれのプリンタはブート時に /dev/lp[0-9] としてランダムに割り当てられます。これにより、CUPS の設定などが機能しなくなります。

ディレクトリ /dev/lp/by-id/dev/lp/by-path 内に永続的なブロックデバイスの命名規則に似たシンボリックリンクを作成する以下のルールを作成することができます:

/etc/udev/rules.d/60-persistent-printer.rules
ACTION=="remove", GOTO="persistent_printer_end"
# これは必須では無いはずです
#KERNEL!="lp*", GOTO="persistent_printer_end"

SUBSYSTEMS=="usb", IMPORT{builtin}="usb_id"
ENV{ID_TYPE}!="printer", GOTO="persistent_printer_end"

ENV{ID_SERIAL}=="?*", SYMLINK+="lp/by-id/$env{ID_BUS}-$env{ID_SERIAL}"

IMPORT{builtin}="path_id"
ENV{ID_PATH}=="?*", SYMLINK+="lp/by-path/$env{ID_PATH}"

LABEL="persistent_printer_end"

ディスクをシリアル番号で識別する

特定のディスクデバイス /dev/sdX に対して何らかのアクションを実行する際、udevadm info /dev/sdX コマンドで出力されるユニークかつ永続的なシリアル番号 ID_SERIAL_SHORT を使ってデバイスを指定するには、以下のようなルールを使うことができます。以下はその例です:

/etc/udev/rules.d/69-disk.rules
ACTION=="add", KERNEL=="sd[a-z]", ENV{ID_SERIAL_SHORT}=="serial_number", RUN+="/path/to/script /dev/%k"

USB デバイスでサスペンドから復帰させる

udev ルールを用いることで、マウスやキーボードといった USB デバイスの復帰トリガーを有効化して、そのデバイスを使ってシステムをスリープから復帰させることができます。

ノート: デフォルトでは、全ての USB のホストコントローラで復帰 (トリガー) が有効化されています。デバイスの状態は cat /proc/acpi/wakeup を使って確認できます。復帰が有効化されている場合以下のルールは必要ありませんが、他のアクション (復帰機能の無効化など) を実行するためのテンプレートとして使用できます。

まず、対象の USB デバイスのベンダー ID とプロダクト ID を調べてください。これらの ID は udev ルール内でデバイスを識別するために使用します。例えば:

$ lsusb | grep Logitech
Bus 007 Device 002: ID 046d:c52b Logitech, Inc. Unifying Receiver

次に、以下のコマンドを使ってデバイスの接続先を調べてください:

$ grep c52b /sys/bus/usb/devices/*/idProduct
/sys/bus/usb/devices/1-1.1.1.4/idProduct:c52b

最後に、USB デバイス自体と、USB デバイスの接続先である USB コントローラの power/wakeup 属性をデバイスの接続時に変更するルールを作成してください:

/etc/udev/rules.d/50-wake-on-device.rules
ACTION=="add", SUBSYSTEM=="usb", DRIVERS=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c52b", ATTR{power/wakeup}="enabled", ATTR{driver/1-1.1.1.4/power/wakeup}="enabled"

イベントをトリガーする

udev イベントをトリガーすると便利である場合があります。例えば、リモートマシン上の USB デバイスの切断をシミュレートしたい場合などです。そのような場合は udevadm trigger を使ってください:

# udevadm trigger --verbose --type=subsystems --action=remove --subsystem-match=usb --attr-match="idVendor=abcd"

このコマンドは、ベンダー ID が abcd の全 USB デバイスに対して USB リモートイベントをトリガーします。

Udev ルールからデスクトップ通知をトリガーする

notify-send を呼び出す外部スクリプトを udev から実行してデスクトップに通知を表示させるのは、場合によっては困難です。以下の例では、notify-sendudev ルールから正しく実行するために、どのファイルにどのコマンドや環境変数を記述すべきかを説明しています。

ノート: この例では多くの変数がハードコードされています。なので、この例を理解したあとは、これらをよりポータブルにする (例えば、ユーザー名ではなく $USER を使うなど) ことを検討してください。

1) 以下の udev は、ノート PC の電源状態によって画面の輝度が変更された際に通知音を再生しデスクトップ通知を送信するスクリプトを実行します。以下のファイルを作成してください:

/etc/udev/rules.d/99-backlight_notification.rules
# バッテリー駆動に切り替わったときのルール
ACTION=="change", SUBSYSTEM=="power_supply", ATTR{type}=="Mains", ATTR{online}=="0", ENV{DISPLAY}=":0", ENV{XAUTHORITY}="/home/USERNAME/.Xauthority" RUN+="/usr/bin/su USERNAME_TO_RUN_SCRIPT_AS -c /usr/local/bin/brightness_notification.sh"
# AC 電源に切り替わったときのルール
ACTION=="change", SUBSYSTEM=="power_supply", ATTR{type}=="Mains", ATTR{online}=="1", ENV{DISPLAY}=":0", ENV{XAUTHORITY}="/home/USERNAME/.Xauthority" RUN+="/usr/bin/su USERNAME_TO_RUN_SCRIPT_AS -c /usr/local/bin/brightness_notification.sh"
  • USERNAME_TO_RUN_SCRIPT_ASUSERNAME は、通知が表示されるグラフィカルセッションのユーザーのショートネームに変更してください。
  • スクリプトは /usr/bin/su で実行する必要があります。そうすることで、(root としてではなく) 通知が表示されるグラフィカルセッションのユーザーとしてプロセスを実行します。

2) udev のトリガー時に実行する実行可能スクリプトの内容:

/usr/local/bin/brightness_notification.sh
#!/bin/sh

export XAUTHORITY=/home/USERNAME_TO_RUN_SCRIPT_AS/.Xauthority
export DISPLAY=:0
export DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/UID_OF_USER_TO_RUN_SCRIPT_AS/bus"

/usr/bin/sudo -u USERNAME_TO_RUN_SCRIPT_AS /usr/bin/paplay --server=/run/user/UID_OF_USER_TO_RUN_SCRIPT_AS/pulse/native /home/USERNAME/.i3/sounds/Click1.wav > /dev/null 2>&1

/usr/bin/notify-send --icon=/usr/share/icons/gnome/256x256/status/battery-full-charging.png 'Changing Power States' --expire-time=4000
  • USERNAME_TO_RUN_SCRIPT_ASUID_OF_USER_TO_RUN_SCRIPT_ASUSERNAME は、通知が表示されるグラフィカルセッションのユーザーのショートネームや UID に置き換える必要があります。
  • /usr/bin/sudo は、pulseaudio で音声を再生するために必要です。
  • 通知が表示されるグラフィカルセッションのユーザーに対して、3つの環境変数 (XAUTHORITYDISPLAYDBUS_SESSION_BUS_ADDRESS) を定義し export する必要があります。
ヒント: ユーザーのディスプレイ環境変数を取得し、IMPORT キーで udev ルールに変数を export する方法については xpubAUR を参照してください。

3) 作成した udev ルールを (再) ロードし、ノート PC から電源アダプタを抜いてテストしてください。

ノート: 上記のルールが X サーバーの開始前にトリガーされてしまうと、意図したとおりに動作しない場合があります。#X サーバーが存在しない場合に RUN ルールの X プログラムがハングする 章を参照してください。

長時間稼働するプロセスを生成する

udev からプログラムを開始するとそのデバイス以降のイベントがブロックされ、また、udev ルール内で生成されたタスクはイベント処理の完了後に終了されます。長時間稼働するプロセスを udev から生成する必要がある場合は、at を使うか (使用例: your_command | at now または batch)、udev ルールから直接トリガーできる systemd ユニットを作成してください。

トラブルシューティング

モジュールをブラックリストに追加する

稀なケースですが、udev が間違って、誤ったモジュールをロードしてしまうことがあります。間違ったモジュールをロードしないようにするには、モジュールをブラックリストに追加することができます。ブラックリストに追加すると、起動時にも、ホットプラグイベントが発生したとき (USB フラッシュドライブを挿入したときなど) にも、udev はそのモジュールをロードしなくなります。

デバッグ出力

ハードウェアのデバッグ情報を表示するには、udev.log-priority=debug カーネルパラメータを使ってください。あるいは、以下の設定を行うこともできます:

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

このオプションは、mkinitcpio の FILES 配列にこの設定ファイルを追加することで、initramfs 内に組み込むことも可能です:

/etc/mkinitcpio.conf
FILES="... /etc/udev/udev.conf"

mkinitcpio.conf を変更した後は、initramfs を再生成してください。

起動時に udevd が止まる

LDAP に移行したり LDAP を使っているシステムを更新した後 udevd が起動時 "Starting UDev Daemon" というメッセージを出したときに止まることがあります。これは通常 udevd が LDAP にある名前を検索しようとして、ネットワークがまだ立ち上がっておらず、失敗していることが原因です。解決方法は全てのシステムグループの名前をローカルで存在させることです。

udev ルールで参照されているグループ名とシステム上に実際に存在しているグループ名を抽出してください:

# grep -Fr GROUP /etc/udev/rules.d/ /usr/lib/udev/rules.d/ | sed 's:.*GROUP="\([-a-z_]\{1,\}\)".*:\1:' | sort -u >udev_groups
# cut -d: -f1 /etc/gshadow /etc/group | sort -u >present_groups

違いを確認するために、side-by-side の diff を実行してください:

# diff -y present_groups udev_groups
...
network							      <
nobody							      <
ntp							      <
optical								optical
power							      |	pcscd
rfkill							      <
root								root
scanner								scanner
smmsp							      <
storage								storage
...

この場合、何らかの理由で pcscd グループがシステム上に存在していないことがわかります。欠けているグループを追加してください。また、LDAP よりも前にローカルのリソースを参照するように設定してください。/etc/nsswitch.conf には以下の行が含まれている必要があります:

group: files ldap

リムーバブルデバイスとして扱われなくてはならないデバイスがそう扱われない

問題のリムーバブルデバイスに対してカスタムの udev ルールを作成する必要があります。デバイスの不変な情報 (そのデバイスを識別するために利用できる情報) としては、ID_SERIALID_SERIAL_SHORT が使えます (以下の /dev/sdb の部分は必要に応じて変更してください):

$ udevadm info /dev/sdb | grep ID_SERIAL

次に、デバイスが自動マウントされるようにするために UDISKS_AUTO="1" を、デバイスを "リムーバブル" として指定するために UDISKS_SYSTEM="0" を設定します。詳細は udisks(8) を見てください。

/etc/udev/rules.d/99-removable.rules
ENV{ID_SERIAL_SHORT}=="serial_number", ENV{UDISKS_AUTO}="1", ENV{UDISKS_SYSTEM}="0"

udevadm control --reload を実行して udev ルールを再読み込みするのを忘れないでください。次回デバイスを挿入すると、外部ドライブとして扱われます。

一部のモジュールが自動でロードされず、サウンドの問題が発生する

一部のユーザーは、この問題は /etc/modprobe.d/sound.conf の古いエントリが原因であることを突き止めているようです。このファイルの古いエントリをクリーンアップして、問題が発生しないか確かめてください。

ノート: udev>=171 から、デフォルトで OSS エミュレーションモジュール (snd_seq_osssnd_pcm_osssnd_mixer_oss) は自動的にロードされなくなりました。

IDE CD/DVD ドライブのサポート

udev はバージョン 170 から、ide_cd_mod モジュールによって従来の IDE ドライブとしてロードされデバイスファイルが /dev/hd* となる CD-ROM/DVD-ROM をサポートしなくなりました。このようなドライブはハードウェアに直接アクセスするツール (cdparanoia など) によって依然として利用可能ですが、より高いレイヤーのユーザー空間のプログラム (KDE など) からは不可視です。

ide_cd_mod モジュールが他のモジュール (sr_mod など) よりも優先されてロードされる原因は、何らかの理由により initramfs 内で piix モジュールがロードされてしまっているなどが考えられます。その場合は、/etc/mkinitcpio.conf で piix モジュールを ata_piix モジュールに置き換えると問題が解決します。

光学ドライブのグループ ID が "disk" に設定される

光学ドライブのグループ ID が disk に設定されるが、optical に設定されるようにしたい場合は、カスタムの udev ルールを作成することで可能です:

/etc/udev/rules.d
# permissions for IDE CD devices
SUBSYSTEMS=="ide", KERNEL=="hd[a-z]", ATTR{removable}=="1", ATTRS{media}=="cdrom*", GROUP="optical"

# permissions for SCSI CD devices
SUBSYSTEMS=="scsi", KERNEL=="s[rg][0-9]*", ATTRS{type}=="5", GROUP="optical"

X サーバーが存在しない場合に RUN ルールの X プログラムがハングする

xrandr や他の X ベースのプログラムが X サーバに接続する際に失敗すると、TCP 接続にフォールバックします。しかし、systemd-udev サービスの設定ファイルIPAddressDeny が設定されているため、ハングしてしまいます。最終的には、プログラムは kill され、イベントの処理が再開されます。

対象のルールが drm デバイスに対するものであり、X サーバが開始されるとハングによってイベントの処理が終わってしまう場合、failed to authenticate magic エラーで 3D アクセラレーションが機能しなくなってしまう可能性があります。

参照

翻訳ステータス: このページは en:udev の翻訳バージョンです。最後の翻訳日は 2023-12-28 です。もし英語版に 変更 があれば、翻訳の同期を手伝うことができます。