使用zfs-dkms在arch linux(X86)编译安装ZFS
警告
本文正在根据自己近期 MacBook Air上运行Arch Linux 之后的ZFS实践重写,和以前 使用zfs-dkms在arch linux(ARM)编译安装ZFS 有所不同。部分内容参考和基于以前的 使用zfs-dkms在arch linux(ARM)编译安装ZFS (可能有重复)
zfs-dkms 软件包提供了 动态内核模块支持(DKMS) 支持,可以自动为兼容内核编译ZFS内核模块
优点:
- 可以定制自己的内核 
- 可以不必等待内核发行版更新 
缺点:
- 编译比较缓慢(对于现代超强CPU可以忽略) 
- 如果DKMS编译失败很少有告警(需要仔细关注) 
需要自己按照内核来编译,也就是采用 动态内核模块支持(DKMS) 安装对应的 zfs-dkms
安装
- 检查内核variant(变种): 
INST_LINVAR=$(sed 's|.*linux|linux|' /proc/cmdline | sed 's|.img||g' | awk '{ print $1 }')
验证:
echo $INST_LINVAR
输出是:
linux
- 检查内核版本: 
INST_LINVER=$(pacman -Qi ${INST_LINVAR} | grep Version | awk '{ print $3 }')
可以验证一下:
echo $INST_LINVER
输出是:
6.11.3.arch1-1
- 安装内核头文件: 
if [ "${INST_LINVER}" = \
"$(pacman -Si ${INST_LINVAR}-headers | grep Version | awk '{ print $3 }')" ]; then
 pacman -S --noconfirm --needed ${INST_LINVAR}-headers
else
 pacman -U --noconfirm --needed \
 https://archive.archlinux.org/packages/l/${INST_LINVAR}-headers/${INST_LINVAR}-headers-${INST_LINVER}-x86_64.pkg.tar.zst
fi
可以看到对应安装的是:
linux-headers-6.11.3.arch1-1
- 安装zfs-dkms: 
yay -S zfs-dkms
备注
安装过程需要从 github 下载 zfs-2.2.6.tar.gz ,这个过程会被GFW阻塞,所以需要设置 Linux代理环境变量
- 加载内核模块: 
modprobe zfs
我这里遇到报错显示zfs内核模块不存在:
modprobe: FATAL: Module zfs not found in directory /lib/modules/6.11.3-arch1-1
仔细检查  yay 安装 zfs-dkms 安装输出信息,可以看到在内核模块 动态内核模块支持(DKMS) 安装时会提示信息显示不支持过高内核:
(2/3) Install DKMS modules
==> dkms install --no-depmod zfs/2.2.6 -k 6.11.3-arch1-1
configure: error: 
	*** Cannot build against kernel version 6.11.3-arch1-1.
	*** The maximum supported kernel version is 6.10.
			
Error! Bad return status for module build on kernel: 6.11.3-arch1-1 (x86_64)
Consult /var/lib/dkms/zfs/2.2.6/build/make.log for more information.
==> WARNING: `dkms install --no-depmod zfs/2.2.6 -k 6.11.3-arch1-1' exited 10
这个问题在 使用zfs-dkms在arch linux(ARM)编译安装ZFS 也遇到过,但是当时我采用了 Btrfs 来替换ZFS绕开这个问题。不过,这个问题毕竟需要解决
参考 archlinux wiki: ZFS#DKMS 可以看到有如下 DKMS 解决方法:
- zfs-dkms是面向稳定版本的动态内核模块支持,也就意味着它可能不能支持最新内核
- zfs-dkms-staging-compat-git从ZFS最新补丁加上backport来支持最新内核
- zfs-dkms-staging-git跟踪最新发布候选版本(release candidate, RC)以及最新ZFS分支(如果还没有RC)
- zfs-dkms-gitDKMS的开发者版本
我决定回退到特定内核版本(6.1),然后重新安装 zfs-dkms 。需要注意 Arch Linux 内核 安装 6.1 LTS内核是通过 Arch Linux AUR 实现的,所以执行:
yay -S linux-lts61
备注
没有使用安装 linux-lts 是因为当前 长期稳定支持 内核已经滚动升级到 6.5 系列,已经超出了zfs支持范围。
警告
编译安装最新的内核非常消耗计算资源,所以务必先在系统激活 makepkg并行任务 ( 不是配置 并行make )以充分利用CPU的多核心,否则效率会低到无法忍受的程度。我曾经在 MacBook Air 11" Late 2010 单CPU核心编译超过16小时依然失败,实在非常低效。
内核编译错误处理
内核编译oom
  BTF     .btf.vmlinux.bin.o
scripts/link-vmlinux.sh: line 111: 498795 Killed                  LLVM_OBJCOPY="${OBJCOPY}" ${PAHOLE} -J ${PAHOLE_FLAGS} ${1}
  LD      .tmp_vmlinux.kallsyms1
  NM      .tmp_vmlinux.kallsyms1.syms
  KSYMS   .tmp_vmlinux.kallsyms1.S
  AS      .tmp_vmlinux.kallsyms1.o
  LD      .tmp_vmlinux.kallsyms2
  NM      .tmp_vmlinux.kallsyms2.syms
  KSYMS   .tmp_vmlinux.kallsyms2.S
  AS      .tmp_vmlinux.kallsyms2.o
  LD      vmlinux
  BTFIDS  vmlinux
FAILED: load BTF from vmlinux: No such file or directory
make[1]: *** [scripts/Makefile.vmlinux:34: vmlinux] Error 255
make[1]: *** Deleting file 'vmlinux'
make: *** [Makefile:1250: vmlinux] Error 2
==> ERROR: A failure occurred in build().
    Aborting...
 -> error making: linux-lts61-exit status 4
 -> Failed to install the following packages. Manual intervention is required:
linux-lts61 - exit status 4
可以看到编译进程被突然杀死,检查系统 dmesg -T 日志查找可能OOM的killer日志
再次编译时,我关闭所有图形程序,退出 sway - i3兼容Wayland compositor 桌面,采用 tmux多会话终端管理 运行编译,以节约内存使用。
内核编译需要大量空间
==> Starting package_linux-lts61-headers()...
Installing build files...
install: error copying 'vmlinux' to '/home/admin/.cache/yay/linux-lts61/pkg/linux-lts61-headers/usr/lib/modules/6.1.113-1-lts61/build/vmlinux': No space left on device
==> ERROR: A failure occurred in package_linux-lts61-headers().
    Aborting...
 -> error making: linux-lts61-exit status 4
 -> Failed to install the following packages. Manual intervention is required:
linux-lts61 - exit status 4
real    1561m40.335s
user    929m55.798s
sys     84m58.420s
检查可以看到 Arch Linux AUR 使用了用户目录下 $HOME/.cache/ 目录来保存编译过程数据,而编译内核达到了惊人的 21GB 空间占用。也就是说,要完整编译 linux-lts61 需要 至少21GB磁盘空间
检查zfs内核:
lsmod | grep zfs
此时可以看到zfs相关内核模块已经加载:
zfs                  3096576  0
zunicode              360448  1 zfs
zzstd                 491520  1 zfs
zlua                  196608  1 zfs
zcommon               114688  1 zfs
znvpair               131072  2 zfs,zcommon
zavl                   65536  1 zfs
icp                   278528  1 zfs
spl                   147456  6 zfs,icp,zzstd,znvpair,zcommon,zavl