Android 10 推出了使用者資料查核點 (UDC),可讓 Android 在 Android 無線 (OTA) 更新失敗時,回復至先前的狀態。有了 UDC,如果 Android OTA 更新失敗,裝置就能安全地回復至先前的狀態。雖然 A/B 更新可解決早期啟動時的這個問題,但如果修改使用者資料分區 (掛載在 /data
上),系統就不會支援回溯。
UDC 可讓裝置在經過修改後還原使用者資料分區。UDC 功能可透過檔案系統的檢查點功能達成此目標,這是在檔案系統不支援檢查點時的替代實作方式,可與引導程式 A/B 機制整合,同時支援非 A/B 更新,並支援金鑰版本繫結和金鑰復原防護功能。
使用者影響
由於 OTA 更新失敗時,使用者遺失資料的情況會減少,因此 UDC 功能可改善 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
來提交目前的查核點,並繼續正常更新。
管理 Keymaster 金鑰
Keymaster 金鑰可用於裝置加密或其他用途。為了管理這些金鑰,Android 會延遲刪除鍵刪除呼叫,直到查核點提交為止。
監控健康狀態
健康監控 Daemon 會驗證磁碟空間是否足夠,以便建立檢查點。健康守護程式位於 Checkpoint.cpp
中的 cp_healthDaemon
。
健康守護程式可設定下列行為:
ro.sys.cp_msleeptime
:控管裝置檢查磁碟用量頻率。ro.sys.cp_min_free_bytes
:控管健康守護程式尋找的最低值。ro.sys.cp_commit_on_full
:控制健康監控守護程序是否在磁碟已滿時重新啟動裝置或提交檢查點,並繼續執行。
Checkpoint API
Checkpoint API 由 UDC 功能使用。如需瞭解 UDC 使用的其他 API,請參閱 IVold.aidl
。
void startCheckpoint(int retry)
建立查核點。
架構會在準備開始更新時呼叫此方法。系統重新啟動後,系統會在將檢查點檔案系統 (例如 userdata) 掛載為讀寫模式前建立檢查點。如果重試次數為正值,API 會處理追蹤重試,更新程式會呼叫 needsRollback
,檢查是否需要回復更新。如果重試次數為 -1
,API 會延遲至 A/B 開機載入程式的判斷。
進行一般 A/B 更新時,系統不會呼叫這個方法。
voidCommitChanges()
提交變更。
當可修訂變更時,架構會在重新啟動後呼叫這個方法。這個方法會在資料 (例如相片、影片、簡訊、伺服器收據) 寫入 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
已標示為 earlymount
或 first_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 版本支援檢查點。詳情請參閱「不同檔案系統中的檢查點功能」。
針對掛載在 /data
的裝置,將 checkpoint=fs
旗標新增至 fstab 的 <fs_mgr_flags>
部分。
非 F2FS 系統
對於非 F2FS 系統,必須在核心設定中啟用 dm-bow
。
針對掛載在 /data
的裝置,將 checkpoint=block
旗標新增至 fstab 的 <fs_mgr_flags>
部分。
檢查記錄
系統會在呼叫 Checkpoint API 時產生記錄項目。
驗證
如要測試 UDC 實作方式,請執行 VtsKernelCheckpointTest
組的 VTS 測試。