如何创建一个 GRUB 可以读取的 ZFS zpool

sta*_*fry 6 zfs arch-linux grub2

Arch Linux ZFS wiki 页面解释了与grub 兼容的池创建这个关于引导 Fedora 的页面也是如此,但我无法创建一个 Grub 可读的池。Arch Linux wiki 页面关于在 ZFS 上安装 Arch Linux突出显示了某些错误,但并没有真正解释如何克服它们。

链接页面解释了 Grub 支持zpool 功能的子集,并且无法读取使用它不支持的功能的池。他们继续解释如何配置合适的池,但我一直无法使其工作。支持的功能子集似乎没有记录在任何地方。

我正在使用虚拟机来测试 Grub 2.02 和 Arch Linux 内核 4.16.13-1-ARCH,这是最新的并且与当前的zfs-linux软件包版本 ( zfs-linux-0.7.9.4.16.13.1-1)兼容。我(还)没有尝试制作可引导系统,只是为了证明 Grub 可以读取 zpool。这是我尝试过的:

首先,就像arch wiki 页面建议的那样,通过禁用不需要的功能:

# zpool create \
    -o feature@multi_vdev_crash_dump=disabled \
    -o feature@large_dnode=disabled           \
    -o feature@sha512=disabled                \
    -o feature@skein=disabled                 \
    -o feature@edonr=disabled                 \
    testpool mirror \
    /dev/disk/by-id/ata-VBOX_HARDDISK_VB{5f2d4170-647f16b7,f38966d8-57bff7df}
Run Code Online (Sandbox Code Playgroud)

这导致了这些功能:

testpool  feature@async_destroy          enabled                       local
testpool  feature@empty_bpobj            active                        local
testpool  feature@lz4_compress           active                        local
testpool  feature@multi_vdev_crash_dump  disabled                      local
testpool  feature@spacemap_histogram     active                        local
testpool  feature@enabled_txg            active                        local
testpool  feature@hole_birth             active                        local
testpool  feature@extensible_dataset     active                        local
testpool  feature@embedded_data          active                        local
testpool  feature@bookmarks              enabled                       local
testpool  feature@filesystem_limits      enabled                       local
testpool  feature@large_blocks           enabled                       local
testpool  feature@large_dnode            disabled                      local
testpool  feature@sha512                 disabled                      local
testpool  feature@skein                  disabled                      local
testpool  feature@edonr                  disabled                      local
testpool  feature@userobj_accounting     active                        local
Run Code Online (Sandbox Code Playgroud)

然后,像Fedora 示例一样,通过启用想要的功能:

zpool create -d \
    -o feature@async_destroy=enabled \
    -o feature@empty_bpobj=enabled \
    -o feature@spacemap_histogram=enabled \
    -o feature@enabled_txg=enabled \
    -o feature@hole_birth=enabled \
    -o feature@bookmarks=enabled \
    -o feature@embedded_data=enabled \
    -o feature@large_blocks=enabled \
    testpool mirror \
    /dev/disk/by-id/ata-VBOX_HARDDISK_VB{5f2d4170-647f16b7,f38966d8-57bff7df}
Run Code Online (Sandbox Code Playgroud)

这导致了这些功能:

# zpool get all testpool | grep feature
testpool  feature@async_destroy          enabled                       local
testpool  feature@empty_bpobj            active                        local
testpool  feature@lz4_compress           disabled                      local
testpool  feature@multi_vdev_crash_dump  disabled                      local
testpool  feature@spacemap_histogram     active                        local
testpool  feature@enabled_txg            active                        local
testpool  feature@hole_birth             active                        local
testpool  feature@extensible_dataset     enabled                       local
testpool  feature@embedded_data          active                        local
testpool  feature@bookmarks              enabled                       local
testpool  feature@filesystem_limits      disabled                      local
testpool  feature@large_blocks           enabled                       local
testpool  feature@large_dnode            disabled                      local
testpool  feature@sha512                 disabled                      local
testpool  feature@skein                  disabled                      local
testpool  feature@edonr                  disabled                      local
testpool  feature@userobj_accounting     disabled                      local
Run Code Online (Sandbox Code Playgroud)

在每种情况下,我都加载了一些内容:

# cp -a /boot /testpool
Run Code Online (Sandbox Code Playgroud)

然后,重新启动到 Grub:

grub> search --set --label testpool
grub> ls /
@/
grub> ls /@
error: compression algorithm 80 not supported
.
grub> ls /@/
error: compression algorithm inherit not supported
.
Run Code Online (Sandbox Code Playgroud)

我尝试启用/禁用某些功能,最显着的是lz4_compress. 我还尝试在池上创建数据集。我在 Grub 中没有尝试过任何工作。

我希望能够列出/boot/@/boot.

遇到的错误包括

  • compression algorithm inherit not supported
  • compression algorithm 66 not supported
  • compression algorithm 80 not supported
  • incorrect dnode type

应该如何创建 ZFS zpool 以便 Grub 可以读取它?

sta*_*fry 6

由于通过邮件列表确认的错误,Grub 无法可靠地执行 zpool 的目录列表:

Grub 中的目录内容列表已损坏,我有一个补丁可以修复该特定问题。如果您收到奇怪的错误消息(例如,无效的 BP 类型或压缩算法之类的内容),很可能是这个问题。

从 ArchLinux 和 Fedora 28 安装的 Grub 中都存在此问题。但是,Ubuntu 似乎已修补其 Grub 来修复此问题(已在 Ubuntu 16.10 中得到确认)。

然而,Grub 可以读取引导所需的文件。您可以创建一个 Grub 将启动的 zpool,如下所示:

zpool create -m none "$ZPOOL" "$RAIDZ" "${DISKS[@]}"
Run Code Online (Sandbox Code Playgroud)

其中变量定义池的名称(例如)mypool、RAID 级别(例如mirror)和磁盘/dev/disk/by-id/...(例如,镜像需要两个磁盘)。

您需要创建一个数据集

zfs create -p "$ZPOOL"/ROOT/archlinux
Run Code Online (Sandbox Code Playgroud)

您需要设置数据集的挂载点:

zfs set mountpoint=/ "$ZPOOL"/ROOT/archlinux
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用以下命令通过 Grub 启动它:

insmod part_gpt
search --set --label mypool
linux /ROOT/archlinux@/boot/vmlinuz-linux zfs=mypool rw
initrd /ROOT/archlinux@/boot/initramfs-linux.img
boot
Run Code Online (Sandbox Code Playgroud)

编写了这个脚本来在 VirtualBox 机器上测试它。我将 Arch 从 ISO 安装到普通的 ext4 根目录上,然后使用它将新的 ZFS 根目录安装到两个镜像虚拟磁盘上。以上是摘要 -有关完整详细信息,请参阅脚本。

  • 当然,@drookie,我的 Grub 版本在 Grub 屏幕上显示为 2.03。我确实从源代码构建了它,因为我也使用这些[加密扩展](http://grub.johnlane.ie),我专门从[这个标签](https://github.com/johnlane/grub/tree /cryptopatch_v4)(这不会对 ZFS 支持产生任何影响)。 (2认同)