2009年5月28日木曜日

Kingmax U-DriveをFreeBSD7.1で使う

多分FreeBSD7.2でも同様だと思う。

Kingmax U-Drive 8GBとやらが安かったので買ってきたが、FreeBSDではこいつがUSBデバイスとして定義されていないので、ZFSで使用する時に盛大にエラーが出る。kernelを再構築すれば使える。

vi usbdevs
(追加)
vendor KINGMAX 0x1687 Kingmax
product KINGMAX UDRIVE 0x6211 Kingmax U-Drive

(追加)
vi umass.c
{ USB_VENDOR_KINGMAX, USB_PRODUCT_KINGMAX_UDRIVE, RID_WILDCARD,
UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
NO_GETMAXLUN | NO_SYNCHRONIZE_CACHE
},

多分これだけ。ちゃんちゃん。

…と思ったらmakeが通らない… めんどくさい。やっぱやーめた。。

2009年5月5日火曜日

エラーの多いUSBメモリ対策

USBメモリがよく壊れる。

USBメモリから起動させて数日経つと、フリーズしてしまう。原因は、どうやらUSBメモリのデータ破損らしい。ZFSのCKSUMがうなぎ登り。やはり激安USBメモリではムリがあったか。

対策としては、信頼性の高いストレージを導入することだが、いまさらHDDに切り替えも困難。物理的に搭載できる限界に達してしまっている。USBメモリで何とかするしかない。

SLCのUSBメモリを買えば信頼性は向上するだろうが、今のメモリが無駄だし高いし、そもそも所詮USBメモリなので、根本的解決にはならないだろう。MLCだって1万回程度の書き換え耐久はある(と言われているようだが、どう考えても2~3回くらいしか書き換えてないが…)はずで、それが10倍になったところでこの現象が収まるとは思えない。2~3日で壊れるのが、20~30日で壊れるようになっても、ねぇ。

今回はZFSのミラーリングを利用し、データが破損すること前提で、対策を打ってみる。ZFSが全ブロックチェックサムでデータ破損を検知し、正常なミラーブロックのデータで上書きして動き続ける仕組みを活用する。

バッドノウハウですけれども。。


■ディスク構成
・1GBのUSBメモリ 1本(da0)
・4GBのUSBメモリ 1本(da1) こいつが腐ってるUSBメモリ。

■構築方法
1. da0にFreeBSDをインストールする。
2. da0のFreeBSDでkernelを再構築する(da1が腐っているので、その対策のため設定改変)
3. da1を4分割し、ZFSミラープールを構築する(rpoolという名前にした)。
4. /boot以外のデータをrpoolにコピーする。
5. 起動時にrpoolをrootとしてマウントするように設定する。

■問題点
・2本1セットでないと運用できない(目をつぶる)
・bootパーティションはミラー化されていない(ddでバックアップしておくことにする)

ミラーを3本にすれば1本のUSBメモリで何とかなる気もするが、なにせ信用ならないUSBメモリなので、bootパーティションが破壊された時のために分割しておくことにします。da0のほうはわりと運用実績あるので、信用する。

■やりかた要旨(基本、3つ前のエントリーに沿って作業する)
da0にFreeBSDをインスコして、kernel再構築する。
…と思ったら1GBメモリでは容量不足で再構築できなかったので、腐ったUSBメモリで再構築した/boot以下を上書きコピーしちゃう。

○シングルモードで起動
mount -w /
mkdir /mnt/temp
mount /dev/da1s1a /mnt/temp
rm -rf /boot
cp -a /mnt/temp/boot /
umount /mnt/temp
rmdir /mnt/temp
reboot

○マルチユーザモードで起動
sysinstall->fdiskでスライスを同容量で4つ確保する(da1)
7843838/4 = 1960959

sysinstall->labelでそれぞれパーティションを1つづつ作る
da1s1d/da1s2d/da1s3d/da1s4d

ミラープール作成
zpool create rpool mirror /dev/da1s1d /dev/da1s2d /dev/da1s3d /dev/da1s4d

ZFSパーティション作成。読み書き速度が1/4になる&容量ちょっと足んないので、全部圧縮しちゃう。
zfs create rpool/root
zfs set compress=gzip rpool/root
zfs set atime=off rpool/root
zpool export rpool
reboot

○シングルユーザモードで起動
mount -w /
zpool import rpool

da0のデータをrpoolにコピーしてboot時にマウントされるようにする。
find -x / | cpio -pmd /rpool/root

rm -rf /rpool/root/boot
mkdir /rpool/root/bootdir
cd /rpool/root
ln -s bootdir/boot boot
echo 'vfs.root.mountfrom="zfs:rpool/root"' >> /boot/loader.conf

vi /rpool/root/etc/fstab
(変更前)/dev/da0s1a / ufs rw 1 1
(変更後)/dev/da0s1a /bootdir ufs rw 1 1

cd /
zfs set mountpoint=/ rpool/root
zfs set mountpoint=legacy rpool

zpool export
reboot

これだけ。ナイスだZFS。
安定性はまた後日レポします。

--追記(2009/5/15)--
極めて安定している。嘘のように安定している。エラーが出ない・・・orz
4組ミラーはさすがに無駄が多いので、2組ミラーのストライピングに切り替えちゃいました。
zpool detach rpool da1s3d
zpool detach rpool da1s4d
zpool add rpool mirror /dev/da1s3d /dev/da1s4d

うーん、再起動不要。ナイスだZFS。