对于 FreeBSD 的另一种 ZFS 规划

在之前的文章我记录了如何把 FreeBSD 安装到纯 ZFS,并对此提出了疑问,现在这个疑问已经解决了,详细过程记录如下。

大部分过程和之前一样,我就照抄了。采用这种规划的好处是具有更大的灵活性,不必受制于 zpool 的同名 zfs 根。

已知问题
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,把它命名为 rpool,同时分配好未来的 /。

# zpool create -R /mnt -m none rpool /dev/ada0p2
# zfs create -o mountpoint=none rpool/ROOT
# zfs create -o mountpoint=/ rpool/ROOT/freebsd
# zpool set bootfs=rpool/ROOT/freebsd rpool
# zfs set checksum=fletcher4 rpool/ROOT/freebsd

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

# zfs create -o sync=always -o primarycache=metadata -o secondarycache=none -V 8G rpool/swap
# zfs set checksum=off rpool/swap
# zfs set org.freebsd:swap=on rpool/swap

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

# zfs create -o mountpoint=/usr rpool/ROOT/usr
# zfs create -o mountpoint=/var rpool/ROOT/var
# zfs create -o mountpoint=/home rpool/HOME
# zfs create -o compression=on -o exec=on -o setuid=off -o mountpoint=/tmp rpool/ROOT/tmp
# zfs create -o mountpoint=none rpool/FREEBSD
# zfs create -o compression=lzjb -o setuid=off -o mountpoint=/usr/ports rpool/FREEBSD/ports
# zfs create -o compression=off -o exec=off -o setuid=off -o mountpoint=/usr/ports/distfiles rpool/FREEBSD/distfiles
# zfs create -o compression=off -o exec=off -o setuid=off -o mountpoint=/usr/ports/packages rpool/FREEBSD/packages
# zfs create -o compression=lzjb -o exec=off -o setuid=off -o mountpoint=/usr/src rpool/FREEBSD/src
# zfs create -o compression=lzjb -o exec=off -o setuid=off -o mountpoint=/var/crash rpool/FREEBSD/crash
# zfs create -o exec=off -o setuid=off -o mountpoint=/var/db rpool/FREEBSD/db
# zfs create -o compression=lzjb -o exec=on -o setuid=off -o mountpoint=/var/db/pkg rpool/FREEBSD/pkg
# zfs create -o exec=off -o setuid=off -o mountpoint=/var/empty rpool/FREEBSD/empty
# zfs create -o compression=lzjb -o exec=off -o setuid=off -o mountpoint=/var/log rpool/FREEBSD/log
# zfs create -o compression=gzip -o exec=off -o setuid=off -o mountpoint=/var/mail rpool/FREEBSD/mail
# zfs create -o exec=off -o setuid=off -o mountpoint=/var/run rpool/FREEBSD/run
# zfs create -o compression=lzjb -o exec=on -o setuid=off -o mountpoint=/var/tmp rpool/FREEBSD/tmp

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

# zpool export rpool
# zpool import -o cachefile=/tmp/zpool.cache -R /mnt rpool

现在,你所规划的 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:rpool/ROOT/freebsd"' >> /mnt/boot/loader.conf

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

# touch /mnt/etc/fstab

设置 /var/empty 的只读属性。

# zfs set readonly=on rpool/FREEBSD/empty

然后重启系统,应该就可以顺利进行引导至纯 ZFS 的 FreeBSD 了。

进系统后,可以进行如下设置。

设定时区

# tzsetup

设置 root 密码

# passwd