ここのことはなかったことにするかもしれない

仕事がらみの記事を主として扱いますが、あくまで個人ブログです。2013年以前の記事は https://yellow-73.hatenablog.com/ にあります。

ほぼZFS構成なうえキャッシュファイルをbsdinstallのシェルからアクセスできるようにしてみた

http://d.hatena.ne.jp/yellow_73/20131003#p1のつづきというか改訂版。

クリーンインストールをやりたい

これまで、わざわざファイルシステムをrpool/rootとrpool/homeに分けてきてましたが、これは、システムのクリーンインストールができるようにしたかったため、それだけです。rpool/rootをぶっ潰してい、でもrpool/homeは無傷にしたかったのです。

だがしかし、bsdinstallでクリーンインストールを試みると、ファイルシステムはおろか、そもそもプールが発見できない。zpool createでプールを作ることは可能ですが、そんなことしちゃうと、完全に上書きして、以前のファイルシステムは消えてなくなります。これは困った。

/dev/gpt/disk[n]の内容は書き換わっていないはずなので、どうにかプールの構成を教えてやるとOKになるはず。いろいろ見てると、キャッシュファイルにプールの構成設定が書いてあるので、それを使うといいはず。

でもキャッシュファイルをzfs内に保存すると、プールさえ復活させられてないので読めない。見事に詰んだわorz

とりあえず、ufsならマウント可能なので、そちらにキャッシュファイルを複製しとけば、bsdinstallのシェルからでもマウントできるんじゃないかと試したところ、なんとかうまくいきました。

その作業の手順を以下にメモしておきます。

前回との相違点

  • キャッシュファイルをufs上に保存するようにしました
  • rpool/rootについてもレガシーにしました

セットアップ

前提
  • プール名はrpool
  • ルートは128G上限
  • swapはzvolを利用
  • その他はホーム
  • レガシーにする
  • キャッシュファイルをufs上に保存
bsdinstallの途中でシェルを起動する

bsdinstallを使って、いつものインストール調子でパーティションを切る直前"Partitioning"ダイアログまで行き、ここで"Shell"を選択。

パーティションをクリア

まずパーティションが残ってるようなら強制削除してやる。

gpart destroy -F /dev/mfisyspd0
gpart destroy -F /dev/mfisyspd1
gpart destroy -F /dev/mfisyspd2
gpart destroy -F /dev/mfisyspd3
gptを作成
gpart create -s gpt /dev/mfisyspd0
gpart create -s gpt /dev/mfisyspd1
gpart create -s gpt /dev/mfisyspd2
gpart create -s gpt /dev/mfisyspd3
ブートパーティション作成とbootcode書き込み
gpart add -s 64K -t freebsd-boot /dev/mfisyspd0
gpart add -s 64K -t freebsd-boot /dev/mfisyspd1
gpart add -s 64K -t freebsd-boot /dev/mfisyspd2
gpart add -s 64K -t freebsd-boot /dev/mfisyspd3
gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 /dev/mfisyspd0
gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 /dev/mfisyspd1
gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 /dev/mfisyspd2
gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 /dev/mfisyspd3

全てのHDDにブートコードを書いていますが、これはHDD0が壊れた際でもブートするようにするためです。

キャッシュファイル保存用ファイルシステムを作成・マウント。
gpart add -s 8M -t freebsd-ufs /dev/mfisyspd0
gpart add -s 8M -t freebsd-ufs /dev/mfisyspd1
gpart add -s 8M -t freebsd-ufs /dev/mfisyspd2
gpart add -s 8M -t freebsd-ufs /dev/mfisyspd3

newfs /dev/mfisyspd0p2
newfs /dev/mfisyspd1p2
newfs /dev/mfisyspd2p2
newfs /dev/mfisyspd3p2
mkdir -p /tmp/cache/disk0
mkdir -p /tmp/cache/disk1
mkdir -p /tmp/cache/disk2
mkdir -p /tmp/cache/disk3

# 繰り返しごとに2箇所変更
mount /dev/mfisyspd0p2 /tmp/cache/disk0
mount /dev/mfisyspd1p2 /tmp/cache/disk1
mount /dev/mfisyspd2p2 /tmp/cache/disk2
mount /dev/mfisyspd3p2 /tmp/cache/disk3

全てのHDDに作成しているのもブートパーティションと同じ理由。

zfsパーティションを作成

disk[n] と mfisyspd[n] の2箇所が0,1,2,3となっているので注意しましょう。
4コマンドすべてdisk0にしてしまって、/dev/gpt/disk0だけしかない!なんてことにならないようorz

# 繰り返しごとに2箇所変更
gpart add -t freebsd-zfs -l disk0 /dev/mfisyspd0
gpart add -t freebsd-zfs -l disk1 /dev/mfisyspd1
gpart add -t freebsd-zfs -l disk2 /dev/mfisyspd2
gpart add -t freebsd-zfs -l disk3 /dev/mfisyspd3
zfsプールの作成
zpool create -f -m none rpool raidz1 \
  /dev/gpt/disk0 /dev/gpt/disk1 /dev/gpt/disk2 /dev/gpt/disk3
swapのためにzvolを切り出す

rpool/swap0という名前で64Gのzvolを切り出す("-V"でzvol切りだしになります)

zfs create -V 64G -o checksum=off rpool/swap0
rpool/root, rpool/home 作成

rpool/rootには128Gの制限をかけました。
rpool/rootをbootfsにしました。そうしないと、インストール完了後のリブート時にこけます。

zfs create -o mountpoint=legacy rpool/root
zfs create -o mountpoint=legacy rpool/home
zfs set quota=128G rpool/root

zpool set bootfs=rpool/root rpool

mount -t zfs rpool/root /mnt

試しに、/mnt/homeを作り、rpool/homeをマウントしてみます。

mkdir /mnt/home
mount -t zfs rpool/home /mnt/home
キャッシュファイルの作成と退避
zpool export rpool
# どうも/dev/mfisyspd0p2()を検索に行っているので、/dev/gptに限定して探索させる。
zpool import -d /dev/gpt -o cachefile=/tmp/rpool.cache rpool

cp -p /tmp/rpool.cache /tmp/cache/disk0
cp -p /tmp/rpool.cache /tmp/cache/disk1
cp -p /tmp/rpool.cache /tmp/cache/disk2
cp -p /tmp/rpool.cache /tmp/cache/disk3
再マウント

zpool exportでマウントが外れているので、マウントをやり直しておく。

mount -t zfs rpool/root /mnt
いったん終了してbsdinstallを続行

シェルをexitで抜けて、bsdinstallを続行します。
でもリブートまでしたらダメです。

インストール完了直前でシェルに入る

最後に"Manual Configuration"ダイアログが出て、最後の手動設定をしますか?と聞かれるので"Yes"とします。

設定ファイルを記述

loaderでzfsモジュールを読むことと、ルートをrpool/rootとすることを設定します。zfsモジュールが依存するopensolarisモジュールはzfsを読む場合に自動で読みます。

vi /boot/loader.conf

zfs_load="YES"

/etc/rc.d/zfs を実行できるようにします。

vi /etc/rc.conf

zfs_enable="YES"

レガシーなマウントのエントリを書きます。

vi /etc/fstab

/dev/zvol/rpool/swap0 none swap sw 0 0
rpool/root / zfs rw 0 0
rpool/home /home zfs rw 0 0
設定完了

シェルを終了して、リブートしましょう。

クリーンインストール

bsdinstallの途中でシェルを起動する

bsdinstallを使って、いつものインストール調子でパーティションを切る直前"Partitioning"ダイアログまで行き、ここで"Shell"を選択。

キャッシュファイルのあるファイルシステムをマウント
mkdir -p /tmp/cache/disk0
mount /dev/mfisyspd0p2 /tmp/cache/disk0
キャッシュファイルを使って復活
zpool import -f -d /dev/gpt -o cachefile=/tmp/cache/disk0/rpool.cache rpool

"-d /dev/gpt" は、復活対象プールが使うデバイスの検索範囲を指定するためです。そうしないと、/dev/mfisyspd0p2 (ufsにしている)にアクセスしようとして、結果、インポートに失敗します。

"-f"は、これが無いと、このファイルシステムは他のシステムで使われてるみたい…とか言われて拒否られるためです。

rpool/rootの作り直し

rpool/rootをつぶして、作って、クォータ付けて、bootfsに設定して(プールの設定ではあるけどzfs destroyで設定を消してるもよう)、マウントします。

zfs destroy rpool/root
zfs create -o mountpoint=legacy rpool/root
zfs set quota=128G rpool/root

zpool set bootfs=rpool/root rpool

mount -t zfs rpool/root /mnt
mkdir /mnt/home
mount -t zfs rpool/home /mnt/home
シェル終了、完了直前で設定ファイルを記述

シェルを終了して、bsdinstallを続行していきます。

あとは先に書いている通りでOKです。

  • "Manual Configuration"ダイアログで"Yes"
  • /boot/loader.conf を編集
  • /etc/rc.conf を編集
  • /etc/fstab を編集
  • シェルを終了してリブート

修正は最初のシェルでもOKなんだけどキーボードがUS

bsdinstallの起動直後の選択肢でシェルの実行が可能です。たとえば「bootfsを設定していなかったよぅ…システムが上がってこないよぅ…」といった場合には、かなり早い時期にzfsモジュールを読んでくれているので、ここからのシェルでもzfs関連の操作はOKです。パーティションを切るところまで進める必要はありません。ただ、キーボードがUSなので、日本語106を使っていると、ちょっと我慢しないといけないかも知れません。