LWN:塞一个文件系统进来!

关注了就能看到更多这么棒的文章哦~

An operation for filesystem tucking

By Jonathan Corbet
March 31, 2023
DeepL assisted translation
https://lwn.net/Articles/927491/

一般来说对一个文件系统进行 mount 操作,目的都是希望使该文件系统的内容可以让系统看到,或者至少在 mount 时的命名空间中是可见的。基于这个原因,把一个文件系统 mount 在另一个文件系统之上不是一个正常操作,因为这会导致被 mount 的文件系统的内容被隐藏掉。不过,凡事都有例外,mount 文件系统也是一样;Christian Brauner 提出的 "tucking (隐藏)"机制的目的就是希望把 mount 了的文件系统隐藏在另一个 mount 了的文件系统之下,至少暂时是这样。

Brauner 的封面邮件中详细描述了适用场景;本文中的记录则是希望将这一讨论进一步归纳一下。他的解释在很大程度上依赖于共享子树(shared subtrees)和挂载传播(mount propagation)的概念;之前 LWN 文章中提供了一些背景信息,可以让读者更容易理解。

文件系统 tucking 操作,主要是用于运行服务和/或容器这种工作负载的系统上,也就是不断发展中的 image-based 工作模式上。在这样的系统中,每个 service 或 container 都有一个文件系统层次结构,是由若干个不可修改的 base 文件系统组成的,然后在上面 mount 一些 overlay 文件系统。base 文件系统提供了操作系统核心部分,而 overlay 文件提供了跟具体任务相关的组件、更新和配置文件。每个容器都可以有自己的文件系统层次结构,但通常大多数容器会共享许多组件;每个容器在自己的 mount namespace 中来组装生成自己特有的层次结构。

举个例子,一个 container 可能会从 host 上的一个不可变镜像中来 mount 它的 root 文件系统。然后可以通过 overlay 来提供一些需要的二进制文件或者 /etc 中的必要配置文件。通过使用 overlayfs,就相当于实现了在底层镜像上添加文件或替换特定文件的效果,从而为容器提供了所需的文件。

这种机制可以很好地工作,但当一个 overlay image 需要更新(比如采用最新的配置变动或者加上一个安全更新)时,就会出现潜在的问题。一种方式是向每个容器发送消息,要求它 mount 新的 overlay,但这个动作可能会消耗大量 CPU 资源,而且需要每个容器都给出正确的反馈。相反,mount propagation 则可以用来把旧的 overlay 给 unmount 掉,并在 host 上挂载新的 overlay;然后这些变动将自动传播到使用了该 overlay 的每个 mount namespace 上去。

然而,这种方法面临着一个特别的问题:在 mount 新的 overlay 层之前,需要先 unmount 旧的 overlay 层,也就会有一小段是没有这层 overlay 的,从而导致各种奇怪的行为,或者有可能给 downgrade attack 提供了一个漏洞可以利用。如果有一种方法可以自动将容器无缝地迁移到新的 overlay 镜像上去,而不会产生这个短暂的窗口,那么也就不需要单独管理每个容器了,那就最好了。

这个答案就是文件系统 tucking。比如说,我们有下面这样一个简单的 mount 在/etc 上的 overlay:

370174c36de49afe403178197f6b5725.png

[在/etc 上的 overlay]

base 镜像给系统中的所有容器都提供了/etc 里的内容,而且是以不可改变的形式;然后 overlay 层为正在运行的容器类型提供所需的其他补充内容。在某些时候,需要对配置进行修改,所以需要替换掉 overlay 层。与其立即 unmount 现有的 kdoverlay,不如先把新的 overlay 层 "tuck(塞)" 在旧的 overlay 层下面:

c8a27b055f3088b2157f13fb6682cc93.png

[塞进来的 overlay]

mount propagation 会让这个新的 overlay 在每个需要它的容器中都被 mount 上,但新的覆盖层此时不会对文件系统内容做出任何用户可见的改变,因为旧的 overlay 还被 mount 在它之上。对于容器内运行的应用程序而言,看不到没有任何变动。但是,旧的 overlay 可以被 unmount 掉,于是产生下面的结果:

e1882ba3aa9ef8f2c4f6fe32dac6dad9.png

[新的 overlay 生效了]

旧的 overlay 不再遮盖住新的 overlay,所以新的 overlay 就生效了。当遵循这个顺序时,从容器的角度来看,对新的 overlay 的更改是以原子方式完成的;所以不会出现一小段时间窗口直接使用 base image 的内容。

现在是可以进行这种 tucking 操作的,但并不容易;mount 系统调用(即使使用新的 mount API)不允许以这种方式将一个文件系统 mount 到另一个文件系统之下。感兴趣的读者可以阅读 Brauner 的封面邮件,了解具体如何做到这一点。为了让大家的生活更简单,Brauner 建议在 move_mount()系统调用中增加一个新的 flag,MNT_TREE_TUCK(后来在 patch set 的某个修改版中改为一个单独的操作,名为 MOVE_MOUNT_BENEATH);它会导致新的 mount 动作被放在现有 mount 之下,而不是在它之上。这个操作有一些限制,包括禁止在 root 文件系统下进行 mount,以及要求调用者拥有 unmount 新的文件系统的权限。

在命令行方面,Brauner 介绍了 mount 命令的一个新选项,用来创建一个 tuck mount。在第一版中,这个选项被称为 –tuck,但也许是担心这将导致 mount 与 fsck 一起被加入一些文明词语(和发音)的黑名单,Brauner 在第二次修订版中把它改为 –beneath。

截至目前,这一个方案还没有收到任何回应;也许潜在的 review 者还在努力阅读封面材料。文件系统 tuck 似乎有可能在五月的 LSFMM/BPF 峰会上进行讨论。不过,这个功能可能确实是有用的,而且没有直接的坏处,所以预计最终会以某种形式被纳入 mainline。

全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。

欢迎分享、转载及基于现有协议再创作~

长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~

format,png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值