RFC-0170:從更新套件中移除二進位映像檔

RFC-0170:從更新套件中移除二進位映像檔
狀態已接受
區域
  • 軟體推送
說明

為節省空間,在 OTA 期間重新排列圖片寫入作業。

問題
變更
作者
審查人員
提交日期 (年/月)2022-05-12
審查日期 (年/月)2022-06-22

摘要

如要收回系統空間,我們必須分割更新套件。至少針對一項空間受限的產品,可以省下約 14 MiB。這是一項重大的變革 需要逐步推出根據 RFC 103,所有逐步堆疊版本都需要自己的 RFC。此 RFC 會詳細說明新的更新套件格式。

提振精神

無線下載 (OTA) 更新機制是在執行中裝置上升級 Fuchsia 版本的機制。如果有可用的更新,system-updater 將會擷取更新套件。如要擷取套件,表示套件的內容會寫入 BlobFS,且不會進行垃圾收集。更新套件包含在 Zircon 分區上保留空間的映像檔 (例如復原映像檔和 Zircon Boot 映像檔),以及其他要下載以完成更新作業的套件清單。

目前 Fuchsia 裝置必須儲存每張圖片的兩份副本:

  1. 裝置在執行階段使用的目的地分區 (例如 ZIRCON_A) 有一個副本。
  2. 一個 blobf 中的副本,因為圖片會以更新套件內的 blob 形式傳送至裝置。

透過防止圖片垃圾收集,更新可確保在中斷時繼續轉送。前進進度是保證更新系統的重要屬性。然而,在空間受限的產品上,將圖片寫入磁碟分區和 BlobFS 無法達到最佳預算設定。

切換映像檔之前,映像檔寫入是 OTA 程序中的最終步驟,之後會切換使用中的分區是有效分區,並重新重新啟動至新的系統映像檔。在下次更新之前,核心、韌體和復原映像檔都不會經過垃圾收集和刪除。透過在 OTA 期間重新排列圖片寫入作業,我們可以先將 BlobFS 映像檔收集為垃圾,然後才下載 OTA 中的多數套件,並收回空間預算供其他套件使用。變更 SWD 設計以移除重複的影像副本,可能可以節省大量空間,這是部分 Fuchsia 裝置的極佳做法。

為了在 OTA 期間對二進位映像檔進行垃圾收集,同時確保後續進展,我們需要變更更新套件的格式。

相關人員

講師:hjfreyer@google.com

審查者:

  • 軟體推送服務:wittrock@google.com、jsankey@google.com
  • MOS:gtsai@google.com
  • 安全性:ampearce@google.com
  • 產品組合:awolter@google.com
  • 版本:billstevenson@google.com

設計

目前更新套件是一個套件,其中包含擷取更新套件時擷取並寫入 blobfs 的圖片。

建議您從更新套件中提取映像檔,並將每個映像檔放入自己的套件中。

這與目前的 OTA 程序與套件格式恰當,但需要變更更新套件格式。

為了參照這些新套件,我們會在更新套件中新增檔案 (名為 images.json),此套件包含描述映像檔套件的中繼資料。該檔案的範例如下:


{
  "version": "1",
  "contents": {
    "partitions": [
      {
        "type": "zbi",
        "slot": "fuchsia",
        "size": 1,
        "hash": "0a",
        "url": "fuchsia-pkg://fuchsia.com/fuchsia-zbi/0?hash={merkle_hash}#path/to/fuchsia.zbi"
      },
      {
        "type": "vbmeta",
        "slot": "fuchsia",
        "size": 2,
        "hash": "0b",
        "url": "fuchsia-pkg://fuchsia.com/fuchsia-vbmeta/0?hash={merkle_hash}#path/to/fuchsia.vbmeta"
      },
      {
        "type": "zbi",
        "slot": "recovery",
        "size": 3,
        "hash": "0c",
        "url": "fuchsia-pkg://fuchsia.com/recovery-zbi/0?hash={merkle_hash}#path/to/recovery.zbi"
      },
      {
        "type": "vbmeta",
        "slot": "recovery",
        "size": 4,
        "hash": "0d",
        "url": "fuchsia-pkg://fuchsia.com/recovery-vbmeta/0?hash={merkle_hash}#path/to/recovery.vbmeta"
      }
    ],
    "firmware": [
      {
        "type": "",
        "size": 5,
        "hash": "0e",
        "url": "fuchsia-pkg://fuchsia.com/update-images-firmware/0?hash={merkle_hash}#path/to/firmware"
      },
      {
        "type": "bl2",
        "size": 6,
        "hash": "0e",
        "url": "fuchsia-pkg://fuchsia.com/update-images-firmware/0?hash={merkle_hash}#path/to/firmware"
      }
    ]
  }
}

version 屬性會定義內容屬性的解譯方式。使用此 RFC 定義的格式時,版本一律必須為「1」。不過,推出版本屬性現在可簡化日後可能需要進行的其他變更。這個模式已用於 SWD 堆疊資訊清單的其他位置,並與 Serde 完美整合。

系統更新工具會剖析資訊清單,判斷是否需要擷取圖片 (根據包含對應雜湊的檔案是否已位於合適的插槽中)。系統會擷取每張已變更的圖片,並將其寫入其分區,然後從 BlobFS 收集垃圾。如果 images.json 中沒有圖片,系統就不會覆寫 zircon 分區中顯示的圖片。

包括圖片尺寸和雜湊資訊以供驗證檢查。雜湊是以十六進位表示的圖片檔案 SHA256 雜湊。由於分區是不同裝置的變數,因此我們必須瞭解圖片的大小才能進行比較。網址包含墨爾雜湊值。Merkle 雜湊較複雜,因此會選擇 SHA256 雜湊來加快比較速度。

我們提議的 OTA 程序如下:

  1. 下載更新套件
  2. 剖析含有更新圖片套件參照的新中繼資料檔案
  3. 針對該檔案中列出的每個圖片,如果圖片與非使用中分區指定 Zircon 分區中的圖片相同,請繼續操作。中繼資料檔案包含圖片的雜湊和大小 (因為圖片大小不等於分區大小),我們可以快速比較非使用中分區的圖片雜湊。其他:
    1. 擷取含有映像檔的套件,該套件會將圖片寫入 BlobFS 並處理完整性檢查。將套件新增至保留的索引。
    2. 寫入分區。
    3. 從保留的索引中移除垃圾收集 (從保留的索引中移除套件),以取回空間。
  4. 繼續下載更新套件中指定的其餘套件,並完成 OTA。

變更更新套件的結構讓我們解決空間限制問題。將資料寫入 BlobFS,然後進行垃圾收集,讓我們可以使用目前儲存架構提供的全方位安全保證。

實作

如要對更新套件進行這項變更,我們必須要有三個階段版本:首先處理目前更新套件格式的超集和新更新套件的格式,第二個版本則只處理新格式,而最後一個版本則用於停止處理舊版更新套件的邏輯。

系統會修改第一階段 system_updater,以成功剖析原始更新套件格式和此 RFC 中提議的修改格式。MOS 仍會使用原始格式產生更新套件。系統會將包含這項工作的這個版本標示為步數,確保所有 Fuchsia 裝置都會收到可剖析新格式的 system_updater,經過能先剖析新格式的 System_updater 後,才會收到採用新格式的更新套件。

在第二階段中,MOS 將開始使用這個 RFC 提議的新格式產生更新套件。

在第三階段,一旦我們確定所有裝置都不需要復原至使用原始更新套件格式的版本,system_updater 便會修改以停止支援原始更新套件格式。

如果未階段發布版本,則只能解讀更新套件目前版本的裝置在收到更新套件時就會處於破壞狀態。我們需要將第一個階段版本標示為「逐步踏板」版本,以確保所有裝置都通過該版本。

更新套件的使用者需要瞭解階段版本。已知使用者為 Security vis visrutiny、MOS、產品組合和軟體推送。

效能

預計不會出現重大變化。

我們需要對圖片進行雜湊處理,才能進行比較。在最佳情況下,雜湊相符,不必花時間擷取或寫入。在大部分情況下,當所有圖片有所變更,我們還是需要下載及寫入相同的位元組數量。

安全性考量

Scrutiny (我們的建構時間安全性分析工具) 會分析更新套件,從中擷取 ZBI。我們必須更新 Scrutiny 測試,以反映更新套件中的 ZBI 新位置。

映像檔的完整性檢查不會改變。我們會繼續使用相同的方法擷取更新套件,而更新套件中包含映像檔套件的雜湊值,也會在裝置重新啟動新系統時,透過驗證開機程序強制執行所有其他安全性屬性。

隱私權注意事項

此 RFC 不會對映像檔的建立或內容造成任何變更,只有傳送順序,因此不會影響隱私。

測試

我們已針對更新套件和系統更新工具進行單元和端對端整合測試。我們必須擴充這些測試,以涵蓋從目前版本的更新套件改為中繼版本,以便用於首次進行初始石頭版本。在第二個版本中,我們需要執行測試,以便處理更新套件的中繼版本和新版更新套件。作業完成後,我們會移除中繼測試,並測試使用舊版更新套件的降級 OTA 是否會一直失敗。

說明文件

這項變更獲得核准後,請更新套件說明文件OTA 文件

缺點、替代方案、未知

替代方案是完全不會將圖片寫入 BlobFS 的設計。

基本方法是將映像檔直接存放在各自的分區,以垃圾收集從 blobfs 收集更新套件,最後再下載屬於保留索引的新套件 blob。這個替代方案易於實作、避免重複的寫入,且不需要逐步發布。但我們無法保證未來的進展。如果更新中斷,裝置可能會完全無法更新。

有一種替代方法可將圖片保留在更新套件中,但要將更新套件當做比目前更特別的處理,我們可以避免將圖片儲存至 blob。這種設計就不必變更更新套件的格式,但需要對系統更新工具邏輯進行大量變更,並將更新套件與「一般」套件的處理方式分開處理。我們認為提議的設計只會重構更新套件,而不是引入特殊的處理邏輯。

既有圖片

更新套件的設計先前也記錄在 fuchsia.dev。