在纯 ZFS 安装 FreeBSD

感觉 FreeBSD 对于 ZFS 的支持相对 Linux 要更完善一些,直接在基础系统就包含了ZFS模块,不像 Linux 需要安装额外的包。操作上也相对简单一点,安装过程如下。

已知问题
FreeBSD-9.x 虽然以全新 bsdinstaller 来安装,可以通过 gpart 来把硬盘格式化成 GPT+freebsd-zfs,但可惜仍不支持直接安装在纯 ZFS。简单来说,FreeBSD-9.x 仍不支持 GPT+ZFS 直接安装。

本文范围
重新划分分区表,把所有旧资料清空。 使用 GPT 规划硬盘分区表。 使用 Single Pool 规划 ZFS。 使用 ZFS 来规划 swap,不必另加独立 swap 分区。 最少安装 FreeBSD Base,reboot 后可以成功从 ZFS 启动 FreeBSD。

硬件环境
Asus N73SV 笔记本电脑 CPU:Intel Core i7 2630QM 12GB DDR3 RAM 750GB 硬盘

安装介质
FreeBSD-9.1-RELEASE-amd64-memstick.img

硬件准备
BIOS 中把 SATA 设为 AHCI 模式。 BIOS 设定由 U 盘启动。

安装介质准备
下载 FreeBSD-9.1-RELEASE-amd64-memstick.img,把它写入 U 盘。

U 盘启动 FreeBSD 9.1

进入 LiveCD 模式
不要选 install 选 LiveCD 输入 root 按 Enter 进入 Live 系统(不用密码)

创建一个 Ramdisk,挂载于 /tmp,用来暂存下文提及的必要文件 /tmp/zpool.cache(可不做)

# umount /dev/md1
# mdmfs -s 512M md1 /tmp

建立 GPT+ZFS 分区 找出硬盘的名称,第一个 AHCI 硬盘通常是 /dev/ada0(FreeBSD-9.x 内核内建 AHCI 支持)。

# ls /dev/ad*

检查硬盘是否有分区

# gpart show ada0

如果有分区,使用 gpart 清空。

由于每部电脑情况不同,这部份请自行 man gpart 学习有关 gpart delete 和 gpart erase 的语法。

清空旧资料后,现在可以重新划分 GPT 分区表。

# gpart create -s gpt ada0

给 FreeBSD 分出一个分区用于启动,注意,如果是物理扇区为 4KB 的高级格式硬盘,要加入 -a 4K 参数以保证扇区对齐

# gpart add -s 64k -t freebsd-boot ada0

剩下的容量都给 ZFS 作为第二个分区,注意,如果是物理扇区为 4KB 的高级格式硬盘,要加入 -a 4K 参数以保证扇区对齐

# gpart add -t freebsd-zfs ada0

把 FreeBSD GPT+ZFS 的 boot loader 写入第一分区。

# gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada0

在第二个分区中,创建 Single Pool 模式的 ZFS,把它命名为 tank。

# zpool create tank /dev/ada0p2
# zpool set bootfs=tank tank
# zfs set checksum=fletcher4 tank

使用 zfs create 命令,在 ZFS 中创建 swap,我建立了 8GB 的 swap。

# zfs create -V 8G tank/swap
# zfs set checksum=off tank/swap
# zfs set org.freebsd:swap=on tank/swap

使用 zfs create 命令,创建系统目录结构。

# zfs set mountpoint=/mnt tank
# zfs create tank/usr
# zfs create tank/usr/home
# zfs create tank/var
# zfs create -o compression=on -o exec=on -o setuid=off tank/tmp
# zfs create -o compression=lzjb -o setuid=off tank/usr/ports
# zfs create -o compression=off -o exec=off -o setuid=off tank/usr/ports/distfiles
# zfs create -o compression=off -o exec=off -o setuid=off tank/usr/ports/packages
# zfs create -o compression=lzjb -o exec=off -o setuid=off tank/usr/src
# zfs create -o compression=lzjb -o exec=off -o setuid=off tank/var/crash
# zfs create -o exec=off -o setuid=off tank/var/db
# zfs create -o compression=lzjb -o exec=on -o setuid=off tank/var/db/pkg
# zfs create -o exec=off -o setuid=off tank/var/empty
# zfs create -o compression=lzjb -o exec=off -o setuid=off tank/var/log
# zfs create -o compression=gzip -o exec=off -o setuid=off tank/var/mail
# zfs create -o exec=off -o setuid=off tank/var/run
# zfs create -o compression=lzjb -o exec=on -o setuid=off tank/var/tmp

使用 zpool exportzpool import 把刚才规划的 ZFS 挂载到 /mnt,以便下一步安装系统。

# zpool export tank
# zpool import -o cachefile=/tmp/zpool.cache tank

现在,你所规划的 ZFS 已挂载到 /mnt,你可以 ls /mnt,会发现有 /mnt/usr/mnt/var/mnt/tmp,此时请完成以下命令。

# chmod 1777 /mnt/tmp
# chmod 1777 /mnt/var/tmp

正式把 FreeBSD 9.x 安装进 /mnt 中的 ZFS,此时以转用 sh 做 shell 为佳,请留意 for 那一行,因为太长,宜使用 \ 分行输入。

# sh
# cd /usr/freebsd-dist
# export DESTDIR=/mnt
# for file in base.txz lib32.txz kernel.txz doc.txz games.txz ports.txz src.txz;\do (cat $file|tar --unlink -xpJf - -C ${DESTDIR:-/});\done

你已把所有基本系统安装进 /mnt 中的 ZFS 了,以下一步必需要做,否则你重启电脑会失败,把zpool.cache拷贝到指定位置。

# cp /tmp/zpool.cache /mnt/boot/zfs/zpool.cache

最后,为新系统编写相关的 /etc/rc.conf/etc/fstab/boot/loader.conf,指示新系统由 ZFS 启动。注意,未重新启动之前,有关文件是放在 /mnt 下。

编写 rc.conf

# echo 'zfs_enable="YES"' >> /mnt/etc/rc.conf

编写 loader.conf

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

编写 fstab(其实这个文件一般是空的,因为一切挂载点和 swap 都会在启动 ZFS 时自动挂载好,这个空 fstab 是为了满足一些系统脚本而存在而已)。

# touch /mnt/etc/fstab

还有最后一步!把 ZFS 的挂载点指定为 /。

# zfs set readonly=on tank/var/empty
# zfs unmount -a
# zfs set mountpoint=legacy tank
# zfs set mountpoint=/tmp tank/tmp
# zfs set mountpoint=/usr tank/usr
# zfs set mountpoint=/var tank/var

然后进行重启,就可以顺利进入新装好的 FreeBSD-9.x based on ZFS 了,当然,为了方便起见,可以把 /usr/home 连接到 /

# ln -sf /usr/home /home

设定时区

# tzsetup

设置 root 密码

# passwd