魔術師見習いのノート

プロフィール

魔術師見習い
Author魔術師見習い-_-.
Twitter魔術師見習い

コンピュータ関係のメモを主に書きます.

MENU

gmirror

投稿日:
編集日:
編集日:
タグ:

本稿はgmirrorの使い方に関するメモ.復旧と構築関連の使い方は次に使うまでの間隔が長すぎて良く忘れるので(そして調べた後にたったこれだけだったと嘆くので).ちなみにOSはfreeBSD8.2.

gmirrorとは

gmirrorとはGEOMのクラスの1つで,これによりソフトウェアraid1(ミラーリング)が可能となる.

GEOMとはデバイスドライバとカーネルの上位レイヤの間に位置するフレームワークのことである.ユーザはGEOMにクラスを追加することで新しい機能を簡単に追加することができる.参考までに以下に他のクラスの例をいくつか載せる.

  • gstripe
  • graid3
  • gjournal
  • gvinum


ソフトウェアraid1(ミラーリング)の構築

raidを組む補助記憶装置がマウントされていない必要がある.そのため,OSを書き込んだ補助記憶装置でraidを行うためには,それ以外からGEOMが使えるOSを起動するか、sysctlでkern.geom.debugflagsというパラメータを変更しなければならない.私の場合,インストールしたFreeBSDのディスクからOSをブートし,そこで処理を行った.

gmirrorでソフトウェアraid1を行う場合,大まかに次の手順で行う.

  1. GEOMのmirrorクラス(モジュール)を読み込む.
  2. 新しいミラーを作る.
  3. ミラーにコンポーネントを追加.
ミラーとはgmirrorによって仮想的に作成された補助記憶装置のことで,コンポーネントとはここでは補助記憶装置を指す.

GEOMのmirrorクラスの読み込み

GEOMのmirrorクラスを読み込む方法はさまざまある.

  • kldload
  • gmirror load
  • geom mirror load
それぞれの詳細はmanを見れば良いので省略し,ここではgmirrorを使った例だけ示す.
user% gmirror load
モジュールはkern.module_pathで設定されたパス群のいずれかから読み込まれる.パスは次のコマンドで確認できる.
user% sysctl kern.module_path
kern.module_path: /boot/kernel;/boot/modules
これらのパスの中を探すとgeomのmirrorモジュールが見つかるはずである.
ls /boot/kernel /boot/modules | grep geom_mirror
geom_mirror.ko
geom_mirror.ko.symbols

新しいミラーを作成

新しいミラーを作るための最も単純なコマンドは次の通りである.

user% gmirror label gm0 /dev/ad1
labelではさらにオプションを指定することでいくつかの設定を行える.例えば-bを使うことでバランス(実際に補助記憶装置にアクセスする際にどれにアクセスするかを決める方針)を指定できる.バランスに指定できる方針は次の4つである.
load最も負荷の低いコンポーネントを優先的に読み込む.
prefer優先度の高いコンポーネントを優先的に読み込む.
round-robinそれぞれのコンポーネントを順番に読み込む.
splitsliceサイズ以上の読み込み要求に対してアクティブなコンポーネントの数で分けて読み込む.sliceサイズはlistコマンドで確認できる.
sliceサイズはlabelのオプション-sで指定可能である.また,labelを含むgmirrorの多くのコマンドは-vを付けることで詳細な情報を出力してくれる. そのため-vを付ける人も少なくない.オプションを指定した場合次のような感じになる.
user% gmirror label -v -b round-robin gm0 /dev/ad1

ミラーにコンポーネントを追加

前述の方法で作成したミラーはコンポーネントが1つ登録されているだけの状態である.それゆえさらにコンポーネントを追加して冗長化しなければgmirrorを使う意味はない.コンポーネントの追加にはinsertを使用する.使い方は次の通りである.

user% gmirror insert gm0 ad6
以上まででミラーの設定は終了であるが,まだ冗長化された訳ではない.insert直後にstatusコマンドを使用すると,恐らく次のような結果が出力される.
user% gmirror status
      Name    Status  Components
mirror/gm0  DEGRADED  ad1
                      ad6(0%)
ad6(0%)は同期率を表している.それゆえこれが100%になるまではまだ冗長化は完了していない.しばらく放置して,次のような状態になれば同期完了である.
user% gmirror status
      Name    Status  Components
mirror/gm0  COMPLETE  ad1
                      ad6

OSを書き込む場合

OSの入ったコンポーネントでソフトウェアRAID1を構築する方法は2通りある。

  • 別のコンポーネントからOSを起動しそちらで設定を行う。
  • GEOMモジュールのデバッグフラグを設定し、起動中のHDDの書き換えを可能にする。
後者はkern.geom.debugflagsを0x10に設定すれば良い。設定は次のようにsysctlコマンドで行うことができる。
user% sysctl kern.geom.debugflags=16
パラメータの値は"=16"を省略することで確認可能である。

また、ソフトウェアRAID1を行ったコンポーネントからOS及びそれを格納したファイルシステムを読み込むには、次の2つの設定が必要である。

  • ローダの設定(/boot/loader.conf)をGEOMのmirrorクラスを読み込むように設定.
  • ファイルシステムのマウント設定(/etc/fstab)を修正.

GEOMのmirrorクラスは標準では自動的に読み込まれないので,ローダの設定を修正する必要がある.具体的には/boot/loader.confに以下の文を追加する.

geom_mirror_load="YES"

OSのマルチユーザモードでは/etc/fstabに記述されたファイルシステムをマウントするので,/etc/fstabを修正する必要がある./dev/ad1にOSをインストールした場合,ad1s1aやad1s1bなどのパスが使用されているはず.なので/dev/ad1の部分を全て作成したミラーのパス(/dev/mirror/gm0)に置き換えれば良い.以下に私の環境の例を示す.

# Device                Mountpoint      FStype  Options         Dump  Pass#
/dev/mirror/gm0s1b      none            swap    sw  		0       0
/dev/mirror/gm0s1a      /               ufs     rw 	 	1       1
/dev/mirror/gm0s1e      /tmp            ufs     rw  		2       2
/dev/mirror/gm0s1f      /usr            ufs     rw  		2       2
/dev/mirror/gm0s1d      /var            ufs     rw  		2       2


補助記憶装置が壊れた際の処理

あるコンポーネントでエラーが多発すると,gmirrorはそのコンポーネントをミラーへの接続から解除する.statusコマンドで確認すると,恐らく状態がDEGRADEDになり,コンポーネントの一覧からそれが消えているはずである.また,より詳細な情報を出力するlistコマンドを使用すると,正常なディスクはStateがACTIVEで,故障したディスクはSTALEとなっているはずである.故障してHDDを交換する場合,まずforgetコマンドを使用する.

user% gmirror forget gm0
これによりミラーに登録されたコンポーネントの中で接続されていないコンポーネントの情報を削除する.そして次に補助記憶装置を交換し,最後にinsertコマンドで新しいコンポーネントを追加すれば,あとは同期終了まで待つだけである.
user% gmirror insert gm0 ad1

また、もし以前のメンバと異なる場合、"Not all disks connected"というエラーメッセージが出力される。その場合、一度forgetを使用する必要がある。

user% gmirror forget gm0

再構成

gmirrorのメタ情報を全て削除するには、コンポーネントがbusyじゃない状態(例えば、モジュールをアンロードした状態やコンポーネントが停止した状態)で次のように行う。

user% gmirror clear /dev/ad0
そして、改めて新しいミラーの作成を行えば良い。コンポーネントの停止やモジュールのアンロードは次のように行える。
  • user% gmirror stop /dev/ad0
  • user% gmirror unload

gmirrorとgpart

gmirrorを使い、かつパーティションでHDDを区切る場合、次のような実装方法がある。

  • パーティション毎にミラーリングする方法
  • ミラーリングした仮想コンポーネントをパーティショニングする方法
本稿では、gpartを使用した後者の方法を紹介する。gpartを使用する上では「19.3. RAID1 - Mirroring」を参考にした。
  1. モジュールのロード。
    user% gmirror load
  2. ソフトウェアRAID1コンポーネントの構築
    user% gmirror label -v -b round-robin gm0 /dev/ada1
  3. GUIDパーティションを生成。
    user% gpart create -s MBR /dev/mirror/gm0
  4. /dev/mirror/gm0s1を作成。
    user% gpart add -t freebsd -a 4k /dev/mirror/gm0

  5. BSDの論理パーティションを生成。
    user% gpart create -s BSD mirror/gm0s1
  6. 200GBの/dev/gm0s1aを生成
    user% gpart -t freebsd-ufs -a 4k -s 200g /dev/mirror/gm0s1
  7. 250GBの/dev/gm0s1d(たぶんd)を生成
    user% gpart -t freebsd-ufs -a 4k -s 250g /dev/mirror/gm0s1

  8. gm0s1aのファイルシステムを構築。
    user% newfs -U /dev/mirror/gm0s1a
  9. gm0s1dのファイルシステムを構築。
    user% newfs -U /dev/mirror/gm0s1d
なおパーティション情報は次のようにshowコマンドで取得できる。
user% gmirror show /dev/mirror/gm0s1
試したところ、OSのインストール前であれば、インストール前にシェルを起動して、この処理を行ってからインストール先に作成したパーティションを指定することが可能だった。ただし、OSを起動する前に/boot/loader.confを書き換える必要がある。また、OSを格納したファイルシステムをブート可能にするには、次のような処理が必要である。ここで、カーネルはgm0s1aに格納されており、マウント位置は"/"とする。
user% gpart bootcode -b /boot/mbr /dev/mirror/gm0
user% gpart set -a active -i 1 /dev/mirror/gm0
user% gpart bootcode -b /boot/boot /dev/mirror/gm0s1

エラー

gpartやgmirrorの処理を行った後にインストーラでOSをした時、次のようなエラーが出力された(/boot/loader.confは変更済みだった)。

Mounting from ufs:/dev/mirror/gm0s1a failed with error 19.

Loader variables:
  vfs.root.mountfrom=ufs:/dev/mirror/gm0s1a
  vfs.root.mountfrom.options=rw

Manual root filesystem specification:
  <fstype>:<device> [options]
      Mount <device> using filesystem <fstype>
      and with the specified (optional) option list.

    eg. ufs:/dev/da0s1a
        zfs:tank
        cd9660:/dev/acd0 ro
          (which is equivalent to: mount -t cd9660 -o ro /dev/acd0 /)

  ?               List valid disk boot devices
  .               Yield 1 second (for background tasks)
  <empty line>    Abort manual input

mountroot>
私の場合、"ufs:/dev/gm0s1a"を指定して起動し、そこで再度前述の"gpart bootcode"の処理を行うことで解決できた。

一覧