HDD のパーティションの一つを ZFS にして、その ZFS に、FreeBSD 8.0 をインストールする手順。

注意

 この文章は、あくまでも私がおこなった作業の個人的な記録として作成したものです。その内容の大部分は、裏付けのない個人的な推測や妄想などによって構成されています。事実の誤認や、不適切な処理や、誤った翻訳なども含んでいるかと思われます。

 もし万が一にも、このような信頼のできない文章を何かの参考にしようとしたり、その記述に何らかの事実が含まれていると誤認してしまったために、損害を被ったとしても、私にその責任は負えません。

はじめに

なにをしようとしているのか。

 これからやろうとしていることは、二つ。まず一つは、SOTEC C103 というノートパソコンの HDD の空き領域の一つを、ブート可能な ZFS ファイルシステムとする。そして二つは、その ZFS ファイルシステム上に、FreeBSD 8.0 をインストールする。

 なお、このノートパソコン SOTEC C103 の HDD は、過去に FreeBSD 7.2 をインストールしたときに、パーティションを四つほどに区切ってある。先頭の二つは、Windows XP のリカバリ領域と、Windows XP の領域。三つめは、何か他の OS などを使ってみたくなったときのために開けてある未使用の領域。四つめは、FreeBSD 7.2 をインストールした領域。

 今回は、この四番目の領域を更地にして、ここに ZFS ファイルシステムを構築し、FreeBSD 8.0 をインストールしてみようと思う。

 インストールが無事に完了したら、第二パーティションにすでにインストールずみの Windows XP と、これから四番目のパーティションにインストールする FreeBSD 8.0 とあわせて、デュアルブートになるだろう。

その手順の大雑把な説明。

 大雑把に四つの手順から成る。

0. 下準備
まず、8.0-RELEASE-i386-memstick.img というファイルを USB メモリに書き込み、起動可能な USB メモリを作成する。完成する USB メモリは、FreeBSD 8.0 i386 版のインストールディスクとなる。
1. ブート可能な ZFS ファイルシステムを構築する。(1. Creating a bootable ZFS Filesystem)
下準備で作成した USB メモリを用いて SOTEC C103 を起動する。そしてこの C103 の HDD の四番目のパーティションに、ブート可能な ZFS ファイルシステムを作成する。
2. ZFS filesystem に FreeBSD 8.0 をインストールする。(2. Installing FreeBSD to the ZFS filesystem)
作成した ZFS ファイルシステム上に、FreeBSD 8.0 をインストールする。
3. 最後の総仕上げ。(3. Finish install)
最後にこまごまとした設定を行ないインストールを完了し、再起動。

 なお、ここで言う「パーティション」とは、FreeBSD の用語に従えば「スライス」ということになるそうだ。*1

 以下の私の文章でも、この FreeBSD の語法に従うことにした。なので以降の文中に登場する「スライス」は MS-DOS などでいう「パーティション」を指す。また以降の文中で「パーティション」という言葉があれば、それは「スライス」の中をさらにいくつかに区切った小領域のことを指す。(小領域といっても、優に 90GB はあるが)


作業環境と用意したもの。
  • ノートパソコン。SOTEC C103 (CPU Atom N270, メモリ 1GB, HDD 160GB. この HDD は過去に GParted Live によって、四つほどにパーティションを区切ってある。)
  • 1GB の USB メモリ
  • 8.0-RELEASE-i386-memstick.img ファイル。
  • すでに FreeBSD をインストールずみのデスクトップパソコン一台。(Windows 機や、Linux 機などでも可)

 8.0-RELEASE-i386-memstick.img は、Bittorrent を用いてダウンロード()し、FreeBSD 8.0-RELEASE Announcement のページで Checksum を確認。

0. 下準備

 この下準備では、以下の二つのことを行なう。

  1. まず、起動可能な USB メモリを作成し、
  2. つぎにそのUSB メモリからノートパソコン C103 を起動する。
起動可能な USB メモリを作成

 あらかじめダウンロードしておいた 8.0-RELEASE-i386-memstick.img を USB メモリに書き込む。この作業は、ノートパソコンとは別のデスクトップパソコンで行なった。

 まず、USB メモリをデスクトップパソコンに挿入。 dmesg などのコマンドで、この USB メモリが /dev/da0 として認識されていることを確認。

 ルートになって、dd コマンドを用いて、 /dev/da0 に対して、 8.0-RELEASE-i386-memstick.img を書き込む。

# dd if=8.0-RELEASE-i386-memstick.img of=/dev/da0 bs=10240 conv=sync

 これで、起動可能な USB メモリができあがった。今回は、FreeBSD マシンで行なったが、起動可能な USB メモリを作成できるのであれば、Linux でも、Windows でも、どんなマシンを使ってもかまわない。

USB メモリから C103 を起動

 完成した USB メモリを SOTEC C103 に差し込み、BIOS を設定し、USB メモリからブート。これであとは、キーボードなどの設定画面を経ると、以下のような FreeBSD 8.0 のインストール画面(sysinstall)に進むことになるだろう。

┌───────── FreeBSD/i386 8.0-RELEASE-p2 - sysinstall Main Menu ──┐
│ Welcome to the FreeBSD installation and configuration tool.  Please      │
│ select one of the options below by using the arrow keys or typing the    │
│ first character of the option name you're interested in.  Invoke an      │
│ option with [SPACE] or [ENTER].  To exit, use [TAB] to move to Exit.     │
│ ┌──────────────────────────────────┐ │
│ │   Usage         Quick start - How to use this menu system          │ │
│ │  Standard       Begin a standard installation (recommended)        │ │
│ │  Express        Begin a quick installation (for experts)           │ │
│ │   Custom        Begin a custom installation (for experts)          │ │
│ │  Configure      Do post-install configuration of FreeBSD           │ │
│ │  Doc            Installation instructions, README, etc.            │ │
│ │  Keymap         Select keyboard type                               │ │
│ │  Options        View/Set various installation options              │ │
│ │  Fixit          Repair mode with CDROM/DVD/floppy or start shell   │ │
│ │  Upgrade        Upgrade an existing system                         │ │
│ │  Load Config..  Load default install configuration                 │ │
│ │  Index          Glossary of functions                              │ │
│ └──────────────────────────────────┘ │
├─────────────────────────────────────┤
│                        [ Select ]    X Exit Install                      │
└─────────────────────────────────────┘

 ここから先の作業手順はすべて基本的には、以下の URL に従った。
http://wiki.freebsd.org/RootOnZFS/ZFSBootPartition

 以下の文章も、そのほとんどは上記の wiki に提示されていた処理を、逐次的に実行した結果を記録したもの。上記の記事中で、途中、何ヶ所か、私の環境にあわない記述に関しては、その都度、読み替えて実行した。

1. ブート可能な ZFS ファイルシステムを構築する。(1. Creating a bootable ZFS Filesystem)

 さて、この FreeBSD のインストール画面から、Fixit というオプションを選択し、ここから手動で HDD のジオメトリをいじりつつ、ブート可能な ZFS ファイルシステムをつくりあげていくことになる。

 ここでは、以下の6つの作業を順番に行なっていく。これら6つが完了したら、2. ZFS filesystem に FreeBSD 8.0 をインストールするに進むことになる。なお括弧内には、上記 wiki の対応する項目を記述した。

手順
  1. C103 の四番目のスライスの全パーティションを、削除する。
  2. 四番目のスライスに、二つパーティションを作成する。一つは ZFS 用に。一つは swap 用に。(6. Create partitions (ad0s3a and ad0s3b) )
  3. つぎに、ZFS kernel module を load する。(7. Load ZFS kernel module)
  4. ZFS Pool zroot を作成する。(8. Create ZFS Pool zroot)
  5. boot マネージャのインストール。(9. Install boot Manager )
  6. ZFS boot のインストール。(10. Install ZFS boot)
1. C103 の四番目のスライスの全パーティションを、削除する。

 さて。私のノートパソコン C103 は、その内蔵 HDD の四番目のスライスに、FreeBSD 7.2 をインストールしている。

 いまからこの四番目のスライスの中身をぜんぶ削除して、ここに FreeBSD 8.0 をインストールしようと思う。そのため上記 wiki 中の、"3. Create MBR disk" と "4. Create Slice using gpart" の手順は省略した。

 まず、 ls /dev コマンドなどで、この内蔵 HDD が、/dev/ad4 と認識されていることを確認した。つぎに、この /dev/ad4 の四番目のスライスである ad4s4 の構成を gpart show コマンドで確認してみよう。

Fixit# gpart show ad4s4
=>	0		198905868	ad4s4	BSD		(95G)
	0		1048576		1	freebsd-ufs	(512M)
	1048576		8388608		2	freebsd-swap	(4.0G)
	9437184		4141056		4	freebsd-ufs	(2.0G)
	13578240	8388608		5	freebsd-ufs	(4.0G)
	21966848	176939020	6	freebsd-ufs	(84G)


 つぎに、gpart delete で 以上の ad4s4 スライス内の全パーティションを消してしまう。

Fixit# gpart delete -i 1 ad4s4
Fixit# gpart delete -i 2 ad4s4
Fixit# gpart delete -i 4 ad4s4
Fixit# gpart delete -i 5 ad4s4
Fixit# gpart delete -i 6 ad4s4


 消えたかどうか gpart show で確認してみよう。

Fixit# gpart show ad4s4
=>	0	198905868	ad4s4	BSD		(95G)
	0	198905868		- free -	(95G)

 どうやら無事に消えて、かわりに 95GB の空き領域が生まれたようだ。

2. 四番目のスライスに、二つパーティションを作成する。一つは ZFS 用に、一つは swap 用に。(6. Create partitions (ad0s3a and ad0s3b) )

 では、この 95GB の空き領域のある ad4s4 スライス内に、あらためて ad4s4a と ad4s4b の二つのパーティションを作成しよう。そしてそのうちの一つを ZFS 用の領域にしよう。もう一つは、スワップ用の領域にしよう*2。とりあえずスワップ領域には 4GB もあればいいと思う。

 なぜなら、このノートパソコンが搭載できるメモリが最大で 2GB であるので、その2倍ということで、4GB にすることにした。また、上記 wiki 中の例でも、4GB として、8380811セクタを割り当てていることであるし。*3

 さて、ではこの ad4s4 の空き領域 95GB から、まず ZFS 用の領域を割り当てよう。swap 用の領域に 4GB を割り当てることにしたわけだから、4GB 分を残して、91GB をぜんぶ ZFS 用に割り当てることになる。

 割り当ては gpart コマンドを用いて、セクタ数で指定しているようだ。wiki の記述によれば、1セクタが、512バイトらしい。

 私の HDD の空き容量は、さきほどの gpart show で示されたように、95 GB の 198905868 セクタ。ここから、swap 用に 4GB の 8380811 セクタを引いて計算すると、198905868 - 8380811 = 190525057 となる。

 なので、さっそく以下のコマンドで、190525057 セクタを ZFS 用に割り当てよう。実行後は、gpart show コマンドで、その結果を確認してみよう。

Fixit# gpart add -i 1 -b 0 -s 190525057 -t freebsd-zfs ad4s4
ad4s4a added
Fixit# gpart show ad4s4
=>	0		198905868	ad4s4	BSD		(95G)
	0		190525057	1	freebsd-zfs	(91G)
	190525057	8380811			- free -	(4.0G)

 これで上記の出力結果が示しているように、8380811 セクタこと、4.0GB の空き領域が残った。あとはこの残りの 190525057 番目のセクタから、残余の 8380811 個のセクタを、以下のコマンドで swap 領域に割り当てる。やはりここでも実行後は、gpart show で、その結果を確認している。

Fixit# gpart add -i 2 -b 190525057 -s 8380811 -t freebsd-swap ad4s4
ad4s4b added
Fixit# gpart show ad4s4
=>	0		198905868	ad4s4	BSD		(95G)
	0		190525057	1	freebsd-zfs	(91G)
	190525057	8380811		2	freebsd-swap	(4.0G)

Fixit#

 これで上記の出力結果が示しているように、無事に、ZFS に 91GB、swap に 4.0GB の領域が設定できた。このあとは基本的に、上記 wiki とほぼ同じ手順をたどることになる。

3. つぎに、ZFS kernel module を load する。(7. Load ZFS kernel module)
Fixit# kldload /mnt2/boot/kernel/opensolaris.ko
Fixit# kldload /mnt2/boot/kernel/zfs.ko

 FreeBSD のカーネルは、モジュール化に対応しているそうだ。つまり動作中のカーネルに、何か別のモジュール(部品)を取り付けてやれば、そのカーネルはその取り付けたモジュールが提供するいろいろな機能を新たに実行できるようになるらしい。

 上記の kldload コマンドが、そのモジュールをカーネルに取り付けるためのコマンド。上記の kldload を実行することによって、このカーネルは、zfs.ko や opensolaris.ko というモジュールが提供する ZFS 機能を使用できるようになった。

4. ZFS Pool zroot を作成する。(8. Create ZFS Pool zroot)

 まずはじめに、下の zpool create zroot /dev/ad4s4a というコマンドによって、zroot という名前の ZFS pool を作成している。(この /dev/ad4s4a の部分は、自分の環境にあわせて読み替えることを忘れずに。)

Fixit# mkdir /boot/zfs
Fixit# zpool create zroot /dev/ad4s4a
Fixit# zpool set bootfs=zroot zroot

 ZFS pool とは、ZFS ファイルシステムの記憶領域。

 ZFS というファイルシステムは、実際のさまざまな種類のディスクデバイスなどをいくつかまとめあげて、まずプール (pool) という記憶領域をつくり、この記憶領域の上にデータセット (dataset) というファイルシステムを構築し、そしてそこに対してデータの読み書きなどを行なうという考え方のシステムらしい。

 上の例では、そのプールは、/dev/ad4s4a (ad4 というハードディスク・デバイスの、四番目のスライスの、aというパーティション)によって実際には担われることになる。

 また、man zpool コマンドによれば、プールはいくつかのプロパティを持っているそうだ。上記三行目の zpool set というコマンドによって、いま作ったばかりの zroot という名前のプールに対して、プロパティを設定している。具体的にいえば、zroot プールの bootfs というプロパティに、zroot という値を設定している。

 この bootfs というプロパティは、デフォルトのブート可能な dataset を指定するためのものだそうだ。なお、dataset というのは、pool の上に構築される ZFSファイルシステムのことを指すようだ。(以上は、man コマンドの zpool(1M) より)


 なにがなんだか、よくわからないので検索してみた。下のようなページが見つかった。

Booting from a ZFS file system differs from booting from UFS file system because with ZFS, a device specifier identifies a storage pool, not a single root file system. A storage pool can contain multiple bootable datasets or ZFS root file systems. When booting from ZFS, you must specify a boot device and a root file system within the pool that was identified by the boot device.

Oracle Documentation

かなりあやふやな翻訳:(ZFS ファイルシステムからブートするということは、UFS ファイルシステムからブートするということとは、違う。なにが違うのかといえば、ZFS では、ストレージ・プールを起動デバイスとして指定できる。そしてストレージ・プールは、複数のブート可能なデータセットや、複数の ZFS ルート・ファイルシステムなどから構成され得る。つまり ZFS は、単一のルート・ファイルシステムだけからなるようなシステムとは違う。

 なので、ZFS からブートさせる場合は、あなたは、どのデバイスからブートさせるのかをまず指定しなければならないし、それだけではなくさらに、そのブートデバイスが指定するストレージ・プールのなかのどのファイルシステムをルート・ファイルシステムとするのかも指定してやる必要がある。)

 というわけで、この bootfs というプロパティは、zroot プール内の、どのファイルシステム(どのデータセット)からブートさせるのか(つまりどのデータセットを、デフォルトのルートファイルシステムとするのか)を、指定するためのプロパティのようだ。ここでは「bootfs=zroot」と入力しているので、デフォルトではこの zroot プールのそのトップディレクトリ(という表現が正確なのかわからないが)からブートし、そのトップディレクトリをルートとするように設定したということになるのだろうか。

5. boot マネージャのインストール。(9. Install boot Manager )

 私のノートパソコン C103 には、すでに boot マネージャがインストールされている。以前、FreeBSD 7.2 をインストールしたさいに、boot マネージャをインストールしたのだ。なので下の gpart bootcode -b の手順は省略し、つぎの6. ZFS boot のインストール(10. Install ZFS boot)に進んだ。

Fixit# gpart bootcode -b /mnt2/boot/boot0 ad4
ad4 has bootcode
6. ZFS boot のインストール。(10. Install ZFS boot)

 boot コードをインストールする前に、まず zroot を export しよう。下のコマンドによって、先ほど作成した zroot という名前のプールが、export される。(おそらく、これからこの zroot を実装しているハードディスク・スライス (ad4s4) に直接書き込みを行なうので、その書き込みの前に zroot を unmount しておくような感じだろうか)

Fixit# zpool export zroot

 つぎは、dd コマンドを用いて boot1 stage をインストールする。dd コマンドに渡してやるデバイス名 (/dev/ad4s4) は、自分の環境に応じて読み替えることを忘れずに。(この of=/dev/ad4s4 は、どのディスクにデータを書き込むかを指定している。この指定を間違えると、意図しないディスクにデータを書き込むことになる。)

Fixit# dd if=/mnt2/boot/zfsboot of=/dev/ad4s4 count=1
1+0 records in
1+0 records out
512 bytes transferred in 0.004847 secs (105631 bytes/sec)
Fixit# 

 私は、無事に /dev/ad4s4 に、ブート用コードである boot1 stage を書き込むことができた。もし以下のようなエラーが表示されて、書き込みに失敗した場合は、sysctl コマンドを実行すると良いらしい。

This may fail with an "operation not permitted" error message, since the kernel likes to protect critical parts of the disk. If this happens for you, run:

Fixit# sysctl kern.geom.debugflags=0x10

翻訳:(もしかしたら、"operation not permitted" というエラーメッセージが表示されて、dd コマンドの実行に失敗するかもしれない。なぜ失敗するかといえば、カーネルは、ディスクの重要な部分を保護したがるからだ。もし失敗した場合は、以下を実行すると良い。)

Fixit# sysctl kern.geom.debugflags=0x10


 私はうまくいったので、上記の sysctl の手順は無視して、先にすすむ。つぎは boot2 zfs stage を インストール。

Install the boot2 zfs stage into the convienient hole in the ZFS filesystem on-disk format which is located just after the ZFS metadata (this is the seek=1024).

翻訳:( boot2 zfs stage をインストールしよう。どこにインストールするのかといえば、ZFS metadata のすぐあとに。つまり 1024 以降に)

 以下の dd コマンドを実行するときも、やはり /dev/ad4s4a を自分の環境にあわせて読み替えることを忘れずに。

Fixit# dd if=/mnt2/boot/zfsboot of=/dev/ad4s4a skip=1 seek=1024
64+0 records in
64+0 records out
32768 bytes transferred in 0.010192 secs (3215021 bytes/sec)
Fixit# 

 さて、これで ZFS boot (ZFS の起動コード)をインストールしおわった。起動可能な ZFS ファイルシステムの構築はこれで完了である。あとはさきほど一度 export した zroot を以下のコマンドで import したら、つぎに進もう。

Fixit# zpool import zroot

2. ZFS filesystem に FreeBSD 8.0 をインストールする。(2. Installing FreeBSD to the ZFS filesystem)

 さて、前記の手順によって、ad4s4a に、起動可能な ZFS が構築できたので、こんどは、この ZFS 内に FreeBSD 8.0 をインストールする。なかなか面倒な作業だった。つぎにインストールするときまでには、全部、自動化してると嬉しいなと思った。

手順
  1. ZFS ファイルシステムのヒエラルキーを作成する。(1.Create ZFS filesystem hierarchy)
  2. zroot プールに FreeBSD をインストールする。(2. Install FreeBSD to zroot)
  3. /var/empty ディレクトリを readonly にする。(3.Make /var/empty readonly)
  4. chroot コマンドで、/zroot ディレクトリを一時的にルートディレクトリにする。(4.chroot into /zroot)
  5. /etc/rc.conf を作成。(5.Create /etc/rc.conf)
  6. /boot/loader.conf を作成する。(6. Create /boot/loader.conf)
  7. FreeBSD 8.0-RELEASE や 7.0〜7.2-RELEASE なら、ZFS aware /boot/loader をインストール。(7.Install ZFS aware /boot/loader (Required for 8.0-RELEASE and 7.{0-2}-RELEASE) )
  8. root のパスワードを設定。(8. Change root's password)
  9. 時間の設定。(9. Set the local time zone)
  10. Create /etc/mail/aliases.db
  11. chroot を終了して /zroot から抜ける。(11. Exit from the /zroot)
  12. Install zpool.cache to the ZFS filesystem
1. ZFS ファイルシステムのヒエラルキーを作成する。(1.Create ZFS filesystem hierarchy)

 この手順において、zroot プールのなかに、さまざまなファイルシステム(データセット)を作成している。プールのなかのファイルシステム(データセット)とは、旧来のパーティションのようなものだと考えれば良いのだろうか。またここではファイルシステム(データセット)の作成と同時に、各ファイルシステムの圧縮率をどのくらいにするかなども設定している。私はすべて wiki 中にあるサンプル例に従った。

 もし、CPU の計算速度がそれなりに早くて、HDD の容量が乏しいマシンなら、圧縮率を高めに指定すると良いと思う。

 またもし、今後、この FreeBSD マシンをファイルの保存用サーバや、ファイルのアップローダとして使用するのであれば、そしてそれらのファイルが、zip ファイルなどの圧縮ずみのファイルばかりなのであれば、それらのファイルを保存しておく予定のディレクトリは、圧縮設定を off にしておくと良いのだろう。(圧縮ずみのファイルを圧縮しても、あまりファイルのサイズは小さくならないため。圧縮を行なうための計算機資源が無駄になる。)

 実際、wiki のサンプル例においても、/usr/ports/distfiles や /usr/ports/packages ディレクトリは、圧縮しないように指定している。(基本的に、これら二つのディレクトリには、圧縮ずみファイルが配置されることになるため。)

Fixit# zfs set checksum=fletcher4 zroot
Fixit# zfs create -o compression=on    -o exec=on      -o setuid=off   zroot/tmp
Fixit# chmod 1777 /zroot/tmp
Fixit# zfs create  zroot/usr
Fixit# zfs create  zroot/usr/home
Fixit# cd /zroot ; ln -s /usr/home home
Fixit# zfs create -o compression=lzjb -o setuid=off   zroot/usr/ports
Fixit# zfs create -o compression=off   -o exec=off     -o setuid=off   zroot/usr/ports/distfiles
Fixit# zfs create -o compression=off   -o exec=off     -o setuid=off   zroot/usr/ports/packages
Fixit# zfs create -o compression=lzjb  -o exec=off     -o setuid=off   zroot/usr/src
Fixit# zfs create  zroot/var
Fixit# zfs create -o compression=lzjb  -o exec=off     -o setuid=off   zroot/var/crash
Fixit# zfs create                      -o exec=off     -o setuid=off   zroot/var/db
Fixit# zfs create -o compression=lzjb  -o exec=on      -o setuid=off   zroot/var/db/pkg
Fixit# zfs create                      -o exec=off     -o setuid=off   zroot/var/empty
Fixit# zfs create -o compression=lzjb  -o exec=off     -o setuid=off   zroot/var/log
Fixit# zfs create -o compression=gzip  -o exec=off     -o setuid=off   zroot/var/mail
Fixit# zfs create                      -o exec=off     -o setuid=off   zroot/var/run
Fixit# zfs create -o compression=lzjb  -o exec=on      -o setuid=off   zroot/var/tmp
Fixit# chmod 1777 /zroot/var/tmp
2.Install FreeBSD to zroot

 下のスクリプトの kernels のところは wiki では lib32 となっていた。だが、スクリプトの実行前に ls コマンドで確認してみた結果、私の環境では lib32 というディレクトリが存在しなかった。かわりに、kernels というディレクトリがあったので、lib32 のかわりに kernels と入力してスクリプトを実行した。

 だが、おそらくここで kernels と入力したのは間違いだったと思われる。なぜなら、このしばらくあとの手順で、kernels ディレクトリに別個に移動し、必要な引数をあたえたうえで、install.sh スクリプトを実行しているからだ。(幸い、この私の間違いは、これまでのところ、とくに大きな問題を生じていないようではあるが。)

 なお、lib32 ディレクトリが私の環境下で存在していないのは、おそらく私のインストールしようとしている FreeBSD 8.0 が i386 用のものだからだと思う。amd64 用の FreeBSD 8.0 などなら、lib32 が存在しているのだろうと思う。

Fixit# cd /dist/8.0-RELEASE
Fixit# export DESTDIR=/zroot
Fixit# for dir in base catpages dict doc games info kernels manpages ports; \
          do (cd $dir ; ./install.sh) ; done
You are about to extract the base distribution into /zroot - are you SURE you want to do this over your installed system (y/n)? y
You are about to extract the doc distribution into /zroot - are you SURE you want to do this over your installed system (y/n)? y
You must specify which kernel to extract.
Extracting ports tarball into /zroot/usr
Fixit#

 スクリプトの実行中には、Yes か No かで、同意を求められるので、これには y で回答した。

 とりあえず、上記の "for dir in" 云々というスクリプトについて、私の理解の及ぶ範囲で解説すると、まず /dist/8.0-RELEASE/base ディレクトリに移動し、そのディレクトリ中にある install.sh スクリプトを実行。

 その実行が終わったら、つぎに /dist/8.0-RELEASE/catpages ディレクトリに移動し、そのディレクトリ中にある install.sh スクリプトを実行。

 以下、同様に /dist/8.0-RELEASE/dict や、/dist/8.0-RELEASE/doc や、/dist/8.0-RELEASE/games や、/dist/8.0-RELEASE/info や、/dist/8.0-RELEASE/kernels や、/dist/8.0-RELEASE/manpages や、/dist/8.0-RELEASE/ports ディレクトリに移動して、その各ディレクトリの install.sh スクリプトを順番に実行している。

 なお、 /dist/8.0-RELEASE/kernels ディレクトリ中の install.sh スクリプトは、どうも実行するときは、引数を与えてやる必要があるようだ。そのために上記の出力結果に "You must specify which kernel to extract." (どのカーネルを解凍するのかちゃんと指定してください) という表示が出ているのだろう。やはり、上記で kernels を入力したのは間違いだったのだろう。幸い、とくに問題は引き起こしていないようであるが。


 つぎは、以下のように、src ディレクトリに移動し、install.sh スクリプトを実行。おそらくこれで、$DESTDIR が指し示すディレクトリ(つまり /zroot ディレクトリ配下のディレクトリ)に、 src ディレクトリの中身が解凍されていくのだろう。

Fixit# cd src ; ./install.sh all
  Extracting source component: base
  Extracting source component: bin
  Extracting source component: cddl
  Extracting source component: contrib
  Extracting source component: crypto
  Extracting source component: etc
  Extracting source component: games
  Extracting source component: gnu
  Extracting source component: include
  Extracting source component: krb5
  Extracting source component: lib
  Extracting source component: libexec
  Extracting source component: release
  Extracting source component: rescue
  Extracting source component: sbin
  Extracting source component: secure
  Extracting source component: share
  Extracting source component: sys
  Extracting source component: tools
  Extracting source component: ubin
  Extracting source component: usbin
Done extracting sources.
Fixit#

 さて、上記の処理がおわったら、こんどこそ先ほど間違えた /dist/8.0-RELEASE/kernels ディレクトリ中の install.sh スクリプトをただしく実行しよう。以下のようにして、ディレクトリを移動したうえで、引数に generic を与えて、install.sh スクリプトを実行する。

 そしてスクリプトの実行後は、cd /zroot/boot コマンドで、 /zroot/boot ディレクトリに移動し、そのディレクトリ内にある GENERIC ディレクトリの中身を、/zroot/boot/kernel/ ディレクトリにコピーしよう。

Fixit# cd ../kernels ; ./install.sh generic
Fixit# cd /zroot/boot ; cp -Rlp GENERIC/* /zroot/boot/kernel/
3. /var/empty ディレクトリを readonly にする。(3.Make /var/empty readonly)
Fixit# zfs set readonly=on zroot/var/empty
4. chroot into /zroot する。(4.chroot into /zroot)

 chroot コマンドで、 /zroot ディレクトリをルートディレクトリに設定しよう。

Fixit# chroot /zroot
5. /etc/rc.conf を作成。(5.Create /etc/rc.conf)

 以下の echo コマンドは、早い話が echo を使って /etc/rc.conf を作成しているにすぎない。なお、さきほど chroot /zroot コマンドを実行したので、実際には zroot 上の /etc に rc.conf ファイルが作成されることになる。(つまり /zroot/etc/rc.conf が実際には作成される。)

 なお実行の前に、下記の re0 や "beastie.mydomain.local" の記述は、自分の環境に応じて、読み替えることを忘れてはいけない。re0 のところでは、ネットワークインターフェイスのデバイス名を指定している。"beastie.mydomain.local" では、このマシンにネットワーク上で、どのような名前を与えるかを設定している。

(まあここで肝心なのは、zfs_enable="YES" だけだと思う。hostname と ifconfig の設定は、書き間違えたとしても、起動後にネットワークに接続できないだけで、OS 自体は、おそらく起動すると思う。なので起動後に、sysinstall コマンドなどであらためて設定しても良いかもしれない。よくわからないときは、sysinstall の操作方法について解説しているサイトや、/etc/rc.conf ファイルの書き方について解説しているサイトや、man コマンドなどで、あらためて確認してみると良いと思う。)

Fixit# echo 'zfs_enable="YES"' > /etc/rc.conf
Fixit# echo 'hostname="beastie.mydomain.local"' >> /etc/rc.conf
Fixit# echo 'ifconfig_re0="DHCP"' >> /etc/rc.conf

 入力間違いなどがなければ、以下のような内容のファイルが作成されたと思う。念のため、cat /etc/rc.conf などと入力し、内容を確認しておくと良いと思う。

zfs_enable="YES"
hostname="beastie.mydomain.local"
ifconfig_re0="DHCP"

 もし入力間違いがあったときは、あらためて上記の三行からなる echo コマンドを入力しなおし、そして cat コマンドで中身を確認すれば良いはず。(なにか間違った場所に、rc.conf ファイルを作成してしまったときは、それを削除してからやりなおせば、多分どうにかなるはず)

6. /boot/loader.conf を作成する。(6. Create /boot/loader.conf)

 つぎも同じように echo コマンドを用いて、/boot/loader.conf を作成しよう。

Fixit# echo 'zfs_load="YES"' > /boot/loader.conf
Fixit# echo 'vfs.root.mountfrom="zfs:zroot"' >> /boot/loader.conf

 完成する /boot/loader.conf ファイルは以下のようになるはずだ。cat /boot/loader.conf コマンドなどで中身を確認し、もし間違いがあれば、また上記二行の echo コマンドを入力して、作成しなおせば良いと思う。

zfs_load="YES"
vfs.root.mountfrom="zfs:zroot"
7. FreeBSD 8.0-RELEASE や 7.0〜7.2-RELEASE なら、ZFS aware /boot/loader をインストール。(7.Install ZFS aware /boot/loader (Required for 8.0-RELEASE and 7.{0-2}-RELEASE) )

 もしインストールしようとしている OS のバージョンが、8.0-RELEASE や 7.0〜7.2-RELEASE なら、この手順を実行しよう。もし、それ以降の 8.0-STABLE や 7.2-STABLE などの新しいバージョンをインストールしようとしているのら、この手順は飛ばして、つぎの8. root のパスワードを設定。(8. Change root's password)に行こう。


 さて、私のインストールしようとしているのは FreeBSD 8.0-RELEASE なので、以下を実行することで、 ZFS aware /boot/loader をインストールする必要があるようだ。それ以降の FreeBSD 8.0-STABLE や 7.2-STABLE では、もはやこの手順は必要ないそうだ。(なぜなら、それらの最新版では、ZFS aware boot loader こと /boot/zfsloader なるものをデフォルトでインストールしているためだそうだ。)

 私のわかる範囲で下記の手順を解説すると、まず /etc/src.conf というファイルを作成(実際には、chroot を実行中なので /zroot/etc/src.conf だが)。その内容は LOADER_ZFS_SUPPORT=YES という一行だけのもの。

 つぎに、周辺機器を取り扱えるようにするために、/dev をマウント。(いま現在は、chroot を実行中なので、/dev にアクセスすることもできなくなっている。これを以下の mount -t devfs devfs /dev コマンドによって、再び周辺機器にアクセスできるようにしているのだと思う。)

 つぎに /usr/src/sys/boot ディレクトリに移動し、make obj と入力することで、boot 用のコードをコンパイルする。このコンパイルでは、さきほど /etc/src.conf というファイルを作成したので、その src.conf ファイル中の記述によって、LOADER_ZFS_SUPPORT が有効になる。よって、ZFS を認識できる boot コードがコンパイルされる、という仕組みなのだろう。

Fixit# echo 'LOADER_ZFS_SUPPORT=YES' > /etc/src.conf
Fixit# mount -t devfs devfs /dev
Fixit# export DESTDIR=""
Fixit# cd /usr/src/sys/boot/
Fixit# make obj
Fixit# make depend
Fixit# make

make はけっこう時間がかかるので、お茶でも飲みながら、ゆっくり見守ると良いと思う。無事にコンパイルが完了したら、以下のコマンドでディレクトリを移動し、make install と入力することで、コンパイルずみの boot コードなどのファイルをインストール。

Fixit# cd i386/loader
Fixit# make install
8. root のパスワードを設定。(8. Change root's password)

 以下の passwd コマンドを実行して、root のパスワードを設定しよう。パスワードは、確認のために、二回入力する必要があったと思う。もし入力をうっかり間違えた場合でも、いま現在は、ルートになったままなので、また再び passwd コマンドを入力すれば、何度でもパスワードを再設定できたと思う。

Fixit# passwd
9. タイムゾーンの設定。(9. Set the local time zone)

 以下の tzsetup コマンドで時刻を設定しよう。過去に数回、FreeBSD をインストールしてみたことがあれば、おなじみの画面だと思う。この tzsetup の設定は、ここで行なわなくても、再起動後にあらためて、sysinstall から実行しても問題ないと思う。

Fixit# tzsetup

 ここでは以下のように尋ねられるので、とりあえず私は No と答えた。

Is this machine's CMOS clock set to UTC?

 あとは、5 番の Asia を選び、そこから、18 の Japan を選択した。とくに重要な設定ではないので、適当にすませれば良いと思う。(もちろん適当に設定すれば、時刻の表示は変になるが、OS が起動しなくなるというほどの重要さではないと思う。)

10. Create /etc/mail/aliases.db
Fixit# cd /etc/mail
Fixit# make aliases
11. Exit from the /zroot

 exit コマンドで、chroot を終了しよう。これによってルートディレクトリは、/zroot から、もとの / に戻ることになる。

 ところでもしかしたら exit の前の umount /dev というコマンドは、7. FreeBSD 8.0-RELEASE や 7.0〜7.2-RELEASE なら、ZFS aware /boot/loader をインストールを実行していない場合は、必要ないものかもしれない。私は 7. の手順を実行したので、未確認だが。

Fixit# umount /dev
Fixit# exit
12. Install zpool.cache to the ZFS filesystem
Fixit# cp /boot/zfs/zpool.cache /zroot/boot/zfs/zpool.cache

3. 最後の総仕上げ。(3. Finish install)

 さて、ここまでくれば、あとは細々とした作業を残すのみ。最後の手順は以下の通り。

  1. /etc/fstab を作成。(1. Create /etc/fstab)
  2. 環境変数 LD_LIBRARY_PATH を設定。(2. export LD_LIBRARY_PATH)
  3. すべての zfs ファイルシステムを unmount しよう。(3. Unmount all zfs filesystems)
  4. Change mount points for zroot pool
  5. Fixit mode を終了して、sysinstall 画面に戻り、sysinstall も終了して、再起動しよう。(5. Exit Fixit mode, and then sysinstall. Remove the FreeBSD install DVD/Memstick and the system will boot using the ZFS root.)
1. /etc/fstab を作成。(1. Create /etc/fstab)

 以下のように、cat とヒアドキュメントを用いて、/etc/fstab ファイルを作成しよう。多分、これも echo などで作成しても良いと思う。ad4s4b は、自分の環境にあわせて読み替えることを忘れずに。

Fixit# cat << EOF > /zroot/etc/fstab
# Device Mountpoint FStype Options Dump Pass#
/dev/ad4s4b none swap sw 0 0
EOF

 ただしく入力できたなら、以下のようなファイルが作成されていることだと思う。これも cat /zroot/etc/fstab などで確認してもいいかもしれない。もし内容に間違いがあれば、またあらためて上記の cat コマンドを入力すれば良いと思う。

# Device Mountpoint FStype Options Dump Pass#
/dev/ad4s4b none swap sw 0 0
2. 環境変数 LD_LIBRARY_PATH を設定。(2. export LD_LIBRARY_PATH)

 以下で、環境変数 LD_LIBRARY_PATH に /mnt2/lib を設定。

Fixit# export LD_LIBRARY_PATH=/mnt2/lib 
3. すべての zfs ファイルシステムを unmount しよう。(3. Unmount all zfs filesystems)

 wiki の記述に従い、以下のように zfs unmount -a を実行したのだが、 Device busy と言われてしまった。

Fixit# zfs unmount -a
cannot unmount '/zroot': Device busy

 もしかしたら、どこかで私が何かの手順を飛ばしたのかもしれない。まあこれは、下のように、cd / コマンドによって root ディレクトリに移動してから、あらためて上記の unmount コマンドを実行することで、無事に unmount することができた。蛇足ながら、その手順は以下の通り。

Fixit# pwd
/zroot/boot
Fixit# cd /
Fixit# zfs unmount -a
4. Change mount points for zroot pool
Fixit# zfs set mountpoint=legacy zroot
Fixit# zfs set mountpoint=/tmp zroot/tmp
Fixit# zfs set mountpoint=/usr zroot/usr
Fixit# zfs set mountpoint=/var zroot/var
5. Fixit mode を終了して、sysinstall 画面に戻り、sysinstall も終了して、再起動しよう。(5. Exit Fixit mode, and then sysinstall. Remove the FreeBSD install DVD/Memstick and the system will boot using the ZFS root.)

 インストールは以上で終了。あとは、たしか exit コマンドを入力して、Fixit mode を抜けよう。すると多分 sysinstall 画面に戻ったような気がするので、それも "Exit Install" を選択して終了し、パソコンを再起動しよう。

 インストールが正しく完了しているのであれば、再起動によって、まずブートマネージャが起動するだろう。そのマネージャから、今回 zfs をインストールしたスライスを指定してやれば、FreeBSD 8.0 が起動することだろう。なお、再起動時には、USB メモリを外しておくことを忘れずに。

 これでインストール作業は終了であるけれど、i386 用の FreeBSDZFS を安定的に動かすためには、このあといくつか微調整を行なう必要がある。その微調整をしていないと、ちょっと重たい仕事をさせたりすると、メモリ不足などにより、フリーズしたり、リブートしたりすることになると思う。

 その微調整については、以下を参照。
ZFSTuningGuide - FreeBSD Wiki

*1:[http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/disk-organization.html:title]

*2:swap 用の領域も、ZFS Pool 上に作成することは可能だが、上記 wiki によれば、その場合は crash dump が作成されなくなるそうだ。"While a ZFS Swap Volume can be used instead of the freebsd-swap partition, crash dumps can't be created on the ZFS Swap Volume." [http://wiki.freebsd.org/RootOnZFS/ZFSBootPartition:title] より引用。

*3:ところで、上記 wiki 中の "Fixit# gpart add -i 1 -b 0 -s 40663421 -t freebsd-zfs ad0s3" という記述にある "40663421" という数字は、"406631421" の誤植だと思う