RFC-0155:可选功能路由 | |
---|---|
状态 | 已接受 |
领域 |
|
说明 | 系统会在优惠中添加一个新字段,并使用组件清单中的各个部分来指明何时可能不存在给定 capability。 |
问题 | |
Gerrit 更改 | |
作者 | |
审核人 | |
提交日期(年-月-日) | 2022-02-07 |
审核日期(年-月-日) | 2022-04-14 |
摘要
系统会在优惠中添加一个新字段,并使用组件清单的各个部分实现以下目的: 表示给定 capability 何时可能不存在。
设计初衷
核心领域分片
使用核心领域分片时,会出现以下场景: 路由的来源或目标不存在。例如,
- 组件
/core/wlancfg
使用协议fuchsia.location.sensor.WlanBaseStationWatcher
,但此协议 。 - 组件
/core/bt-a2dp
必须使用fuchsia.power.battery.BatteryManager
capability(如果可用),但 并非适用于所有产品。 /core/omaha-client-service
组件必须使用fuchsia.update.config.OptOut
协议(如果可用,但不可用) 适用于所有商品。CommsAgent
软件包必须使用视频(如果有),但没有可用的视频 视频。- Trace 提供程序是一个组件
fuchsia.tracing.provider.Registry
功能。这对于开发 但不应将此组件包含在 user build 中。
以上场景是我们想要支持的 但目前,组件框架中的几个位置 并引入了与此相关的粗略边缘:
- 如果向清单中不存在的组件提供该组件或从该组件提供,将 会导致清单验证失败。
- 如果从不公开的组件中提供某项功能,将会导致 审查验证失败。
- 功能路由失败(例如,尝试使用非 会导致组件管理器(正确)发出警告级别的日志, 看起来可能会令人担忧,因此会在调查 。
通过集合路由验证
审查是一款组件路线验证工具,可确保所有使用 给定组件树中的功能具有有效的功能路由。旁边 从它提供的系统正确性断言中发现,这是一个非常有用的工具, 因为它可以通过移动路线来缩短开发周期 从运行时到构建时进行验证。
如今,我们维护了一份许可名单,以停用审查功能 检查特定的功能路由。这使得在出现以下情况时构建成功 该组件使用了一个不可用的功能 当功能路由在 功能可用。
此外,https://fxbug.dev/42174612 问题解决后,我们还将进行审查 验证源自会话领域的功能路由。经常 会话组件依赖于源自 这会增加一些阻碍 列入审查许可名单,因为这些组件可能是 fuchsia.git.
利益相关方
谁对是否接受此 RFC 有影响?(此部分为可选内容, encouraged.)
教员:Hunter Freyer (hjfreyer@google.com)
由 FEC 指定通过 RFC 监管此 RFC 的人员 过程。
审核者:
- Mark Dittmer (markdittmer@google.com) - 安全
- Gary Bressler (geb@google.com) - 组件框架
- Marc Khouri (mnck@google.com) - WLAN
- Ani Ramakrishnan (aniramakri@google.com) - 蓝牙
- Yaar Schnitman (yaar@google.com) - 产品
社交化:
收到 https://fxbug.dev/42168255 和 向某些特定人员征求反馈,这是此 RFC 的早期形式 并在利益相关方之间共享。
设计
系统将添加一个名为 availability
的新字段以使用声明。默认
则此字段的值将为 required
,这意味着组件为
预期功能提供,否则很可能会发生故障
可用。此 RFC 没有建议对 required
的行为进行任何更改
功能 - 它们的行为方式与目前所有功能相同
{
use: [
{
protocol: "fuchsia.logger.LogSink",
availability: "required",
},
{
directory: "config-data",
path: "/config",
rights: [ "r*" ],
// The `availability` field defaults to `required` when omitted.
},
],
}
使用声明中的 availability
字段也可设置为 optional
,以
反映当功能不具备相关功能时,组件何时能够正常运行
(行为可能经过修改)。
{
use: [
{
// Emergency location is not present in all products.
protocol: "fuchsia.location.sensor.WlanBaseStationWatcher",
availability: "optional",
},
],
}
系统会将一个名为 void
的新来源添加到以下来源的可能来源列表中:
优惠声明。
{
offer: [
{
protocol: "fuchsia.update.config.OptOut",
from: "void",
},
],
}
一项使用声明是可选的功能可以通过 或来自“void”。功能其使用声明是 发生故障
中间优惠(从父级优惠到子级优惠)可能也会设置 availability
字段设置为下列值之一:
required
(默认):子级必须获得对此功能的访问权限。 无论子女能否处理其缺失问题( 由祖先中的 void 提供)。optional
:子级必须能够处理缺少此功能的情况 (优惠链末尾的使用声明必须是可选的)。same_as_target
:优惠将具有与目标相同的可选性。如果 目标需要该功能,则此报价规定目标 必须获得该功能如果目标对 则此报价会规定目标是否可以接收 这一功能
{
offer: [
{
protocol: "fuchsia.power.battery.BatterManager",
from: "parent",
to: "bt-a2dp",
// Emit a build-time error if this protocol is not correctly routed
// to this child (including offers from void).
availability: "required",
},
{
protocol: "fuchsia.location.sensor.WlanBaseStationWatcher",
from: "parent",
to: "wlancfg",
// Emit a build-time error if this child is unable to handle the
// absence of this protocol.
availability: "required",
},
],
}
如果某个组件使用了 optional
,并且其父级提供如下功能:
required
,
功能无效或以“来自 void
的优惠”结尾。如果某个组件具有
required
用法及其父级提供 optional
功能,然后
编译时错误。此字段可以未设置,但
已忽略。
核心领域组合
如 RFC-0089 中所述,核心领域由“核心领域”和 “分片”,也就是在构建时与核心领域合并的 CML 代码段 。确切的核心分片集由产品定义设定。
通常建议在同一核心中包含面向子级的产品/服务 作为子声明。这有助于确保 那么它正常运行所需的功能也会 可用的资源
如果将子节点的优惠包含在子节点的同一个分片中,
优惠希望有一个也可以包含在 build 中的来源。
如果某个商品以子 a
为目标,其来源为 b
,但 b
为
也位于分片中,则 a
的分片可能仅包含在具有 b
属性的 build 中
shard 文件,否则系统会在
。
为了让子级的优惠与子级的优惠位于同一核心分片中
无论来源为何,都将引入一个新字段来提供
声明名为 source_availability
。此字段将默认为值
present
,但可以设置为 unknown
。
当 source_availability
设置为 unknown
时,优惠声明将传递
清单验证。
在清单编译期间,优惠声明缺失的来源将被
替换为 void
来源,以允许路由以结尾的任何使用声明
确保能够通过设置
对 optional
的可用性,以反映并非所有设备上都提供该功能
产品。
{
offer: [ {
protocol: "fuchsia.examples.Echo",
from: "#child-that-might-not-be-declared",
to: "#echo-user",
source_availability: "unknown",
} ],
}
这样,平台配置维护人员就可以依赖于一组核心
功能、组件和组件,将其用作单一可信来源
省略核心分片不仅会移除子系统
还能准确更新
该子系统从 void
提供,以便任何具有可选属性的组件
则相应子系统上的用量将正常无法获取
(而任何必要的用途除外)
在这种情况下仍然会导致错误)。
示例
核心领域中具有可选功能的组件
在本示例中,我们来看一下 清单文件和核心领域
wlancfg
将根据提议的设计而发生变化。
fuchsia.location.sensor.WlanBaseStationWatcher
协议的优惠
将从 emergency.core_shard.cml
移动到 wlancfg.core_shard.cml
,并且
source_availability
字段设置为 unknown
(因为紧急核心
紧急服务组件不一定会包含在
与 wlancfg
相同的平台配置)。
// src/connectivity/location/emergency/meta/emergency.core_shard.cml
{
offer: [
// This is removed
{
protocol: "fuchsia.location.sensor.WlanBaseStationWatcher",
from: "#emergency",
to: "#wlancfg",
},
],
}
// src/connectivity/wlan/wlancfg/meta/wlancfg.core_shard.cml
{
offer: [
// This is added
{
protocol: "fuchsia.location.sensor.WlanBaseStationWatcher",
from: "#emergency",
to: "#wlancfg",
source_availability: "unknown",
},
],
}
有必要将优惠声明移至 wlancfg
的核心分片
确保 source_availability
字段正常运行,并且与
核心分片最佳实践。
除核心分片更改外,此协议在
wlancfg
会更新为 optional
。
// src/connectivity/wlan/wlancfg/meta/wlancfg.cml
{
use: [
{
protocol: "fuchsia.location.sensor.WlanBaseStationWatcher",
// This line is added
availability: "optional",
},
],
}
现在,当 build 中不包含 emergency.core_shard.cml
文件时
将不会因为 wlancfg
无法访问
fuchsia.location.sensor.WlanBaseStationWatcher
协议。这意味着
可能会从审查许可名单中移除,并且出现任何配置错误
导致平台上的 wlancfg
无法使用此协议
可用的配置会导致构建时错误。
会话中具有可选功能的组件
在本示例中,我们来看看清单和核心领域分片
从 Google Cloud 获取 fuchsia.power.battery.BatteryManager
协议
/core/battery_manager
至
/core/session_manager/session:session/workstation_session/login_shell/ermine_shell
更改将根据提议的设计而变化。
workstation.core_shard.cml
文件中的协议报价为
更新后,将 source_availability
设置为 unknown
:
// src/session/bin/session_manager/meta/workstation.core_shard.cml
{
offer: [
protocol: "fuchsia.power.battery.BatteryManager",
from: "#battery_manager",
to: "#session-manager",
// This line is added
source_availability: "unknown",
],
}
无需更改 core
和 ermine_shell
之间的优惠,并且
系统会更新 ermine_shell
清单,将 availability
字段设置为
optional
(对于协议):
// src/experiences/session_shells/ermine/shell/meta/ermine.cml
{
use: [
{
protocol: "fuchsia.power.battery.BatteryManager",
availability: "optional",
},
],
}
通过这些更改,workstation.core.shard.cml
文件可能会包含在
不使用 battery_manager.core_shard.cml
和没有
导致构建时检查错误,或者将此功能添加到许可名单。
这意味着,电池管理器组件可以安全地从平台中排除
期望在没有外部 IP 地址的硬件上运行工作站会话
电量。
会话所有者希望确保一项可选功能始终为
可用
以前面的示例为基础,假设存在一个名为
workstation-on-laptops
,这与 workstation
会话相同,除了
它具有针对笔记本电脑的额外功能。如果此会话的所有者希望
使用 workstation
会话上提供的相同 ermine
组件,
但想确保它始终能够访问
fuchsia.power.battery.BatteryManager
协议(由构建时强制执行)
错误),那么会话所有者可能会将此协议作为 required
提供给
ermine
。
// src/experiences/session_shells/ermine/session/meta/workstation_on_laptops_session.cml
{
offer: [
protocol: "fuchsia.power.battery.BatteryManager",
from: "parent",
// login_shell offers the capability to ermine
to: "#login_shell",
availability: "required",
],
}
在此示例中,如果将workstation-on-laptops
会话与
提供 fuchsia.power.battery.BatteryManager
的平台配置,
来自 void
的协议(即 battery_manager.core_shard.cml
不是
包含),那么尽管 ermine.cml
该协议的可选用法
会话所有者希望确保组件可以处理缺少
一项可选功能
同样,在“ermine 选择使用 BatteryManager
”进行构建例如,如果
工作站会话的所有者希望确保 ermine
始终为
能够处理缺少 fuchsia.power.battery.BatteryManager
的问题
无论该协议当前是否可用,它们都可能会提供
optional
改为 ermine
。
// src/experiences/session_shells/ermine/session/meta/workstation_session.cml
{
offer: [
protocol: "fuchsia.power.battery.BatteryManager",
from: "parent",
// login_shell offers the capability to ermine
to: "#login_shell",
availability: "optional",
],
}
此可选优惠不会影响
因为 Ermine 还可以选择性地使用该 功能。如果
然而,ermine 经过更改,需要此功能,那么构建时
无论功能路由是否
有效或以“来自void
的优惠”结尾。
实现
为了实施这些更改,fuchsia.component.decl.Component
FIDL 表
和 CML JSON 架构,必须更新这些新字段,
CMC、cm_fidl_validator
和 Scrutiny,能够正确处理
设计部分中介绍的 optional
语义。
性能
建议的更改不会对构建时间或 因为在这些清单中承载额外枚举的成本非常高 小。此外,组件管理器中提议的运行时行为变更 不会对广告效果产生重大影响, 实现新的命名空间汇编逻辑时,该逻辑 工作。
工效学设计
此更改应该会显著改善所有组件作者的工效学设计 目前需要与许可名单互动以抑制审查的用户 验证错误,因为关于预期验证错误的上下文将是 这样审查结果根本不会出现这些预期错误。
向后兼容性
此更改纯粹是对 FIDL 表和 JSON 格式的添加,因此具有 不存在向后兼容性问题。
安全注意事项
这项变更可让组件作者停用审查 未得到安全部门批准的情况下针对未路由功能的错误 因为许可名单将不再用于控制审查错误 禁止未路由功能。
这种做法是可以接受的, 组件路由本身的修改
隐私注意事项
建议的更改不会影响用户数据的收集、处理或 因此就不存在任何隐私问题了。
测试
已经有大量测试涵盖了组件清单流水线。 我们将更改这些测试,以纳入这项新功能的覆盖范围。
文档
将更新组件清单文档,以描述新字段 及其对验证的影响。
缺点、替代方案和未知问题
先验技术和参考资料
TODO