Gentoo root on ZFS

ZFS

zfs 是号称最后的文件系统,有很多有用的特性,我最喜欢的就是它的快照功能了。
由于许可的不兼容,kenrel至今没有包含ZFS。
https://github.com/zfsonlinux/zfs/wiki

Gentoo

Gentoo是一个基于源代码发行元发行版,并且是滚动更新。
https://gentoo.org/

Start

准备工作

首先从下面找到一个基于Gentoo的system rescue CD,它包含了很多有用的程序,其中就包含ZFS。
http://list.zfsonlinux.org/zfs-iso/

写入U盘或者刻录CD,并且从U盘或者CD启动。
输入 startx 以启动图形桌面。

分区,建立pool和数据集

分区

我的分区是
1分区,512M,挂载/boot/efi,因为我是EFI启动。想以legacy方式启动的,这个分区可以不要。
2分区,剩下所有。

我准备使用6块硬盘组成2个raidz1(数据证明这样比一个raidz2的IO要快一点),每一块硬盘都要按照这样的分区来进行分区。但是挂载的时候,只需要挂载一个硬盘到/boot/efi就可以了。

#如果硬盘已有分区,zap掉。
sgdisk -Z /dev/sdX

sgdisk -n1:0:+512M /dev/sdX
sgdisk -n2:0:0 /dev/sdX

#efi分区使用fat格式
mkfs.vfat /dev/sdX1

组成pool

zpool create -f -o ashift=12 -o cachefile=/tmp/zpool.cache -O normalization=formD -O \
atime=off -O compression=lz4 -O xattr=sa -m none -R /mnt/gentoo rpool \
raidz1 \ 
/dev/disk/by-id/wwn-XXX-part2 /dev/disk/by-id/wwn-XXX-part2 /dev/disk/by-id/wwn-XXX-part2 \ 
raidz1 \ 
/dev/disk/by-id/wwn-XXX-part2 /dev/disk/by-id/wwn-XXX-part2 /dev/disk/by-id/wwn-XXX-part2

请尽量使用/dev/disk/by-id中的硬盘名称,它们是唯一的,这样在以后硬盘的顺序更改后,不会出现问题。

看下status

JohnJWorkstation ~ # zpool status
  pool: rpool
 state: ONLINE
  scan: none requested
config:

        NAME                   STATE     READ WRITE CKSUM
        rpool                ONLINE       0     0     0
          raidz1-0           ONLINE       0     0     0
            wwn-XXX-part2     ONLINE       0     0     0
            wwn-XXX-part2     ONLINE       0     0     0
            wwn-XXX-part2     ONLINE       0     0     0
          raidz1-1           ONLINE       0     0     0
            wwn-XXX-part2     ONLINE       0     0     0
            wwn-XXX-part2     ONLINE       0     0     0
            wwn-XXX-part2     ONLINE       0     0     0
        cache
          nvme0n1p1          ONLINE       0     0     0

errors: No known data errors
#如有需要可以自己加上cache和ZIL

建立数据集

数据集的建立,基本思想是分开系统和用户数据。

zfs create -o mountpoint=none -o canmount=off rpool/ROOT
zfs create -o mountpoint=none -o canmount=off -o setuid=off rpool/GENTOO
zfs create -o mountpoint=none -o canmount=off -o setuid=off rpool/HOME
zfs create -o mountpoint=/ rpool/ROOT/gentoo
zfs create -o mountpoint=/boot rpool/ROOT/boot
zfs create -o setuid=off -o mountpoint=/home rpool/HOME/home
zfs create -o mountpoint=/root rpool/HOME/root
zfs create -o canmount=off -o setuid=off -o exec=off -o mountpoint=/var rpool/ROOT/var
zfs create -o com.sun:auto-snapshot=false -o mountpoint=/var/cache rpool/ROOT/var/cache
zfs create -o acltype=posixacl -o xattr=sa -o mountpoint=/var/log rpool/ROOT/var/log
zfs create -o com.sun:auto-snapshot=false -o exec=on -o mountpoint=/var/tmp rpool/ROOT/var/tmp
zfs create -o mountpoint=/srv rpool/ROOT/srv
zfs create -o com.sun:auto-snapshot=false -o mountpoint=/var/lib/nfs rpool/ROOT/var/nfs
zfs create -o mountpoint=/usr/portage -o atime=off rpool/GENTOO/portage
zfs create -o mountpoint=/usr/portage/distfiles rpool/GENTOO/distfiles
zfs create -o mountpoint=/var/tmp/portage -o compression=lz4 -o exec=on -o sync=disabled rpool/GENTOO/build-dir
zfs create -o mountpoint=/usr/portage/packages rpool/GENTOO/packages
zfs create -o mountpoint=/var/tmp/ccache -o compression=lz4 -o exec=on rpool/GENTOO/ccache
zfs create -o mountpoint=/home/johnj rpool/HOME/johnj

#建立swap分区,这一步可以省略,如果你打算用其他设备。
zfs create -V 4G -b $(getconf PAGESIZE) -o logbias=throughput -o sync=always -o primarycache=metadata rpool/SWAP

看下结果

NAME                     USED  AVAIL  REFER  MOUNTPOINT
rpool                   1.10T  19.9T   128K  none
rpool/GENTOO            7.34G  19.9T   128K  none
rpool/GENTOO/build-dir  18.9M  19.9T  18.3M  /var/tmp/portage
rpool/GENTOO/ccache      128K  19.9T   128K  /var/tmp/ccache
rpool/GENTOO/distfiles  6.21G  19.9T  6.21G  /usr/portage/distfiles
rpool/GENTOO/packages    128K  19.9T   128K  /usr/portage/packages
rpool/GENTOO/portage    1.11G  19.9T   999M  /usr/portage
rpool/HOME              1.03G  19.9T   128K  none
rpool/HOME/home          139K  19.9T   139K  /home
rpool/HOME/johnj        1.03G  19.9T   862M  /home/johnj
rpool/HOME/root          432K  19.9T   256K  /root
rpool/ROOT              13.9G  19.9T   128K  none
rpool/ROOT/boot         96.9M  19.9T  79.3M  /boot
rpool/ROOT/gentoo       13.3G  19.9T  11.3G  /
rpool/ROOT/srv           128K  19.9T   128K  /srv
rpool/ROOT/var           589M  19.9T   128K  /var
rpool/ROOT/var/cache    19.4M  19.9T  12.8M  /var/cache
rpool/ROOT/var/log       538M  19.9T  31.8M  /var/log
rpool/ROOT/var/nfs       128K  19.9T   128K  /var/lib/nfs
rpool/ROOT/var/tmp      31.4M  19.9T  20.8M  /var/tmp
rpool/SWAP              68.1G  19.9T   111M  -

不要忘记设置bootfs

#因为我们有单独的boot
zpool set bootfs=rpool/ROOT/boot

安装Gentoo

下载stage3

一般情况下,我们使用muiltilib版本,并且使用openrc的版本。
国内速度慢,我们使用163的源。
http://mirrors.163.com/gentoo/releases/amd64/autobuilds
自行寻找最新的build。

cd /mnt/gentoo
wget ${stage3-url}
tar xpf ${stage3-file}

一些配置

# 首先,我们zpool.cache cp进去
mkdir -p /mnt/gentoo/etc/zfs 
cp /tmp/zpool.cache /mnt/gentoo/etc/zfs/zpool.cache 
# 然后就是Gentoo的官方的安装指南了
# 更新/etc/portage/make.conf
nano -w /mnt/gentoo/etc/portage/make.conf
# 加入以下,请按照自己的实际情况修改
CFLAGS="-march=native -O2 -pipe"
CXXFLAGS="${CFLAGS}"
MAKEOPTS="-j33"
PORTAGE_NICENESS="19"
ACCEPT_LICENSE="*"
FEATURES="parallel-fetch -collision-protect -protect-owned -xattr"
CPU_FLAGS_X86="aes avx avx2 fma3 mmx mmxext pclmul popcnt sse sse2 sse3 sse4_1 sse4_2 ssse3"
VIDEO_CARDS="nvidia"
GRUB_PLATFORMS="efi-64"
GENTOO_MIRRORS="http://mirrors.163.com/gentoo/"
# CPU_FLAGS_X86 是使用cpuid2cpuflags 得到的。
# GENTOO_MIRRORS 也可以使用 mirrorselect -i -o >> /mnt/gentoo/etc/portage/make.conf 得到

# 把DNS信息拷贝进去,把repo信息拷贝进去。
cp --dereference /etc/resolv.conf /mnt/gentoo/etc/
mkdir --parents /mnt/gentoo/etc/portage/repos.conf
cp /mnt/gentoo/usr/share/portage/config/repos.conf /mnt/gentoo/etc/portage/repos.conf/gentoo.conf

chroot进去

cd /mnt/gentoo
mount -t proc none proc
mount --rbind /sys sys
mount --rbind /dev dev
chroot /mnt/gentoo /bin/bash 
source /etc/profile
#把efi分区挂上
mkdir -p /boot/efi
mount /dev/sdX1 /boot/efi

安装基本系统

emerge-webrsync
#选择你的profile
eselect profile list
eselect profile set 19
# 更新世界
emerge --ask --update --deep --newuse @world
# 更新时区
echo "Asia/Hong_Kong" > /etc/timezone
emerge --config sys-libs/timezone-data
# 更新locale
nano -w /etc/locale.gen
# 反注释掉以下
en_US ISO-8859-1
en_US.UTF-8 UTF-8
# 执行以下
locale-gen
# 更新系统locale
eselect locale list
eselect locale set 4
# reload
env-update && source /etc/profile

配置和编译内核

我们需要把ZFS功能以内核模块的方式挂进kernel,需要配置内核,十分烦人。我们使用Gentoo提供的内核配置工具来自动生成配置。

# 安装genkernel
# 还需要将>=sys-apps/util-linux-2.30.2 static-libs 加入到use文件
emerge sys-kernel/genkernel
# 安装kernel source
emerge sys-kernel/gentoo-source
# 先运行以下genkernel以得到一个.config文件,这个文件在安装ZFS的时候会检查
genkernel kernel --no-mountboot

安装ZFS,我们需要将ZFS加入到accept_keywords文件。

nano -w /etc/portage/package.accept_keywords/gentoo
# 加入以下
sys-kernel/spl **
sys-fs/zfs-kmod **
sys-fs/zfs **
# 然后
emerge sys-fs/zfs
# 这里将从github直接clone代码,网速较慢,请自行更新hosts文件

安装完成后,我们将ZFS服务启用

rc-update add zfs-import boot
rc-update add zfs-mount boot
rc-update add zfs-share default
rc-update add zfs-zed default

安装grub2,我们需要更新USE变量,使grub2能够引导ZFS分区。

# 在文件/etc/portage/package.use/gentoo 加入以下
sys-boot/grub:2 libzfs
# 在文件/etc/portage/package.accept_keywords/gentoo 加入以下
sys-boot/grub:2 ~amd64
# 然后
emerge sys-boot/grub:2
# 完成后,查看是否一些正常
JohnJWorkstation ~ # grub-probe /
zfs
# 安装引导程序, 我们使用的EFI,所以使用下面的命令安装。
grub-install --target=x86_64-efi --efi-directory=/boot/efi
# 如果有只读的错误报出,执行以下
mount -o remount,rw /sys/firmware/efi/efivars
# 然后重新执行安装。
# 给一个空的grub.cfg,后续的grub-mkconfig会检查
touch /boot/grub/grub.cfg

至此,一些准备就绪,开始编译内核。

genkernel all --no-mountboot --zfs --bootloader=grub2 --callback="emerge @module-rebuild"
# --zfs,告诉genkernel我们的内核需要ZFS的支持
# 一般情况下,我们需要重新编译kernel的module,所以有了--callback

收尾工作

# swap分区的启用略。
# 增加一个日常使用的账户
useradd -m -G users,wheel,audio -s /bin/bash johnj
# home/johnj目录我们之前已经建好。 
# 退出chroot环境
exit
# umount 目录
umount -lR {proc,dev,sys}
cd /
zpool export rpool
reboot

End

惯例

# johnj @ JohnJWorkstation in ~ [21:27:23] 
$ neofetch
         -/oyddmdhs+:.                johnj@JohnJWorkstation 
     -odNMMMMMMMMNNmhy+-`             ---------------------- 
   -yNMMMMMMMMMMMNNNmmdhy+-           OS: Gentoo/Linux x86_64 
 `omMMMMMMMMMMMMNmdmmmmddhhy/`        Host: Z10PE-D8 WS 
 omMMMMMMMMMMMNhhyyyohmdddhhhdo`      Kernel: 4.17.4-gentoo 
.ydMMMMMMMMMMdhs++so/smdddhhhhdm+`    Uptime: 10 hours, 33 mins 
 oyhdmNMMMMMMMNdyooydmddddhhhhyhNd.   Packages: 1253 
  :oyhhdNNMMMMMMMNNNmmdddhhhhhyymMh   Shell: zsh 5.5.1 
    .:+sydNMMMMMNNNmmmdddhhhhhhmMmy   Resolution: 3840x2160 
       /mMMMMMMNNNmmmdddhhhhhmMNhs:   DE: KDE 
    `oNMMMMMMMNNNmmmddddhhdmMNhs+`    WM: KWin 
  `sNMMMMMMMMNNNmmmdddddmNMmhs/.      WM Theme: Breeze 
 /NMMMMMMMMNNNNmmmdddmNMNdso:`        Theme: Breeze Dark [KDE], Breeze [GTK2/3] 
+MMMMMMMNNNNNmmmmdmNMNdso/-           Icons: Breeze-dark [KDE], Breeze [GTK2/3] 
yMMNNNNNNNmmmmmNNMmhs+/-`             Terminal: konsole 
/hMMNNNNNNNNMNdhs++/-`                CPU: Intel Xeon E5-2620 v4 (32) @ 3.000GHz 
`/ohdmmddhys+++/:.`                   GPU: NVIDIA GeForce GTX 1080 Ti 
  `-//////:--.                        Memory: 5437MiB / 64211MiB 

                                                              
                                            

至此就安装完成了。至于DM, WM, DE环境,请自行查看Gentoo的文档。

你可能感兴趣的:(Gentoo root on ZFS)