RFC-0107:動態優惠 | |
---|---|
狀態 | 已接受 |
區域 |
|
說明 | 允許在 CFv2 的執行階段建立商品。 |
Gerrit 變更 | |
作者 | |
審查人員 | |
提交日期 (年-月-日) | 2021-05-24 |
審查日期 (年-月-日) | 2021-06-24 |
摘要
在元件架構 2 (CFv2) 中,父項元件可使用集合,在執行階段將動態子項元件新增至拓樸。不過,無法在執行階段為這類動態子項元件設定提供的功能組合。優惠會在父項元件的資訊清單中宣告,父項元件開始執行時,該資訊清單就無法再變更。
父項元件的資訊清單會將指定集合中的所有動態子項一視同處理;甚至無法討論集合中的個別元件。這表示有以下限制:
- 無法為個別動態子項提供能力。為集合提供能力,可為該集合中的所有動態子項提供能力。
- 您無法將個別動態子項的能力提供給其他元件。透過集合提供能力會建立匯總 FIDL 服務,可連線至該集合中的任何動態子項。
本文件提出了動態優惠,可在執行階段加入至元件拓樸。
相關人員
- 在執行階段建構動態拓樸的 CFv2 使用者。這些內容將由 Driver Framework 團隊代表。
- 元件架構專責人員:可驗證設計是否合理,且不會與任何未來計畫衝突。
- 安全性:確保這項功能不會破壞系統的安全性屬性。
提振精神
大多數的 CFv2 用途都涉及元件組成的靜態拓樸,這些元件會共同完成某項工作。所有元件之間的 ID 和關係都會事先知悉,並可硬式編碼至元件資訊清單。
在其他用途中,開發人員不知道要執行的元件確切組合,但知道這些動態元件之間的關係。開發人員可以將所有動態元件分組成集合,在特定集合中,每個元件都會提供相同的功能組合。
不過,部分 CFv2 使用者希望在執行階段建立複雜的拓樸圖,為每個動態子項提供一組獨特的功能,並在動態子項之間路由功能。
用途:Drivers-as-Components
在驅動程式架構的「驅動程式做為元件」專案中,動態例項化的驅動程式庫元件會依附於其他動態例項化的驅動程式庫元件提供的功能。我們將從一個驅動程式庫元件提供給另一個的功能稱為「驅動程式庫功能」。
CFv2 不支援原生驅動程式庫間功能。驅動程式架構團隊已在 driver_manager
中實作類似能力導向功能,以解決這個問題。這個解決方法有點粗糙,而且會顯示驅動程式庫間功能與「一般」功能之間的差異,這點令人困惑:
- 元件會在其傳入命名空間中開啟路徑,連結至「一般」功能,但會透過特定驅動程式架構的
exposed_dir
欄位,連結至驅動程式庫間的功能。 - 接收元件收到
exposed_dir
後,即可存取其依附元件實作的「所有」通訊協定。driver_manager
不會讓接收端只存取所需的通訊協定。Driver Framework 團隊可以修正這個問題,但這樣做會進一步複製元件架構機制。 - 驅動程式元件需要在其資訊清單的
use
部分宣告所依賴的「一般」功能,但不應以相同方式列出驅動程式庫間的功能。如果是這樣,元件管理服務就無法找到可滿足use
的offer
。- 目前,元件管理服務大多會忽略這些多餘的
use
,但這可能會在短期內造成混淆,而多餘的use
可能會在長期內變成錯誤。
- 目前,元件管理服務大多會忽略這些多餘的
驅動程式作者不應將「一般」功能視為與驅動程式庫程式之間的功能不同,因此應盡快移除這項區別。等待時間越長,模型變更時就必須遷移的驅動程式就越多。
設計
這項提案會擴充 fuchsia.sys2.Realm/CreateChild
API,以便接受 OfferDecl
清單,說明除了通常提供的功能之外,還會向新建立的子項提供其他功能。我們會將以這種方式指定的 OfferDecl
稱為「動態優惠」。以一般方式指定的 OfferDecl
(也就是在元件資訊清單中列出的) 會稱為「靜態優惠」。
任何類型的商品 (例如通訊協定、目錄等) 都可以做為動態商品使用。
動態優惠一律會指定新建立的子項元件。因此,指定元件的動態優惠集合會在元件建立時顯示,之後就無法變更。(API 審查會決定是否必須實際指定 OfferDecl
的 target
欄位)。
任何適用於靜態商品的來源,也適用於動態商品。此外,與靜態優惠不同,動態優惠可以使用「同胞」動態子項元件 (也就是與目標具有相同父項的元件) 做為來源。如果動態優惠含有以動態子項做為來源的來源,則目標不必與來源位於相同的集合中。
建立子元件後,動態優惠的運作方式應與靜態優惠完全相同,包括元件關閉順序等考量。
破壞
動態優惠的來源或目標遭到刪除時,就會遭到刪除。優惠遭到銷毀後,系統的運作方式將與從未存在的情況完全相同。
動態優惠的使用者應盡可能在來源之前銷毀目標。如果是遭到銷毀的目標,從拓樸圖中移除商品的程序就會變得簡單 (如果商品位於森林中,且沒有任何元件可聽到該商品...)。不過,有時無法避免,來源會在目標之前遭到銷毀。值得注意的是,使用單執行集合 (在 RFC-0101 中引進) 時,動態元件會在終止後立即遭到銷毀,而這可能隨時發生。
即使是來源遭到刪除,程序也十分簡單:
- 元件管理員會關閉來源元件。這可防止目標開啟任何與來源的新連線,並指示執行元件停止來源元件 (如果正在執行)。
- 來源元件停止時,來源和目標之間的任何管道都會關閉。
- 來源元件和動態優惠會同時從拓樸圖中移除。
從目標的角度來看,對應於該能力的管道會關閉,且任何嘗試重新取得該能力動作都會永久失敗,就好像該能力從未經過路由一樣。
本 RFC 並未提供重新建立這類產品的機制。
避免相依性循環
CFv2 要求元件和元件之間的強力優惠形成有向無環圖,以便元件可依依附順序順利關閉。針對靜態商品,我們可以查看元件資訊清單,確保沒有依附元件週期。
針對動態商品,只要遵循下列規則,即可確保無環依附元件圖表:
- 動態元件建立順序是嚴格的總順序。換句話說,不會有兩個動態元件同時新增至拓樸圖。
- 動態優惠一律會與目標元件同時建立。
- 所有優惠 (包括靜態和動態) 皆無法變更。
- 所有商品 (包括靜態和動態) 都必須具備有效的來源和目標。
CreateChild
會在建立動態優惠時檢查這個屬性,且只要來源或目標遭到銷毀,優惠也會一併銷毀。
綜合來說,這表示動態優惠的來源一律會比目標舊。如果來源較新,表示在建立目標時不存在,因此商品在建立時就會含有無效來源。由於「建立順序」是嚴格的總順序,因此不會出現依附元件循環。
處理無效路由
截至本文撰寫時,元件管理服務不會主動拒絕含有無效轉送設定的元件資訊清單。也就是說,如果某項能力是由不公開該功能的來源提供,或是元件未收到所用能力的供應項目,則在元件建立時不會發生錯誤。只有在元件嘗試開啟無效路由能力時,才會發生錯誤。
秉持「動態商品應與靜態商品的行為相同」的精神,我們會在此實作相同的行為。元件可能會為來源未公開的能力建立動態優惠。同樣地,父項元件可以建立動態子項元件,而不需要為所使用的每項能力提供商品。
日後,如果元件管理服務在這些情況下變更為提早傳回錯誤,我們也會變更 CreateChild
的合約,以便傳回錯誤。
實作
這項異動對使用者而言,主要影響如下:
- 對
CreateChild
API 進行回溯相容性變更,以便接受動態商品清單做為引數。 - 每個產品組合都有一個選擇加入設定,可讓動態優惠指定該產品組合中的元件。(請參閱「安全性考量」一節的討論內容)。
- 可選擇加入的父項元件許可清單。(注意:請參閱「更新:移除許可清單」)
(1) 的實作內容將完全在元件管理服務中執行。實作 (2) 和 (3) 可能需要變更剖析 CML 檔案的工具。無論是哪種情況,都不需要跨團隊協調。
成效
這項變更不會影響系統效能,除非呼叫 CreateChild
和 DestroyChild
,但這類操作很少發生,且對效能而言並非必要。即使是這些作業,也不會對效能造成不利影響。
人體工學
提供銷毀行為是新的行為,可能會對元件作者造成人體工學問題,因為元件的依附元件會突然消失。
從目標元件的角度來看,判斷優惠遭到銷毀後發生的情況並不完全明確:它只會看到管道關閉。目標元件無法立即判斷來源元件是否已遭到銷毀、停止或關閉管道。為判斷來源是否確實已遭到銷毀,目標必須嘗試重新連線,並等待元件管理服務的回應,指出無法永久重新導向。
安全性考量
這項設計本身會破壞 CFv2 的一項重要安全目標:應宣告所有能力路徑 (或潛在能力路徑),以便進行稽核。在測試以外使用動態優惠時,請務必確保潛在的能力路徑可透過元件資訊清單以外的其他機制進行稽核。
使用這項功能時,Driver Framework 會負責確保可稽核的潛在能力路徑空間。目前,這些規則會在多個位置進行編碼:去中心化繫結規則、主機板驅動程式的原始碼、ACPI 和其他可能的項目。這會使稽核作業變得困難。這個差距並非新問題,需要由 Driver Framework 解決,但如何解決則超出本 RFC 的範圍。
系統會在 CollectionDecl
中新增選擇加入設定,當該設定存在時,父項元件就能將動態優惠傳遞至該集合中建立的元件。這樣一來,CML 審查員就能清楚瞭解動態優惠正在使用中,且需要參照元件資訊清單以外的來源,才能瞭解潛在能力路徑的範圍。
此外,元件架構團隊會將選擇加入功能加入許可清單,以確保所有使用方式都適當。(注意:請參閱「更新:移除許可清單」)
日後的作業
如果我們發現動態商品的用途更多,可能會在元件資訊清單架構中引入商品上限。您可以使用商品上限來限制在執行階段可建立的動態商品類型。
資訊清單會包含以下陳述式:
- 「Protocol
fuchsia.example.Foo
可從元件A
動態提供至集合B
中的任何元件」或 - 「任何目錄能力都可以在集合
C
的任兩個元件之間動態提供」。
對於初始的 Driver Framework 用途,我們認為粗略的收集層級選擇加入功能就足夠了。在允許列入任何其他用戶端之前,請務必重新評估這項立場。
隱私權注意事項
這項提案不會將系統的任何部分公開給未經授權存取的資料,因此不會對隱私權造成影響。
測試
系統會新增單元和整合測試涵蓋率,類似於任何其他元件架構功能。驅動程式架構的整合測試會間接提供額外的涵蓋率。
這項功能不應影響元件架構 API 的可測試性,也不能改善可測試性。使用集合和 Realm
通訊協定時,就必須在整合測試設定中使用實際的元件管理服務例項,這一點將持續適用。
說明文件
由於動態優惠會列入許可清單,且一開始只供單一用戶端使用,因此高階元件架構概念說明文件不應更新,以便提及這項功能的存在。您只需提供 CreateChild
、DestroyChild
和 CollectionDecl
的變更說明即可。
在允許其他用戶端之前,必須重新評估這項立場。
缺點、替代方案和未知事項
這項設計的主要缺點是,它會讓稽核能力路徑變得更複雜,因為並非所有可能的能力路徑都會顯示在元件資訊清單中。不過,這正是驅動程式架構的本質:驅動程式庫元件的拓樸結構本質上是動態的,因為裝置可隨時在機器上新增及移除。靜態優惠顯然不夠,因此故事必須變得更複雜。動態商品會盡可能模擬靜態商品的行為,以盡量減少這項額外複雜的情況。
替代做法:能力權杖
我們先前曾提出能力權杖,用於解決相關問題。該提案可視為此 RFC 的泛用版本,其中動態商品可跨領域。來源元件的父項會「鑄造」能力權杖,並將其傳遞至其他父項元件 (可能會透過中繼元件鏈結)。接收元件可以將此權杖傳遞至 CreateChild
,後者會做為授權機制,證明雙親都同意優惠。
建立後,這項動態優惠的運作方式應與靜態優惠相同,但主要差異在於這些動態優惠可跨運作範圍。靜態商品 (以及主要提案中的動態商品) 一律會在單一父項元件中執行。
跨領域優惠的影響尚未完全明確,我們認為這並非必要,因此已拒絕這項選項。
替代做法:提供「即時能力供應商」
在主要提案中,動態商品是靜態資料。提供項目代表元件管理服務應如何將能力要求導向,但不會自行提供能力存取權。
我們可以改為傳遞功能提供者,也就是可用來直接取得功能的管道。CreateChild
接著會接受命名能力提供者的向量。當動態子元件嘗試開啟動態提供的能力時,該 Open
要求會轉送至能力提供者。
父項元件可以透過以下方式取得這類能力提供者:
- 自行實作能力供應器。
- 呼叫
Realm
API,為其父項或子項公開的功能取得能力提供者,或 - 透過管道接收其他元件提供的能力。
這會開啟與能力符記相同的用途,但有額外的好處 (或可說是缺點),即家長可以直接為孩子提供能力供應器:只要在記憶體中啟動伺服器,並將能力供應器傳遞至 CreateChild
。
不過,能力提供者與 CFv2 路由架構的許多重要屬性不相容,例如能力路徑的可稽核性、重新啟動之間的持續性等。
替代方案:破壞
當動態元件 (即優惠來源) 遭到刪除時,除了刪除優惠之外,還有許多合理的行為。本節將討論這些替代方案。
禁止來源破壞
這份 RFC 的早期草稿建議,如果元件是動態優惠的來源,就禁止銷毀該元件。在這些商品的目標遭到銷毀之前,元件會以這種方式「固定」。
從一開始,這項做法就似乎不夠穩定,且可能會出現人體工學問題 (也就是「無法銷毀元件」錯誤可能很難處理)。不過,隨著 RFC-0101 的接受,這項做法已無法運作,因為該 RFC 引入了自動銷毀元件的情況。
刪除項目的傳播
另一個提案則是讓銷毀作業沿著商品傳播。也就是說,如果動態商品的來源遭到刪除,目標也會遭到刪除,以此類推,以遞迴方式進行。
這個選項似乎很可怕,而且與其他 CFv2 行為不一致。在許多情況下,功能無法路由或無法使用,但在這些情況下,即使依附元件的依附程度很高,也不會強制終止或刪除這些元件。元件可以觀察其依附元件無法使用的事實,並在需要時退出。
更新:移除許可清單
這項功能已證實可在動態元件中成功強制執行最低權限。
在將 web_instance
元件遷移至新式元件架構後,這項功能可能會在 Chromium 程式碼庫中發揮效用。目前,這個元件會使用舊版元件架構的功能啟動動態子項。這些子項的功能集可在執行階段變更,如果啟用特定功能,子項會在舊版元件建立期間透過 additional_services
欄位提供額外的通訊協定功能。動態商品可讓 web_instance
在執行階段決定哪些動態子項會接收額外功能,為這項行為提供明確且簡單的遷移路徑,以便將這項行為遷移至現代元件架構。
因此,我們將移除許可清單,讓用戶端不必取得元件架構團隊的核准,即可使用這項功能。
為了移除許可清單,系統會進行下列變更:
- 編寫說明文件,說明如何使用動態優惠。
- 從 CMC 中移除
dynamic_offers
受限功能金鑰。 - 刪除
//tools/cmc/build/restricted_features
中的dynamic_offers
許可清單。