suzuna (スズナ)

The suzuna is a ruby library that provides an infrastructure for virtualized block devices.

"suzuna" is means "Turnip" in japanese.


(in Japanese)

suzuna は ruby 拡張ライブラリで、仮想ブロックデバイス基盤を提供します。

名称は春の七種の一つである『スズナ』から取りました。


LIBRARY

require "suzuna"

SYNOPSIS

module Suzuna

module Suzuna::Template

Suzuna.join(unit_object)

DESCRIPTION

suzuna は ruby で GEOM Gate を用いて GEOM クラスを書くためのライブラリです。

module Suzuna は、suzuna の名前空間として使われるモジュールです。

module Suzuna::Template は、I/O 要求処理を担当するクラスに include することを想定したモジュールです (必ず必要なモジュールではありません)。このモジュールには、I/O 要求処理に必要となるインスタンスメソッドが予め定義してあります。ただし raise NotImplementedError を発生させるだけのメソッドがあるので、このようなメソッドは利用者側で実装する必要があります。このあたりは EXAMPLE が参考になると思います。

Suzuna.join(unit_object) は、I/O 要求処理オブジェクトを与えて実際に GEOM Gate オブジェクトを作成するためのメソッドです。このメソッドはスレッドを停止させます。現在の実装では、このメソッドから返ってくる場面は例外が発生した時のみとなります。

EXAMPLE

以下は FreeBSD 上でローカルな GEOM Gate (ggate) を用いた、ruby による仮想ブロックデバイスプログラミングです。

#!ruby

require "stringio"
require "fattr"
require "suzuna"

class MyUnit
  include Suzuna::Template

  fattr(:mediasize) { @pool.size }
  fattr sectorsize: 512,
        timeout: 30,
        flags: 0 # or Suzuna::G_GATE_FLAG_READONLY

  def initialize
    @pool = File.open("testsuzuna.img", File::BINARY | File::RDWR | File::CREAT)
    @pool.truncate(80.MiB) unless @pool.size >= 80.MiB
  end

  def cleanup
    @pool.flush rescue nil
    @pool.close rescue nil
  end

  def read(offset, size, buf)
    puts "#{File.basename caller(0, 1)[0]}: offset=#{offset}, size=#{size}"
    @pool.pos = offset
    @pool.read(size, buf)
    buf.resize(size)
    nil
  end

  def write(offset, buf)
    puts "#{File.basename caller(0, 1)[0]}: offset=#{offset}, size=#{buf.bytesize}"
    @pool.pos = offset
    @pool.write(buf)
    nil
  end

  def delete(offset, size)
    puts "#{File.basename caller(0, 1)[0]}: offset=#{offset}, size=#{size}"
    nil
  end
end

Suzuna.join(MyUnit.new)

これを管理者権限で実行すると /dev/ggate0 が作成されて、/dev/ada0/dev/da0 などと同様の扱いをすることが出来ます。

停止させる場合は、Ctrl+C をするか、他の(擬似)端末から $ sudo ggate -du0 と入力します。

環境によっては /usr/local/lib/ruby/gems/2.1/gems/suzuna-0.0.1-freebsd/lib/suzuna.rb:in `initialize': No such file or directory @ rb_sysopen - /dev/ggctl (Errno::ENOENT) などと例外が出るかもしれません。この場合はカーネルに geom_gate.ko を読み込ませてから試して下さい。

$ sudo kldload geom_gate

DEMERIT

  • geom gate + ruby のため、実行性能はカーネルに置かれた geom オブジェクトよりもかなり劣ります。

    個人・研究用途としては十分かもしれませんが、大規模な用途には向かないでしょう。

  • geom gate ネットワークデーモンとしての機能は持っていません。

    ggated を組み合わせて利用できるかもしれません (試していません)。

  • 現在の実装は、マルチスレッド化されていません。

    I/O 要求の処理は単体のスレッドのみで行われます。

SEE ALSO