カーネル/VM Advent Calendar 16日目: USB/IPで遊んでみる

USB/IPはご存知ですか?

その名の通り、USBデバイスをIPネットワーク上で共有しようというプロジェクトです。 このプロジェクトはLinux 2.6.38でカーネルにマージされていて、遊んでみようと思いながらなかなか機会がなかったので、今回のネタにすることにしました。

1. USB/IPについて

USB/IPはもともとNAISTの研究がもとになって作られました。下のページに詳しい論文が掲載されています。

http://kawai.naist.jp/~eiji-ka/publications/remote-dev-j.html

仕組みとしては以下のようになっています。

A. クライアントがUSBデバイスにリクエストを投げる

B. クライアント側のVHCIドライバがホストコントローラーをエミュレーションして、リクエストを受け取る

C. VHCIドライバがリクエストをカプセル化してサーバーに送信する

D. サーバー側のスタブドライバがリクエストを受け取り、実際のデバイスにリクエストを投げる

E. スタブドライバがリクエストの結果をクライアント側に返す

 このVHCIドライバやStubドライバというのはすでにカーネルのstagingに入っています。また、VHCIドライバはWindows向けの実装も進んでいます。

2. サーバー側を準備する

サーバー側(デバイスを提供する側)は現在Linuxしか対応していません。なので、試して見る際はLinuxを用意しましょう。

まず、カーネルコンフィグで”USB/IP support”とその下にある”Host driver”を有効にしてカーネルをビルドしましょう。モジュールにしたならusbip-core.koとusbip-host.koをinsmodしておいてください。

つぎに、ユーザーランドのツールをビルドしましょう。これは上の図の”Device Control Manager”にあたるものです。カーネルのソースのdrivers/staging/usbip/userspaceにソースがおいてあるので、READMEを読みながらビルドしてください。

そして、デバイスマネージャとなるusbipdを起動しましょう。

# usbipd

それからbind_driverコマンドで共有するデバイスを設定してやります。

# bind_driver --list

で、USBデバイスとbusidの一覧がでてくるので、以下のようにしてデバイスを指定します。

# bind_driver --usbip <選択したデバイスのbusid>

3. クライアント側を準備する ーWindows編ー

クライアント側はWindowsも対応しているので、はじめにWindowsで試してみたいと思います。

まず、ここからWindows用のバイナリをダウンロードしてきて、展開します。

そして、デバイスマネージャーを開き、「操作」の「レガシハードウェアの追加」をクリックします。ヴィザードがはじまるので、「次へ」を押して、「一覧から選択したハードウェアをインストールする」を選択します。

ここで、「すべてのデバイスを表示」を選択したまま「次へ」進み、「ディスク使用」のボタンを押して、さきほど展開したディレクトリを選択します。

上のような画面になったら「次へ」を押してインストールを開始させます。 インストールが終われば準備は完了したので、実際に試しましょう。

コマンドプロンプトでさきほど展開したディレクトリに行って、以下のように実行します。

> usbip -l <サーバーのIPアドレス>

すると、サーバー側で共有しているデバイスのリストが出るはずです。

> usbip -a <サーバーのIPアドレス> <デバイスのbusid>

というふうにすると、ちゃんとデバイスが共有されます。

3. クライアント側を準備する ーLinux編ー

まず、カーネルコンフィグで”USB/IP support”とその下にある”VHCI hcd”を有効にしてカーネルをビルドしましょう。モジュールにしたならusbip-core.koとvhci-hcd.koをinsmodしておいてください。それから、先程と同じようにユーザーランドのツールをビルドしましょう。

これで使えるはずです。あと、3240番ポートをSSHポートフォワーディングしたりしても使えます。

# ほんとはscpとUSB/IP over SSHとかでスピードの差とか測ってみたかったんですが
# リモートの仮想マシンでのカーネルビルドが3時間かかっても終わらなかったので
# こんどちゃんと測って結果書きます

 

4. 感想など

すごく面白いです。

手前のノートパソコンにつないだマウスが奥のWindowsでうごいているっていうのはとっても奇妙で楽しかったです。

802.11nでマウスを使用しても気になる程度のタイムラグなどはなかったので、同じLAN内で使うには十分じゃないでしょうか?