RFC-0241:SDK 介面中的明確平台 / 外部分割

RFC-0241:SDK 介面中的明確平台 / 外部分割
狀態已接受
領域
  • FIDL
說明

更精確地說明 Fuchsia 介面的哪些部分可以在 Fuchsia 平台外實作。

問題
更小鳥
作者
審查人員
提交日期 (年月分)2024-01-29
審查日期 (年-月-日)2024-04-09

摘要

Fuchsia IDK 不會指定外部元件應針對其定義的各種 FIDL 通訊協定實作用戶端或伺服器。這會導致難以正確評估 Fuchsia API 變更對回溯相容性的影響。這個 RFC 可讓您以人類和機器可讀的方式,在 FIDL 中表達這些資訊。這有助於改善 Fuchsia 型產品的正確性和穩定性。

提振精神

許多 Fuchsia 系統介面FIDL 表示,以一組通訊協定和透過這些通訊協定交換的類型表示。通訊協定與用戶端和伺服器端是不對稱,但做為 SDK/IDK 的一部分提供的 FIDL 宣告無法指定 Fuchsia Platform 向產品所提供外部元件提供的介面是針對伺服器端、用戶端還是雙方通訊協定。

這種缺乏精準度會嚴重限制可在 Fuchsia 系統介面 (通常為外部元件) 的情況下,安全地在 Fuchsia 系統介面進行的變更類型,實際上,大部分的通訊協定只會有伺服器或只在 Fuchsia 平台中實作的用戶端,但這項資訊不會以工具檢查或由開發人員發現的方式呈現。

舉例來說,如果系統介面的一部分包含 string:100 (以 UTF-8 編碼時最多佔用 100 個位元組的字串),之後我們發現需要支援較長的字串。如果這種類型只會從外部元件傳送到平台元件 (透過通訊協定方法要求),則長度限制可以安全提高,因為對包含該字串的訊息解碼的元件將永遠至少與元件編碼一樣新。如果該類型可從平台元件傳送至外部元件,就無法安全地增加長度,因為在平台中以較新 API 級別建構的元件可能會意外將格式錯誤的訊息傳送至外部元件。

相關人員

誰有權規範這份 RFC?

講師:

FEC 委任的人員透過 RFC 程序來破壞這個 RFC。

審查者:

  • abarth@google.com
  • chaselatta@google.com
  • hjfreyer@google.com

諮詢時間:

  • aaronwood@google.com
  • awolter@google.com
  • crjohns@google.com
  • mkember@google.com
  • pesk@google.com
  • surajmalhotra@google.com
  • wittrock@google.com

社會化:

利用單頁簡介,向參與平台版本管理的人員說明問題和提案。

相關規定

本文件中的關鍵字「必須」、「不得」、「必要」、「應」、「不應」、「應該」、「不應該」、「建議」、「可能」和「選用」等關鍵字均以 IETF RFC 2119 中所述的方式解釋。

我們必須能夠明確指出哪些系統介面通訊協定「可能」具有用戶端或伺服器,或是同時在平台或外部元件中實作。這項資訊「必須」可存取用於評估平台變更相容性的工具,以便使用者取得。

這項資訊應提供給在軟體組合時執行的工具,且可在執行階段提供給元件架構使用。開發人員應透過產生的 API 說明文件和建構時間檢查,向開發人員顯示這項資訊。

為協助評估 Fuuchsia 平台和其根據它建構的元件之間的相容性,外部元件「必須」根據平台支援的穩定 API 級別建構。

設計

數據分析

平台 ABI 介面的整體相容性可細分為評估個別類型是否與外部元件和平台元件交換的個別類型相容性,包括透過管道的通訊協定和序列化,以及在頻外交換。

元件之間所有 FIDL 資料交換都會以下列其中一種形式運作:

  • 透過元件架構通訊協定功能交換的 FIDL 通訊協定。這些項目都標有 @discoverable 屬性。
  • 透過非 FIDL 交換的 FIDL 通訊協定,例如程序引數
  • 序列化且在檔案中交換的 FIDL 類型 (例如元件資訊清單) 或自訂處理序間通訊 (IPC) 傳輸。

以檢視我們所能檢視的整個 Fuchsia 系統介面 FIDL 為例,收集可能從用戶端傳送至伺服器,以及從伺服器傳送至用戶端的類型組合。

通訊協定

如果我們知道每個「根」通訊協定是否可在外部元件或平台元件中實作其用戶端和伺服器,我們可以收集從外部元件到平台元件的類型組合,包括平台元件到外部元件、平台元件之間及外部元件之間。

通訊協定:

@discoverable
protocol {
    M(Req) -> (Resp);
}

在允許用戶端和伺服器實作的情況下,可以查看要求中的類型 (Req) 與回應 (Resp) 在外部元件 (E) 和平台元件 (P) 之間可能流動的位置:

用戶端 伺服器 E 到 P P 至 E P 至 P E 到 E
E E 需求、Resp
E P 要求 Resp
E P、E 要求 Resp 需求、Resp
P E Resp 要求
P P、E Resp 要求 需求、Resp
P、E E Resp 要求 需求、Resp
P、E P 要求 Resp 需求、Resp
P、E P、E 需求、Resp 需求、Resp 需求、Resp 需求、Resp

平台程式碼保證會朗讀外部程式碼所說的通訊協定版本的超集,因此即可說明以下有關類型限制是否可強化或鬆鬆:

寄件者 接收器 限制
外部 平台 無法強化
平台 外部 無法放鬆
外部 外部 無法變更

因此,我們必須限制用戶端和伺服器的實作位置。

幾乎所有根層級通訊協定都會透過元件架構功能交換。這些都不是低階且容易引起的,其中包括 fuchsia.io.Directoryfuchsia.posix.socket 中的一些網路通訊端控制管道通訊協定。我們應該擴充 @discoverable 的意義來整合這些通訊協定,而不是設計新方法將這些通訊協定標示為通訊根。事實上,fuchsia.posix.socket 中具有通訊端控制通訊協定名稱的常數,這些常數在標示為 @discoverable 後會自動產生。

類型

目前,任何元件 (外部或平台) 程式碼都可以將原始位元組中的任何非資源類型進行序列化或還原序列化。為了允許相容性工具瞭解哪些 FIDL 類型「不會」在特定情況下進行序列化或去序列化,我們應明確標示在一般 FIDL IPC 外元件之間傳遞的類型。

語法

通訊協定

我們日後會將可偵測的屬性延伸至可實作的通訊協定位置。根據預設,標示為 @discoverable 的通訊協定可能包含由外部元件和平台元件實作的用戶端和伺服器。

serverclient 選用屬性會列出可實作該端點類型的元件。根據預設,這兩個端點都可由任何元件實作。

例如:

// All servers in the platform, all clients in external components.
@discoverable(client="external", server="platform")
protocol P {};

// All servers in external components, all clients in the platform.
@discoverable(client="platform", server="external")
protocol Q {};

// Only clients allowed in external components, both clients and servers allowed in the platform.
@discoverable(client="platform,external", server="platform")
protocol R {};

// Servers are only allowed in platform components. Clients are allowed anywhere.
// If both clients and servers are allowed that argument can (and should) be omitted.
@discoverable(server="platform")
protocol S {};

類型

系統會將新的 @serializable 屬性新增至 FIDL,以標示哪些類型可序列化並傳遞至 FIDL 通訊協定以外的元件之間。

這個屬性只適用於非 resource structtableunion

此參數有兩個選用引數:readwrite。每個元素都會取得一份以半形逗號分隔的 platformexternal 清單,指出應讀取或寫入該類型平台元件或外部元件。每個引數的預設值為 "platform,external",表示可從該種類的元件讀取及寫入。

實作

FIDL 工具鍊

系統會更新 fidlc,以接受這些引數給 @discoverable 和新的屬性 @serializable目前不會修改 FIDL 繫結產生器 (fidlgen_*)。

Fuchsia 系統介面

partnerpartner_internal 程式庫中所有可供探索的 FIDL 通訊協定都會更新。大多數都會標示為 @discoverable(server="platform"),表示外部元件只能實作用戶端,但平台元件可以實作用戶端和伺服器。有些 (例如 fuchsia.io 中的許多項目) 會標示為 @discoverable(),指出任何元件可能會實作用戶端和伺服器。少數的驅動程式會標示為 @discoverable(client="platform", server="external"),表示外部元件應只實作伺服器,平台元件應只實作用戶端。

進行實驗和原型設計後,對於計算每個通訊協定屬於哪個類別,似乎沒有這麼簡單。檢查元件圖的執行階段檢查與 CML 資料分割的靜態評估都不明顯。我們會改為查看外部元件的資訊清單 其使用及提供的通訊協定功能

針對獨立資料類型,我們會尋找各種語言繫結的明確序列化 API 來呼叫,並適當地為其中使用的類型加上註解。

相容性工具

我們正在開發一項工具,用於評估 Fuchsia 系統介面不同版本 FIDL IPC 部分的相容性。這與 FIDL IR 的影響,並會納入可發現屬性的資訊。這項工具將實作的相容性規則完整說明請參閱另一個 RFC。

未來商機

相容性工具是這項強化 FIDL 語法的基礎。不過,這些有關 Fuchsia 系統介面的詳盡資訊,或許可以證明在其他地方派上用場。

FIDL 繫結

FIDL 繫結產生器可以瞭解其是否正在建構以平台元件或外部元件為目標的繫結,並調整這些程式碼產生的程式碼,鼓勵開發人員僅在具備相容性保證的情況下,實作通訊協定的用戶端和伺服器。

防止任何不支援的用戶端或伺服器會造成反效果,因為開發人員必須能夠在測試中偽造或模擬同事,但我們也許可以設定防護機制,避免將其用於非測試環境。

獨立序列化程式碼可以更新,只允許標示為 @serializable 的類型傳遞。

元件架構

在元件架構中,通訊協定功能為非類型。通常以其隨附的 FIDL 通訊協定命名,但這只是慣例,也是違反的。針對元件用於與對等方通訊的通訊協定,工具必須根據使用的通訊協定名稱猜測。

如果元件架構在模型中新增通訊協定類型,這些工具就會變得更簡單、更完善,也更正確。

軟體組件

軟體組件會透過設定、平台元件和外部元件產生 Fuchsia 系統映像檔。這項工具可以運用可能由平台元件提供的通訊協定資訊或外部的資訊,拒絕組合違反這些規則的產品。這可確保產品負責人在無意間建構具備相容性保證的產品,確保 Fuchsia 並未提供產品,並協助平台開發人員避免以他們不想支援的方式揭露功能。

安全性

瞭解哪些通訊協定功能會在外部/平台邊界轉送,有助於評估系統的安全性屬性。這項作業可以臨時設定完成,或整合至現有工具中。

效能

成效則維持不變。

人體工學

這需要系統的某些假設必須明確。這需要預先多做一點工作,但可能會使得系統更容易理解及運作。

回溯相容性

現有的 FIDL 程式庫不會受到影響。不含引數的 @discoverable 仍是有效的屬性。

起初,我們不希望針對可探索及可序列化的屬性建立版本版本,因為這些屬性是版本管理的輸入內容、不會影響來源或執行階段相容性,而且必須廣泛採用,才能瞭解相關優點。如果根據可探索的引數更新 FIDL 繫結來變更,我們必須考慮對這些繫結進行版本管理,因為變更這些繫結可能會破壞現有原始碼。

安全性考量

這部分未來可能會有機會提升整體系統安全性。

隱私權注意事項

測試

這將使 Fuchsia 平台的相容性測試更容易確認,方法是明確編碼我們保證與何種通訊協定的相容性。

針對所有 fidlc 變更,我們會新增 fidlc 測試。

在我們於組裝時驗證所有元件均符合 FIDL 檔案所描述的規則前,我們不知道在 SDK 中表達的外部/平台分割區與 Fuchsia 產品的實際狀況相符。

說明文件

部分 FIDL 說明文件需要更新:

缺點、替代項目和未知

我們可以維持現狀,但這會大幅限制我們支援的變更類型,或限制工具檢查變更安全性時的信心。

我們可以在 API 工具中表達外部 / 平台分割,而不是 FIDL 語言 (如同 SDK 類別),但由於此分類是在宣告層級進行,這樣較不方便,且更可能過時。

我們不必使用 @discoverable 來標記 fuchsia.io.Directory 之類的通訊協定,而可以想出對等的屬性,原本就的相容性相同,但不支援對通訊協定功能的支援。這感覺就像是我們需要的複雜性

我們只需編寫使用這些類型的預留位置 FIDL protocol,並加上適當的屬性標示 @discoverable,以暗示可讀取和寫入這些類型的位置,而不是將 @serializable 新增至錶帶外交換的類型。這意味著,通訊協定一律不得說出,且通常難以正確理解。

我們不使用 @discoverable(server="platform", client="external") 等語法,而是使用 @discoverable(platform="server", external="client") 一段時間,但目前的語法更容易理解。

優先藝術與參考資料

不適用