关注了就能看到更多这么棒的文章哦~
The ABI status of filesystem formats
By Jonathan Corbet
October 8, 2020
DeepL assisted translation
https://lwn.net/Articles/833696/
Linux 内核开发有一个关键原则,那就是内核和用户空间之间的 ABI 不能被破坏。任何改动如果破坏了以前能正常工作的程序的话(除了特殊情况外)都会被 revert 掉,恢复原状。这个规则似乎很明确了,但是在确定到底什么是内核 ABI 的时候,却存在着分期。tracepoints 就是一个经常被拿出来说的例子。最近的一次讨论让另一个有歧义的地方暴露了出来:Linux 文件系统在磁盘上的存放格式。
那些报告了 kernel 功能回退的用户,会根据这个回退问题发生的位置而得到不同程度的同情。对于那些使用了系统调用 API 的、正常的用户空间程序来说,几乎绝对会得到同情,那些破坏了这部分的改动将会需要重新实现。ABI 的概念也延伸到了虚拟文件系统上,比如/proc 和 sysfs 这些由内核 export 出来的文件系统。如果只有一个程序使用了某个接口,而且这个程序也被相应地更新了,那么这种内核改动可能会被允许。此外,没有人会关注那些导致内核树外的模块(out-of-tree kernel modules)不能用了的改动,因为它们用到的接口被认定是内核内部接口,不会保证今后不改变。
但这些并不是 user space 和内核的唯一接口。Josh Triplett 报告的这次回退时间就是个例子。看起来 5.9-rc2 中合入的一个 ext4 文件系统 bug fix,破坏了他需要用到的一些 ext4 文件系统的 mount 功能。
这些文件系统是用一个未发布的内部工具来创建的,主要针对一些特定的内部使用目的。这种文件系统使用场景是完全只读的,所以永远不会有需要(或能力)在其中创建新文件。这个工具为了节省空间,就将所有的 block bitmap 和 inode bitmap 都 overlay 到同一个 block 上,并把所有 bit 都置为 1,表示所有的 block 和 inode 都已经分配完毕。这个工具会用一个特殊的标志(EXT4_FEATURE_RO_COMPAT_SHARED_BLOCKS)来对文件系统打上标记,提示它采取了这种共享 block 的行为。这个 flag 在工具中有定义,但内核并不会使用这个 flag。这个 flag 被放在 read-only 的兼容性标志区域中,这意味内核如果看到文件系统有这个标记的话,就会知道这个文件系统可以安全地进行 mount 操作,但只能是在 read-only 模式下。
在 5.9-rc2 版本之前,mainline 内核都可以正常 mount 这些文件系统。Triplett 指出这个提交(https://git.kernel.org/linus/e7bfb5c9bb3d )产生了变化,在 mount 时的 ext4 verifier 代码中增加了一些检查,以确保文件系统镜像是有效的。这些新的检查会检测到上述的重叠的 bitmap,内核会报错,这些 mount 文件系统的操作相应地都会失败。一些以前能用的东西就不再能用了,这也就是人们所说的发生了回退(regression)。Triplett 在他报告这个问题的邮件中加入了一个小 patch,当 EXT4_FEATURE_RO_COMPAT_SHARED_BLOCKS 标志存在时,该 patch 就会禁用检查,从而使他的文件系统重新可以 mount。
这个改动很可能会被合并,但文件系统开发者并没有因此而放心,相反他们认为这是一个错误的做法。XFS 维护者 Darrick Wong 认为,不应该支持 "非官方(unofficial)" 的文件系统变体。
我不同意。这样会为现有的 ondisk format 创建出一种文档中未记载的变种(尤其是在正常工具中会看到不一致的 metadata),当这种不兼容的变种与正常的规范实现产生冲突时,会给未来的用户和维护者带来很大的麻烦。
Triplett 回应认为,文件系统镜像(filesystem images)应该属于内核 ABI 的范畴。
我一般认为,mount 现有的根文件系统(root filesystem)的行为,属于 kernel<->userspace 或 kernel<-> existing-system boundary (现有系统边界)的范畴,这是由现在内核可以接受、并且用户空间已经成功使用的内容所定义的,升级内核应该可以让现有的用户空间程序和系统都能正常工作。我没听说过还有其他什么特有规则在文件系统这方面。
Ext4 维护者 Ted Ts'o 表示,他并不反对 Triplett 的补丁,但估计后续进一步支持这个工具的 patch 可能不会收到热烈欢迎。随后他讲述了 make_ext4fs 工具的故事,这是一个独立开发的 ext4 文件系统创建工具,Android 有许多年都在使用它。但是它产生了许多的兼容性和文件损坏问题,耗费了几年时间才解决。第三方文件系统工具很容易出现这样的问题,他说:
在我看来,这不仅仅是磁盘上文件系统格式的问题,也是跟官方发布的用户空间工具有关。如果你创建了一个内核可以接受的文件系统镜像,但是并不是用官方的用户空间工具创建的,那么因为文件系统中有许多种状态和变体,所以出现错误结果(mischief)的可能性就很大。
文件系统开发者对 "mischief " 天生相当反感,因此,Ts'o 的观点(希望这些外部工具根本不要存在)也就不足为奇了。他建议,未来的规则至少应该规定,只有由官方指定的工具来创建和管理的镜像,碰到了 filesystem-image regression,才需要解决。他要求 Triplett 想办法能摆脱他的特制工具。
Triplett 不同意这个规则,他说更合理的做法是,任何能通过 e2fsck checker 的文件系统映像都应该得到支持。并非所有使用 ext4 格式的工具都得放在 e2fsprogs 仓库中的。他补充说,如果不这样做,就等于说有 ext4 文件系统驱动的 FreeBSD 内核也应该放在 e2fsprogs 中。按 Triplett 的描述来看,本文中讨论到的这个工具,似乎也是不适合放在 e2fsprogs 仓库中的。
Triplett 在那封邮件的最后重申了他的要求:
我在这里唯一的要求就是 "不要破坏已经能正常工作功能"。除了这个特定需求以外,我也愿意将目标缩小到 "不要破坏 e2fsck 之前认可的东西"。
Ts'o 的回应明确表明他并不愿意实现这个需求。他说,这将导致无法修复那些与无效的(invalid)文件系统映像相关的安全问题,而这种问题有很多。许多这些无效的映像–通常是由模糊工具或攻击者产生的——都可以通过 e2fsck 的检查,直到人们发现并修复这些问题。因此,他说,将任何通过 e2fsck 的镜像都判定为需要支持的话,就是在要求需要永远支持那些无效的文件系统。最后,他对解决 Triplett 问题提出了一些其他的建议,并要求 Triplett 在未来能与 ext4 开发者更紧密地合作。
讨论目前就到此为止了。Ts'o 愿意打上这个 fix patch 来解决眼前的问题,这意味着并不需要马上来解决这些文件系统的回归相关的更大范畴的问题。但是这又意味着这个问题很可能在某个时候再次出现。内核 ABI 是一个庞大而且尚未明确定义的东西,很多边界,哪怕用最乐观的词汇来说也都是模糊的(fuzzy)。文件系统这里的边界则是又一个尚未被充分探索的领域。很可能有人后续在不经意间会再次碰到错误。
全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。
欢迎分享、转载及基于现有协议再创作~
长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~