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_manager
和
power_manager
。不過,它們都位於 ZBI 中,因此沒有什麼明顯的
分層問題無論如何,都沒有足夠的依附元件
因為重新啟動會導致裝置的電源狀態發生變化
就是驅動程式庫責任感
如果呼叫 Admin/Reboot
失敗,component_manager
會改回使用
恐慌,觸發未順利重新啟動。
這是敏感功能;我們不希望任意元件
決定在裝置終止時觸發重新啟動作業。因此,使用時會受到限制
依據 component_manager
安全性政策的許可清單進行檢查
在元件啟動時顯示載入容器此外,我們也可以使用
restricted_features
GN 許可清單,產生
啟用這個選項時,建構時間失敗
您無權使用新功能。
實作
on_terminate
選項
我們需要將 on_terminate
選項新增至資訊清單的
child
專區。這需要變更 cmc
、cmc_fidl_validator
和
cm_rust
將選項移動到下一個位置。由於這是特殊功能
允許在 ComponentDecl
中設為 None
(預設為
on_terminate: none
)。
我們會將新的 restricted_feature
新增至 cmc
,以供 on_terminate
使用。僅限 CML
這個許可清單中的檔案將可在其上設定「on_terminate: reboot
」
。首先,這份許可清單含有「core
」和「network
」
運作範圍
我們也會在component_manager
的 reboot_on_terminate_enabled
布林值
設定,可以對元件管理員的非根執行個體停用此功能 (適用於
例如測試中的巢狀結構執行個體)。
偵測終止時元件重新啟動
必須將邏輯新增至 component_manager
,才能偵測裝置重新啟動時
元件就會終止在 Stop
動作期間,component_manager
可以檢查
on_terminate
選項。如果已設定此屬性且元件未關閉
component_manager
呼叫 Admin/Reboot
。關機是指
元件停止,且永遠不會再次啟動,此時
下列情況:
- 在系統關閉期間,裝置本身是由
Admin/Reboot
通訊協定。在此情況下,系統已經關閉了 因此不會再次觸發關機程序。 - 當元件遭到刪除時。這可能是 (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 新增至
cmc
「on_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_manager
在power_manager
導入反轉的依附元件。 不過,它們都存在於 ZBI 中,因此不會構成重大分層違規。 - 由於 CML 結構定義變更涉及 CML 結構定義,因此必須搭配採用這個選項
透過多個位置追蹤:
cmc
、cm_fidl_validator
、cm_rust
和用戶端cm_rust
,雖然這是分眾功能。
替代文案:在 program
上的 system_critical
位元
除了將選項新增至 ChildDecl
以外,我們可以直接將該選項新增到
元件資訊清單的 program
部分。主要差異
這種做法是在元件本身設定選項,
而非父項的子項宣告
將位元放入 program
的好處是保留特殊功能
(共 ComponentDecl
項)。從 program
的 ComponentDecl
開始
具有任意形式語法,我們不需要變更 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"可讓消費者監控事件 (
例如 Started
和 Stopped
事件),而且範圍僅限於單一元件
執行個體。接著,介紹一個稱為「超級程序」的元件,該元件會使用
以便監控是否異常終止或失敗,然後重新啟動
回應系統
元件範圍內的事件
元件架構團隊參與討論的想法,就是提供 可將事件功能範圍限定為單一元件執行個體 而不是整個領域這項設計提供了具體的應用程式 這個想法監督者只需要監控特定元件,因此 因此需要接收這些元件的事件 整個領域
為了加快處理速度,我們提議採用最小幅度的 CML 變更
以啟用此功能。日後
以不同方式指定事件範圍的大量語法修訂版本
請參閱元件事件 RFC。我們將加入 scope
欄位新增至 offer event
宣告中,可指定 #child
或 realm
(預設)。
// 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",
},
],
由於日後語法可能會修訂,因此我們可以設定 cmc
將 scope
功能加入 core.cml
和整合測試的許可清單。
元件範圍內的事件不含 元件,例如路徑名稱或網址一般來說,事件 在酬載中移轉機密資訊,例如元件單眼 網址,這些是為了在有知情必要的情況下而公開。由於 不需要這項資訊 元件範圍內的事件都不會提供 產生事件的元件身分其餘 酬載中的資訊是時間戳記和終止狀態, 則不具敏感性
主管
監督器本身很簡單。這是 core
下的元件,可執行
包括:
- 使用包含
Started
和Stopped
事件清單的靜態event_stream
。 - 如果針對這個 event_stream 接收到
Started
事件, 錯誤或含有酬載的Stopped
事件; 呼叫 fuchsia.hardware.power.statecontrol/Admin.Reboot.
這是 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
中的類似問題。 如果我們在這之前延遲設計出更通用的解決方案 讓各位更瞭解問題空間
日後的工作
basemgr
和 sessionmgr
會實作自己的當機復原策略,
生成式 AI 可以在
supervisor 的替代方法。
fshost
和archivist
目前使用 main_process_critical
。有可能
改用「在重新啟動後終止」這樣我們就能限制
針對與重新啟動程序相關的元件main_process_critical
(driver_manager
和 power_manager
)。
部分路徑仍會觸發不安全重新啟動:
- 這項設計會在以下項目中建立反轉的
component_manager
依附元件:power_manager
和間接driver_manager
。因此 元件無法在重新啟動時終止,因此會標示為main_process_critical
,這表示 元件會導致未安全重新啟動。 - 如果
Reboot
呼叫本身失敗,component_manager
也會造成恐慌 觸發未順利重新啟動。
我們或許可以在映像檔
情況;舉例來說,component_manager 可執行
關機後再結束另一方面,自 power_manager
和
driver_manager
對系統運作而言非常重要,我們可能不會希望
如果系統當機的話,該系統可持續運作任何時間長度。
我們可能可以回想一下電源管理的責任
分散式;舉例來說,或許 component_manager
能
並自行重新啟動 (仍需要透過 driver_manager
才能進行設定)
電源狀態)。
系統完全遷移至 Components v2 後 元件管理員,透過使用 對依附元件圖表的瞭解
既有藝術品和參考資料
有 critical_components
功能的私人設計文件和
事件 API 修訂版本