最近はストレージとは関係のないことをしていますが、 一応dm-devel(DMのメーリングリスト)はたまに見ていて、 すると興味を引く投稿がありました。
dm: dm-user: New target that proxies BIOs to userspace
と題したその投稿では、dm-userという新しいDM Targetが提案されています。 ではこれが何をするものかというと、DM層が受け取ったbioをそのままユーザランドにプロキシするということです。 実装としてはFUSEと似たようなものだと思います。
おれがこの投稿を見た時に何を思ったかというと、「これはおれが欲しかったやつだ!!!」です。
Rustという素晴らしい言語に出会った時、2014年の段階で、 これがシステムプログラミングの将来を担う言語だという確信があったわけで、 性能に関してそこまでシビアではない仮想ブロックデバイスについては、 Rustで開発出来れば、 すごく助かると思ったのです。
FUSEバインディングはどの言語にもあり、とりわけRustには良い実装が存在します (Rustコミュニティのライブラリは洗練されている割合が高いです) が、ブロックデバイス向けには存在しません。 なぜかというと、FUSEのようにカーネル側にこれだという口がないからです。
一時期、dm-userと同じ発想で、 DM Targetを実装しようかと思ったことはあるのですが、 よくよく考えていると、結構めんどくさい上にただやるだけの退屈な作業なのでやめました。 投稿主はGAFAでAndroidの開発をしているそうで、それに必要なので作ったものを アップストリームに還流するという経緯のようです。
やりとりを読んで見るとdm-userは結構劣勢で、このままでは拒絶されそうです。 カーネルとユーザランドの間でコピーが発生するから遅いとか、 NBDと何が違うんだというのが主な理由です。 性能については、性能がそれほど大事でないものやプロトタイプなどに使えばよいし、 運用を考えるとNBDより優れているという意見をおれは持っています。
今、おもむろにNBDといいましたが、一応、ユーザランドで仮想ブロックデバイスを作る方法はあります。 NBDプロトコルを使って、IOリクエストを送信して、その中で仮想ブロックデバイスを実装出来るようにすればよいのです。 他にもiscsiでも何でもやりよう自体はあります。 この方式はCではBUSEという実装がありますが、実装が全く持って洗練されておらず、改善される様子もありません。 というかたぶん、未確認ではありますが、ハンドシェイクの実装が古くて今のNBDクライアントとは通信出来ないのではないかと思います。
「というわけで」おれが作ることにしました。 ramdiskのようなものを実装し、そこにbadblocksでテストするというところまでは動いたので公開しました。 名前は悩んだのですが、おれは「ユーザランド」という言葉の響きが好きで、フルで入れることにしました。 ユーザランドというのはカーネルガイがアプリ野郎をバカにして使う言葉なんですけどね。
万が一、dm-userがドロップしてしまった場合でも、 最低でもNBDを使って仮想ブロックデバイスを作れることになりますし、 dm-userがアップストリームに入ればこのライブラリでdm-userを使う実装も提供しますから、 潜在的なユーザとして立候補することで、dm-userをアップストリームに入れるための後押しには多少なりともなれます。 そういうモチベーションで、一気に作りました。
やはりRustはいいですね。 コンパイルが通るならばほぼ動くという状態を作りやすいです。 このソフトウェアは、上で書いたbadblocksのテストが動かせるようになるまで コンパイラだけを頼りに一気に書き上げて、テストを一発でパスしました。 簡単な実装ということは差し置いても、Rustの力はすごすぎます。 Rubyとは違います。