雑記

2000|01|
2003|05|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|
2007|01|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|09|11|
2009|02|03|05|06|07|08|10|11|12|
2010|01|03|04|05|06|07|08|09|10|
2011|05|06|09|10|
2012|03|07|09|12|
2013|01|02|04|05|07|08|10|11|
2014|04|05|08|10|12|
2015|01|05|
2016|09|

2013-02-03 [長年日記]

[FreeBSD] HP MicroserverでのRAID構成とホットスワップの検証

今回ちょっと必要に迫られた事もあり、HPのMicroserverでのFreeBSDのホットスワップについてちゃんと検証してみました。本体は2011年6月に購入したもので、これに9.1-RELEASEを入れての実験です。 先に結論を書いておくと、少なくとも手元の個体では、以下のような感じになりました。

  • Microserverでは4台でのraidzを使うとホットプラグができなくなり、raid10、raidz(3台) + ホットスペア、raidz2のように、2台までの障害に耐える構成にする必要がある。いずれも容量は同じなので性能的にmirror一択。
  • mirrorするHDDはスロット1/2のグループと3/4のグループに分けなければならない
  • 4台構成では、上記グループを跨ぐ2台が故障したら電源を落としての交換が必要
  • 増設や障害発生時の手間を考えると、rootパーティションはgmirrorを使った方が良さげ

パーティション構成の検討(gmirrorかzfsか)

インストールの際にパーティション構成をどうするか決める必要があります。最近は root パーティションもzfs化できるようですが、いろいろ調べたり試行錯誤したりした結果、以下の方針で行くことにしました。

  • boot, root, swapはgmirror
  • 残りをzpoolにして、必要であれば論理パーティションに分ける

理由としては、まずboot,rootについては、

  • zfsのmirrorでは既存のプールにHDDの増設はできない(別のmirrorプールを追加しての容量アップは可能だが、ストライピングになるらしい)
  • gmirrorでは3台目,4台目のmirror登録もでき、boot,rootをgmirror化しておけば最大4重化(!)まで対応できる
  • gmirrorでは正常なHDDを抜いてからまた挿した(ように見える)時のリカバリは自動でやってくれる(zfsでもautoreplace=on指定でできるかも:未確認)

swapについては、

  • swapを別パーティションにする理由はこの辺参照
  • 2台のswap領域を別々に使うというのは一見よいアイデアだが、一方のHDDが壊れるとおそらくその瞬間にOSがクラッシュする(ここのコメント欄のAdam Strohl(9/7/12 at 10:54 am)のコメント参照)。それでは意味が無いので、ここはmirror一択。
  • ただし4台体制の時に4台mirrorやraid10ではなく、zfsの構成と合わせたmirror x 2の分散構成はありうる

最後にその他の領域についてですが、ここでは機能の充実や設定の柔軟性も鍵になってきます。

  • zfsには論理パーティションがあり、以下の点で有利
    • パーティションを後から簡単に追加/削除できる
    • パーティションのサイズ(上限)を自由に設定可能。また設定しなければ全体をシェアできる
    • パーティション毎にクォータの設定が可能
    • プールの容量を(上記注意点はあるものの)後から増やせる
    • OS標準のディスククォータはGENERICカーネルに入っていないので、freebsd-updateが面倒くさい(愚痴)
  • これと前述の記述も考慮して
    • /tmpは突発的に使用量が増える事があり、読み難いのでzfs
    • /varにはログがどんどん溜まっていくのでzfs
    • あとは気分で、/usr/localや(/usr)/homeあたりを論理パーティションに

インストール

上記方針に従ってインストールします。9.1のインストーラではパーティションの設定時に<Shell>というオプションが増え、gmirrorの構成を作った上でそこにインストールすることもでるようになっています。具体的な手順は"HOWTO: Installing FreeBSD 9.0 or 9.1 with gmirror"を参考にしました。

BIOSの設定

と、その前にMicroserverのBIOS設定画面で以下を設定しておきます。

 Advanced
   IDE Configuration
     SATA Controller Mode を "AHCI" に
     Drive Write Cache を "Enabled" に
インストール手順

ここではHDD2台にミラーリングでインストールすることを前提に話を進めます。

  1. HDDをスロット左から1番目と3番目に挿します。2番目と4番目とかでもよいですが、{[orangered] 1と2や3と4の組み合わせは駄目}です
  2. インストーラのディスクかUSBメモリから起動し、<Install>に進みます
  3. (((

Partitioningの画面まで進んだら<Shell>を選択して以下の手順でgmirrorパーティションを作成します

最初のディスクの設定

boot, root, swap, zfs用のパーティションを作成して、ブートコードを書き込む

gpart create -s gpt ada0
gpart add -a 4k -s 64k -t freebsd-boot -l boot0 ada0
gpart add -a 4k -s 8G -t freebsd-ufs -l root0 ada0
gpart add -a 4k -s 8G -t freebsd-swap -l swap0 ada0
gpart add -a 4k -t freebsd-zfs -l zfs0 ada0
gpart bootcode -b /boot/pmbr -p /boot/gptboot -i 1 ada0
2台目のディスクの設定

1台目と同じ構成でパーティションを作成する。ラベル名に注意

gpart create -s gpt ada1
gpart add -a 4k -s 64k -t freebsd-boot -l boot1 ada1
gpart add -a 4k -s 8G -t freebsd-ufs -l root1 ada1
gpart add -a 4k -s 8G -t freebsd-swap -l swap1 ada1
gpart add -a 4k -t freebsd-zfs -l zfs1 ada1
gpart bootcode -b /boot/pmbr -p /boot/gptboot -i 1 ada1
確認

パーティション情報が正しく設定できたか確認

true > /dev/ada0
true > /dev/ada1

ls -l /dev/gpt
crw-r-----  1 root operator   0, 164 Feb  2 00:00 boot0
crw-r-----  1 root operator   0, 134 Feb  2 00:00 boot1
crw-r-----  1 root operator   0, 166 Feb  2 00:00 root0
crw-r-----  1 root operator   0, 136 Feb  2 00:00 root1
crw-r-----  1 root operator   0, 168 Feb  2 00:00 swap0
crw-r-----  1 root operator   0, 138 Feb  2 00:00 swap1
crw-r-----  1 root operator   0, 170 Feb  2 00:00 zfs0
crw-r-----  1 root operator   0, 140 Feb  2 00:00 zfs1
ミラーの作成

作成したboot,root,swap領域を使ってミラーを作成します。

gmirror label boot /dev/gpt/boot0 /dev/gpt/boot1
gmirror label root /dev/gpt/root0 /dev/gpt/root1
gmirror label swap /dev/gpt/swap0 /dev/gpt/swap1
カーネルモジュールの読み込み
kldload geom_mirror
(以下のメッセージが出力されます)
GEOM_MIRROR: Device mirror/swap launched (2/2)
GEOM_MIRROR: Device mirror/root launched (2/2)
GEOM_MIRROR: Device mirror/boot launched (2/2)
rootパーティションの初期化とインストール先へのマウント
newfs -U -L root /dev/mirror/root
mount /dev/mirror/root /mnt
fstabの記述

/tmp/bsdinstall_etc/fstabを編集する。このファイルがインストール後の/etc/fstabになるらしい。

vi /tmp/bsdinstall_etc/fstab
(以下を入力)
# Device          Mountpoint      FStype  Options Dump    Pass#
/dev/mirror/swap  none            swap    sw      0       0
/dev/mirror/root  /               ufs     rw      1       1
インストール

ここでexitでシェルを終了するとインストールが始まります。

exit

)))

  1. (((

インストール終了後、final manual modifications? で<Yes>を選んで最後の設定を行います。

echo 'geom_mirror_load="YES"' >> /boot/loader.conf
echo 'daily_status_gmirror_enable="YES"' >> /etc/periodic.conf
再起動

exitでシェルを終了して再起動します )))

  1. (((

シングルユーザモードで起動してzfsの設定を行います。

プールの作成

"zpl"プールを作成してマウントポイントを/mnt/zplにします。

zpool create zpl mirror ada0p4 ada1p4
zfs set mountpoint=/mnt/zpl zpl
個別パーティションの作成とデータのコピー
zfs create -o mountpoint=/usr/local zpl/local
zfs create zpl/var
(cd /var; tar cf - .) | tar xvfpC - /mnt/zpl/var/
zfs set mountpoint=/var zpl/var
zfs create zpl/tmp
(cd /tmp; tar cf - .) | tar xvfpC - /mnt/zpl/tmp/
zfs set mountpoint=/tmp zpl/tmp
zfs create zpl/home
(cd /home; tar cf - .) | tar xvfpC - /mnt/zpl/home/
zfs set mountpoint=/home zpl/home
zfsの有効化
echo 'zfs_load="YES"' >> /boot/loader.conf
echo 'zfs_enable="YES"' >> /etc/rc.conf
リブートと確認

再起動してミラーおよびzfsのパーティションが正しくマウントできているか、スワップが有効になっているか確認します。

# df
Filesystem       1K-blocks    Used     Avail Capacity  Mounted on
/dev/mirror/root   8106712 1477060   5981116    20%    /
devfs                    1       1         0   100%    /dev
zpl/home         941358401      47 941358353     0%    /usr/home
zpl              941358384      31 941358353     0%    /mnt/zpl
zpl/tmp          941358388      35 941358353     0%    /tmp
zpl/local        941358384      31 941358353     0%    /usr/local
zpl/var          941358711     357 941358353     0%    /var

# swapinfo
Device          1K-blocks     Used    Avail Capacity
/dev/mirror/swap   8388604        0  8388604     0%

)))

CAMデバイスの順番について

ここでちょっと脇道に逸れますが、スロットを飛ばしてHDDを挿しているため、後から増設した時には3番スロットのディスクのデバイス番号が変わってしまいます。が、結論からいうとそこを気にする必要はありません。 gmirrorもzfsもデバイス番号が初期設定の時と変わっても自動的にその変化に対応してくれました。デバイス番号が変わるのが気持ち悪い場合は、以下のような記述を/boot/device.hintsに追加すれば、インストールした時のデバイス番号が維持されます。

hint.scbus.0.at="ahcich0"
hint.scbus.0.bus="0"
hint.scbus.1.at="ahcich2"
hint.scbus.1.bus="0"
hint.scbus.2.at="ahcich1"
hint.scbus.2.bus="0"
hint.scbus.3.at="ahcich3"
hint.scbus.3.bus="0"
hint.ada.0.at="scbus0"
hint.ada.0.target="0"
hint.ada.0.unit="0"
hint.ada.1.at="scbus1"
hint.ada.1.target="0" 
hint.ada.1.unit="0" 
hint.ada.2.at="scbus2"
hint.ada.2.target="0" 
hint.ada.2.unit="0" 
hint.ada.3.at="scbus3"
hint.ada.3.target="0"
hint.ada.3.unit="0"

HDD障害への対応

HDDに障害が発生した場合は以下の手順で対処します。都合良くHDDを故障させることはできないので、片方のディスクをおもむろに抜いて、パーティション情報を消してから挿し直すという方法で検証しました。

  1. (((

ディスクを抜くと、以下のようなメッセージが表示されます。

(ada1:ahcich2:0:0:0:0): lost device
(pass1:ahcich2:0:0): passdevgonecb: devfs entry is gone
GEOM_MIRROR: Device boot: provider ada1p1 disconnected.
GEOM_MIRROR: Device swap: provider ada1p3 disconnected.
GEOM_MIRROR: Device root: provider ada1p2 disconnected.
(ada1:ahcich2:0:0:0): removing device entry

)))

  1. (((

交換ディスクを挿します。以下のようなメッセージが表示されます。

ada1 at ahcich2 bus 0 scbus1 target 0 lun 0
ada1: <WDC WD10EADS-00L5B1 01.01A01> ATA-8 SATA 2.x device
ada1: 300.000MB/s transfers (SATA 2.x, UDMA6, PIO 8192bytes)
ada1: Command Queueing enabled
ada1: 953869MB (1953525168 512 byte sectors: 16H 63S/T 16383C)
ada1: Previously was known as ad6

)))

  1. (((

インストール時と同じ手順でパーティション情報を書き込みます。

gpart create -s gpt ada1
gpart add -a 4k -s 64k -t freebsd-boot -l boot1 ada1
gpart add -a 4k -s 8G -t freebsd-ufs -l root1 ada1
gpart add -a 4k -s 8G -t freebsd-swap -l swap1 ada1
gpart add -a 4k -t freebsd-zfs -l zfs1 ada1
gpart bootcode -b /boot/pmbr -p /boot/gptboot -i 1 ada1

)))

  1. (((

ミラーに登録します

gmirror forget boot
gmirror insert boot ada1p1
gmirror forget root
gmirror insert root ada1p2
gmirror forget swap
gmirror insert swap ada1p3

確認します

gmirror status
       Name    Status  Components
mirror/boot  COMPLETE  ada0p1 (ACTIVE)
                       ada1p1 (ACTIVE)
mirror/root  DEGRADED  ada0p2 (ACTIVE)
                       ada1p2 (SYNCHRONIZING, 1%)
mirror/swap  DEGRADED  ada0p3 (ACTIVE)
                       ada1p3 (SYNCHRONIZING, 1%)

)))

  1. (((

zpoolのミラーを再構築します

zpool replace zpl ada1p4

確認します

zpool status
  pool: zpl
 state: ONLINE
  scan: resilvered 708K in 0h0m with 0 errors on Mon Feb  4 01:30:43 2013
config:

	NAME        STATE     READ WRITE CKSUM
	zpl         ONLINE       0     0     0
	  mirror-0  ONLINE       0     0     0
	    ada0p4  ONLINE       0     0     0
	    ada1p4  ONLINE       0     0     0

)))

以上でデータのコピーが終了したら作業完了です。

おまけ1 - カーネルパニックの原因切り分け

さてこの動作検証なのですが、当初スロットの1番目と2番目でミラーしていてドハマりしました。

上記障害対応と同じ手順で確認すると、新しいHDDを挿した瞬間にカーネルパニック。そこから長い試行錯誤の始まりです。

  • HDDをハード的に飛ばしたかと思いましたが、普通に再インストールはできるのでそうではない
  • gmirrorのドライバの問題かと思ってrootパーティションをzfsにしても変化無し
  • 電源を落としてHDDを差し込んでから起動すると問題無し。でもこれではホットスワップになりません
  • 抜いたあとにgmirror forgetやcamcontrol stop/eject/rescanなどを試すが、どれも効果無し

などさんざんやった挙げ句に

  • 2番目の代わりに3番目のスロットに挿してみるとパニックしない

ということに気付き、もしかして挿した時の衝撃で瞬断?とか思って

  • ゆっくり挿す。パニック。

ただ、パニックしない組み合わせが見つかったので、次にカーネルパニックするスロットの切り分けです。

  • 1 + 4: ok
  • 2 + 3: ok
  • 2 + 4: ok
  • 3 + 4: ng

ということで、1と2、3と4の組み合わせが駄目なようでした。

最後に、スロット1と3で正常に動いている状態でスロット2に3台目のディスクを挿してみると、その瞬間に

(ada0:ahcich0:0:0:0): lost device
(pass0:ahcich0:0:0:0): passdevgonecb: devfs entry is gone
GEOM_MIRROR: Device root: provider ada0p2 disconnected.
GEOM_MIRROR: Device swap: provider ada0p3 disconnected.
GEOM_MIRROR: Device boot: provider ada0p1 disconnected.
(ada0:ahcich0:0:0:0): removing device entry
ada0 at ahcich0 bus 0 scbus0 target 0 lun 0
ada0: <WDC WD10EADS-00L5B1 01.01A01> ATA-8 SATA 2.x device
ada0: 300.000MB/s transfers (SATA 2.x, UDMA6, PIO 8192bytes)
ada0: Command Queueing enabled
ada0: 953869MB (1953525168 512 byte sectors: 16H 63S/T 16383C)
ada0: Previously was known as ad4
ada1 at ahcich1 bus 0 scbus2 target 0 lun 0
ada1: <WDC WD10EADS-00L5B1 01.01A01> ATA-8 SATA 2.x device
ada1: 300.000MB/s transfers (SATA 2.x, UDMA6, PIO 8192bytes)
ada1: Command Queueing enabled
ada1: 953869MB (1953525168 512 byte sectors: 16H 63S/T 16383C)
ada1: Previously was known as ad8

と、スロット1のディスクが一瞬だけ見えなくなってからスロット1,2のディスクが認識される、という動きになっているようでした。これは逆のディスクを挿した時も同じで、スロット3と4の組でも同じ状況でした。

というわけで、どうもMicroserverでは、スロット1/2と3/4がペアの関係になっていて、どちらか一方にディスクを挿すと、もう一方もリセットもしくは瞬断されるようです。HPがホットプラグ非対応と言っているのは、もしかするとこの挙動の事なのかもしれません。

おまけ2 - 増設について

本体にこのような癖があるので、容量を増やしたい場合、単体でその容量のHDDがあるのなら、zfsのexpand機能を使って2台構成のまま容量を増やす(こちらの3.容量の多いディスクとzpool replaceを使って交換していく)方法にするのが良さそうです。

[green]