2013年11月13日水曜日

libudev による USB デバイスのモニタリング

libudev により USB に接続されているデバイスをモニターする例題です。
※ テスト環境 Linux picuntu 3.0.8+:ディストリビューションによる動作の差異はあるかもしれませんが、Ubuntu 系なら問題なく動作するかと思います。

Linux では udevd というデーモンが起動しており、/etc/udev/rules.d/ 内に記述された udev ルールに応じて、USB に接続されたデバイス毎のプロセス起動やマウント等の処理を行うことができます。

USB メモリを挿入した際に実行する処理の記述例: 一方、挿入された際の処理(ACTION=add)に対して抜かれた際の処理に関しては(ACTION=remove)、デバイスの情報が取得できず処理が実行されない可能性があります(デバイスノードからデバイスディスクリプタが取得されないのが原因かと思われる)。

そこで、挿入された際のイベントに対して起動するプロセスに対して、終了する際のイベントに関してはデバイスが抜かれた際のデバイスへのノード(/dev/usbdev2.4 etc..)を調べ、挿された際のノードと一致するかによって目的のデバイスが抜かれたかを監視する方が無難な監視方法になるかとは思います。

以下の例題では、アプリ起動時に接続されているデバイスの一覧を表示し、目的のデバイスが挿入されているかを監視しています。
目的のデバイスが挿入された際に記憶しておいたノードの情報により、デバイスが抜かれたことを検知し、デバイスが挿入されていない状態になればアプリを終了しています。

この例題をそのままアプリ化して udev ルールから実行してデバイスが抜かれた際に終了するようにしても、上手く終了されない可能性があります(exit コマンドを行ってもアプリが終了しない)。
※ 原因はよく分からないのですが、デーモン用のプロセスとして実行しないと挿入されている間は常時プロセスが起動するような形で再実行されているのかもしれません。
その場合、start-stop-daemon コマンドを利用して下記のようなシェルスクリプトにて実行するようにすれば上手くアプリを終了させることができます。
パスやユーザーを適当に編集した上、udev ルールに下記スクリプトへのパスを設定した後に udevd をリスタートしてください。
※ [/path/udevMonitor.sh start] を RUN+= に追加
start-stop-daemon はアプリをデーモン化するためのコマンドですが、インストールされていない場合にはソースが配布されていますので、そちらをコンパイルしてインストールすることもできます。
start-stop-daemon

udevMonitor.sh コンパイルには libudev を利用しますが、インストールされていない場合には apt-get から libudev-dev をインストールしてください。 実行結果

0 件のコメント:

コメントを投稿