udev rulesでLinuxのデバイス名を固定する方法|udevadm infoで属性確認からデバイス接続スクリプトまで

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)Linuxtips > udev rulesでLinuxのデバイス名を固定する方法|udevadm infoで属性確認からデバイス接続スクリプトまで
「/dev/sdb だと思ってバックアップスクリプトを組んだら、再起動後に /dev/sdc になっていた」——外付けHDDやUSBストレージを複数台つなぐサーバーでは、起動時のデバイス検出順序によってデバイス名がずれることがあります。

Linuxのudev(Userspace DEVice manager)はカーネルがデバイスを検出した瞬間に動き出し、/dev/配下のデバイスファイルを作成・管理します。udev rulesを書けば「このシリアル番号のUSBストレージは必ず/dev/backup-diskとして現れる」「外付けディスクを挿したらバックアップスクリプトを自動実行する」という設計が実現できます。

この記事では、udev rulesの基本書式とudevadm infoによる属性確認、デバイス名固定の実践手順、接続時スクリプト実行の設計まで順を追って解説します。RHEL 9.4 / Ubuntu 24.04 LTSで動作確認済みです。

この記事のポイント

・udevはカーネルのueventを受けて/dev/を管理するデーモン
・rulesは/etc/udev/rules.d/に配置し番号順に評価される
・udevadm infoでATTR名を特定してから条件式を書く
・ACTION=="add", RUN+="スクリプト"でデバイス接続時に自動実行できる


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

udevとは何か(Linuxでデバイス名が変わる理由)

Linuxがデバイスを検出すると、カーネルは/sys/ファイルシステムにデバイス情報を展開してueventを送出します。このueventを受け取るのがudevdデーモンです。udevdはudev rulesを上から評価し、条件に一致した場合に/dev/配下のデバイスファイルを作成したり、シンボリックリンクを張ったりします。

デバイス名がずれる根本原因は、カーネルがデバイスを検出する順序にあります。SATA/SASのディスクは接続ポートの順序で/dev/sda、/dev/sdb…と割り当てられますが、USB外付けディスクは接続のタイミングによって名前が変わります。udev rulesでSYMLINKを使えば、どのデバイス名が割り当てられていても「特定のシリアル番号のデバイスは常に/dev/backup-disk」として参照できます。

udevの設定ファイルは/etc/udev/配下に置かれます。

/etc/udev/udev.conf:udevdの動作パラメータ(ログレベル等)
/etc/udev/rules.d/*.rules:ユーザーが書くカスタムルール
/lib/udev/rules.d/*.rules:ディストリビューションが提供するデフォルトルール

/etc/udev/rules.d/と/lib/udev/rules.d/のファイルは、ファイル名の数字部分の昇順で評価されます。数字が同じ場合はアルファベット順です。ユーザールールは99-*.rulesのように数字を大きくして最後に評価させるのが一般的です。

udevルールファイルの書き方

udev rulesの1行は「マッチキー==値」と「アクションキー=値」を組み合わせたカンマ区切りの式です。

# 書式 MATCH_KEY=="値", MATCH_KEY=="値", ..., ACTION_KEY="値" # 例:ラベル名でUSBドライブを特定してシンボリックリンクを張る SUBSYSTEM=="block", ENV{ID_FS_LABEL}=="BACKUP_USB", SYMLINK+="backup-disk"

1. 代表的なマッチキー

SUBSYSTEM:デバイスが属するサブシステム(block・net・usb・input など)
KERNEL:カーネルが割り当てたデバイス名(sdb・sdb1・ttyUSB0 など)のパターン
ACTION:イベントの種類(add・remove・change)
ATTR{属性名}:/sys/のデバイスエントリにある属性値(vendor・model など)
ENV{変数名}:udevが設定する環境変数(ID_SERIAL・ID_FS_TYPE・ID_FS_LABEL など)

2. 代表的なアクションキー

NAME:/dev/配下に作るデバイスファイル名(通常はSYMLINKを使う方が安全)
SYMLINK+=:デバイスファイルへのシンボリックリンクを追加する
OWNERGROUP:デバイスファイルの所有者・グループを指定する
MODE:デバイスファイルのパーミッション(例:"0660")
RUN+="スクリプトのパス":ルールにマッチした時に実行するコマンド

udevadm infoでデバイスの属性を確認する

rulesを書く前にまず属性を確認します。存在しないATTR名を書いてもルールは単に無視されるため、必ず実機で属性名を確認してから書いてください。

1. udevadm info --query=all --name= で属性一覧を取得する

USBストレージを例に確認してみます。

# /dev/sdb の属性一覧を取得する udevadm info --query=all --name=/dev/sdb

実行例(出力の主要部分):

P: /devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.0/host3/target3:0:0/3:0:0:0/block/sdb N: sdb L: 0 S: disk/by-id/usb-BUFFALO_Portable_HDD_XXXXXXXX-0:0 E: DEVPATH=/devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.0/host3/target3:0:0/3:0:0:0/block/sdb E: DEVNAME=/dev/sdb E: DEVTYPE=disk E: SUBSYSTEM=block E: ID_VENDOR=BUFFALO E: ID_MODEL=Portable_HDD E: ID_SERIAL=BUFFALO_Portable_HDD_XXXXXXXX E: ID_SERIAL_SHORT=XXXXXXXX E: ID_TYPE=disk E: ID_BUS=usb E: ID_USB_DRIVER=usb-storage E: ID_FS_TYPE=ext4 E: ID_FS_LABEL=BACKUP_USB E: MAJOR=8 E: MINOR=16

「E:」行は環境変数(ENV{}でマッチ)、「A:」行があれば属性(ATTR{}でマッチ)です。

2. udevadm info -a -n で親デバイスの属性も調べる

USBのベンダーIDやプロダクトIDはブロックデバイス(/dev/sdb)の親デバイス(USBバスのエントリ)が持っています。親デバイスの属性まで調べたい場合は -a オプションを使います。

# 親デバイスの属性まで再帰的に表示する udevadm info -a -n /dev/sdb | head -60

looking at device '/devices/.../block/sdb': KERNEL=="sdb" SUBSYSTEM=="block" looking at parent device '/devices/.../target3:0:0/3:0:0:0': KERNELS=="3:0:0:0" SUBSYSTEMS=="scsi" ATTRS{vendor}=="BUFFALO " ATTRS{model}=="Portable_HDD" ATTRS{serial}=="XXXXXXXX" looking at parent device '/devices/.../usb1/1-2': KERNELS=="1-2" SUBSYSTEMS=="usb" ATTRS{idVendor}=="0411" ATTRS{idProduct}=="01ce" ATTRS{serial}=="XXXXXXXX"

-aオプションの出力では、同一ルールの中で参照できる属性は同じ「looking at parent」ブロック内のものに限られます。異なる階層の属性を同一ルールで組み合わせることはできません。

デバイス名を固定するルールを作成・適用する

1. シリアル番号でデバイスを特定するルールを書く

udevadm infoで確認したID_SERIALを使って、このデバイスを/dev/backup-diskとして参照できるシンボリックリンクを作成します。

# /etc/udev/rules.d/99-backup-disk.rules を作成する # BUFFALO Portable HDD(シリアル: XXXXXXXX)を /dev/backup-disk として固定する SUBSYSTEM=="block", ENV{ID_SERIAL}=="BUFFALO_Portable_HDD_XXXXXXXX", SYMLINK+="backup-disk", GROUP="disk", MODE="0660"

SYMLINKは既存の/dev/sdbを置き換えるのではなく、追加のシンボリックリンクを作ります。スクリプトは/dev/backup-diskを参照すれば、デバイス名が変わっても影響を受けません(mountコマンドでのファイルシステムマウントも同じシンボリックリンクをデバイスとして指定できます)。

2. ルールを反映して動作確認する

# ルールを再読み込みする udevadm control --reload-rules # 現在接続済みのデバイスに対してルールを再評価する udevadm trigger --subsystem-match=block # シンボリックリンクが作成されたか確認する ls -la /dev/backup-disk

lrwxrwxrwx 1 root root 3 Sep 10 12:34 /dev/backup-disk -> sdb

/dev/backup-diskが/dev/sdbを指すシンボリックリンクとして作成されていれば成功です。

デバイス接続時にスクリプトを自動実行する

1. 接続イベントでスクリプトをRUN+=で起動する

デバイスが接続(add)された時にスクリプトを実行したい場合はACTIONとRUN+=を組み合わせます。

# /etc/udev/rules.d/99-backup-disk.rules SUBSYSTEM=="block", ACTION=="add", ENV{ID_SERIAL}=="BUFFALO_Portable_HDD_XXXXXXXX", SYMLINK+="backup-disk", GROUP="disk", MODE="0660", RUN+="/usr/local/bin/usb-backup.sh"

2. 長時間処理はsystemd oneshotサービス経由にする

重要な注意点:udevdはRUN+=に指定したスクリプトを同期的に実行します。スクリプトが長時間かかるとudevdがブロックされ、その間に発生した他のデバイスイベントが遅延します。rsyncのように時間のかかる処理はudev rulesから直接呼ぶのではなく、systemdのoneshot型サービス経由で実行するのが正しい設計です。

udev rulesからsystemctlを呼ぶ方法:

# udev rulesでsystemdサービスを起動する SUBSYSTEM=="block", ACTION=="add", ENV{ID_SERIAL}=="BUFFALO_Portable_HDD_XXXXXXXX", SYMLINK+="backup-disk", RUN+="/usr/bin/systemctl start usb-rsync-backup.service"

/etc/systemd/system/usb-rsync-backup.service:

[Unit] Description=USB Backup via rsync [Service] Type=oneshot ExecStart=/usr/local/bin/usb-backup.sh StandardOutput=journal StandardError=journal

udevルールのデバッグとトラブルシュート

1. udevadm test でルールをシミュレーションする

rulesを書いたがSYMLINKが作られない、スクリプトが実行されないといったケースでは、まずudevadm testでシミュレーションを実行します。デバイスファイルには/dev/sdbではなく/sys/のデバイスパスを指定します。

# /dev/sdb のデバイスパスを確認する udevadm info --query=path --name=/dev/sdb # 出力例: /devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.0/host3/target3:0:0/3:0:0:0/block/sdb # シミュレーションを実行する(実際のデバイスファイルは変更しない) udevadm test /devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.0/host3/target3:0:0/3:0:0:0/block/sdb

calling: test ... Reading rules file: /etc/udev/rules.d/99-backup-disk.rules ... LINK 'backup-disk' /etc/udev/rules.d/99-backup-disk.rules:2 ... creating symlink '/dev/backup-disk' to 'sdb' ... run: '/usr/local/bin/usb-backup.sh'

「LINK 'backup-disk'」や「run:」の行が出ていれば、ルールが正しく評価されています。何も出ない場合は条件式のマッチが失敗しています。

2. udevadm monitor でイベントをリアルタイム確認する

デバイスを抜き挿しした際のイベントをリアルタイムで確認できます。

# 別ターミナルで実行しておく udevadm monitor --udev --subsystem-match=block

USBドライブを接続すると以下のように出力されます:

UDEV [12345.678901] add /devices/.../block/sdb (block) UDEV [12345.679012] add /devices/.../block/sdb/sdb1 (block)

3. よくあるエラーと対処

SYMLINKが作られない:マッチ条件が正しくない。udevadm testで評価されているルール行を確認し、属性名・値のスペルを検証する
スクリプトが実行されない:スクリプトに実行権限がない(chmod +x /usr/local/bin/usb-backup.shを実行)か、フルパスで指定していない
スクリプトは動くが/dev/backup-diskがない:ACTIONとSYMLINKを別々のルール行に書いた場合、SYMLINKを設定する行にはACTION条件を含めないか、別行に分けて書く
変更が反映されないudevadm control --reload-rulesの実行を忘れている

udevdのログはjournalctlで確認できます。

# udevdのログを直近50行確認する journalctl -u systemd-udevd -n 50

まとめ

udev rulesを活用することで、デバイス名の変動に依存しない堅牢なスクリプト設計が実現できます。
やりたいこと コマンド・設定
デバイスの属性を確認する udevadm info --query=all --name=/dev/sdb
親デバイスの属性まで確認する udevadm info -a -n /dev/sdb
デバイス名(シンボリックリンク)を固定する SYMLINK+="名前" を /etc/udev/rules.d/に記述
ルールを反映する udevadm control --reload-rules && udevadm trigger
ルールをシミュレーションする udevadm test /sys/のデバイスパス
デバイスイベントをリアルタイム確認する udevadm monitor --udev --subsystem-match=block
デバイス接続時にスクリプトを実行する ACTION=="add", RUN+="スクリプトのフルパス"
udevdのログを確認する journalctl -u systemd-udevd -n 50
デバイス名固定の基本はSYMLINKで固定した論理名(/dev/backup-disk等)をスクリプトから参照する設計です。RUN+=でスクリプトを呼ぶ場合は、長時間処理はsystemdのoneshot経由にしてudevdをブロックしないよう注意してください。

デバイス管理からサービス設計まで、Linuxの実務スキルを体系的に学ぶ

udev rulesやsystemdのサービス設計は、Linuxサーバーを現場で安定運用するための知識の一部です。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、20年以上の現場経験を持つ現役エンジニアが2日間ハンズオンで直接指導します。3,100名以上の受講者が現場で活用しているスキルを最短で習得できます。

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。