RFC-0110:終止重要元件並重新啟動

RFC-0110:重新啟動以終止重要元件
狀態已接受
領域
  • 元件架構
說明

第 2 版元件的功能,提供與第 1 版重大_components 一致的功能

毛皮變化
作者
審查人員
提交日期 (年-月-日)2021-05-26
審查日期 (年-月-日)2021-07-21

摘要

介紹「終止即重新啟動」的提案套用至元件的選項 資訊清單的子項宣告,可與 sysmgr 的 critical_components 功能。

提振精神

在元件 v1 中,sysmgr 支援 名為 critical_components 的功能 系統服務元件會自行標示為「重大」也就是說 元件因任何原因 (包括正常退出) 終止,Symgr 就會觸發 並重新啟動系統重新啟動是安全重新啟動power_manager 驅動,導致元件拓撲執行 終止服務安全重新啟動,以一致的方式拆解系統 讓元件有機會乾淨地關閉 以及檔案系統進行乾淨地關閉

客戶如果不確定,通常是在元件上設定這個選項 通常系統行為可以在元件故障時繼續進行。 出乎意料的是,傾向為針對其服務 系統作業中的中央角色,例如:

  • netstack
  • wlanstack
  • omaha-client-service
  • system-update-checker

除了 由 critical_components 實作相對簡單。這種設計 說明如何解決該用途不僅異常終止 critical_components 提供超出範圍 (但 。

需求條件

主要要求是提供與 critical_components 相同的功能。 這表示,對於 core 下的元件,或 core 的子領域,選擇是否要觸發安全重新啟動 (如果元件元件) 終止服務。

為何現在發行?

使用動機中提及的元件 critical_components 無法遷移至 Components v2,直到 您需要提供同等功能

設計

我們會在 ChildDecl 中新增 on_terminate 列舉 (相當於 新增至元件資訊清單children 區段,提供 語意相當於 critical_component。選項有以下兩種:none (預設) 或 reboot。含有 on_terminate: reboot 的子項元件 因任何原因 (包括正常出口) 終止,component_manager 透過Admin/Reboot fuchsia.hardware.power.statecontrol.Admin 通訊協定,由 power_manager 觸發安全系統重新啟動。

這樣就需要介於 component_managerpower_manager。不過,它們都位於 ZBI 中,因此沒有什麼明顯的 分層問題無論如何,都沒有足夠的依附元件 因為重新啟動會導致裝置的電源狀態發生變化 就是驅動程式庫責任感

如果呼叫 Admin/Reboot 失敗,component_manager 會改回使用 恐慌,觸發未順利重新啟動。

這是敏感功能;我們不希望任意元件 決定在裝置終止時觸發重新啟動作業。因此,使用時會受到限制 依據 component_manager 安全性政策的許可清單進行檢查 在元件啟動時顯示載入容器此外,我們也可以使用 restricted_features GN 許可清單,產生 啟用這個選項時,建構時間失敗 您無權使用新功能。

實作

on_terminate選項

我們需要將 on_terminate 選項新增至資訊清單child 專區。這需要變更 cmccmc_fidl_validatorcm_rust 將選項移動到下一個位置。由於這是特殊功能 允許在 ComponentDecl 中設為 None (預設為 on_terminate: none)。

我們會將新的 restricted_feature 新增至 cmc,以供 on_terminate 使用。僅限 CML 這個許可清單中的檔案將可在其上設定「on_terminate: reboot」 。首先,這份許可清單含有「core」和「network」 運作範圍

我們也會在component_managerreboot_on_terminate_enabled 布林值 設定,可以對元件管理員的非根執行個體停用此功能 (適用於 例如測試中的巢狀結構執行個體)。

偵測終止時元件重新啟動

必須將邏輯新增至 component_manager,才能偵測裝置重新啟動時 元件就會終止在 Stop動作期間,component_manager 可以檢查 on_terminate 選項。如果已設定此屬性且元件未關閉 component_manager 呼叫 Admin/Reboot。關機是指 元件停止,且永遠不會再次啟動,此時 下列情況:

  1. 系統關閉期間,裝置本身是由 Admin/Reboot 通訊協定。在此情況下,系統已經關閉了 因此不會再次觸發關機程序。
  2. 當元件遭到刪除時。這可能是 (a) 呼叫 DestroyChild (b) transient 的父項 停止收集作業,或 (c) single-run 集合中的元件 。在 (a) 和 (b) 的情況下,沒有觸發重新啟動的狀況似乎是 是對元件外部的動作,而非 導致該元件終止的元件有這種情況 (c),我們仍可確保退出元件時觸發重新啟動程序, 透過觸發刪除程序謹慎實作功能 直到元件終止為止

呼叫 fuchsia.hardware.power.statecontrol.Admin 通訊協定

為了觸發安全重新啟動,裝置會連線至通訊協定 fuchsia.hardware.power.statecontrol.Admin 和呼叫 Admin/Reboot。這個通訊協定是由 power_manager 元件實作。 (由於歷史因素,實際上是由 shutdown_shim 代理伺服器)。自此 通訊協定是由元件實作,component_manager 如何取得存取權 該怎麼辦?為此,我們可以透過 root 公開通訊協定從 將 #bootstrap 套用至其父項。也就是說,根層級會向 高於根節點的節點,也就是 component_manager。請參閱設計中的 詳細說明

原型

您可以前往這裡查看原型。

成效

這項設計沒有效能方面的考量。「component_manager」只會 連線至 fuchsia.hardware.power.statecontrol.Admin on_terminate: reboot 元件實際上會終止。

人體工學

這項設計具備簡單的人因工程,只要準備 元件上重新啟動時,執行以下作業:

  • 在父項的 ChildDecl (children) 中設定 on_terminate: reboot 宣告)。
  • 如果尚未提供,請將父項的 CML 新增至 cmcon_terminate: reboot」的restricted_features許可清單。
  • 將元件的路徑名稱新增至政策許可清單,以便在裝置重新啟動時啟動。

on_terminate 選項是由父項設定,而非元件 可運用在實際工作環境中,應觸發重新啟動的元件 進行測試,而不必修改 CML此外,這麼做也能 然後在您希望 選項,而無須變更元件。

回溯相容性

這項變更並不會破壞相容性。客戶必須明確選擇加入 。

安全性考量

假設使用者將元件標示為 意外重新啟動,這異常觸發重新啟動。 然而,用途受到安全性政策許可清單限制,因此新用途 必須經過明確核准。請注意,如果攻擊者無法信任 元件,誘騙 component_manager 授予其重新啟動權限, 嵌入已加入許可清單的元件,因為元件已加入許可清單 路徑名稱 (頂層路徑),而非網址。

隱私權注意事項

本提案沒有針對新的隱私權注意事項。

測試

藉由模擬 fuchsia.hardware.power.statecontrol.Admin 通訊協定。我們要記得 例如通訊協定遺失或失敗

在理想情況下,您應針對重新啟動的元件新增 E2E 測試涵蓋範圍。 ,確認是否觸發了安全重新啟動。

說明文件

請務必修改以下說明文件:

  • 新增文件來讓 on_terminate 選項平行處理 critical components
  • 更新遷移指南以說明遷移方式 critical_component

缺點、替代方案和未知

優點和缺點

福利

  • 設定方式相當簡單。
  • 與 v1 直接一致,方便您進行遷移。
  • 這項功能完全位於 component_manager 中,因此 較易於實作,且較不容易出現故障模式的風險 例如遺失事件
  • 我們可以將 main_process_critical 的部分用途替換成 on_terminate: reboot,這是非常優的。
  • 可讓用戶端控管已在下列位置設定 on_terminate: reboot 的元件 不需修改就能正式環境

缺點

  • 並非以能力為基礎,而是與 Orthodox 架構模型不同。
  • 直接在 component_manager 中編碼部分當機復原政策。雖然 我們不建議這麼做 政策簡單,因此費用雖然不是零,但成本看似小。
  • 透過 component_managerpower_manager 導入反轉的依附元件。 不過,它們都存在於 ZBI 中,因此不會構成重大分層違規。
  • 由於 CML 結構定義變更涉及 CML 結構定義,因此必須搭配採用這個選項 透過多個位置追蹤:cmccm_fidl_validatorcm_rust和用戶端 cm_rust,雖然這是分眾功能。

替代文案:在 program 上的 system_critical 位元

除了將選項新增至 ChildDecl 以外,我們可以直接將該選項新增到 元件資訊清單program 部分。主要差異 這種做法是在元件本身設定選項, 而非父項的子項宣告

將位元放入 program 的好處是保留特殊功能 (共 ComponentDecl 項)。從 programComponentDecl 開始 具有任意形式語法,我們不需要變更 cmc、驗證工具 或 Rust 繫結來處理新選項。我們只需要在 component_manager 本身,會從 program 擷取選項 元件停止 (判斷是否需要重新啟動)。

不過,這個方法有個顯著的缺點:如果 system_critical 元件,必須修改其 CML,才能移除 system_critical 位元 (因為測試中不得設定位元) 且我們不希望測試觸發系統重新啟動)。這樣一來, 針對運用 元件。

替代做法:使用 main_process_critical

ELF 執行元件支援名為 main_process_critical,亦即 元件結束時,當元件使用 非零狀態或遭終止。這會造成 。重新啟動是無害的,進而導致系統關閉 也沒有機會讓系統持續診斷 指標。

main_process_critical」只能在觸發優雅的地方使用 無法重新啟動。舉例來說,power_manager 本身已標示 main_process_critical。因為任何重要元件都沒有這種情況 這個選項不會被視為可行的替代做法,但列於下方 完整度。

替代文案:主管

我們不必在 component_manager 中管理當機復原功能,而是在以下位置管理這項功能: core 領域。這個替代做法包含兩個部分。第一,介紹 "component-scoped"可讓消費者監控事件 ( 例如 StartedStopped 事件),而且範圍僅限於單一元件 執行個體。接著,介紹一個稱為「超級程序」的元件,該元件會使用 以便監控是否異常終止或失敗,然後重新啟動 回應系統

元件範圍內的事件

元件架構團隊參與討論的想法,就是提供 可將事件功能範圍限定為單一元件執行個體 而不是整個領域這項設計提供了具體的應用程式 這個想法監督者只需要監控特定元件,因此 因此需要接收這些元件的事件 整個領域

為了加快處理速度,我們提議採用最小幅度的 CML 變更 以啟用此功能。日後 以不同方式指定事件範圍的大量語法修訂版本 請參閱元件事件 RFC。我們將加入 scope 欄位新增至 offer event 宣告中,可指定 #childrealm (預設)。

// core.cml
offer: [
    {
        event: "started",
        from: "framework",
        scope: "#wlanstack",
        to: "#supervisor",
        as: "started-wlanstack",
    },
    {
        event: "stopped",
        from: "framework",
        scope: "#wlanstack",
        to: "#supervisor",
        as: "stopped-wlanstack",
    },
],

由於日後語法可能會修訂,因此我們可以設定 cmcscope 功能加入 core.cml 和整合測試的許可清單。

元件範圍內的事件不含 元件,例如路徑名稱或網址一般來說,事件 在酬載中移轉機密資訊,例如元件單眼 網址,這些是為了在有知情必要的情況下而公開。由於 不需要這項資訊 元件範圍內的事件都不會提供 產生事件的元件身分其餘 酬載中的資訊是時間戳記和終止狀態, 則不具敏感性

主管

監督器本身很簡單。這是 core 下的元件,可執行 包括:

這是 critical_components 功能的簡易實作目標。於 未來,主管可能會進化以支援更多用途 多個主管 -- 請參閱未來的工作

將事件轉送至主管

元件範圍內的事件必須從每個重要元件轉送至 。對於 core 子項的重要元件,這會要求 兩項變更:

  • 修改 Core.cml,以從 新增元件 (請參閱 元件範圍事件)
  • 修改主管的 CML,以在靜態資料中使用事件 事件串流。

如果重要元件以巢狀結構嵌入 core 的子領域底下,則另一個步驟是 必填:

  • 修改每個中繼元件,以向子項公開事件 設定。

舉例來說,網路堆疊的 本來可能是 netstack的溫度為「core」的「network」子領域。

主管 CML 的範例如下:

// supervisor.cml
use: [
    {
        events: [
            "netstack-started",
            "netstack-stopped",
            "wlan-started",
            "wlan-stopped",
        ],
    },
    // The supervisor will trigger reboot under the following conditions:
    // - It receives a `started` event with an error.
    // - It receives a `stopped` event with a non-ok status.
    {
        event_stream: "EventStream",
        subscriptions: [
            {
                event: [
                    "netstack-started",
                    "netstack-stopped",
                    "wlan-started",
                    "wlan-stopped",
                ],
                on_receive: "start",
            },
        ],
    },
],
...

請注意,您不需要修改正在觀看的元件。這是 蓄意:監督領域是指領域管理 而非元件本身也就是說, 元件必須負責決定監督方式或規範方式

正在啟動監管程序

我們需要確保主管一律及時啟動,才能接收事件。 為此,我們建議在 event_stream 訂閱方案中新增一個選項 名為 on_receive: "start"on_receive: "start" 造成component_manager 讓元件在收到該事件時自動啟動如此一來 component_manager 可確保活動絕不會遺失。預設選項是 "dispatch_if_started",只會在元件執行時,將事件分派給元件 正在執行 (預設行為)。

這需要變更事件調度系統。具體來說 分派事件,component_manager 必須追蹤所有已轉送的事件 功能。否則, 即使元件標示為 on_receive: "start",元件仍可能錯過事件 因為這類問題尚未解決

可能有引數將 on_receive: "start" 設為預設行為 但超出本提案的範圍

優點和缺點

福利

  • 避免在 component_manager 中使用編碼當機復原政策。即將宣傳 可以將問題區隔開來 因為一般來說,我們沒有 充分瞭解當機復原政策 能一般大眾化,使我們能在 component_manager
  • 這個方法比 recovery 選項更有適應。使用 basemgr 和 必須執行當機復原政策 代理程式和工作階段本身並不相同。

缺點

  • 需要建構的事件系統支援。這麼做可將 變得複雜,進而可能需要更多時間和精力 而不是直接在 component_manager 中導入解決方案。
  • 需要比 recovery 多的樣板。每個重要事件 元件都必須從每個重要元件轉送至主管。
  • 我們最終需要解決 basemgr/sessionmgr 中的類似問題。 如果我們在這之前延遲設計出更通用的解決方案 讓各位更瞭解問題空間

日後的工作

basemgrsessionmgr 會實作自己的當機復原策略, 生成式 AI 可以在 supervisor 的替代方法。

fshostarchivist目前使用 main_process_critical。有可能 改用「在重新啟動後終止」這樣我們就能限制 針對與重新啟動程序相關的元件main_process_critical (driver_managerpower_manager)。

部分路徑仍會觸發不安全重新啟動:

  • 這項設計會在以下項目中建立反轉的 component_manager 依附元件: power_manager和間接 driver_manager。因此 元件無法在重新啟動時終止,因此會標示為 main_process_critical,這表示 元件會導致未安全重新啟動。
  • 如果 Reboot 呼叫本身失敗,component_manager 也會造成恐慌 觸發未順利重新啟動。

我們或許可以在映像檔 情況;舉例來說,component_manager 可執行 關機後再結束另一方面,自 power_managerdriver_manager 對系統運作而言非常重要,我們可能不會希望 如果系統當機的話,該系統可持續運作任何時間長度。

我們可能可以回想一下電源管理的責任 分散式;舉例來說,或許 component_manager 能 並自行重新啟動 (仍需要透過 driver_manager 才能進行設定) 電源狀態)。

系統完全遷移至 Components v2 後 元件管理員,透過使用 對依附元件圖表的瞭解

既有藝術品和參考資料

critical_components 功能的私人設計文件和 事件 API 修訂版本