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

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

在 OTA 期間重新排序映像檔寫入作業,以節省空間。

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

摘要

為回收系統空間,我們必須分割更新套件。在至少一個空間受限的產品上,我們將節省約 14 MiB。這項變更並非微不足道,需要發布過渡版本。根據 RFC 103,所有過渡版本都需要各自的 RFC。這份 RFC 詳細說明瞭新的更新套件格式。

提振精神

無線 (OTA) 更新機制可讓執行中的裝置升級 Fuchsia 版本。如有可用的更新,系統更新程式會擷取更新套件。擷取套件是指將套件內容寫入 BlobFS,並防止垃圾收集作業刪除這些內容。更新套件包含映像檔 (例如復原映像檔和 Zircon 開機映像檔),這些映像檔也會在 Zircon 分割區保留空間,以及要下載的其他套件清單,以便完成更新。

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

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

藉由保護圖片免於垃圾收集,更新可確保在發生中斷時繼續進行。前進進度是更新系統極為重要的屬性,不過,在空間受限的產品上,將映像檔寫入磁碟分割區和 BlobFS 都是不理想的預算分配方式。

在 OTA 程序中,映像檔寫入是倒數第二個步驟,之後系統會切換作用中磁碟分割區,並重新啟動至新的系統映像檔。在下次更新前,核心、韌體和復原映像檔不會遭到垃圾收集和刪除。在 OTA 期間重新排序圖片寫入作業,我們就能在下載 OTA 中的大多數套件之前,從 BlobFS 垃圾收集圖片,並回收空間預算供其他套件使用。變更 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

設計

目前更新套件也是一種套件,其中包含在擷取更新套件時擷取並寫入 blob 檔案系統的圖片。

我們建議從更新套件中取出圖片,並將每張圖片放在各自的套件中。

這與目前的 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"
      }
    ]
  }
}

版本屬性會定義內容屬性的解讀方式。 使用本 RFC 定義的格式時,版本一律為「1」,但現在導入版本屬性可簡化日後可能需要的額外變更。SWD 堆疊的資訊清單中其他位置也使用這個模式,且與 serde 整合良好。

系統更新程式會剖析資訊清單,判斷是否需要擷取映像檔 (根據相應雜湊值的檔案是否已位於適當的插槽)。系統會擷取每個變更的圖片,寫入其分割區,然後從 BlobFS 進行垃圾收集。如果 images.json 中沒有圖片,我們就不會覆寫 zircon 分區中的內容。

圖片大小和雜湊值會一併傳送,以供驗證檢查。雜湊值是圖片檔案的 SHA256 雜湊值,以十六進位表示。由於不同裝置的分割區大小不一,我們也需要知道圖片大小,才能進行比較。網址含有 Merkle 雜湊值。Merkle 雜湊的計算較為複雜,因此系統會選擇 SHA256 雜湊,以便快速比較。

我們建議的 OTA 流程如下:

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

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

實作

如要對更新套件進行這項變更,我們必須發布三個階段的版本: 首先,處理目前更新套件格式和新更新套件格式的超集; 其次,只產生新格式; 最後,停止處理舊版更新套件的邏輯。

在第一階段,系統更新程式會經過修改,以便成功剖析原始更新套件格式和本 RFC 建議的修改格式。MOS 仍會使用原始格式產生更新套件。這個包含這項工作的發布版本會標示為墊腳石,確保所有 Fuchsia 裝置在收到使用新格式的更新套件前,都會收到能夠剖析新格式的 system_updater。

在第二階段,MOS 將開始使用本 RFC 建議的新格式,製作更新套件。

在第三階段,我們確信所有裝置都不需要還原至使用原始更新套件格式的版本後,就會修改 system_updater,移除對原始更新套件格式的支援。

如果我們未分階段發布,裝置只能解讀目前版本的更新套件,一旦收到更新後的更新套件,就會無法運作。我們需要將第一階段發布版本標示為「墊腳石」版本,確保所有裝置都通過該版本。

更新套件的使用者必須留意階段性發布。已知使用者為安全與審查、MOS、產品組裝和軟體交付。

效能

預計不會有顯著變化。

我們需要取得圖片的雜湊值並進行比較。在最佳情況下,雜湊值會相符,我們不需要花時間擷取或寫入雜湊值。即使所有圖片都變更,我們仍需下載並寫入相同位元組數。

安全性考量

Scrutiny (我們的建構階段安全分析工具) 會分析更新套件,從中擷取 ZBI。我們需要更新 Scrutiny 測試,以反映更新套件中 ZBI 的新位置。

圖片的完整性檢查不會改變。我們會繼續使用相同方法擷取更新套件,且更新套件包含映像檔套件的雜湊值,裝置重新啟動進入新系統時,驗證啟動會強制執行所有其他安全性屬性。

隱私權注意事項

這項 RFC 不會對圖片的建立或內容進行任何變更,只會影響圖片的傳送順序,因此不會影響隱私權。

測試

我們已針對更新套件和系統更新程式進行單元和端對端整合測試。我們需要擴大這些測試的範圍,涵蓋從目前版本的更新套件到第一個踏腳石版本的過渡版本。對於第二個版本,我們需要測試來處理更新套件的中間版本和新版本。完成後,我們會移除中介測試,並測試以舊版更新套件格式進行 OTA 降級時,一律會失敗。

說明文件

如果這項變更獲得核准,我們需要更新更新套件說明文件OTA 文件

缺點、替代方案、不明

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

最簡單的方法是直接將映像檔鋪平到分割區、從 blobfs 進行垃圾收集更新套件,最後下載屬於保留索引的新套件 blob。這個替代方案實作簡單、可避免重複寫入,且不需要過渡版本。但我們無法保證後續進展。如果更新中斷,裝置可能無法完成更新。

另一種做法是將圖片保留在更新套件中,但將更新套件視為比現在更特別的項目:完全避免將圖片儲存至 blobfs。這項設計可免除更新套件的格式變更需求,但需要大幅修改系統更新程式邏輯,並使更新套件的處理方式與「一般」套件的處理方式不同。我們認為提議的設計只是重構更新套件,而非導入特殊處理邏輯。

先前技術

更新套件的設計先前已在 fuchsia.dev 上記錄