4
2

More than 3 years have passed since last update.

mruby 上で動作する GEOM Gate ローカルプロバイダ

Last updated at Posted at 2019-12-15

FreeBSD アドベントカレンダー初参加です。

FreeBSD には GEOM という仕組みがありますが、みなさんは ggatel って使っていますか?
僕は最初、mdconfig があるからいらないでしょ?
って思ってました。

でも詳しく調べてみると、ユーザ空間でいろいろと出来そうだと認識を改めました。

この文書で取り上げるのは、mruby 上で動作する Ruby スクリプトによって構築された、GEOM Gate ローカルプロバイダのお話となります。

僕が五年前に作ったまま放置している CRuby 向け gem の二番煎じのようなものです。
匿名巨大掲示板の某スレにあった最近の書き込みをネタにしました。

なおこの mruby で GEOM Gate ローカルプロバイダを提供するソフトウェアは、https://github.com/dearblue/mruby-bin-suzuna として公開しています。

ビルド

ビルド環境を整える

まず最初に、mruby をビルドする環境づくりからです。

  • mruby のビルドに最低限必要なパッケージ:
    ruby git bison
  • mruby-bin-suzuna のサンプルをビルドするために必要なパッケージ:
    sqlite3 oniguruma

pkg でさくっとインストール。

% sudo pkg install ruby git bison sqlite3 oniguruma

mruby と mruby-bin-suzuna のソースコードの取得と展開

最初にソースコードの展開やバイナリ実行が可能なディレクトリへ移動して下さい。

そうしたらソースコードの取得と展開を行います。

% mkdir -p ~/sandbox
% cd ~/sandbox
% fetch -o- https://github.com/mruby/mruby/archive/2.1.0.tar.gz | tar xf -
% fetch -o- https://github.com/dearblue/mruby-bin-suzuna/archive/master.tar.gz | tar xf -

もし mruby の最新版が欲しいのであれば、"https://github.com/mruby/mruby/archive/master.tar.gz" に置き換えて下さい。

suzuna のビルド

ビルドは mruby ディレクトリの中で行なうのが無難でしょう。

% cd mruby-2.1.0
% ruby minirake -j8 MRUBY_CONFIG=../mruby-bin-suzuna-master/quick_config.rb

これで bin/suzuna (あるいは build/suzuna/bin/suzuna) ファイルが出来ます。
mruby でワンライナーを使ったり、Ruby スクリプトを単純に実行させたりしたいなれば bin/mruby (あるいは build/suzuna/bin/mruby) を試して下さい。

mruby 上で動作する GEOM Gate ローカルプロバイダ

200 MiB のブロックデバイスとして動作させるサンプルスクリプトを mruby-bin-suzuna/sample.rb として用意してあります。
このファイルを bin/suzuna に渡すと、/dev/ggateXX が生えます。

スーパーユーザーで動作させる必要があります。

% sudo ./bin/suzuna -u99 ../mruby-bin-suzuna-master/sample.rb

これで mruby 上で動作する GEOM Gate ローカルプロバイダは /dev/ggate99 でアクセス出来ます。

% sudo newfs /dev/ggate99
% sudo mkdir /media/ggtest
% sudo mount /dev/ggate99 /media/ggtest

終了したい場合、別の仮想端末から ggatel destory を行って下さい。

% sudo umount /media ggtest
% sudo ggatel -u99

Ctrl+C でも終了できますが、ggate99 は残ったままになります。修正は今後の課題。

バグ×バグ?=カーネルパニック

zpool create する場合、zpool の作成途中で suzuna がセグフォると zpool がフリーズします。
一度目の ggatel -fu99 を行うと、zpool create はエラーを出力してプロンプトに戻ってきます。
再度 suzuna -u99 .... のあとに zpool create で同じプール名の作成途中で suzuna がセグフォった場合、ggatel -fu99 するとカーネルパニックします。

簡単な GEOM Gate ローカルプロバイダスクリプト

mruby-bin-suzuna/sample.rb の再掲となりますが、冗長なコメントを抜くと短く…………う〜ん、まあ40行くらいなので、充分短いでしょう。
200 MiB の容量を持つ揮発性ボリュームはこんな感じで組むことが出来ます。

sample.rb
mystorage = Object.new

mystorage.instance_eval do
  @buf = StringIO.new("\0" * (200 * 1024 * 1024))
end

class << mystorage
  def mediasize
    @buf.size
  end

  def flags
    Suzuna::FLAG_READWRITE
  end

  def sectorsize
    512
  end

  def info
    "Powered by #{MRUBY_DESCRIPTION}"
  end

  def readat(offset, size, buf)
    @buf.seek offset
    @buf.read(size, buf)
    nil
  end

  def writeat(offset, buf)
    @buf.seek offset
    @buf.write(buf)
    nil
  end

  def deleteat(offset, size)
    nil
  end
end

Suzuna.unit(mystorage)
4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2