目次

FreeBSD 9.2RをHDDからSSDに移動する

前書き

slog/L2ARC用にSSDを購入したが、たかがキャッシュのために全領域を割り当てるのは流石に勿体ないので、HDDにあるシステムをSSDに移動して高速化を図ると共に/homeの領域を増やそう大作戦。

環境

システム FreeBSD 9.2-RELEASE-p12 [Root on ZFS環境]
移行元 HDD 1 TOSHIBA MQ01ABD100 (1TB) ZFSミラー構成
HDD 2 TOSHIBA MQ01ABD100 (1TB) ZFSミラー構成
移行先 SSD 1 [ada9] INTEL SSDSC2BA200G3T (200GB)
SSD 2 [ada1] Crucial CT128M550SSD1 (128GB)

手順

SSDの準備

仮のプールzssdを作る。

M550

$ sudo gpart create -s gpt ada1
ada1 created
$ sudo gpart add -a 4k -s 64k -t freebsd-boot ada1
ada1p1 added
$ sudo gpart add -a 4k -s 30g -t freebsd-zfs ada1
ada1p2 added
$ gpart show ada1
=>       34  250069613  ada1  GPT  (119G)
         34          6        - free -  (3.0k)
         40        128     1  freebsd-boot  (64k)
        168   62914560     2  freebsd-zfs  (30G)
   62914728  187154919        - free -  (89G)

DC S3700

$ sudo gpart create -s gpt ada9
ada9 created
$ sudo gpart add -a 4k -s 64k -t freebsd-boot ada9
ada9p1 added
$ sudo gpart add -a 4k -s 30g -t freebsd-zfs ada9
ada9p2 added
$ gpart show ada9
=>       34  390721901  ada9  GPT  (186G)
         34          6        - free -  (3.0k)
         40        128     1  freebsd-boot  (64k)
        168   62914560     2  freebsd-zfs  (30G)
   62914728  327807207        - free -  (156G)

忘れずにブートコードを書き込む。

$ sudo gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada1
bootcode written to ada1
$ sudo gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada9
bootcode written to ada4

例によって4kセクタでzpoolを作る。

$ sudo gnop create -S 4096 /dev/ada1p2
$ sudo gnop create -S 4096 /dev/ada9p2
$ sudo zpool create ssd_zroot mirror ada1p2.nop ada9p2.nop
$ sudo zpool export ssd_zroot
$ sudo gnop destroy /dev/ada1p2.nop
$ sudo gnop destroy /dev/ada9p2.nop
$ sudo zpool import zssd
$ zpool status zssd
  pool: zssd
 state: ONLINE
  scan: none requested
config:

	NAME        STATE     READ WRITE CKSUM
	ssd_zroot   ONLINE       0     0     0
	  mirror-0  ONLINE       0     0     0
	    ada1p2  ONLINE       0     0     0
	    ada9p2  ONLINE       0     0     0

errors: No known data errors

システムの移動

現行のHDDのシステムzrootをシングルユーザーモードで起動し、移行先の仮プールzssdにsnapshotをsend/recvする。作業自体は通常起動のシステムでも行えるけど、シングルユーザーモードの方がスナップショットと現状との差分が少なくて済むかなーと。

尚、システムはzroot/ROOTに入っている。

# zfs snapshot -r zroot/ROOT@mig
# zfs send -Rp zroot/ROOT@mig | zfs recv -vuFd zssd
receiving full stream of zroot/ROOT@mig into zssd/ROOT@mig
received 769MB stream in 2 seconds (385MB/sec)
receiving full stream of zroot/ROOT/usr@mig into zssd/ROOT/usr@mig
received 6.45GB stream in 99 seconds (66.8MB/sec)
...

送受信が終わったら、忘れずに移行先のbootfsを設定する。

# zpool set bootfs=zssd/ROOT zssd

移行先システムの起動確認

移行元システムのHDDを物理的に外し、移行先のSSDでシステムが起動するか確認する。

mountrootで失敗するので、移行先のルートzfs:zssd/ROOTを指定する。

Mounting from zfs:zroot/ROOT failed with error 2.

Loader variables:
  vsf.root.mountfrom=zfs:zroot/ROOT
  
Manual root filesystem specification:
  <fstype>:<device> [options]
      Mount <device> using filesystem <fstype>
      and with the specified (optional) option list.

    eg. usf:/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> zfs:zssd/ROOT

これで正常に起動しなければ何かがおかしいので、最初から手順を見直す。

移行先プールの名称変更

USBメモリやCDなどのFreeBSDインストーラで起動しShellに落ちる(以後、fixit環境と呼ぶ)。

ルートプール名を移行前と同じにしたいので、移行先のzssdプールをzrootにリネームする。

念のためzssdがあるか確認。

# zpool import -N -o cachefile=/tmp/zpool.cache zssd
ZFS filesystem version: 5
ZFS storage pool version: features support (5000)
cannot import 'zroot': pool may be in use from other system
use '-f' to import anyway

案の定「別システムのプールだよ」と警告されるので、-fオプションでインポート&名前変更。ついでにzpool.cacheを生成。

# zpool import -N -o cachefile=/tmp/zpool.cache -f zssd zroot
# zpool export zroot
# zpool import -N -o cachefile=/tmp/zpool.cache zroot

Root on ZFS環境ではルートディレクトリのmountpointはlegacyになっているハズなので、適切にmountして生成したzpool.cacheを/boot/zfs/にコピーする。

mkdir /tmp/zroot
mount -t zfs zroot/ROOT /tmp/zroot
cp /tmp/zpool.cache /tmp/zroot/boot/zfs/

マシンをシャットダウンする。

移行元ルートプールの削除

今度は移行先のSSDを物理的に外し、移行前のシステムを付け、fixit環境に入る。

移行元のzrootがある事を確認し、問題がなければ躊躇せずに消す。大丈夫、さっき移行先のシステムの起動を確認したんだから。自分を信じて。でも、もしシステムが再起不能になっても責任は負いません(←

# camcontrol devlist
<TOSHIBA MQ01ABD100 AX0P7E>        at scbus0 target 0 lun 0 (ada0,pass0)
<TOSHIBA MQ01ABD100 AX0P7E>        at scbus8 target 0 lun 0 (ada2,pass4)
# zpool import -Nf zroot
# zpool status zroot
zpool status zroot
  pool: zroot
 state: ONLINE
  scan: none requested
config:
 
	NAME        STATE     READ WRITE CKSUM
	zroot       ONLINE       0     0     0
	  mirror-0  ONLINE       0     0     0
	    ada0p3  ONLINE       0     0     0
	    ada2p3  ONLINE       0     0     0
# zpool destroy zroot

作業途中で旧システムを消すのは恐ろしく、こういう事を趣味にしている人々は往々にして「何かあった時」のために保全しておきたくなるが、それは今回に限っては悪魔の囁きってヤツだ。下手に残しておくと新旧システムのプール情報が入り乱れる事になり逆に危険である。

念には念を入れ、zrootの構成パーティションも削除(多分ここまでしなくても大丈夫)。

# gpart delete -i 3 ada0
ada0p3 deleted
# gpart delete -i 3 ada2
ada2p3 deleted

各種パーティションの準備

移行先のシステムで起動し、slog/L2ARC/スワップ/VM用のパーティションを作る。

M550

$ sudo gpart add -a 4k -s 8g -t freebsd-zfs ada1
ada1p3 added
$ sudo gpart add -a 4k -s 8g -t freebsd-zfs ada1
ada1p4 added
$ sudo gpart add -a 4k -s 40g -t freebsd-zfs ada1
ada1p5 added

DC S3700

$ sudo gpart add -a 4k -s 8g -t freebsd-zfs ada9
ada9p3 added
$ sudo gpart add -a 4k -s 8g -t freebsd-zfs ada9
ada9p4 added
$ sudo gpart add -a 4k -s 40g -t freebsd-zfs ada9
ada9p5 added
$ sudo gpart add -a 4k -s 80g -t freebsd-zfs ada9 
ada9p6 added
$ sudo gpart add -a 4k -s 8g -t freebsd-swap ada9 
ada9p7 added

スワップを有効化

/etc/fstabにスワップ情報を書く。

#Device        Mountpoint    FStype    Options    Dump    Pass#                              
/dev/ada9p7    none          swap      sw         0       0                                  

正しくマウントされるか確認。

$ sudo swapon -aq
$ swapinfo -m
Device          1M-blocks     Used    Avail Capacity
/dev/ada9p7          8192        0     8192     0%

/home用プールの拡張

HDDからシステム&スワップパーティションが無くなったので、晴れて/home用のパーティションを拡張する。ZFSミラー構成なので、行儀は悪いが片方をデタッチ→パーティション作り直し→ミラー再構築の繰り返しで対応する。

ホームディレクトリ用プールをインポート

sudo zpool import zhome

現状を確認。

$ zpool status zhome
  pool: zhome
 state: ONLINE
  scan: scrub canceled on Sun Mar 22 10:40:24 2015
config:
 
	NAME        STATE     READ WRITE CKSUM
	zhome       ONLINE       0     0     0
	  mirror-0  ONLINE       0     0     0
	    ada3p4  ONLINE       0     0     0
	    ada0p4  ONLINE       0     0     0
 
errors: No known data errors

ミラーの片割れada0p4を外す。

$ sudo zpool detach zhome ada0p4
$ zpool status zhome
  pool: zhome
 state: ONLINE
  scan: scrub canceled on Sun Mar 22 10:40:24 2015
config:
 
	NAME        STATE     READ WRITE CKSUM
	zhome       ONLINE       0     0     0
	  ada3p4    ONLINE       0     0     0
</code bash>
 
現在のパーティション構成を確認し、不要なものを消す。
<code bash>
$ gpart show ada0
=>        34  1953525101  ada0  GPT  (931G)
          34           6        - free -  (3.0k)
          40         128     1  freebsd-boot  (64k)
         168    41943040     2  freebsd-swap  (20G)
    41943208   125829120        - free -  (60G)
   167772328  1785548000     4  freebsd-zfs  (851G)
  1953320328      204807        - free -  (100M)
 
$ sudo gpart delete -i 2 ada0
ada0p2 deleted
$ sudo gpart delete -i 4 ada0
ada0p4 deleted
$ sudo gpart delete -i 1 ada0
ada0p1 deleted

でもって/home用のパーティションを作り直す。後ろに少し空きを持たせてるのは、HDD交換時に同容量を謳っていても微妙な容量違いで交換出来ない\(^o^)/という状況を防ぐため(1.5Gはやり過ぎだけど)。

$ sudo gpart add -a 4k -s 930g -t freebsd-zfs ada0
ada0p1 added
$ gpart show ada0
=>        34  1953525101  ada0  GPT  (931G)
          34           6        - free -  (3.0k)
          40  1950351360     1  freebsd-zfs  (930G)
  1950351400     3173735        - free -  (1.5G)

今しがた作ったパーティションで再びミラーにする。

$ sudo zpool attach zhome ada3p4 ada0p1
$ zpool status zhome
  pool: zhome
 state: ONLINE
status: One or more devices is currently being resilvered.  The pool will
	continue to function, possibly in a degraded state.
action: Wait for the resilver to complete.
  scan: resilver in progress since Sun Mar 29 11:57:01 2015
        34.4M scanned out of 389G at 1.19M/s, 93h9m to go
        34.1M resilvered, 0.01% done
config:
 
	NAME        STATE     READ WRITE CKSUM
	zhome       ONLINE       0     0     0
	  mirror-0  ONLINE       0     0     0
	    ada3p4  ONLINE       0     0     0
	    ada0p1  ONLINE       0     0     0  (resilvering)
 
errors: No known data errors

389GBを2.5時間程でリビルド出来た。ada3の方も同様に行う。

両HDDとも拡張ができたら、仕上げにzpoolに容量拡張を通知して初めてプール容量が増える(autoexpandプロパティがonになってれば勝手に増えるけども)。

$ zfs list zhome
NAME    USED  AVAIL  REFER  MOUNTPOINT
zhome   389G   446G   152K  /zhome
 
$ sudo zpool online -e zhome ada0p1
zfs list zhome
NAME    USED  AVAIL  REFER  MOUNTPOINT
zhome   389G   525G   152K  /zhome

slog/L2ARCの有効化

/home用プールzhomeにslogとL2ARCを追加する。slog追加時mirror指定をしないとミラーにならなず、かと言って付けなくても失敗はしないので要注意。

$ sudo zpool add zhome log mirror ada1p3 ada9p3
$ sudo zpool add zhome cache ada9p5
$ zpool status zhome
  pool: zhome
 state: ONLINE
  scan: resilvered 389G in 2h31m with 0 errors on Sun Mar 29 16:58:56 2015
config:

	NAME        STATE     READ WRITE CKSUM
	zhome       ONLINE       0     0     0
	  mirror-0  ONLINE       0     0     0
	    ada0p1  ONLINE       0     0     0
	    ada3p1  ONLINE       0     0     0
	logs
	  mirror-1  ONLINE       0     0     0
	    ada1p3  ONLINE       0     0     0
	    ada9p3  ONLINE       0     0     0
	cache
	  ada9p5    ONLINE       0     0     0