容量の少ないプールに zroot を移動した

ストレージサーバを組んだ時、適当に zroot に 100GB を割り当てました。
4 ヶ月程運用してきましたが、zroot の容量はたったの 3GB 強です。
また、zvol を使えばいいものを、swap 用にパーティションを作っていました。

そこで、swap を含め、新しい SSD の 30GB のパーティションに zroot を移行することにしました。

zfs send、zfs receive を使うことで、容量の小さいプールにファイルシステムをコピーできます。
もちろん、移行前の "使用容量" が、移行先のプール容量より小さい必要があります。

また、

  • なるべく停止せずに移行したい
  • プール名・構成デバイス名を保ったまま移行したい (無駄なこだわり)

ということで、別の FreeBSD マシンを用意し、ssh 経由で移行することにしました。

  • 移行元環境
    • FreeBSD 8.2-RELEASE amd64

移行先の準備

FreeBSD 8.2-RELEASE amd64 の Fixit 環境を用意します。
移行先の SSD を接続し、インストーラを起動、Fixit 環境に入ります。

Fixit 環境での sshd の起動

Ramdisk の作成

Fixit# mdconfig -a -t malloc -s 2048m -u 10
Fixit# newfs -U /dev/md10
Fixit# mkdir /ramdisk
Fixit# mount /dev/md10 /ramdisk

Ramdisk 領域にシステムをコピー

Fixit# cp -pR /dist /ramdisk

システムのコピー先に chroot

Fixit# mount -t devfs devfs /ramdisk/dist/dev
Fixit# chroot /ramdisk/dist tcsh

設定

# ifconfig re0 192.168.1.254 netmask 255.255.255.0
# passwd

sshd 起動

# echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config
# echo 'sshd_enable="YES"' >> /etc/rc.conf
# /etc/rc.d/sshd start

移行先プールの用意

移行先のデバイス (/dev/adaX) に GPT パーティションを切り、プールを作成します。
(ここで、GPT パーティションラベル名とプール名が、移行元と同じになっています。)

パーティション作成

# gpart create -s gpt adaX

# gpart add -s 64k -t freebsd-boot         adaX
# gpart add -s 30g -t freebsd-zfs  -l sys0 adaX
# gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 adaX

プール作成

# kldload /boot/kernel/opensolaris.ko
# kldload /boot/kernel/zfs.ko

# zpool create zroot /dev/gpt/sys0
# zpool set bootfs=zroot zroot

移行

ssh 経由で ZFS ストリームを送信します。
その後、zpool.cache を再生成するため、ちょっとした操作を行います。

プールの移行

# ssh root@<移行元ホスト> "zfs send -R root@snapshot_hoge" | zfs receive -vF -d zroot

zpool.cache の再生成

zpool.cache は、zpool import の際に、マウントポイント変更のための -R オプションを付けると生成されません。
なので、以下のような少し面倒な手順を踏むことになります。

マウントポイントの変更

# zfs set mountpoint=/zroot     zroot
# zfs set mountpoint=/zroot/tmp zroot/tmp
# zfs set mountpoint=/zroot/usr zroot/usr
# zfs set mountpoint=/zroot/var zroot/var

再インポートして zpool.cache を生成・コピー

# zpool export zroot
# zpool import zroot
# cp /boot/zfs/zpool.cache /zroot/boot/zfs/zpool.cache

マウントポイントを元の設定に戻す

# zfs umount -a
# zfs set mountpoint=legacy zroot
# zfs set mountpoint=/tmp   zroot/tmp
# zfs set mountpoint=/usr   zroot/usr
# zfs set mountpoint=/var   zroot/var

ディスク交換作業

移行元マシンの電源を落とし、ディスクを光の速さで交換し、起動します。
停止時間はこの間の数分のみです。