虛擬 A/B 版本總覽

虛擬 A/B 是 Android 的主要更新機制。虛擬 A/B 是以舊版 A/B 更新為基礎 (請參閱「A/B 系統更新」),並在 15 中淘汰非 A/B 更新,以減少更新的空間負擔。

虛擬 A/B 測試實際上沒有動態分區的額外位置,請參閱動態分區。而是將差異寫入快照,然後在確認開機成功後,合併至基本分割區。虛擬 A/B 測試會使用 Android 專屬的快照格式。請參閱「壓縮快照的 COW 格式」,瞭解如何壓縮快照並盡量減少磁碟空間用量。完整 OTA 的快照大小會壓縮約 45%,增量 OTA 快照大小則會壓縮約 55%。

Android 12 提供虛擬 A/B 壓縮選項,可壓縮快照分割區。虛擬 A/B 測試提供下列功能

  • 虛擬 A/B 更新與 A/B 更新一樣順暢 (更新完全在背景進行,裝置運作不受影響)。虛擬 A/B 更新可盡量縮短裝置離線和無法使用的時間。
  • 虛擬 A/B 測試更新可以回溯。如果新版 OS 無法啟動,裝置會自動還原為先前的版本。
  • 虛擬 A/B 更新只會複製啟動載入程式使用的磁碟分割區,因此佔用的額外空間最少。其他可更新的分區則會建立快照

背景與術語

本節定義術語,並說明支援虛擬 A/B 測試的技術。在 OTA 安裝期間,新的作業系統資料會寫入實體分割區的新位置,或是 Android 專用的 COW 裝置。裝置重新啟動後,系統會透過 dm-user 和 snapuserd 精靈,將動態分割區資料合併回基本裝置。這項程序完全在使用者空間中進行。

Device-mapper

裝置對應程式是 Linux 虛擬區塊層,Android 經常使用此層。有了動態分區/system 等分區就會成為分層裝置堆疊:

  • 堆疊底部是實體超級分割區 (例如 /dev/block/by-name/super)。
  • 中間是 dm-linear 裝置,指定超級分割區中的哪些區塊會形成指定的動態分割區。在 A/B 裝置上會顯示為 /dev/block/mapper/system_[a|b],在非 A/B 裝置上則會顯示為 /dev/block/mapper/system
  • 頂端是為已驗證分割區建立的 dm-verity 裝置。 這個裝置會驗證 dm-linear 裝置上的區塊是否已正確簽署。顯示為 /dev/block/mapper/system-verity,是 /system 掛接點的來源。

圖 1 顯示掛接點下的堆疊外觀。/system

在系統下方堆疊分區

圖 1. 堆疊在 /system 掛接點下方

壓縮快照

在 Android 12 以上版本中,由於 /data 分區的空間需求可能很高,因此您可以在建構作業中啟用壓縮快照,以解決 /data 分區空間需求較高的問題。

虛擬 A/B 壓縮快照是以 Android 12 以上版本提供的下列元件為基礎建構而成:

  • dm-user:類似 FUSE 的核心模組,可讓使用者空間實作區塊裝置。
  • snapuserd,使用者空間精靈,用於實作新的快照格式。

這些元件可啟用壓縮功能。如要實作壓縮快照功能,還需要進行其他變更,詳情請參閱下列章節:壓縮快照的 COW 格式dm-usersnapuserd

壓縮快照的 COW 格式

在 Android 12 以上版本中,壓縮快照會使用 Android 專用的 COW 格式。COW 格式包含 OTA 的中繼資料,以及含有 COW 作業和新作業系統資料的獨立緩衝區。相較於僅允許「取代」作業 (將基本映像檔中的區塊 X 取代為快照中的區塊 Y) 的核心快照格式,Android 壓縮快照 COW 格式更具表現力,且支援下列作業:

  • 複製:將基本裝置中的區塊 X 換成區塊 Y
  • 取代:基礎裝置中的區塊 X 應替換為快照中的區塊 Y 內容。每個區塊都經過 gz 壓縮。
  • :基本裝置中的 X 區塊應全數以零取代。
  • XOR:COW 裝置會儲存區塊 X 和區塊 Y 之間的 XOR 壓縮位元組。(適用於 Android 13 以上版本)。

完整 OTA 更新只包含「取代」和「零」作業。增量 OTA 更新可能還包含複製作業。

磁碟上的完整快照版面配置如下所示:

cow 格式

圖 2. 磁碟上的 Android COW 格式

dm-user

dm-user 核心模組可讓 userspace 實作裝置對應程式區塊裝置。dm-user 資料表項目會在「/dev/dm-user/<control-name>」下建立雜項裝置。userspace 程序可以輪詢裝置,接收來自核心的讀取和寫入要求。每個要求都有相關聯的緩衝區,供使用者空間填入 (讀取) 或傳播 (寫入) 資料。

dm-user 核心模組提供新的使用者可見核心介面,不屬於上游 kernel.org 程式碼集。在此之前,Google 保留修改 Android dm-user 介面的權利。

snapuserd

snapuserd使用者空間元件會dm-user實作 Virtual A/B 壓縮功能。Snapuserd 是負責寫入及讀取 Android COW 裝置的使用者空間精靈。所有快照 I/O 都必須透過這項服務。 在 OTA 安裝期間,snapuserd 會將新的作業系統資料寫入快照 (並進行壓縮)。這裡也會處理中繼資料的剖析作業,以及新區塊資料的解壓縮作業。

XOR 壓縮

如果裝置搭載 Android 13 以上版本,預設會啟用 XOR 壓縮功能,讓使用者空間快照在舊區塊和新區塊之間儲存 XOR 壓縮位元組。在虛擬 A/B 更新中,如果只有區塊中的幾個位元組發生變化,XOR 壓縮儲存空間配置使用的空間會比預設儲存空間配置少,因為快照不會儲存完整的 4K 位元組。由於 XOR 資料包含許多零,且比原始區塊資料更容易壓縮,因此快照大小可以縮減。在 Pixel 裝置上,XOR 壓縮可將快照大小縮減 25% 至 40%。

如果裝置升級至 Android 13 以上版本,必須啟用 XOR 壓縮。詳情請參閱 XOR 壓縮

快照合併

如果是搭載 Android 13 以上版本的裝置,虛擬 A/B 壓縮的快照和快照合併程序會由 snapuserd 使用者空間元件執行。如果裝置升級至 Android 13 以上版本,必須啟用這項功能。詳情請參閱「使用者空間合併」。

以下說明 Virtual A/B 壓縮程序:

  1. 架構會從 dm-verity 裝置卸載 /system 分割區,該裝置會堆疊在 dm-user 裝置上方。也就是說,根檔案系統的所有 I/O 都會轉送至 dm-user
  2. dm-user 將 I/O 轉送至使用者空間 snapuserd 精靈,該精靈會處理 I/O 要求。
  3. 合併作業完成後,架構會摺疊 dm-veritydm-linear (system_base) 頂端,並移除 dm-user

虛擬 A/B 壓縮程序

圖 3. 虛擬 A/B 壓縮程序

快照合併程序可能會中斷。如果裝置在合併程序期間重新啟動,合併程序會在重新啟動後繼續執行。

初始化轉場效果

使用壓縮快照啟動時,第一階段 init 必須開始掛接分割區。snapuserd這會造成問題:載入並強制執行 sepolicy 時,snapuserd 會進入錯誤的環境,導致讀取要求失敗,並遭到 SELinux 拒絕。

為解決這個問題,snapuserd 會與 init 同步轉換,如下所示:

  1. 第一階段 init 會從 ramdisk 啟動 snapuserd,並將開啟的檔案描述元儲存至環境變數。
  2. 第一階段的 init 會將根檔案系統切換至系統分割區,然後執行 init 的系統副本。
  3. 系統副本的 init 會將合併的 sepolicy 讀取到字串中。
  4. 會對所有 ext4 支援的頁面呼叫 mlock()Init接著,系統會停用快照裝置的所有裝置對應表,並停止 snapuserd。之後就禁止從分割區讀取資料,否則會造成死結。
  5. 使用開放描述元重新啟動精靈的 ramdisk 副本 snapuserdinit 會使用正確的 SELinux 內容。系統會重新啟用快照裝置的裝置對應表。
  6. Init 會叫用 munlockall(),因此可以再次執行 IO。

空間用量

下表比較了使用 Pixel OS 和 OTA 大小時,不同 OTA 機制的空間用量。

大小影響 非 A/B A/B 虛擬 A/B 測試 虛擬 A/B (壓縮)
Original Factory Image 4.5 GB 超大容量 (3.8 GB 圖片 + 700 MB 保留空間)1 9GB 超級 (3.8G + 700M 保留,適用於兩個插槽) 4.5 GB 超級 (3.8 GB 圖片 + 700 MB 保留) 4.5 GB 超級 (3.8 GB 圖片 + 700 MB 保留)
其他靜態分割區 /cache
OTA 期間的額外儲存空間 (套用 OTA 後會釋出空間) /data 上的 1.4 GB 0 /data 上 3.8 GB2 /data 上 2.1 GB2
套用 OTA 時所需的總儲存空間 5.9 GB3 (超級和資料) 9 GB (超級) 8.3 GB3 (超級和資料) 6.6 GB3 (超級和資料)

1:根據 Pixel 對應顯示的預設版面配置。

2假設新系統映像檔與原始映像檔大小相同。

3重新啟動前,空間需求為暫時性。

Android 11 虛擬 A/B

Android 11 的虛擬 A/B 測試功能使用 Kernel COW 格式寫入動態分割區。由於 Kernel COW 格式不支援壓縮,因此最終遭到淘汰。

Android 12 虛擬 A/B

在 Android 12 中,壓縮功能以 Android 專屬 COW 格式提供。這個版本的虛擬 A/B 測試需要將 Android 專屬的 COW 轉換為 Kernel COW 格式。Android 13 最終取代了這項功能,不再依賴 Kernel COW 格式,也移除了 dm-snapshot

如要導入虛擬 A/B 測試或使用壓縮快照功能,請參閱「導入虛擬 A/B 測試」一文。