RFC-0257: storage-host: 将上层存储驱动程序组件化

RFC-0257: storage-host: 将上层存储驱动程序组件化
状态已接受
领域
  • 存储
说明

将上层存储驱动程序(GPT、FVM 等)移至新的存储主机组件。

问题
Gerrit 更改
作者
审核人
提交日期(年-月-日)2024-07-08
审核日期(年-月-日)2024-08-13

摘要

目前,块存储设备在驱动程序框架中的分层式 。实际与硬件交互的低级驱动程序(例如 sdmmc、 virtio)实现内部 fuchsia.hardware.block.driver 协议,以及 较高级别的驱动程序(如 GPT、FVM、zxcrypt)与此协议交互, 在这些驱动程序的基础上提供更高级别的功能(包括 fuchsia.hardware.blockfuchsia.hardware.block.partition 协议)。周三 建议将所有上层块驱动程序都移到一个新组件中, storage-host:仅在驱动程序框架中保留低层级驱动程序。

设计初衷

此更改的主要目标是将存储堆栈与 Devfs 和 驱动程序框架,从而支持驱动程序框架团队的工作 Devfs(以及将驱动程序堆栈迁移到驱动程序框架 V2 的更广泛的应用)。

目前,存储堆栈广泛依赖 Devfs 进行发现和 以及对块设备的拓扑访问移除此依赖项需要 对存储堆栈进行大量重构,以使用替代解决方案 Devfs(在编写本文档时尚未 )。由于需要创建新的 API 和存储堆栈, 进行哪些更改,现在正是重新考虑 这些 API 实际上也已实现

可以说,GPT 等上层块设备并不是 才是真正的意义它们不与硬件互动,而是与 底层块设备换言之,该驱动程序框架 与上层块存储设备不同。Storage 堆栈 一直以来都是非同寻常的 Driver Framework 客户(例如, 使用 Devfs 中的拓扑路径),并且看起来 有利于驱动程序框架或存储团队维护, 不匹配。

除了推动驱动程序框架团队弃用 Devfs 之外, 如果迁移这些上层资源 块存储设备到存储主机:

  • 通过简化和导出操作来提高存储团队的工程速度 将我们的技术栈整合到熟悉的语言 (Rust) 和框架中 (常规非驱动程序组件)、
  • 启用需要跨平台工作(例如 也可能将文件系统与上层块驱动程序或 API 更改,例如 I/O 优先级所需的更改),
  • 让存储团队能够控制哪些组件可以访问 块存储设备,这应通过存储政策(而不是访问)进行中介 至 /dev/class/block)。
  • 我们省去了将这些驱动程序移植到驱动程序框架 V2 的工作。

利益相关方

教员

  • hjfreyer@google.com

审核者

  • garratt@google.comm
  • csuter@google.com
  • curtisgalloway@google.com
  • surajmalhotra@google.com

已咨询

  • 咨询了驱动程序框架团队。

社交化

在此之前,此 RFC 与驱动程序框架团队进行了社交讨论 。

要求

此更改必须对 Fuchsia 的其余部分公开;我们预计 迁移过程中会发生一些变化

此变更不应导致性能出现任何明显下降, 内存或存储空间用量

设计

存储主机组件将管理分区和嵌套的块设备 物理块存储设备它将在 Rust 中实现。

为便于说明,我们介绍的启动流程适用于 GPT 格式的块存储设备。存储主机将能够处理 例如 MBR 和 FVM。

Fshost 目前监听来自驱动程序框架的块存储设备, 其格式,并确定要绑定的块设备驱动程序。例如: 当 GPT 格式的设备gpt 。fshost 中的更改非常简单:无需启动 gpt 设备驱动程序,fshost 会改为将设备交给存储主机。

storage-host 会从 GPT 中解析出分区表,并导出一个 为每个分区创建 fuchsia.hardware.block.partition.Partition 服务。这些 服务将在其导出的partitions目录中 storage-host。此目录用于替换 dev-topological Devfs 中的路径,从而允许分层式发现和访问嵌套 分区。

Fshost 会监测发布到 partitions 的设备,并执行正常操作 匹配,其中可能包括启动文件系统。嵌套分区有效 (例如 GPT 中的 FVM),而在这种情况下,fshost 只会要求存储主机 装载和取消嵌套指定的分区。

文件系统和其他客户端用于执行块 I/O 的协议 因为存储主机将实现相同的 以及驾驶员使用的协议尽管如此,我们仍可能会 出于其他原因(例如提高性能)。

目前使用 Devfs 发现和连接到块的客户端 设备需要使用 partitions 进行移植。许多用法已经 由 fshost 或 paver 进行中介,因此最好将长 以通过 fshost 进行中介访问,因此我们拥有更严格的控制 以及块存储设备的使用情况例如,我们可以在 fshost 中公开一个 API, 访问特定分区,而不是授予对所有块的全面访问权限 设备。partitions 目录将仅在树内使用,且应 客户数量有限,因此我们可以根据需要灵活地进行更改。

fshost 和 storage-host 之间的来回关系(fshost 通过 块存储设备到存储主机,存储主机绑定到分区,传递 将嵌套块设备返回至 fshost)可能看起来不正常, 优势。实际上,它可以加快存储主机的实现速度, 只需在 fshost 中进行更改即可。它还可将 责任:fshost 实施存储政策(要绑定哪些文件系统、 要装载的块设备等),而 storage-host 则可帮助执行 通过托管嵌套块设备来实施政策。循环关系可以 如果有必要,日后再对架构进行重新设计

请注意,前期启动没有任何变化,也就是说,从 ZBI。启动序列中的这部分在启动 fshost 之前,因此是 此提案未对其更改。

多个存储主机实例

尽管目前不需要,但我们将避免做出如下假设: 系统上只有一个存储主机实例。例如,我们可能会 需要为嵌入式存储设备创建一个单独的存储主机实例,以及 可插入 USB 设备,以在两者之间保持一定程度的隔离 多种存储堆栈来增强安全性。或者,我们可能希望 运行不同格式,例如例如 GPT 和 FVM 隔离。

当前架构

图 1:当前架构。

提案架构

图 2:提案架构。

实现

这项更改可以在迁移过程中逐步实施, 各种影响因素

例如,vim3 配置只需要迁移 GPT 驱动程序, 我们可以先实现该解决方案 已经转移完毕智能商品需要 FVM 和 zxcrypt;它们将是 稍后会实现

我们需要确保客户端可以从以下位置临时访问块设备: 即 devfs 或 storage-host,这很简单,因为我们计划使用 类似的面向目录的发现界面

我们将在 fuchsia.fshost.StorageHost 上限制存储主机的使用 并在特定产品/开发板上 配置可以切换。

一旦所有使用方式都完成转换并被视为稳定,我们便可移除 完成迁移所需的过渡逻辑。

storage-host 将作为单体式 Rust 二进制文件实现。如果变为 (例如,为了减少二进制文件的膨胀程度),我们可以将功能分离出来, (例如 zxcrypt)导入库中,并根据需要在 但为了简单起见,我们先介绍 单体式二进制文件。

请注意,由于存储主机和 基于驱动程序框架的等效实现, 则会还原为初始状态

请注意,FVM 和 GPT 也附带各种主机工具。周三 不打算将这些代码移植到 Rust,因为它们很稳定, 并且目前没有激励措施可以更改它们。

性能

我们认为,此项变更对 不依赖于 FVM 和 zxcrypt。虽然现在 文件系统和块设备驱动程序后,该组件就可以从 只需进行一些简单的 API 更改即可(例如,storage-host 可以代理窗口化视图) 底层块存储设备的映像,然后文件系统 直接通信到底层块驱动程序)。

对于 FVM 和 zxcrypt,存储主机需要拦截每个请求并进行修改 因此与目前采用的数据相比, 驱动程序框架实现。对于 FVM,必须这样才能 对于 zxcrypt,这对于加密来说是必要的。

之所以出现延迟时间增加是因为需要将请求从 块 FIFO 从存储主机重新排队,并在底层 FIFO 上重新排队。请注意, 驱动程序框架实现仍需要拦截、修改和重新排队 但驾驶员与驾驶员之间的沟通是通过班卓琴进行的 协议 (fuchsia.hardware.block.driver.Block),它使用更高效的 两个驱动程序位于同一位置时的传输机制。换句话说, 由于经过存储主机的额外进程跃点而导致的延迟。

我们认为可以通过几种方式来解决此问题(这些方式更简单或可行)。 使用 storage-host):

  • 在 Rust 中引入并发会更加简单,因此我们或许可以改进 通过流水线或并行化工作来增加吞吐量。
  • Blobfs 使用外部解压缩程序来提高安全性, 往返文件读取。这项操作可以移动到存储主机中 与 I/O 请求同时运行,从而消除由 storage-host。(从安全角度来看,如果 Blobfs 因为 Blobfs 并不假设块设备本身 值得信赖;从安全角度来看,主要目标是避免 解压缩,这可能会破坏 Blobfs 进程。其他文件系统 也就是说,Minfs 没有像 Blobfs 那样具有验证数据的能力, 如果存储主机被盗,我们得称重 此优化的性能和安全权衡)。

展望未来,我们希望能够在 storage-host,将帮助我们完成未来的性能优化工作。对于 例如,我们最终可能需要引入 I/O 优先级,这需要 在整个堆栈中进行的更改。这使得 Cloud Storage 通过 在一个语言和环境中整合了代码库,使我们能够更快地工作 位置

向后兼容性

由于我们只修改树内代码和 API,因此不会 与此次更改存在的兼容性问题。

安全注意事项

重新实现 zxcrypt 将需要进行安全审核, 安全敏感型服务

此变更将从以下几个方面增强安全性:

  • 驱动程序将使用 Rust(而非 C++)实现,从而减少内存用量 损坏修复漏洞
  • 我们将有机会通过 因为所有这些用例都需要 已迁移。

需要注意的一点是,此提案将涉及对 安全域。我们可以考虑 与托管在单个安全网域中,同时托管在同一进程中;令人讨厌的 一种意味着损害另一种。与每个 Pod 通信的组件 其他 FIDL 或其他 IPC 机制与 (这并不意味着对攻击具有免疫力)。此提案会提高 隔离(将存储设备管理与其他位于同一位置的驱动程序分离)、 但我们认为 隔离边界(如果必须确保性能共置) 软件组件。请参阅“设计”部分中的图表。

隐私注意事项

不适用。

测试

现有的 fshost 测试套件为我们进行验证打下坚实基础 因为这些测试执行的是端到端检测流程, 绑定至块存储设备

我们应该借此机会开发更强大的块堆栈测试, 我们可以使用此数据来验证两者之间的行为 完全相同

文档

Storage 的较低层历史历来较少, 这是通过一些高级架构 文档。存储对于最终开发者来说通常是不透明的, 系统开发者和其他的 Fuchsia 团队 存储空间。

缺点、替代方案和未知问题

缺点

我们无法将这些上层驱动程序与最低层级驱动程序共置到一起 因为最低级别的驱动程序会理所当然地 继续保持在驱动程序框架中尽管如此,我们并不认为这是一个问题, 仅移动了驱动程序中存储堆栈所在的边界 并且该边界不太可能包含整个 堆栈(包括文件系统),因此它们之间始终会有一些边界, 在 DF 中保留的部分和在非 DF 中的部分

这项变更加大了实现 OOT 存储驱动程序的难度,但 还不是我们打算支持的功能;我们希望所有与存储相关的 在可预见的未来,代码将保留在树中。

我们首先对存储主机进行静态编译, 而在旧版驱动程序框架中,驱动程序由系统动态加载 只会包含相应产品使用的那些属性如上所述, 如果认为这是一个问题,我们稍后可以使用动态链接加以解决, 。

替代方案

显而易见的替代方案是不进行此项更改, 驱动程序框架中的驱动程序。但请注意,这并不意味着 您无需执行任何操作。我们仍然需要:

  • 将上层块驱动程序迁移到 DFv2。
  • 设计一个用于发现和连接块存储设备的新接口, 与驱动程序框架团队密切合作。
  • 移植所有客户端以使用以下新界面,而不是开发拓扑。

换言之,两种整合工作的广度和广度相同, 范围。此提案所需的额外工作是重新实施 而不是将其移植到 DFv2 中。这些推动因素均 我们可以在 Google Cloud 中 创建一个有效的 GPT 原型 这只是一个比较简单的费用, 。

另一种选择是等待引入基于 Rust 的驱动程序, 驱动程序框架,然后将现有驱动程序移植到 Rust,从而将这些驱动程序 驱动程序框架不过,具体时间安排与实际情况不符。通过 Devfs 的目标日期为 2024 年底,而且没有 稳定支持 Rust 驱动程序的时间表,因此我们不得不处理 无论如何,都应弃用 Devfs;我们也有可能会获得 storage-host。

先验技术和参考资料

不适用。