在纯 ZFS 安装 Gentoo Linux

关于 ZFS 文件系统,不多做介绍,在这里有详细信息。

ZFS 一直到版本 5,zpool 版本 28 都是开源的。后续版本由 Oracle 所掌控,因此闭源了。虽然 ZFS 先前的版本开源,但是由于 ZFS 的 CDDL 许可证和 Linux 的 GPL 许可证并不兼容,因此 ZFS 无法进入 Linux 内核。尽管如此,并不代表我们无法实现 Root On ZFS。

注意:目前能安装到 ZFS 的发行版不多,只有 Ubuntu、Gentoo 和 Arch 等有限的几种。经过我的测试,个人认为 Gentoo 是最方便安装到 ZFS 的,Ubuntu 需要进行 debootstrap,而且由于教程步骤有错,导致无法卸载 /mnt/dev,步骤无法进行下去。本文仅以 amd64 为例,i386 未测试。

本文主体内容来自 ryao 的教程,感谢 ryao 的贡献。本人主要负责资料整理和步骤完善。

安装介质准备: 推荐使用 Gentoo LiveDVD 2012.1,可以写入 U 盘启动,因为这个 ISO 包含了 ZFS 模块。

硬盘分区要求: GPT 分区表,分出 1MB 的 BIOS boot partition,另外的部分随便分一个分区,文件系统随意,之后给 ZFS 用。 以我的为例,我的 BIOS boot partition 在 /dev/sdb3,ZFS 在 /dev/sdb2

安装步骤:
启动 Gentoo LiveDVD 2012.1

创建 zpool

# zpool create -f -o ashift=12 -o cachefile= -O normalization=formD -m none -R /mnt/gentoo rpool /dev/sdb2

创建 rootfs

# zfs create -o mountpoint=none rpool/ROOT
# zfs create -o mountpoint=/ rpool/ROOT/gentoo

创建 home 目录

# zfs create -o mountpoint=/home rpool/HOME

创建 portage 目录

# zfs create -o mountpoint=none rpool/GENTOO
# zfs create -o mountpoint=/usr/portage rpool/GENTOO/portage
# zfs create -o mountpoint=/usr/portage/distfiles rpool/GENTOO/distfiles

创建 packages 目录(可选)

# zfs create -o mountpoint=/usr/portage/packages rpool/GENTOO/packages

创建 ccache 目录(可选)

# zfs create -o mountpoint=/var/tmp/ccache -o compression=gzip-9 rpool/GENTOO/ccache

下载 stage3

# wget ftp://gentoo.osuosl.org/pub/gentoo/releases/amd64/current-stage3/stage3-amd64-*.tar.bz2

解压 stage3

# tar -xf stage3-amd64-*.tar.bz2 -C /mnt/gentoo

把 zpool.cache 复制到目标 ZFS 分区

# mkdir -p /mnt/gentoo/etc/zfs
# cp /etc/zfs/zpool.cache /mnt/gentoo/etc/zfs/zpool.cache

把 resolv.conf 复制到目标 ZFS 分区

# cp /etc/resolv.conf /mnt/gentoo/etc/resolv.conf

挂载必要的文件系统

# mount -t proc none /mnt/gentoo/proc
# mount --rbind /dev /mnt/gentoo/dev
# mount --rbind /sys /mnt/gentoo/sys

chroot

# chroot /mnt/gentoo /bin/bash
# env-update;source /etc/profile;export PS1="(chroot) $PS1";cd

同步 portage

# emerge --sync

由于 Gentoo 的 stage3 相当老旧,最好先 emerge -avuDN world,把所有包升级一遍,有几个软件冲突也要处理一下。

安装 genkernel(最好在 /etc/make.conf 设置 ACCEPT_KEYWORDS="~amd64"

# emerge -av sys-kernel/genkernel

安装内核源代码

# emerge -av sys-kernel/gentoo-sources

安装完内核源代码之后,请到 /usr/src/linux 按照自己的硬件配置内核,推荐把驱动编入内核,而不是编为模块

初步安装内核(sys-kernel/splsys-fs/zfs 会检查内核文件)

# genkernel kernel --no-clean --no-mountboot

安装 ZFS

# emerge -av sys-fs/zfs

把 ZFS 添加到 boot 运行级

# rc-update add zfs boot

安装 grub2

# echo "sys-boot/grub libzfs" >> /etc/portage/package.use
# emerge -av sys-boot/grub
# touch /etc/mtab
# grub2-install /dev/sdb
# grub2-mkconfig -o /boot/grub2/grub.cfg

如果此时 grub2 提示无法安装,/boot/grub2 不可读,那么就先重启重新进入 LiveDVD 环境,然后用以下命令导入 zpool

# zpool import -f -o cachefile= -R /mnt/gentoo rpool

然后按照之前 chroot 的步骤重新进入 chroot 环境

安装 module-rebuild

# emerge -av module-rebuild

编译内核和 initramfs

# genkernel all --no-clean --no-mountboot --zfs --bootloader=grub2 --callback="module-rebuild rebuild"

使用 Bliss Initramfs Creator 创建初始化内存盘

由于 genkernel 创建的内存盘效率较差,而且有时候会出问题导致无法 import zpool,因此 fearedbliss 写了这个工具来代替。

安装 busybox

# echo "sys-apps/busybox static" >> /etc/portage/package.use
# echo "sys-fs/cryptsetup static" >> /etc/portage/package.use
# echo "sys-libs/e2fsprogs-libs static-libs" >> /etc/portage/package.use
# echo "dev-libs/popt static-libs" >> /etc/portage/package.use
# echo "sys-apps/util-linux static-libs" >> /etc/portage/package.use
# echo "dev-libs/libgpg-error static-libs" >> /etc/portage/package.use
# emerge -avt sys-apps/busybox sys-fs/cryptsetup

同步 Bliss Initramfs Creator 代码

# cd /boot
# git clone git://github.com/fearedbliss/Bliss-Initramfs-Creator.git

创建 initramfs

# cd Bliss-Initramfs-Creator
# ./createInit

选择第一项 ZFS

# mv initrd-<kernel_name>.img /boot/

重新生成 grub2 配置文件,并且修改内核参数里面的 “root=zfs=rpool/ROOT/gentoo” 为 “root=rpool/ROOT/gentoo”

之后把 /etc/fstab 里面的 BOOT、ROOT 和 SWAP 行都注释掉

然后按照 Gentoo 手册的 8-12 章节做最后的系统配置

启动进入新系统之后,可以先做个快照

# zfs snapshot rpool/ROOT/gentoo@install

在 ZFS 卷组内创建 swap(实验性的)

# zfs create -o sync=always -o primarycache=metadata -o secondarycache=none -V 8G rpool/swap
# mkswap -f /dev/zvol/rpool/swap

然后配置下 /etc/fstab

# echo "/dev/zvol/rpool/swap    none    swap    sw    0 0" >> /etc/fstab

由于在 ZFS 卷组内创建 swap 尚未有良好支持,最好还是创建一个独立的 swap 分区。
Tips:
ZFS 采用 ARC 来管理其 pool 的 cache,所以会尝试使用所有可用物理内存,内存占用看着就很恐怖,但并不会影响正常使用。可以通过限制 ARC 大小的方法来解决

# echo "options zfs zfs_arc_max=512M" &gt;&gt;/etc/modprobe.d/zfs.conf

基本系统到此安装完毕,后续的软件和设置可以自行参照 Gentoo 的 wiki 和文档。