あっきぃ日誌

鉄道ブログのような技術系ブログのようななにか

CD-ROMドライブのパスをudevで固定する

Ejectコマンドユーザー会って、一見くだらないけれど、課題をクリアするにあたってはわりとLinuxの知識を要求されますね。というわけで、長年気にしてはいたけれど無視してきた、CD-ROMドライブのパスをudevで固定する件について調べました。
つか、Ejectの薄い本向けの検証結果なんだからそっちに書いて、ブログ掲載を後にしろよと思ったけれど、まあいいっか。

固定しないと何がまずいのか

OSCでEjectの展示をするときは、2台同時に稼働させることが多いです。それぞれUSBで接続すると、さした順にsr0, sr1と認識します。Web用のPHPスクリプトもこの挿したた順にあわせて「鉄道模型のEject」「AC100VのEject」みたいなボタンを用意しますが、たまにUSBを抜いた拍子に順番が入れ替わってしまったりしてしまいます。そのたびにスクリプトを書きなおすのも面倒ですし、本番環境でEject用ドライブと読み書きに使用するドライブで入れ替わりが発生するとセキュリティ的にも良くありません。

udev概要(てきとう)

そこでudevの登場。udevは、新たなデバイスが挿された時に、ベンダーIDやプロダクトIDなどなどのパラメータを元に、デバイス名を設定したり、オーナー・グループの設定をしたり、パーミッションの設定をしてくれるみたいな仕組みです。たぶん。
/etc/udev/rules.dの中に色々なルールファイルがあって、普段使うsdaだのsr0だのeth0だのの名前付けはこのへんで設定されているようです。

いざ設定

Eject用CD-ROMドライブのUSBケーブルが挿されたら、/dev/eject_airconというデバイス名で、オーナーはapacheになるように設定したいと思います。
まずはudevinfoコマンドで、今つないでいるEject用CD-ROMドライブの情報を引っ張り出します。

# udevinfo -a -p /sys/block/sr0

なんかたくさんずらずら出てきますが、必要なのはEject用CD-ROMドライブに使用しているIDE-USB変換の情報です。実際にルールに書く条件はベンダーIDとプロダクトIDとシリアルくらいでよさそうです。

(略)
  looking at parent device '/devices/pci0000:00/0000:00:1d.7/usb1/1-1/1-1.2':
    ID=="1-1.2"
    BUS=="usb"
    DRIVER=="usb"
    SYSFS{configuration}=="USB Mass Storage"
    SYSFS{serial}=="222222222222"
    SYSFS{product}=="USB to ATA/ATAPI Bridge"

(略)
    SYSFS{idProduct}=="2338"
    SYSFS{idVendor}=="152d"
(略)

そして、udevのルールを書きます。/etc/udev/rules.d/970eject.rulesとかいうァイルをでっち上げて、以下のように書き込みました。

# CD-ROM drive for aircon remote
BUS=="usb", ACTION=="add", SYSFS{idProduct}=="2338", SYSFS{idVendor}=="152d", SYSFS{serial}=="222222222222", SYMLINK="eject_aircon", OWNER="apache", GROUP="apache", MODE="0666"

条件と設定の違いは、==でつないでいるのが条件で、=でつないでいるのが設定です(参考ページ1参照)。つまり、条件は

BUS=="usb", ACTION=="add", SYSFS{idProduct}=="2338", SYSFS{idVendor}=="152d", SYSFS{serial}=="222222222222"

で、設定は

SYMLINK="eject_aircon", OWNER="apache", GROUP="apache", MODE="0666"

となります。これを1行でズバッと書きます。
書き終わったら保存して、Eject用CD-ROMドライブのUSBを挿し直します。
そしてlsコマンドで確認。SYMLINKという設定で察しがつくと思いますが、eject_airconがsr0というデバイスのシンボリックリンクとして作成されています。また、sr0はオーナー・グループがapacheパーミッションが666と設定通りになっています。

# ls -l /dev/eject_aircon 
lrwxrwxrwx 1 root root 3  8月  4 02:56 /dev/eject_aircon -> sr0
# ls -l /dev/sr0
brw-rw-rw- 1 apache apache 11, 0  8月  4 02:56 /dev/sr0 

シンボリックリンクではなく、直接sr0をeject_airconにしてしまうこともできるのですが、この場合はオーナー・グループとパーミッションの設定がうまくいきません。おそらく、参考ページ2の「ユーザ指定ルールが初期設定を上書きする仕様」に当たるものと思われます。

まとめなど

udevは今まで食わず嫌いしていたのですが、意外と簡単でした。また、EjectのためにCD-ROMドライブをapacheユーザーが使えるようにセキュリティを緩める的な設定もあれこれ試してきましたが、この方法が一番スマートに感じました。次回からはこの方法で紹介しよう。
udevinfoで、IDE-USB変換の先にあるCD-ROMドライブの情報も拾えているようなので、IDE-USB変換ケーブルをたまに他のデバイスで使用したい人はこちらを指定しても良いのかもしれません。いや、むしろ試すべきか。ちなみにこんな感じ。

  looking at parent device '/devices/pci0000:00/0000:00:1d.7/usb1/1-1/1-1.2/1-1.2:1.0/host18/target18:0:0/18:0:0:0':
    ID=="18:0:0:0"
    BUS=="scsi"
    DRIVER=="sr"
(略)
    SYSFS{rev}=="2.00"
    SYSFS{model}=="CD-ROM GCR-8486B"
    SYSFS{vendor}=="HL-DT-ST"
(略)