24.4 更新 ZFS 存储池
ZFS 存储池的可用功能由功能标志(feature flags)控制。FreeBSD 大版本升级后,需手动执行 zpool upgrade 启用新功能集——该操作不可逆,升级后旧版系统将无法识别新功能集,升级前应评估旧系统后续是否会再次导入该池。
警告
由于旧版本系统内置的 ZFS 无法兼容新版 ZFS 文件系统的功能集,请准备好备份和应急 CD 以应对意外情况。
验证 ZFS 版本
首先验证当前系统与 ZFS 版本:
查看当前系统版本
# freebsd-version -kru
15.0-RELEASE
15.0-RELEASE
15.0-RELEASE查看 ZFS/zpool 相关版本
# zpool version
2.4.0-rc4-FreeBSD_g099f69ff5
zfs-kmod-2.4.0-rc4-FreeBSD_g099f69ff5警告
这意味着任何 ZFS 版本低于 2.4.0-rc4 的操作系统在升级后可能无法启动。
执行更新
FreeBSD 升级后,ZFS 新功能标志在 zpool upgrade 执行完成之前不可用。执行升级操作:
状态:存储池上有一些支持且被请求的功能尚未启用。存储池仍然可以使用,但部分功能不可用。
操作:使用‘zpool upgrade’启用所有功能。在完成后,未支持这些功能的软件可能无法再访问该存储池。
警告
zpool upgrade启用新功能集的操作不可逆,升级后旧版系统将无法识别新功能集。执行前请确认所有需要访问该池的系统均已升级至兼容版本。
根据系统提示信息:系统提示需要更新,但更新后旧系统可能无法启动。先预览即将更新的功能:
除了带有 * 的功能需要手动启用外,其余功能在升级后将默认启用。
注意
zpool upgrade并不能实际启用这些功能标志,仅用于预览可启用的功能。要执行更新,必须同时指定存储池名称,例如zpool upgrade zroot。参见:'zpool status' gives confusing suggestion with 'zpool upgrade'[EB/OL]. [2026-03-26]. https://github.com/openzfs/zfs/issues/17910. OpenZFS 项目关于 zpool upgrade 命令的问题讨论。
思考题
有贡献者认为上述 issue 关联的修补 PR 琐碎、无关紧要,并以每行不得超过 80 字符的理由予以拒绝。然而,无数用户都因这类“小事”耗费了大量时间。对文字力量的忽视,代价究竟是什么?
现在执行实际升级操作:
显示所有 ZFS 池的当前状态及健康信息:
升级成功完成,ZFS 池状态正常。
附录:需要手动启用的功能标志
本附录介绍需要手动启用的 ZFS 功能标志及其启用方法:
查看当前有哪些需要手动启用的功能标志(带 * 标记):
可见,可以手动启用 dynamic_gang_header,接下来查询 ZFS 池中该功能标志的状态:
该功能标志未启用,下面在 zroot 池上启用 dynamic_gang_header 功能标志:
再检查 zroot 池中 dynamic_gang_header 功能标志的当前状态:
检查当前可升级的 ZFS 池及其支持的功能标志:
更新 boot loader 引导(UEFI 引导)
警告
请先更新 loader.efi,再更新 ZFS 版本!
使用 EFI 引导的系统,EFI 系统分区(ESP)上有引导加载程序的副本,用于固件引导内核。如果根文件系统是 ZFS,则引导加载程序必须能读取 ZFS 引导文件系统。系统升级后、执行 zpool upgrade 前,必须先更新 ESP 上的引导加载程序,否则系统可能无法引导。虽然不是强制性的,但在 UFS 作为根文件系统时也应如此。
可以使用命令 efibootmgr -v 来确定当前引导加载程序的位置。BootCurrent 的值是当前引导系统所用的引导项编号。输出的相应条目以 + 开头,如下所示:
ESP 通常已挂载到 /boot/efi。如果没有,可手动挂载,使用 efibootmgr 输出中列出的分区(本例为 nda0p1):mount_msdosfs /dev/nda0p1 /boot/efi。另一示例请参阅 loader.efi(8)。
efibootmgr -v 输出中 File 字段的值,如 \efi\freebsd\loader.efi,即 EFI 系统分区中当前使用的引导加载程序路径。若挂载点是 /boot/efi,则此文件为 /boot/efi/efi/freebsd/loader.efi。(在 FAT32 文件系统上大小写不敏感;FreeBSD 使用小写)File 的另一个常见值可能是 \EFI\boot\bootXXX.efi,其中 XXX 是 amd64(即 x64)、aarch64(即 aa64)或 riscv64(即 riscv64);如未配置,则为默认引导加载程序。应将 /boot/loader.efi 复制到 /boot/efi 中的正确路径以更新已配置及默认的引导加载程序。
执行更新
在版本更新后,系统启动时可能会出现引导加载程序版本过旧的提示,将显示如下类似提示。

注意
该界面出现的时间较短,在快速启动的系统中可能一闪而过。可使用相机拍摄后观察。
提示需要更新 loader。还可以通过以下命令验证版本:
/boot/efi/efi/freebsd/loader.efi 为当前正在使用的 loader(版本确实较旧)。
将 /boot/loader.efi 复制到 EFI 系统分区的 FreeBSD 目录下进行更新:
重写引导代码(BIOS 传统引导)
BIOS 传统引导模式下,存储池升级后,可能需要手动重写引导代码,否则系统可能无法正常启动。
警告
bootfs属性是 ZFS 引导 FreeBSD 的关键标志。忽略此提示可能不会立即引发问题,但潜在风险一旦暴露,将导致系统无法启动,因此建议按照提示重写boot code。实践经验表明,未及时更新引导代码可能在后续系统更新中引发启动故障。若系统中不存在 freebsd-boot 分区,则无需执行以下操作。
列出系统中所有磁盘及其分区表信息:
找到类型为 freebsd-boot 的分区,此处分区序号为 1,对应以下命令中的 -i 选项,而后重写 bootcode:
警告
gpart bootcode将写入引导代码到指定分区,操作不当可能导致系统无法启动。请确认分区序号(-i参数)与freebsd-boot分区对应。
再次列出所有 ZFS 池的状态及详细信息:
最后更新于