5.9 使用 ZFS 启动环境更新 FreeBSD 并实现多版本共存
创建启动环境 15.0-RELEASE
使用工具 bectl 创建启动环境
15.0-RELEASE:
# bectl create 15.0-RELEASE注意
我们只是将其命名为 15.0,实际上系统仍然是 14.3-RELEASE。
使用 bectl 检查启动环境:
$ bectl list # 显示所有启动环境
BE Active Mountpoint Space Created
15.0-RELEASE - - 176K 2025-12-05 22:27
default NR / 10.6G 2025-01-14 20:36Active 字段解释(来自 bectl(8) 手册页):
“N”:表示该启动环境当前是否处于活动状态(当前是否位于此环境中)
“R”:在重启时是否处于活动状态(下次是否选中,用于固定选项)
“T”:是否会在下次启动时生效(且仅下次,用于一次性选项)
“NRT”:这些标识(N / R / T)理论上可以组合出现(但实际不会出现,该组合在语义上存在矛盾)
列出系统中所有 ZFS 文件系统及其属性:
# zfs list
NAME USED AVAIL REFER MOUNTPOINT
……其他省略……
zroot/ROOT/15.0-RELEASE 8K 83.8G 10.6G /
……其他省略……注意 zroot/ROOT/15.0-RELEASE 8K 83.8G 10.6G / 这一行是刚刚创建的。
将启动环境中的系统版本更新到 15.0-RELEASE
挂载启动环境 15.0-RELEASE
创建一个临时目录用于更新启动环境 15.0-RELEASE 中的 FreeBSD 系统
将启动环境(实际上是一个数据集)15.0-RELEASE 挂载到上面的路径中
显示已挂载文件系统的磁盘使用情况:
可以看到,已经成功将启动环境 15.0-RELEASE 挂载到了指定路径。
验证当前 FreeBSD 版本
目前 15.0-RELEASE 实际上仍是 14.3-RELEASE。虽然这是已知事实,但仍可使用命令 freebsd-version 进行验证。
在 /mnt/upgrade 环境中运行 freebsd-version:
freebsd-version 参数解释(摘自手册页 freebsd-version(1)):
-k:打印已安装内核的版本和补丁级别。与 uname(1) 不同的是,如果新的内核已经安装但系统尚未重启,freebsd-version会打印新内核的版本和补丁级别。-r:打印正在运行中的内核的版本和补丁级别。与 uname(1) 不同的是,freebsd-version不受环境变量影响。-u:打印已安装用户态的版本和补丁级别。这些信息在构建过程中会被写入程序freebsd-version中。
使用 pkgbase 将启动环境中的 14.3-RELEASE(系统版本)转换到 pkgbase
pkgbase 的设计初衷是为了让 stable、current 和 release(包括 BETA、RC 等)都能使用统一的二进制工具进行更新。之前,stable 和 current 只能通过完整编译源代码的方式进行更新。
注意
仅 FreeBSD 14.0-RELEASE 及更高版本才能直接被转换为 pkgbase。旧版仍需要通过
freebsd-update进行更新(运行时 pkgbasify 会提示Unsupported FreeBSD version,即 FreeBSD 版本不受支持)。
警告
存在风险,可能会丢失所有数据!建议在操作之前做好备份。
在 /mnt/upgrade环境中锁定 pkg 软件包,防止被升级或修改:
下载 pkgbase 转换脚本
使用 pkgbasify 进行转换
警告
在接受
Do you accept this risk and wish to continue? (y/n)这个风险提示后就没有其他二次确认了!
检查启动环境 15.0-RELEASE 中的系统版本
可以看到,pkgbasify 已将系统更新到最新的补丁版本,并完成了向 pkgbase 的转换。
使用 pkgbase 将启动环境中的系统版本更新到 15.0-RELEASE
创建 pkgbase 软件源目录
编辑
/mnt/upgrade/usr/local/etc/pkg/repos/FreeBSD-base.conf,添加 pkgbase 源
警告
请检查
FreeBSD-base.conf的内容,尤其是 不应该 在里面手动硬编码写入指定任何具体的版本(如base_release_3)。
技巧
需要换源的用户可以将
url这行改成url = "https://mirrors.ustc.edu.cn/freebsd-pkg/${ABI}/base_release_${VERSION_MINOR}";。而对于那些优先考虑安全性的读者应该维持默认设置。
刷新软件源
使用 pkgbase 将 14.3-RELEASE 更新到 15.0-RELEASE(即将 ABI 指定为 15)
技巧
如果检查不到任何更新,请检查你当前是否已成功转换为 pkgbase,并确认软件源配置是否正确
检查启动环境 15.0-RELEASE 中的系统版本
这里 r 显示为 14.3-RELEASE 并无异常,说明当前运行的仍是 14.3。结合其他参数,可知重启后才会变成 15.0-RELEASE。
解锁 pkg
将所有第三方软件包的 ABI 更新到 FreeBSD 15.0
更新过程中需要多次确认才能完成。
启动到启动环境 15.0-RELEASE
在下次启动时进入启动环境 15.0-RELEASE
验证设置是否成功。列出系统中所有 ZFS 启动环境:
注意,这是一次性的(T),此处仅用于验证其是否能够正常启动。我们还需要回到目前的主系统 14.3-RELEASE 来更新 ZFS。
重启以进入启动环境 15.0-RELEASE
验证版本:
可以看到,我们已经成功将启动环境 15.0-RELEASE 中的 FreeBSD 系统升级到了 15.0-RELEASE。现在名副其实了。
并且 R 意味着我们再次重启就会回到启动环境 default(14.3-RELEASE)。
附录:永久性使用 15.0-RELEASE
如果读者不需要多版本共存,并且验证过目前的环境满足需要,也可以将启动环境 15.0-RELEASE 设置为永久的:
随后,读者也可以销毁不再需要的启动环境:
将参数 启动环境 替换为命令 bectl list 输出中 BE 列对应的启动环境名称即可将其销毁。
将基本系统中的 ZFS 替换为 Ports 版本
通常,在 FreeBSD 大版本之间,ZFS 池版本和特性都会发生变化,例如从 13 到 14 时 zpool 就有所变动。
可通过 Ports 中的 OpenZFS 实现 13、14、15 等多个系统版本的共存。
警告
如不按照下方进行设置就强行升级 ZFS 池/特性,将无法访问旧版系统。
那些有意愿实现多版本共存的读者可以直接重启,进入启动环境 default(14.3-RELEASE)。
验证当前系统版本
我们需要确定我们的确在启动环境 default(14.3-RELEASE)中。
可以看到,我们已经回来了。
查看内置的 OpenZFS 版本
显示当前 ZFS 工具和内核模块的版本信息:
目前 FreeBSD 基本系统内置的是 OpenZFS 2.2.7(即来自 https://github.com/openzfs/zfs/commit/e269af1b3)
安装 filesystems/openzfs
使用 pkg 安装
使用 ports 安装:
编辑 /boot/loader.conf
/boot/loader.conf为了防止系统加载基本系统内置的 ZFS 版本,需要在 zfs_load=YES 前加上注释 #,取消其开机自动加载。
形如:
再新增下列数行:
完成后重启系统。
检查 ZFS 版本
在重启后,检查 ZFS 版本:
随后即可更新其他存储池或启用新的特性。
警告
考虑到基本系统中的 OpenZFS 版本不一定是最新的,所以你最好对所有版本都使用 Ports 中的版本以期达到统一。换言之,建议读者也在 15.0-RELEASE 中按照相同方法替换 ZFS。
附录:给 pkgbasify 脚本换源
修改示例(使用 USTC)
找到 Lua 脚本中的 create_base_repo_conf 函数:
将这个函数修改如下,其中在 return 部分指定了镜像站:
警告
请删除
return "pkg+https://"这行里面的pkg+,否则会报错。
再找到下面的函数 create_base_repo_conf
修改如下(删除了 srv 相关数行):
注意
对于那些优先考虑安全性的读者应该保持默认设置。
南京大学开源镜像站 NJU
网易开源镜像站 163
附录:配置软件源
FreeBSD 官方源的 pkgbase 信息如下:
分支
更新频率
URL 地址
以上表格中的时间已转换为北京时间(东八区),对应 FreeBSD 官方镜像站的发布时间。
若官方源下载速度慢,可以考虑换成国内镜像。只需要替换 https://pkg.freebsd.org 这部分。
参考文献
ZFS Boot Environments Explained,指出可以手动安装 openzfs 来达到旧系统使用新 zfs 池的目的
man bectl(8)
最后更新于
这有帮助吗?