使用者資料查核點

Android 10 推出使用者資料檢查點 (UDC),如果 Android 無線 (OTA) 更新失敗,Android 就能還原至先前的狀態。使用 UDC 時,如果 Android OTA 更新失敗,裝置可以安全地復原為先前的狀態。雖然 A/B 更新可解決早期啟動的問題,但如果使用者資料分割區 (掛接在 /data 上) 經過修改,系統就不支援回溯。

UDC 可讓裝置還原使用者資料分區,即使分區已修改也一樣。UDC 功能會透過檔案系統的檢查點功能達成此目的,如果檔案系統不支援檢查點,則會採用替代實作方式,並與開機載入程式 A/B 機制整合,同時支援非 A/B 更新,以及支援金鑰版本繫結和防止金鑰復原。

對使用者的影響

UDC 功能可改善使用者的 OTA 更新體驗,因為 OTA 更新失敗時,較少使用者會遺失資料。這樣一來,使用者在更新過程中遇到問題時,就不太需要撥打支援電話。不過,如果 OTA 更新失敗,使用者可能會發現裝置多次重新啟動。

運作方式

不同檔案系統中的檢查點功能

針對 F2FS 檔案系統,UDC 會將檢查點功能新增至上游 4.20 Linux 核心,並回溯至 Android 10 裝置支援的所有常見核心。

對於其他檔案系統,UDC 會使用名為 dm_bow 的裝置對應器虛擬裝置,提供檢查點功能。dm_bow 位於裝置和檔案系統之間。掛接分區時,系統會發出修剪指令,導致檔案系統對所有可用區塊發出修剪指令。dm_bow 會攔截這些修剪內容,並用來設定免費封鎖清單。讀取和寫入作業隨後會傳送至裝置,但必須先將還原所需的資料備份到可用區塊,才能進行寫入作業。

查核點程序

掛接具有 checkpoint=fs/block 標記的分區時,Android 會在磁碟上呼叫 restoreCheckpoint,讓裝置還原任何目前的檢查點。init 接著會呼叫 needsCheckpoint 函式,判斷裝置是否處於系統啟動載入程式 A/B 狀態,或是否已設定更新重試次數。如果其中一個為 true,Android 會呼叫 createCheckpoint,加入掛接標記或建構 dm_bow 裝置。

掛接分割區後,系統會呼叫檢查點程式碼來發出修剪指令。 開機程序隨後會照常繼續。在 LOCKED_BOOT_COMPLETE,Android 會呼叫 commitCheckpoint 來提交目前的檢查點,更新作業會照常繼續。

管理 KeyMint (舊稱 Keymaster) 金鑰

KeyMint 金鑰可用於裝置加密或其他用途。為管理這些金鑰,Android 會延遲金鑰刪除呼叫,直到檢查點已提交為止。

監測健康

健康狀態精靈會驗證是否有足夠的磁碟空間來建立檢查點。健康狀態 Daemon 位於 Checkpoint.cppcp_healthDaemon

健康狀態 Daemon 具有下列可設定的行為:

檢查點 API

UDC 功能會使用檢查點 API。如要瞭解 UDC 使用的其他 API,請參閱IVold.aidl

void startCheckpoint(int retry)

建立檢查點。

架構準備好開始更新時,就會呼叫這個方法。檢查點是在重新啟動後掛接可檢查點的檔案系統 (例如 userdata) R/W 之前建立。如果重試次數為正數,API 會處理追蹤重試,更新程式則會呼叫 needsRollback,檢查是否需要回溯更新。如果重試次數為 -1,API 會延後至 A/B 開機載入程式的判斷。

進行一般 A/B 更新時,不會呼叫這個方法。

void commitChanges()

提交變更。

變更準備好要提交時,架構會在重新啟動後呼叫這個方法。系統會在資料 (例如圖片、影片、簡訊、伺服器收到接收確認) 寫入 userdata 之前,以及 BootComplete 之前呼叫這個函式。

如果沒有作用中的檢查點更新,這個方法就不會產生任何作用。

abortChanges()

強制重新啟動並還原至檢查點。放棄第一次重新啟動後的所有使用者資料修改。

架構會在重新啟動後呼叫這個方法,但會在 commitChanges 之前。呼叫這個方法時,retry_counter 會減少。系統會產生記錄項目。

bool needsRollback()

判斷是否需要回溯。

在非檢查點裝置上,傳回 false。在檢查點裝置上,系統會在非檢查點啟動期間傳回 true

導入 UDC

參考實作

如要瞭解如何實作 UDC,請參閱 dm-bow.c。如需這項功能的其他說明文件,請參閱 dm-bow.txt

設定

init.hardware.rc 檔案的 on fs 中,確認您有:

mount_all /vendor/etc/fstab.${ro.boot.hardware.platform} --early

init.hardware.rc 檔案的 on late-fs 中,確認您有:

mount_all /vendor/etc/fstab.${ro.boot.hardware.platform} --late

fstab.hardware 檔案中,確認 /data 已標記為 latemount

/dev/block/bootdevice/by-name/userdata              /data              f2fs
noatime,nosuid,nodev,discard,reserve_root=32768,resgid=1065,fsync_mode=nobarrier
latemount,wait,check,fileencryption=ice,keydirectory=/metadata/vold/metadata_encryption,quota,formattable,sysfs_path=/sys/devices/platform/soc/1d84000.ufshc,reservedsize=128M,checkpoint=fs

新增中繼資料分區

UDC 需要中繼資料分區來儲存非開機載入程式重試次數和金鑰。設定中繼資料分割區,並在 /metadata 提前掛接。

fstab.hardware 檔案中,確認 /metadata 已標記為 earlymountfirst_stage_mount

/dev/block/by-name/metadata           /metadata           ext4
noatime,nosuid,nodev,discard,sync
wait,formattable,first_stage_mount

將分區初始化為全零。

BoardConfig.mk 中新增下列程式碼:

BOARD_USES_METADATA_PARTITION := true
BOARD_ROOT_EXTRA_FOLDERS := existing_folders metadata

更新系統

F2FS 系統

如果系統使用 F2FS 格式化資料,請確認 F2FS 版本支援檢查點。詳情請參閱「不同檔案系統中的檢查點功能」。

checkpoint=fs 標記新增至 fstab 的 <fs_mgr_flags> 區段,適用於掛接在 /data 的裝置。

非 F2FS 系統

如果不是 F2FS 系統,則必須在核心設定中啟用 dm-bow

checkpoint=block 標記新增至 fstab 的 <fs_mgr_flags> 區段,適用於掛接在 /data 的裝置。

檢查記錄

呼叫 Checkpoint API 時,系統會產生記錄項目。

驗證

如要測試 UDC 實作,請執行 VtsKernelCheckpointTest VTS 測試集。