RFC-0155:可選的功能路徑

RFC-0155:選用能力路徑
狀態已接受
領域
  • 元件架構
說明

我們在優惠中加入一個新欄位,並使用元件資訊清單中的段落來表示特定能力可能不存在的時機。

問題
更小鳥
作者
審查人員
提交日期 (年月分)2022-02-07
審查日期 (年-月-日)2022-04-14

摘要

我們在優惠中加入新欄位,並使用元件資訊清單中的區段指出特定能力可能不存在的時機。

提振精神

核心領域資料分割

使用核心領域資料分割時,這會導致能力路徑來源或目標不存在的情況。例如:

  • 元件 /core/wlancfg 使用 fuchsia.location.sensor.WlanBaseStationWatcher 通訊協定,但某些產品並不適用這個通訊協定。
  • /core/bt-a2dp 元件必須使用 fuchsia.power.battery.BatteryManager 能力 (如有),但該功能並未適用於所有產品。
  • /core/omaha-client-service 元件必須使用 fuchsia.update.config.OptOut 通訊協定 (如果有的話),但不適用於所有產品。
  • CommsAgent 套件必須使用影片 (如果有的話),但部分產品無法觀看影片。
  • 追蹤提供者是提供 fuchsia.tracing.provider.Registry 能力的元件。這在開發過程中相當實用,但是此元件不應包含在使用者建構中。

以上情境是我們希望日後支援的元件設定,但元件架構目前還有幾個地方提供相關的概略邊緣:

  • 如果提供或提供的元件在資訊清單中不存在,會導致資訊清單驗證失敗。
  • 如果提供的能力來自未公開的元件,會導致審查失敗。
  • 能力路徑失敗 (例如嘗試使用未提供的能力) 會導致元件管理員 (正確) 發出警告層級記錄,這可能需要關注,因此在調查刻意省略能力的產品問題時,可能會造成誤導。

透過集合進行轉送驗證

Scrutiny 是元件路徑驗證工具,可確保指定元件樹狀結構中的所有使用的功能都具備有效的能力路徑。除了系統正確性斷言之外,這對於開發來說非常實用,因為這項工具可從執行階段將路徑驗證作業從執行階段轉移到建構時間,縮短開發週期。

現在,系統會維護許可清單,停止對特定能力路徑進行檢查。這可讓版本在元件使用無法使用的能力時成功執行,但幸運的是,如果能力路徑在「能力」可用的情況下設定錯誤,也就可以成功建構。

此外,在 https://fxbug.dev/42174612 解決後,系統還會驗證源自工作階段運作範圍的能力路徑。工作階段元件通常會依賴於工作階段外部產生的功能,如果想要將其中一個元件加入審查許可清單,則這些元件通常會增加阻礙,因為這些元件可能是在 Fuuchsia.git 之外開發的。

相關人員

誰有權規範這份 RFC?(本節為選用,但建議提供)。

講師: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 (預設):無論子項是否能處理是否出現這項功能,子項「必須」獲得這項功能的存取權 (可能不會透過祖系中的無效提供)。
  • 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 程式碼片段會在建構期間與核心領域合併。確切的核心資料分割組則取決於產品定義。

一般而言,建議在與子項宣告相同的核心資料分割中,納入以兒童為目標的優惠。這有助於確保如果子項包含在建構中,其運作所需的功能也會提供給其使用。

如果優惠希望有也可納入建構作業的來源,那麼將子項優惠納入與子項的資料分割中會變得比較複雜。如果優惠目標為子項 a 的來源為子項 b,但 b 也在資料分割中,則 a 的資料分割可能只包含在納入 b 資料分割的版本中,或者資訊清單驗證錯誤會在建構期間發生,因為不存在子項的優惠而在建構期間發出。

無論來源為何,子項的優惠才能與子項宣告的同一個核心資料分割位於同一個核心資料分割中,無論來源為何,系統都會導入新的欄位來提供名為 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",
        },
    ],
}

現在,如果 emergency.core_shard.cml 檔案未包含在建構中,就不會因為 wlancfg 無法存取 fuchsia.location.sensor.WlanBaseStationWatcher 通訊協定,而不會發生建構時間錯誤。這表示該通訊協定可能會從審查人員的許可清單中移除,而在「可使用」的平台設定中,導致該通訊協定無法使用,都會造成建構時間錯誤。wlancfg

工作階段中具有選用能力的元件

在此範例中,我們將看看在從 /core/battery_manager/core/session_manager/session:session/workstation_session/login_shell/ermine_shell 取得 fuchsia.power.battery.BatteryManager 通訊協定時,所涉及的資訊清單和核心領域資料分割,會如何根據提議的設計而發生變化。

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",
    ],
}

您不需要變更 coreermine_shell 之間的優惠,且會更新 ermine_shell 資訊清單,將通訊協定的 availability 欄位設為 optional

// src/experiences/session_shells/ermine/shell/meta/ermine.cml
{
    use: [
        {
            protocol: "fuchsia.power.battery.BatteryManager",
            availability: "optional",
        },
    ],
}

經過這些變更後,您可以在沒有 battery_manager.core_shard.cml 的平台設定中納入 workstation.core.shard.cml 檔案,而不會造成建構時間檢查錯誤,也不會將這項能力加入許可清單。這表示電池管理員元件可安全從用於在硬體無電池的情況下在硬體上執行工作站工作階段的平台設定排除。

工作階段擁有者想確保選用能力一律不會

可供使用

以上述範例為基礎,假設有一個名為 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 工作階段與提供 voidfuchsia.power.battery.BatteryManager 通訊協定的平台設定 (即不含 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 格式,因此沒有回溯相容性問題。

安全性考量

這項變更可讓元件作者在未獲得安全性團隊核准的情況下,停用未轉送功能的 Scrutiny 錯誤,因為他們將無法再利用許可清單控管未轉送功能的 Scrutiny 錯誤。

由於此提案不會影響建立或變更元件路徑的審核程序,因此系統會將其視為可接受。

隱私權注意事項

提議的變更不會影響收集、處理或儲存使用者資料的方式,因此也沒有任何隱私權疑慮。

測試

目前已有涵蓋元件資訊清單管道的廣泛測試。這些測試會經過修改,納入這項新功能的涵蓋範圍。

說明文件

元件資訊清單說明文件會更新,以說明新欄位及其對驗證的影響。

缺點、替代項目和未知

優先藝術與參考資料

待辦事項