| RFC-0089:核心 realm 变体 | |
|---|---|
| 状态 | 已接受 |
| 区域 |
|
| 说明 | 根据产品配置生成自定义核心组件 realm。 |
| 问题 | |
| Gerrit 更改 | |
| 作者 | |
| 审核人 | |
| 提交日期(年-月-日) | 2021-03-04 |
| 审核日期(年-月-日) | 2021-04-19 |
摘要
在产品定义中设置的 GN 变量用于在相应产品的组件框架中生成自定义核心 realm。
设计初衷
如今,组件框架的 CFv2 中的核心 realm 是在 v2 系统中包含大多数其他封装组件的组件。此组件只有一个版本,因此每个产品都具有相同的静态 v2 组件集以及这些组件的功能路由。这会导致出现两个没有用途且永远不会运行的组件,并向组件提供过于广泛的功能,因为核心 realm 必须构建为所有产品配置的并集。
此外,v1 组件框架还支持在构建时有条件地向特定产品的 sys realm 添加功能和组件。随着组件从 v1 迁移到 v2,已经依赖于此的组件将进一步加剧当前模型的问题,即需要核心 realm 具有一个可同时满足每个产品要求的定义。
部分组件已从 v1 sys 领域迁移到 v2 core 领域,预计 2021 年第二季度的迁移速度将有所加快。
鉴于上述原因,我们需要能够根据运行 CFv2 Realm 的产品来量身定制 CFv2 Realm 的中央结构的确切内容。
范围
此设计旨在短期内实现更多组件迁移,直到更先进、更具前瞻性的解决方案准备就绪。此设计并非旨在适用于树外产品,也并非旨在成为合适的长期解决方案。PDK 旨在实现树外产品组装,将以更全面的方式解决此处所述的相同问题。
设计
核心 realm 清单的内容将拆分为一个通用基础和 CML 分片,其中包含产品可选择性包含的组件及其功能路由。例如,目前在 CFv2 中存在的 /core/temperature-logger 组件仅在 astro 产品上正常运行。以下分片将添加到单独的文件中,而不是在基本核心清单中添加与 temperature-logger 相关的内容:
{
children: [
{
name: "temperature-logger",
url: "fuchsia-pkg://fuchsia.com/temperature-logger#meta/temperature-logger.cm",
},
],
offer: [
{
protocol: "fuchsia.thermal.test.TemperatureLogger",
from: "#temperature-logger",
to: [ "#appmgr" ],
},
{
protocol: [ "fuchsia.logger.LogSink" ],
from: "parent",
to: [ "#temperature-logger" ],
},
{
directory: "dev-class",
as: "dev-temperature",
from: "parent",
to: [ "#temperature-logger" ],
subdir: "temperature",
},
{
directory: "dev-class",
as: "dev-thermal",
from: "parent",
to: [ "#temperature-logger" ],
subdir: "thermal",
},
{
directory: "config-data",
from: "parent",
to: [ "#temperature-logger" ],
subdir: "temperature-logger",
},
{
protocol: [
"fuchsia.device.Controller",
"fuchsia.hardware.temperature.Device",
],
from: "parent",
to: [ "#temperature-logger" ],
},
{
protocol: "fuchsia.tracing.provider.Registry",
from: "#appmgr",
to: [ "#temperature-logger" ],
dependency: "weak_for_migration",
},
],
}
此分片将使用 GN 模板为其创建一个包含分片路径的目标。对于 temperature-logger 示例,目标如下所示:
core_shard("temperature_logger_shard") {
shard = "//meta/temperature-logger.shard.cml"
}
每个产品的 .gni 文件(例如 //products/workstation.gni)都能够指定其希望包含在产品核心 realm 中的分片的 GN 目标。
core_realm_shards += [
"//src/sys/core:temperature_logger_shard"
]
在产品组装时,这些目标会使用 GN 的 generated_file() 目标进行收集,并用作 CMC 的合并操作的输入,其中要包含在产品中的分片会与核心 realm 的基本分片合并在一起。在当前示例中,temperature-logger 的分片是唯一与核心基本分片合并的分片。
此生成的核心 realm 将包含在名称源自产品的软件包中。例如,工作站产品的核心清单将打包在 fuchsia-pkg://fuchsia.com/core-workstation#meta/core.cm 中。
这是因为组件是使用网址进行标识的。这些标识符遵循用于标识的 webarch 原则,即“全局命名会带来全局网络效应”。因此,无论组件网址出现在哪个上下文中,它都指向相同的逻辑实体。这种方法意味着,Fuchsia 有一个涵盖所有产品和主板配置的软件宇宙。如果每个产品都能使用相同的网址来引用核心领域,并且该网址后面的内容因产品而异,则不符合此原则。
由于核心 realm 的网址现在在不同产品之间会有所不同,因此在 build 时会修改根组件清单,以包含当前产品的核心 realm 的正确网址。此特定于产品的根 realm 无需像核心 realm 那样以不同的方式打包,因为它直接包含在 ZBI 中,而 ZBI 本身就是特定于产品的。
所有产品上都存在的组件将位于通用基础中,而仅针对某些产品上未包含的组件创建分片。如果添加的新产品希望排除某个组件,而该组件之前一直包含在所有产品中,那么该组件将被重构,从通用基础移到 shard 中。
会话和产品专用路线
如果核心 realm 中的产品专用功能要通过会话管理器路由到会话,则有两种可能的选项。
一种方法是让会话管理器在所有产品中路由所有功能的超集。在这种情况下,不可用功能的路由会在核心 realm 失败。
第二种方法是使用基于分片的方案来构建特定于产品的会话管理器清单,这与本提案中概述的针对核心 Realm 的做法相同。在这种情况下,不可用功能的路由会在会话管理器 realm 失败。这种方法需要使会话管理器和核心分片列表保持同步,并会增加额外的构建复杂性和维护成本。
从会话的角度来看,这两个选项看起来完全相同。
实现
此更改可在单个 Gerrit CL 中完成。由于 GN 实参具有默认值,因此产品定义可以添加替换项,以便稍后启用所需的功能。
如需查看一个不完整但可正常运行的实现,了解此方法的运作方式,请点击此处。
性能
由于此提案中的所有工作都在 build 时进行,因此不会对运行时性能产生任何影响。
安全注意事项
此提案会导致本不应在产品上运行的组件出现在该产品上。这样一来,我们就能为组件提供其在运行的产品中所需的功能,而不是始终为组件提供其在所有产品中可能需要的功能的并集。
此提案会导致 CFv2 Realm 结构出现多种可能的变体,从而导致安全审核和工具(例如 scrutiny)需要能够处理新机制,同时产品之间的共享基础减少。
隐私注意事项
此提案将使组件仅存在于应运行它们的产品上,并且永远不会获得过于广泛的功能集,这两者都有可能提高系统的隐私保护保证。
测试
产品所有者需要确保其产品中包含必需的组件,并且在测试中涵盖这些组件的存在情况。虽然由于存在特定于产品的软件包集,这种情况已经存在,但此处提出的核心 realm 变体增加了一个额外的点,产品定义可能会意外遗漏重要组件。这会给产品所有者带来略高的负担,因为他们需要确保测试配置与产品配置保持一致。
文档
产品所有者可设置的确切 GN 实参将在 GN 中定义这些实参的位置进行记录。此外,我们还会维护 Markdown 文档,其中会描述每个清单分片及其对产品核心 Realm 的影响。