monolithic kernel

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

July 16, 2012

    作ってみましょう。これができるとゲスト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