delphij's Chaos

选择chaos这个词是因为~~实在很难找到一个更合适的词来形容这儿了……

20 Nov 2023

FreeBSD 14.0-RELEASE 发布了

上周末抽时间把服务器升级到了 FreeBSD 14.0-RELEASE。 软件的发布中存在许多的工序,大致上,在 releng/ 分支上的代码树会正式命名为 -RELEASE, 同时由一位 Release Engineer 开始最终的 build(对应的文件会发布到 FTP 上, 并在 网站 上提供链接),并在适当的时候将 releng/ 分支上的代码 tag 成 release。此后, Security Team 需要将 Release Engineer 签名的 -RELEASE 放到 freebsd-update builder 上再次 build、签名,并生成二进制更新所需的文件。

由于安装用的 ISO 映像文件都比较大,传统上将这些映像文件分发到全球的镜像站点上需要一些时间。 现时,云服务提供商往往还有自己的 QA 步骤,因此最终宣布 -RELEASE 的时间往往会比 FTP 上出现的时间晚上一周左右。技术上这段时间这个 build 依然只是一个发布候选版本(Release Candidate), 因此普通用户不应使用这些版本,因为在这一周的时间如果遇到一些突发状况的话可能会需要将这个版本撤回 (例如原本应发布为 FreeBSD 4.6.1 的 FreeBSD 4.6.2 就是这样的情况)。

我个人在机房的机器采用的 FreeBSD 是一套经过定制的版本,因此大版本升级时需要将本地的补丁 rebase 到新的 release 上面。 所以我采用的是使用源代码升级的方法。不过,从 去年启用了 Poudriere 之后, 我通常是在 Poudriere 上先把新的 package 全都 build 好之后用 pkg upgrade -fy 一次性完成升级了。

这次升级遇到的一些比较明显的坑:

第一个是 FreeBSD 14.0-RELEASE 去掉了配置文件中的 $FreeBSD$ 版本标记。在使用 CVSSubversion 的时代,这两个版本控制系统支持关键词扩展,可以将这些标记展开成包含文件路径、版本的字符串,例如:

$FreeBSD: releng/8.2/lib/libc/string/strlen.c 208051 2010-05-13 23:28:20Z delphij $

这些信息有助于在调试时知道一个可执行文件使用了哪些源文件(假如所有的源文件中都正确使用了 __FBSDID 宏, 这个宏会把这些字符串放到 ELF 文件的 .comment 段中)。迁移到 git 之后, 由于 git 不再支持关键词扩展,这些信息的意义大打折扣,于是我们在最近决定将所有的 $FreeBSD$ 一并删去了。

由于 FreeBSD 的配置文件合并程序(包括 etcupdate 和 mergemaster)在合并时都是采用的三路比对, 因此如果原先的 $FreeBSD$ 位置和进行的修改位置接近,则很可能会出现合并冲突,此时会需要手工干预。 如果平时做事不太细心,建议换一个头脑比较清楚的时候再做升级。

假如之前没有用过 etcupdate,个人建议在升级之前做一次初始化来让 etcupdate 认识之前的状态。

第二个坑是在安装过程中某些 shared object 库之间存在依赖关系。例如, libedit.so.8 需要用 libtinfow.so.9, 后者是 FreeBSD 14 中 新引入的,而两个库在安装时并未遵循依赖关系先装后者, 因此如果有 cron 任务恰好在安装过程中的某个时刻进入并且可执行文件恰好用到了 libedit 的话,可能会失败。

总体上,FreeBSD 14 已经在家里的网关等机器上跑了很久,因此并没有太多其他的意外。常见的其他注意事项, 例如在升级 ZFS 存储池之前要记得更新引导记录(或UEFI ESP)基本上每个版本都需要,在此就不赘述了。