monoの開発ブログ

tapdiskドライバを作ってみよう

作ってみましょう。これができるとゲストOSのIOをユーザ空間の比較的わかりやすいコードで自由自在に操ることができるようになります。

tools/blktap2/README に基本的な手順は書いてありますが、かなり古くていろいろ食い違っているのでそれのメモです。ドキュメントと同じような流れで作っていきます。私はxen-4.1.2で試しましたがxen-unstable.hgもそんなに変わっていなさそうなのでなんとかなるかもしれません。

1.tap_disk構造体のインスタンスを前方宣言

tools/bktap2/drivers/tapdisk-disktype.cに前方宣言を追加します。

extern struct tap_disk tapdisk_mynewdisk;

2.disktypeに未使用の番号を割り当て

tools/blktap2/drivers/tapdisk-disktype.hに番号の定義が並んでいるのでそこに追加します。このとき、DISK_TYPE_VINDEXは実装が削除されているにもかかわらずなぜか残骸だけ残っていてよくわからないので消しておきます。

/* #define DISK_TYPE_VINDEX      10 */

#define DISK_TYPE_MYNEWDISK   10

3.disk_info_t構造体のインスタンスを作成

tools/blktap2/drivers/tapdisk-disktype.cに追加します。

static const disk_info_t mynewdisk_disk = {
       "mynewdisk",
       "my new disk (mynewdisk)",
       0,
};

4.tapdisk_disk_typesに作成した構造体を追加

同じくtools/blktap2/drivers/tapdisk-disktype.cにあるtapdisk_disk_typesという配列に作成したdisk_info_t構造体のアドレスを追加します。

const disk_info_t *tapdisk_disk_types[] = {
        ...
        /* [DISK_TYPE_VINDEX]   = &vhd_index_disk, */
        ...
        [DISK_TYPE_MYNEWDISK]   = &mynewdisk_disk,
        0,
};

5.tapdisk_disk_driversにtap_diskを追加

tap_disk構造体も配列に追加しておきます。

const struct tap_disk *tapdisk_disk_drivers[] = {
        ...
        /* [DISK_TYPE_VINDEX]      = &tapdisk_vhd_index, */
        ...
        [DISK_TYPE_MYNEWDISK]   = &tapdisk_mynewdisk,
        0,
};

6.実装する

実装します。とりあえず動作確認するのであれば、tools/blktap2/drivers/block-aio.cをblock-mynewdisk.cとしてコピーし、識別子の名前を書き換えてあげるとよいでしょう。

7.Makefileに追加する

tools/blktap2/Makefileに1行追加してmake時に組み込まれるようにします。

BLK-OBJS-y  += block-mynewdisk.o

8.インストール

# cd /path/to/xen-4.1.2
# make tools
# make install-tools

9.動作確認

前回の記事を参考にしてください。

# tap-ctl create -a mynewdisk:/path/to/test.img
# tap-ctl list
# mkdir /mnt/test
# mount -t ext4 /dev/xen/blktap-2/tapdev0 /mnt/test
# ls /mnt/test