ソースコード・リテラシーのススメ

第22回 ソースコード・リテラシー【実践編】

この記事を読むのに必要な時間:およそ 6.5 分

本連載は「ソースコード・リテラシー」と称しつつ,サイズや規模の関係からCのソースコードそのものを取りあげる機会があまりありませんでした。最近,Plamo-4.51の準備をしている最中に,わりと面白い(?)事例に遭遇したので,ソースコード・リテラシーの実践編として紹介してみようと思います。

今回紹介するのはpmountというコマンドをパッケージ化する際に遭遇したトラブルです。実のところトラブルの原因はこのソフトウェアとは違うところにあったのですが,そこに辿りつくまでの過程はトラブル解決の実例として面白いと思い,ここに紹介する次第です。

pmountとは?

伝統的なUNIXの考え方では,ファイルシステムの構成を変更するmountコマンドはrootユーザの権限で実行すべきコマンドで,一般ユーザからは利用できないようになっています。

mountコマンド自体は一般ユーザでも実行できますが,現在のファイルシステムの構成状況が表示されるだけで,変更することはできません。

UNIXのこの考え方は,ファイルシステムを構成するデバイスがHDDしか無かった時代の産物で,CD-ROMやフロッピーディスクのような,一般ユーザの権限でも読み書きしたいメディアをうまく扱うことができません。そのため,伝統的なUNIX/Linuxの世界では,/etc/fstab のマウントオプションフィールドにuserを指定したデバイスは,一般ユーザの権限でもマウントできるように機能を拡張しています。

たとえば,筆者がメンテナンスしているPlamo Linuxでは,/dev/cdromは一般ユーザでもマウントできるように,/etc/fstabに以下のような設定を追加しています。4つめの欄がマウントオプションフィールドで,このデバイスをマウントする際には,ここで指定したオプションが適用されます。

/dev/cdrom       /cdrom   iso9660   user,ro,noauto,exec,iocharset=euc-jp 0   0

CD-ROMやフロッピーディスクのように,使用するデバイスファイル(上記の例では/dev/cdrom)が決まっているデバイスならば /etc/fstab の設定で対応可能ですが,USBメモリやコンパクトフラッシュのように,活線挿抜が可能で,接続する度に対応するデバイスファイルが変化するデバイスでは,あらかじめデバイスファイルを登録しておくことができません。

Linuxカーネルでは,USBメモリ等の記憶デバイスはSCSI HDDと認識され,すでに接続されているデバイスファイルと競合しないように/dev/sdb*や/dev/sdc*が自動的に割りあてられます。割り当てられるデバイスファイルは使用状況によって変化するため,事前に/etc/fstabに設定することは困難です。

pmount(policy mount)コマンドはこのような問題を解決するためにDebian方面で開発されたコマンドで,USBメモリ等の活線挿抜可能なデバイスに限定して,一般ユーザでもマウントコマンドを実行できるようにするものです。pmountはmountコマンドのラッパーとして働き,マウントしようとしているデバイスやマウントポイントをチェックした上で,mountコマンドを実行するような作りになっています。

トラブル発生

pmountは現在も開発が続いており,最新のソースコードはgit経由で入手できました。入手したソースコードを見ると,configureスクリプトこそありませんでしたが,configureスクリプトを生成するためのautogen.shが用意されていたので,autogen.shを実行してconfigureを生成し,とくに問題なくコンパイルできました。

ところが手元にあったUSBメディアプレイヤーを挿してテストしてみると,正しく動作してくれません。

% ./work/usr/bin/pmount /dev/sda1
Error: device /dev/sda1 is not removable

直接mountコマンドを使えば問題なくマウントできます。

# mount /dev/sdb1 /media
# df
Filesystem           1K-ブロック    使用   使用可 使用% マウント位置
/dev/hda3             19236340  16601960   1657228  91% /
none                   1037060       168   1036892   1% /dev
....
/dev/sdb1               942864    885448     57416  94% /media

しばらくドキュメントを調べたり,システムのログファイルを眺めたりしましたが,カーネルレベルでのデバイスの認識などには異常なく,どうもpmount自身の問題のようです。

pmountのヘルプメッセージを見ると,-dというデバッグ出力用のオプションが用意されているので,試してみました。

% ./work/usr/bin/pmount -d /dev/sdb1
resolved /dev/sdb1 to device /dev/sdb1
Checking for device '/dev/sdb1' in '/etc/fstab'
 -> not foundmount point to be used: /media/sdb1
no iocharset given, current locale encoding is EUC-JP
Cleaning lock directory /var/lock/pmount_dev_sdb1
Checking for device '/dev/sdb1' in '/etc/mtab'
 -> not foundChecking for device '/dev/sdb1' in '/proc/mounts'
 -> not founddevice_whitelist: checking /etc/pmount.allow...
device_whitlisted(): nothing matched, returning 0
find_sysfs_device: looking for sysfs directory for device 8:17
find_sysfs_device: checking whether /dev/sdb1 is on /sys/block/ram0 (1:0)
find_sysfs_device: checking whether /dev/sdb1 is on /sys/block/ram1 (1:1)
...
find_sysfs_device: checking whether /dev/sdb1 is on /sys/block/sda (8:0)
find_sysfs_device: major device numbers match
find_sysfs_device: minor device numbers do not match, checking partitions...
find_sysfs_device: checking whether device /dev/sdb1 matches partition 8:0
...
find_sysfs_device: checking whether device /dev/sdb1 matches partition 8:17
find_sysfs_device: -> partition matches, belongs to block device /sys/block/sdb
device_removable: could not find a sysfs device for /dev/sdb1
Error: device /dev/sdb1 is not removable
policy check failed

-dオプションを指定するとずいぶん詳細なデバッグメッセージを出してくれました。このメッセージを見る限り,新しく装着したUSBメディアプレイヤーをsysfs経由で認識するところまではうまく行っているようですが,最後のリムーバブルメディアか否かの判断でエラーになっているようです。

pmount がどうやってリムーバブルメディアか否かを判断しているかは,ソースコードを見てみる方がよさそうです。

著者プロフィール

こじまみつひろ

Plamo Linuxとりまとめ役。もともとは人類学的にハッカー文化を研究しようとしていたのが,いつの間にかミイラ取りがミイラになってOSSを仕事にするようになってしまいました。最近はスペシャリスト養成を目的とした専門職大学院で教壇に立ったりもしています。

URLhttp://www.linet.gr.jp/~kojima/Plamo/index.html

コメント

  • 指定するデバイスと方法が違うだけでは?

    > % ./work/usr/bin/pmount /dev/sda1
    > Error: device /dev/sda1 is not removable
    >
    > 直接mountコマンドを使えば問題なくマウントできます。
    >
    > # mount /dev/sdb1 /media
    > # df
    > Filesystem 1K-ブロック 使用 使用可 使用% マウント位置
    > /dev/hda3 19236340 16601960 1657228 91% /
    > none 1037060 168 1036892 1% /dev
    > ....
    > /dev/sdb1 942864 885448 57416 94% /media

    /dev/sdb1 がターゲットのデバイスのようですので,

    > % ./work/usr/bin/pmount /dev/sda1

    は論外として,結論として

    % ./work/usr/bin/pmount sdb1

    ではないでしょうか(pmount の引数には /dev は含めない).
    外していたら済みません.

    Commented : #1  齋藤 康之 (2011/04/29, 19:07)

コメントの記入