RFC-0071:OTA 停止

RFC-0071:OTA 反向停止
狀態已接受
領域
  • 系統
說明

防止裝置在版本邊界之間反向執行 OTA。

問題
毛皮變化
作者
審查人員
提交日期 (年-月-日)2021-02-03
審查日期 (年-月-日)2021-02-24

摘要

本文件建議的計畫,是禁止裝置安裝無線更新 (OTA) 的方式 跨越版本邊界

提振精神

當儲存堆疊對檔案系統格式做出破壞性變更時,即會發布主要版本 格式,可避免在舊版系統中執行的驅動程式 掛接並使用新格式的映像檔。

如果在系統更新堆疊中提供同等版本號碼,使用者就無法嘗試 從 OTA 回溯至不支援其裝置的檔案系統映像檔的驅動程式庫版本 包含。也就是說,如果發生「反向 OTA」讓我們失敗作業 就是積木

這麼做可帶來附加價值,原因如下:

  • 對保留狀態的任何應用程式而言非常實用舉例來說: 應用程式維護的 SQLite 資料庫,其結構定義可能會隨時間而改變。
  • 這對儲存空間團隊來說特別實用,因為他們過去必須 投入了大量時間,找出最終因反向 OTA 設定所產生的問題 版本邊界。
  • 這麼做即可加強 Fuchsia 不支援回溯 OTA 的做法。我們會盡力而為

請特別注意,本提案不會影響支援的 OTA 序列 但實際上並非如此只是為了明確表達這項支持。OTA 後端的主要用途是防止 開發人員裝置移至無效狀態。如果是正式版裝置, 沒有反向 OTA 的主要工作應由版本管理強制執行。

如果沒有這個提案,在不相容邊界內嘗試執行反向 OTA 將導致 開發人員嘗試啟動裝置時發生問題 (例如,檔案系統格式可能並非 )。透過本提案,開發人員可以事先瞭解相關資訊 OTA (錯誤會清楚顯示) 可提供更優質的開發人員體驗。

背景

術語

OTA 是一種升級基礎作業系統的機制。Fuchsia 裝置可接收 以及安裝系統和應用程式軟體的 OTA 更新。

「Stepping Stone」版本是無法在 OTA 中略過的版本。例如,假設 依序發布 A、B 和 C 版本傳統上,我們會支援 A->BB->CA->C。如果我們將 B 宣告為階梯堆疊,這麼做會移除 A->C 邊緣,因此唯一的方法 A 的升級方式為 OTA A->B,然後是 B->C。在實務上,這很適合用於有風險的遷移作業 以及減少我們測試的後續網路旅行社數量

OTA 後端與踩踏石之間的關係

OTA 回溯功能和逐步石製版本都是我們確保遷移作業安全的基本要件 (例如儲存空間格式遷移作業)。關於 OTA 重新啟動機制和 Stepping-stone 版本應不在此 RFC 的範圍之內。不過,這裡提供 範例,說明如何將這些基元用於安全遷移。

考慮遷移儲存格式。以下是我們可能採取的步驟:

  1. 新增對新格式的支援,但暫時不要啟用/遷移。將 OTA 推倒停止。
  2. 稍等片刻。
  3. 以上述其中一種遷移策略啟用新格式。

即使確實確實遷移裝置,我們可以進一步採取兩個步驟來啟用 資源清理:

  1. 剪輯包含 (3) 個步驟的踏板版本。
  2. 移除遷移程式碼和舊格式的支援。

逐步石頭發布可讓我們假設裝置會經歷 遷移程式碼,因此我們可移除對舊格式的讀取支援。

將 OTA 推進機制 (1) 可確保裝置不會降級至 支援新格式

顛覆去背的政策

向後停靠站應視需要一次性停止。絕大多數的變更都不需要 反而有壓迫感如果 RFC 獲得核准,便必須發布官方教戰手冊文件來說明 特定步驟不斷衝高倒退與此同時,我們在此提供 本政策。

提出 CL 提案以使反駁時,作者應該:

  • 提供 bug.fuchsia.dev 的問題連結,當中說明需要撞擊的原因及做法 如果開發人員絕對必須將裝置降級至 (例如答案可能是「閃爍」或「路道」)。
  • 取得 //src/sys/pkg/OWNERS 核准。

設計

一起來介紹 epoch.json 檔案,讓它同時出現在 update 套件和系統上。 應是包含兩個字串鍵的 JSON 檔案:

  • 「version」,epoch.json 結構定義版本應有單一字串值。於 執行更新時不會檢查此項目,執行更新時不會檢查此項目;這個索引鍵只是為了讓 在實際工作環境中進行 epoch.json 結構定義變更時,系統會顯而易見。
  • 「epoch」,更新 OTA 反向停止作業的單一整數值。如果更新週期 套件 <,在準備階段,我們應使用 UNSUPPORTED_DOWNGRADE 讓 OTA 失敗。

舉例來說,epoch.json 看起來可能會像這樣:

{
  "version": "1",
  "epoch": 5
}

為了安全地與 Epoch 整合,接下來要介紹用於編譯的 epoch_history 檔案 透過建構系統傳入 epoch.jsonepoch_history 檔案可能採用以下格式:

0=Initial epoch (https://fxbug.dev/42144857)
1=Storage format migration (https://fxbug.dev/XXXXX)
...
N=Most recent change (https://fxbug.dev/YYYYY)

每當有回溯不相容的變更時,都必須手動切換 epoch_history 檔案 。

雖然中介 epoch_history 檔案會增加一層的複雜性,但這種方法 優點:

  • 它會提供所有版本的更新記錄 (強制說明文件!)
  • 如果兩個人基於不同原因嘗試觸碰週期,就會產生合併衝突。

實作

相關變更會完全在平台上進行 (尤其是系統更新堆疊)。

為了順利讓變更生效,請執行以下操作:

  • epoch_history 新增至 //src/sys/pkg/bin/system-updater。
    • 同時建立可將 epoch_history 轉換為 epoch.json 的指令碼。
    • 請建構系統使用這個指令碼,將 epoch.json 新增至 system-updater 的 out 目錄。
  • 修改 BUILD 這樣 epoch.json 就會放入更新套件中
  • system-updater 應在「Prepare」階段結束時檢查 epoch.json
    • 如果更新套件中沒有 epoch.json,或是還原序列化時發生問題,請 假設週期為 0。我們會刻意忽略錯誤,讓 epoch.json 仍可進行 OTA 結構定義變更
    • 如果 system-updater 的目錄中沒有 epoch.json,或者 反序列化作業失敗,因為這是未預期的情況。 建議使用 include_str 巨集 從目錄讀取資料
    • 如果更新套件中的 Epoch 時間System-updater 中的 epoch,失敗準備 原因:UNSUPPORTED_DOWNGRADE。我們需要建立一份新的 PrepareFailureReason (UNSUPPORTED_DOWNGRADE)

安全性

這不是安全防護功能。但可能會與安全防護功能互動,讓開發人員更完善 工作流程舉例來說,假設復原防護功能拒絕以下啟動映像檔 版本:N。如果在終止映像檔版本 N 時遞增 Epoch,開發人員就會遇到這個問題 ,因為這類降級作業會在 OTA 反向停止時失敗,而降級不可啟動的版本。

此外,我們選擇將 epoch.json 嵌入系統更新器二進位檔 (而非 config-data),讓 OTA 彈性應對 Config-data 損毀情形。

隱私權和效能注意事項

測試

我們可以使用現有的系統更新測試架構 (適用於混合單位的 //src/sys/pkg) 以及整合測試

此外,OTA e2e 測試可確保後端作業 且必須使用有效的格式例如:

  • 如果版本 N 將 OTA 降回機制降低,我們就會無法從版本 N-1N 進行持續整合到 OTA。
  • 如果建構 N 在 system-updater 中產生無效的 epoch.json,就無法透過持續整合 (CI) 連線至 OTA。
  • N 建構到 N'

說明文件

我們需要建立文件,說明更新 epoch_history 的相關政策。

同時,我們也會修改:

缺點、替代方案和未知

執行這個提案需要支付哪些費用?

實作此提案的主要成本會增加平台複雜度,因為我們新增了 另一個則是版本 ID

還有哪些策略可以解決相同問題?

另一種策略是正式支援所有反向 OTA。這種做法不切實際,因為我們無法 因此若我們不知道這些變更是什麼,可以寫出可彈性因應日後變更的程式碼。

另一種策略是明確禁止「所有」反向 OTA (即使系統會排除特定的網路旅行社) 可能存在)。舉例來說,我們可以在每次新版本中自動碰到返回站。我們決定不 因為實際上,部分開發人員「確實」採用這類舊版 OTA,我們希望 能夠突破這些開發人員的藩籬

另一個做法是直接整合 Fuchsia 平台版本管理 (請參閱 RFC-0002)。不過 有幾個不明確的問題舉例來說,如果 API 級別中的所有反向 OTA 更新為 還是應該選擇特定層級?我們要打敗誰?由於 Fuchsia 針對系統的不同部分 (例如: 系統都有自己的版本 ID),那情況似乎比較簡單。

既有藝術品和參考資料

Android:進一步瞭解 OTA。

特別銘謝

James Sullivan 執行了激勵人心的動機與踏上石頭部分。Zach Kirschenbaum 撰寫了以下作品 原始設計文件 且由 Dan Johnson 審閱