LWN: Linux 5.12中非常非常不妙的错误!
关注了就能看到更多这么棒的文章哦~
Linux 5.12's very bad, double ungood day
By Jonathan Corbet
March 8, 2021
DeepL assisted translation
https://lwn.net/Articles/848431/
Linus Torvalds 发布内核的 -rc release 是确有必要的:在两周时间的合并窗口中,有 10,000 个左右的改动流入内核后,肯定会有一些错误需要解决。在所有这些 patch 被整合之后,-rc 内核提供了一个更广泛的测试机会。大多数时候,-rc 内核(甚至是最初的-rc1 版本)运行起来出乎意料地稳定。不过偶尔也会出现一些问题,让早期的测试者感到后悔来测试这个版本。事实证明,5.12-rc1 内核就是其中之一。
1 月 26 日,Christoph Hellwig 发布了 17 个 patch 的系列改动,其中清理了分配 BIO 结构的代码。BIO structure 代表了一个一个的 block-I/O request。最后一个 patch里简化了 swap file 所需的 request 分配。这组 patch 在一天后由 block 子系统的维护者 Jens Axboe 合入了。然后被包含在 2 月 17 日的这个 pull request 中,并于 2 月 21 日登陆 mainline,作为 Torvalds 家里恢复电力供应后所合入的大批 pull request 中的一部分。
"swapping",是指当内存紧张时,内核将匿名页面(anonymous pages,那些没有对应的磁盘文件的 page——换句话说,就是程序数据)移动到 persistent storage 中。Linux 可以直接将数据 swap(换出)到块设备上的某个分区,这是传统系统中的常用设置。但是也可以换出到挂载上来的文件系统中的某个文件,而且这两种方式性能差异不大。交换文件(swapping to a file)给管理员带来了一些额外的灵活性。这种方法很简单,可以在不干扰现有 workload 的情况下,给当前正在运行的、内存不足的系统帮忙缓解一下紧张的内存空间。
有问题的 patch 在使用交换分区的情况下效果还不错。但是,当使用交换文件时,错误的丢弃了在文件系统中各个 block 中的 offset 偏移信息。这就导致了数据在 swap 出去的时候会写到错误的位置,而且很可能那里原本就有某些需要保留的数据。换句话说,放置了交换文件的这个文件系统会被破坏。有趣的是,2014 年就引入过一个类似 bug,并且潜伏了很长时间一直没有被发现,因为它只在极其罕见的配置条件下会出错)。
3 月 2 日,在 mainline 中合入了 fix。一天后,Torvalds 向 linux-kernel 邮件列表发送了一个警告邮件,描述了这个问题,并指出:"这就是我们业界所说的'double ungood'" 。他从他的 git 仓库中删除了 5.12-rc1 tag(其实是把它改名为 "5.12-rc1-dontuse"),并明确表示所有人都应该避免使用这个版本。他还对维护者提出了一些要求。
一个要求是关于 5.12-rc1 tag 的,他可以从他的版本库中删除它,但这不会改变其他人的 git 仓库。所以,他要求维护者应该自己手动删除这个 tag,防止不小心使用到这个版本。
除此之外,子系统的维护者经常会基于 -rc release 来开启新的分支,甚至很有可能是基于-rc1。但这次这样做的话,这些分支都会对正常的开发和测试社区造成严重危害,因为它们都不包含这个问题的 fix。git bisect 工具经常被用来寻找确认哪个 patch 导致了质量回退(regression),因此 git bisect 可能会导致当前代码跳到开发历史上的任何位置,如果包含那个错误 commit 的话(但不包含修复),这个 branch 会进一步扩展出去,导致今后发生破坏文件系统的情况。这一点,看起来也是 Linus 所说的"'double ungood'"。
因此需要人们不要基于 5.12-rc1 创建分支,而是要么使用更老的版本,要么等到-rc2。这对于那些已经发布了基于-rc1 的分支的子系统维护者来说,就来不及做什么了。确实有些人肯定已经公开发布了。他们必须做个选择,是保留这个有危险的分支,还是将其 rebase 到一个更安全的 commit 节点上、但是可能会给其他在使用该 branch 的人带来麻烦。这种 rebasing 的做法通常是不受欢迎的,但 Torvalds 明确表示这次可以,也是期望大家这么做。
内核社区大多数人还是把它当作 "bug happened" 的情况,然后继续向前演进。我们确实可以说,这个过程确实已经按照它本该有的方式起作用了:一个灾难性的 bug 在稳定期(during the stabilization)被提前发现,并且永远不会接近生产系统(production system)。话虽如此,但可能还有反省和思考的余地,即如何能把事情做得更好。
例如,有人可能会说,review 过程可以做得更好。这个 patch 只发布了一次,第二天就被合入到了代码库中。mainline 仓库中的 patch 包含两个 Reviewed-by tag 和一个 Acked-by tag,但邮件列表记录里面可以看出这些 tag 都是为该系列中的其他 patch 提供的。也许这三个 reviewer 人都在邮件列表之外提供了他们的 Reviewed-by tag,但从公开的记录来看,看不出这个导致问题的 patch 到底有多少人 review。
就算有更多人 review,但是我们也不能确保这个 BUG 触发之前就被发现,但似乎这次没有太多的 review 机会。人们经常把 "cleanup" 补丁看成天生就是安全的,需要较少的 review,但这些 patch 也可能包含微妙的 bug。
在这个过程中,可以做得更好的是关于提醒整个社区这部分。在上面链接的邮件中,Torvalds 承认他应该更早采取行动,而不是等着确定这个提出的 fix 方案是否真的可以让问题消失。可以想象,下一次的警告邮件会更早发出。
这里还有一个小问题,居然很少有人谈到。vger.kernel.org 上的邮件列表已经有一段时间都有些小问题了。有时候,邮件列表上的邮件会被延迟一两天,或者完全消失了。Torvalds 的警告并没有延迟那么久,但还是花了几个小时才送到 linux-kernel 的接收者手中。这个警告邮件的延迟传递,是否导致了更多的测试者受害呢?还不清楚,但肯定这是没有好处的。
好消息是,目前正在采取措施使 vger mailing list 可以更加稳定、可靠。运气好的话,邮件列表的问题在不久的将来就会成为过去式。
不过,哪怕到了那个时候,只发给 linux-kernel 的警告邮件也有可能消失在其他信息之中。邮件列表中每天都会超过 1000 条信息,很可能会淹没重要的信息,并导致许多开发者完全取消订阅。对于这种紧急信息,我们很可能需要更好的沟通渠道。
最后,这个 bug 造成的实际麻烦可能没有想象中那么大,并没有出现大量的 "它毁了我的文件系统!"的消息。流程确实大部分都能按照预期的方式进行。如果运气好的话,从这次事件中吸取的教训可以帮助这个流程在下一次工作得更好。
全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。
长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~