手痒把 gentoo on zfsboot 的压缩算法从 lz4 改成了 zstdgrub-mkconfig 的时候报错 /usr/sbin/grub-probe: error: unknown filesystem., 一开始不在意,结果重启的时候找不到文件系统了...,果断恢复快照把 lz4 改成 zstd,结果 grub-mkconfig 依然报错,重启还是找不到文件系统,最后无奈只能从历史备份中恢复,本地虚拟机做了完整的数据备份 + 系统盘备份,随便捣 鼓很快就能恢复,但是手滑把远程服务器文件系统的压缩算法也改了,而且无备份和快照,这就很难办了,重做系统是不可能重做系统的,所以就有了下面的曲线救国的方案。

当然如果想使用 gentoo on zfsboot 压缩算法为 zstd 的根分区启动也可以参考这篇文章。

1. 分区

先确定系统有 efi 分区或者 swap 分区,要使用哪个分区来装内核取决于你自己,我使用的是 256M 的 efi 分区,重新格式化了来装内核和 efi,如果要使用 swap 分区就先系统取消卸载 swap,然后使用 fdisk 等分区软件把 swap 分为 ext4 的 boot 和新的 swap,boot 分区建议 512M,如果空间实在不够,128M 也不是不能用。

需要注意的是打包的 /boot 空间不能大于分区的空间,如果大了自己删几个历史内核。

cd /boot
tar cf boot.tar *
mv boot.tar ../
# 安装 fat32 分区工具,并格式化 efi 分区,每个人的分区都不一样,我的是 /dev/sda2,注意别格式化错了
emerge -av  sys-fs/dosfstools
umount /dev/sda2
mkfs.vfat -F 32 /dev/sda2

2. 挂载

# 挂载 /boot
echo "UUID=`blkid /dev/sda2 | awk'{printf($2)}'| awk -F"[\"\"]" '{print $2}'` /boot vfat umask=0077 0 1" >> /etc/fstab
# 删除旧的 efi 分区
sed -i "/\/boot\/efi/d" /etc/fstab
mount -a

如果上面的命令用不了则自己编辑 /etc/fstab。

# blkid 找到 uuid 的值,复制或者记下
blkid /dev/sda
# 编辑 fstab,新增一项,并把之前的 efi 分区的那一行删除,uuid 的值填入 ${uuid}
UUID=`${uuid}` /boot vfat umask=0077 0 1

3. 重建引导

如果根分区压缩算法是 zstd, 目前的 grub 会找不到 zfs 池名字,需要编辑 /etc/default/grub 手动指定

echo "GRUB_CMDLINE_LINUX=\"root=ZFS=`zpool get bootfs | awk '{print $3}' | sed -n '2p'`\"" >> /etc/default/grub

如果将来命令出错自己编辑 /etc/default/grub 新增一行 GRUB_CMDLINE_LINUX="root=ZFS=${zpool_get_bootfs}" ,把 zpool get bootfs 命令输出的 VALUE 填入 ${zpool_get_bootfs}

tar xf /boot.tar -C /boot
cd /boot
rm -rf efi grub
grub-install /dev/sda
# 如果是 uefi 启动,报 efi 错误 `grub-install: error: cannot find EFI directory.` 则添加参数 `--efi-directory=/boot`
grub-install /dev/sda --efi-directory=/boot

grub-mkconfig -o /boot/grub/grub.cfg

最后重启就没有问题了。



本作品采用 知识共享署名 - 相同方式共享 4.0 国际许可协议 进行许可。
 知识共享许可协议