RFC-0135:套件 ABI 修訂版本 | |
---|---|
狀態 | 已接受 |
領域 |
|
說明 | 將系統 ABI 修訂版本編碼為套件。 |
問題 | |
毛皮變化 | |
作者 | |
審查人員 | |
提交日期 (年-月-日) | 2021-09-30 |
審查日期 (年-月-日) | 2021-11-05 |
摘要
將系統 ABI 修訂版本編碼為套件的設計。
提振精神
RFC-0002 介紹 API 級別和 ABI 修訂版本的概念。API level 是單純增加人類可理解的數字, 是一組可在建構應用程式時可用的 API。 ABI 修訂版本會對應至 Fuchsia 公開的特定語意 應用程式預期平台提供的系統介面。API 級別 對應特定 ABI 修訂版本,但多個 API 級別可以參照 相同 ABI 修訂版本。這項功能可讓 Fuchsia 平台持續進化 同時繼續支援舊版應用程式
如要實作平台版本管理,您必須封裝 ABI 級別的套件 所指定的目標,讓平台能得知套件是否 並與運作中系統相容
相關人員
講師:abarth@google.com
審查者:
下列利害關係人獲選為 RFC 規範的 Fuchsia Tools 軟體推送,並最終影響元件架構 選取要向應用程式呈現的元件系統介面
- abarth@google.com (FEC 成員)
- PCdruid@google.com (SWD)
- geb@google.com (CF)
- mkember@google.com (FIDL)
- raggi@google.com (工具)
- wittrock@google.com (SWD)
諮詢:
- 利吉阿明 (PDK)
社交功能:
這個 RFC 經過了軟體推送和 Fuchsia 的設計審查。 工具團隊
術語
Fuchsia 套件是發行和 整理 Fuchsia 程式、元件和服務的檔案。
meta.far 是套件中繼資料封存檔。其中包含 一個向使用者顯示的檔案名稱給定址 blob。這會使用 封裝系統下載套件內容 階層還包含使用者提供的自訂檔案。
設計
這個設計引入了套件 ABI 修訂版本的概念,也就是
指定套件使用的 Fuchsia 平台介面的 ABI 修訂版本。這個
值會寫入為無正負號的 64 位元整數,並寫入
meta/fuchsia.abi/abi-revision
檔案中的 meta.far
。
所有套件產生工具都將更新為必須使用 API 級別 或在建構套件時指定的 ABI 修訂版本。API 級別 工具的指定,工具應對位於 SDK 版本記錄或發生錯誤。同樣地,工具應會 SDK 支援指定的 ABI 修訂版本,或發生錯誤。這個 應避免使用舊版 SDK 建立元件,而將 ABI 只會出現在較新的 SDK 中。最多來說,這樣可產生一個元件 測試失敗而最糟的情況是,元件可能不尋常 更是如此
套件 ABI 修訂版本的用途
本提案僅涵蓋如何將 ABI 修訂版本編碼為套件。位使用者 的套件 ABI 修訂版本將會在日後設計中定義。不過, 以下列舉幾個可能的應用方式:
- RFC-0002 平台說明元件管理服務可使用的機制 ABI 修訂套件,選取要使用的平台介面 執行元件
- 系統組合是指從 套件和其他已編譯的構件系統映像檔 透過不同方式 (OTA、閃爍、鋪砌、 等)。組合器可以使用該套件的 ABI 修訂版本拒絕 在系統不支援所需的套件 ABI 時整合套件。
- 同樣地,花瓣粉或應用程式開發人員可以使用套件 ABI 修訂版本 瞭解複雜樹狀圖中的所有元件能否運作 。
- 臨時套件是視需要下載的套件,而非 內建於系統映像檔中Package Resolver 可以利用 封裝 ABI 修訂版本,藉此拒絕下載已知並非的套件 執行上的檔案請注意,這可能不適用於系統更新。 詳情請參閱「系統更新註意事項」一節 詳細資料。
選取目標 API 級別或 ABI 修訂版本
本提案旨在將 API 級別或 ABI 修改為必要引數 但在初始推出期間,您可以視需求決定是否使用 這項功能瞭解這點後,開發人員應將 目標 API 級別或 ABI 修訂版本的建構規則。這樣您應該 鎖定新版本。您甚至可以設定 以便建立新的 API 級別 目標 API 級別,觀察是否有任何失敗之處。這可能會傳回平台 錯誤回報。
系統更新註意事項
為了讓 Fuchsia 裝置從版本更新, system updater 會解析稱為「更新套件」的特殊套件。這個 套件會針對 新的 Fuchsia 版本。這些新的套件不適合 但會在裝置重新啟動後改為使用 新的系統
有鑑於此,我們決定使用套件 ABI 修訂版本拒絕 下載套件時,必須小心避免破壞 OTA 程序。 如以下範例所示:
假設有兩個 Fuchsia 建構 A
,而這些版本僅支援 ABI-1
和 C
,
支援 ABI-2
。如果是根據 ABI 篩選套件,則該套件的更新套件
「C
」需要 ABI-1
才能下載。不過,C
版基本版本
只有 ABI-2
套件才能使用新的 ABI,但會是
已遭 A
套件解析器版本拒絕。
避免這種情況的一種方式,就是透過逐步 石頭版本Fuchsia 的設計宗旨是要讓裝置略過多個版本 才能更新至最新版本階梯的安裝是特別的 無法略過的版本這項設計旨在提供流暢的轉場效果 經由平台介面提供
重做先前的範例,改為讓 Fuchsia 依序發布 3 個版本:
A
:支援ABI-1
,基礎套件則位於ABI-1
B
:支援ABI-1
和ABI-2
,支援ABI-1
的基本套件。C
:支援ABI-2
,基礎套件為ABI-2
。
如果我們將 B
標示為階梯石版本,那麼搭載 A
的裝置就會
先更新至 B
,再更新為 C
。
將套件定義方式分離,即可進一步實踐這個構想 提供 ABI 修訂版本。我們不打算經常在 如果我們針對套件版面配置做出不相容的變更,我們可以建立套件版面配置的版本, 然後,指出指定的 ABI 修訂版本支援哪些套件版面配置版本。 這樣我們就能安裝更多樣的更新套件 不必建立逐步石製
避免中繼.far 中的命名空間衝突
meta.far
目前含有兩個套件中繼資料檔案:meta/package
和 meta/contents
以及任意使用者指定的檔案。也就是說
使用者檔案和任何新中繼資料可能會發生衝突
我們要導入套件中的檔案為避免這種情況發生,如果為 ABI 套件
修訂版本會寫入目錄 meta/fuchsia.abi
。這個目錄名稱
遵循 Fuchsia 其他地方使用的慣例,例如 FIDL 平台
命名空間我們還會進一步更新套件建立工具,以免使用者
但不需要在 meta/fuchsia.abi
中定義自訂檔案
由於這是由平台控管的目錄,因此您可以使用
儲存 ABI 相關檔案的位置,不會與使用者檔案衝突。這個
可進一步發展套件 ABI 修訂的觀念。舉例來說
想要在套件中支援多個 ABI 修訂版本,我們可以
meta/fuchsia.abi/abi-revision-set
,包含所有支援的修訂版本。
一旦所有使用者都遷移至 meta/fuchsia.abi/abi-revision
新檔案。
儲存空間負擔
在中繼新增套件 ABI 修訂版本時,會產生 8KiB 的負荷 最糟的情況是,前 4KiB 的來源 4KiB,在最糟糕的情況下是未壓縮方式 如果是 FAR 資料區塊,第二個則是「DIRNAMES」區段造成第一個 內容區塊。不過, 實務上不應有顯著影響,因為 blobfs 具有 8KiB 區塊對齊此外,使用預設值時 壓縮機 zstd。以下範例只會加 47 個位元組 對應至 Meta.far:
# Create an empty package.
% mkdir empty && cd empty
% pm init && pm build
% ls -l meta.far
-rw-r--r-- 1 etryzelaar primarygroup 12288 Oct 5 10:21 meta.far
% fx chunked-compress c meta.far meta.far.compressed
Wrote 447 bytes (97% compression)
# Then create a meta.far that contain's the abi-revision.
% cd .. && mkdir with-abi && cd with-abi
% pm init
% mkdir meta/fuchsia.abi
% python3 -c "
import struct;
abi_revision = int('0xC7003BF9', 16)
f = open('meta/fuchsia.abi/abi-revision', 'wb')
f.write(struct.pack('<Q', abi_revision))
"
% pm build
% ls -l meta.far
-rw-r--r-- 1 etryzelaar primarygroup 16384 Oct 5 10:22 meta.far
% fx chunked-compress c meta.far meta.far.compressed
Wrote 494 bytes (97% compression)
實作
我們會擴充所有套件建構工具,支援指定 API 級別 指令列上的 ABI 修訂版本
PM CLI
系統將擴充 pm
CLI,以便在套件中指定 ABI
初始化及套件建構
叫用範例:
# Create a package with an API level. Under the covers this will look up the
# ABI revision from the SDK.
% pm init --api-level 5
# Create a package with an ABI revision. These commands are equivalent.
% pm init --abi-revision 0xC7003BF9
% pm init --abi-revision 3338681337
# Build a package with an ABI revision.
% pm build --abi-revision 0xC7003BF9
選項:
--api-level LEVEL
:要編碼至套件的 API 級別。這個值 必須受到 SDK 支援這個選項與--abi-revision
相衝突 旗標。--abi-revision REVISION
:要放入機器的 ABI 修訂版本 套件。這可以是十進位或十六進制整數, 適用於 SDK 的多種功能這個選項與--api-level
旗標相衝突。
一開始,您可以選擇使用 --api-level
和 --abi-revision
標記
讓花瓣粉和開發人員在一段時間內導入支援服務。
生態系統轉移後,最終將成為必填項目
不需要指定標記
成效
這個 RFC 引入了大量的額外工作,以建構套件 會對儲存空間造成些許負擔,因此效能方面的影響 可以忽略。
人體工學
本提案本身並不會大幅改變福希西亞的人體工學。 然而,這最終可讓產品開發人員指定 元件的系統介面因此,您應確保模型的穩定性 同時仍要阻止 Fuchsia 的發展。
回溯相容性
由於這個設計推出了新檔案,因此這項變更具有回溯相容性 沒有消費者不過,這項功能最終 ,以便淘汰及移除對舊版 ABI 修訂版本的支援。
安全性考量
您必須剖析 meta/fuchsia.abi/abi-revision
檔案。不過,
格式易於剖析,且應易於驗證
正確。
詳情請參閱 RFC-0002 安全性考量。
隱私權注意事項
此提案對隱私權沒有任何實質影響。
測試
我們會擴充封裝工具,驗證是否已產生套件
以及應設定預期的 ABI由於會有過渡期,因此
系統將延長套件解析器測試,驗證是否能與套件搭配使用
是否包含 meta/fuchsia.abi/abi-revision
檔案
說明文件
封裝說明文件將更新,以討論 ABI 的 以及如何選擇 API 級別或 ABI 以及建構套件時的修訂版本
缺點、替代方案和未知
替代 ABI 修訂版本檔案格式
與其將 ABI 修訂版本編碼為較小的位元組整數 請改用:
- 使用者容易理解的整數字串
- JSON
- 永久 FIDL
系統選擇了較小的終點整數,原因如下:
- 我們不認為人類不得濫用此價值。相反地 是指人類可理解的 API 級別
- 系統會將這個值以小端整數形式傳遞,因此可避免 就能產生額外轉換
- 剖析方法很簡單。
包含一組 ABI 修訂版本的套件
RFC-0002 應用程式指出,套件可包含多個元件 分別指定不同的 ABI 修訂版本為了支援這項功能, 套件中的單一 ABI 修訂版本時,套件 ABI 可以是一組 所有元件 ABI 修訂版本
不過,截至本文撰寫為止,沒有任何用途需要套件 包含指定不同系統 ABI 的元件。單一號碼 可簡化支援 ABI 支援的初始實作程序。其實很簡單 當這個情況變得很重要時,您即可擴充此設計。
直接將 ABI 修訂版本編碼為 Meta.far
中繼.far 可以透過下列任一方式直接嵌入 ABI 修訂版本:
- 將 ABI 新增至 FAR 索引區塊。
- 優點:
- 僅會增加 8 個位元組的負擔。
- 缺點:
- 索引區塊沒有任何保留的位元組,因此請在 索引需要破壞 FAR 格式。如想 但我們必須先導入支援功能,才能讀取新的 無需採用 FAR 格式,然後建立逐步石頭版本 最後遷移至格式
- 消費者會更難閱讀 ABI 修訂版本。 套件解析器不會以檔案的形式,直接將 Meta.far 公開給使用者 因此您需要新增 API 來公開這項資訊
- 建立新的 ABI 修訂版本區塊類型。
- 優點:
- 如要新增區塊類型,應具備回溯相容性。
- 位元組負擔應該就會小很多,因為我們不必 可建立 4096 位元組對齊的內容區塊區塊會 64 位元對齊, 有 24 個位元組的索引負擔項目大小,所以此方法 因為未壓縮的 FAR 格式會增加 32 個位元組。
- 缺點:
- 我們未在 FAR 格式中新增區塊類型,因此可以 程式庫若發生新的錯誤,可能會發生錯誤或異常行為 區塊類型
- 我們必須更新所有 FAR 程式庫,才能瞭解新區塊 類型。過去對 FAR 程式庫的任何變更費用皆相當昂貴 待執行。
- 消費者會更難閱讀 ABI 修訂版本。 套件解析器不會以檔案的形式,直接將 Meta.far 公開給使用者 因此您需要新增 API 來公開這項資訊
由於儲存空間負擔極低,尤其是在壓縮時 認為節省空間的價值就是定義新的區塊類型。
存放區中繼資料中的 ABI 修訂版本
我們不直接將 ABI 編碼為套件,而是改為新增 ABI 套件存放區中套件中繼資料的修訂版本這個引數包含 下列缺點:
- ABI 修訂版本是套件的內建屬性。可以是 難以確定 ABI 修訂版本在 TUF 中正確呈現 或基礎套件清單中
- 包裝中繼資料仍包含 ABI 修訂內容,因此包裝 系統仍得會產生額外負載
即將推出的永久 FIDL 套件中繼資料中的 ABI 修訂版本
Software Delivery 撰寫 RFC,提議提出新的 Persistent-FIDL 封裝中繼資料我們可以改為將 ABI 修訂版本儲存在這項中繼資料內,方法是 將提議的結構定義更新為以下內容:
flexible union Contents {
1: ContentsV1 v1;
};
table ContentsV1 {
1: vector<fuchsia.io.Path>:MAX paths;
2: vector<fuchsia.pkg.BlobId>:MAX hashes;
3: vector<uint64>:MAX blob_sizes;
4: uint64 abi_revision;
};
優點:
- 將所有封裝中繼資料整合成單一 FIDL 檔案的好處 就是運用 FIDL 工具 至今使用多個檔案可讓說明文件更容易理解 驗證偏移值會不同步。
- 只有在未壓縮的中繼.far 中,我們只會加入少量位元組 約 4 KiB
使用 FIDL 的缺點:
- 並不保證會接受永久 FIDL 式的 RFC。 以及導入所需時間
- 雖然 Persistent-FIDL 式的方法有版本管理,但內部版本 無法協助我們將封裝中繼資料遷移至其他檔案格式。適用對象 例如,決定從永久的 FIDL 切換至 JSON 檔案。這項服務 使用新的 ABI 版本向包裝系統通知封裝系統 尋找和先前不同的檔案格式
既有藝術品和參考資料
Android
Android 應用程式會指定 SDK 版本,方法是指定 uses-sdk 元素 應用程式資訊清單。
Windows
Windows 應用程式會以指定的 OS 版本為目標,方法是指定 SupportedOS GUID。
macOS
macOS 應用程式會指定 OS 版本,方法是指定
應用程式套件 Info.plist
檔案中的 LSMinimumSystemVersion。
iOS
iOS 應用程式會在 MinimumOSVersion 中指定 OS 版本
應用程式套件的 Info.plist
檔案。