Android 10 引入了用戶資料檢查點 (UDC),它允許 Android 在 Android 無線 (OTA) 更新失敗時回滾到先前的狀態。借助 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 狀態或已設定更新重試計數。如果任一為真,Android 會呼叫createCheckpoint
來新增安裝標誌或建置dm_bow
設備。
分區掛載後,呼叫檢查點程式碼來發出修剪。然後引導過程將繼續正常進行。在LOCKED_BOOT_COMPLETE
處,Android 呼叫commitCheckpoint
來提交目前檢查點,並且更新照常繼續。
管理密鑰主密鑰
Keymaster 金鑰用於裝置加密或其他目的。為了管理這些密鑰,Android 會延遲密鑰刪除調用,直到提交檢查點。
監測健康狀況
執行狀況守護程式會驗證是否有足夠的磁碟空間來建立檢查點。執行狀況守護程序位於Checkpoint.cpp
中的cp_healthDaemon
。
執行狀況守護程式具有以下可設定的行為:
-
ro.sys.cp_msleeptime
:控制設備檢查磁碟使用量的頻率。 -
ro.sys.cp_min_free_bytes
:控制執行狀況守護程式尋找的最小值。 -
ro.sys.cp_commit_on_full
:控制執行狀況守護程式是否重新啟動裝置或提交檢查點並在磁碟已滿時繼續。
檢查點 API
檢查點 API 由 UDC 功能使用。對於 UDC 使用的其他 API,請參閱IVold.aidl
。
無效startCheckpoint(int重試)
建立一個檢查點。
框架在準備好開始更新時呼叫此方法。檢查點是在重新引導後以 R/W 方式安裝檢查點檔案系統(例如使用者資料)之前建立的。如果重試計數為正,則 API 處理追蹤重試,並且更新程式呼叫needsRollback
來檢查是否需要回滾更新。如果重試次數為-1
,則 API 遵循 A/B 引導程式的判斷。
進行正常的 A/B 更新時不會呼叫此方法。
無效提交更改()
提交更改。
當變更準備好提交時,框架會在重新啟動後呼叫此方法。這是在資料(例如圖片、影片、簡訊、伺服器接收的接收)寫入 userdata 之前和BootComplete
之前調用的。
如果不存在活動的檢查點更新,則此方法無效。
中止更改()
強制重新啟動並恢復到檢查點。放棄自第一次重新啟動以來的所有用戶資料修改。
框架在重新啟動後但在commitChanges
之前呼叫此方法。呼叫此方法時, retry_counter
會減少。產生日誌條目。
bool needRollback()
確定是否需要回滾。
在非檢查點設備上,傳回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 版本支援檢查點。有關詳細信息,請參閱不同檔案系統中的檢查點功能。
將checkpoint=fs
標誌新增至掛載在/data
的裝置的 fstab 的<fs_mgr_flags>
部分。
非 F2FS 系統
對於非 F2FS 系統,必須在核心配置中啟用dm-bow
。
將checkpoint=block
標誌新增至掛載在/data
的裝置的 fstab 的<fs_mgr_flags>
部分。
檢查日誌
呼叫 Checkpoint API 時會產生日誌條目。
驗證
若要測試 UDC 實作,請執行 VTS 測試的VtsKernelCheckpointTest
集。