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
位於設備和文件系統之間。當一個分區被掛載時,會發出一個 trim 導致文件系統對所有空閒塊發出 trim 命令。 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
UDC 功能使用檢查點 API。對於 UDC 使用的其他 API,請參閱IVoid.aidl
。
無效的開始檢查點(整數重試)
創建一個檢查點。
框架在準備好開始更新時調用此方法。檢查點是在檢查點文件系統(如用戶數據)在重新啟動後以 R/W 方式掛載之前創建的。如果重試計數為正,API 處理跟踪重試,更新程序調用needsRollback
以檢查是否需要回滾更新。如果重試計數為-1
,則 API 將遵循 A/B 引導加載程序的判斷。
進行正常 A/B 更新時不會調用此方法。
無效的 commitChanges()
提交更改。
當更改準備好提交時,框架會在重新啟動後調用此方法。這在數據(例如圖片、視頻、短信、服務器回執)寫入 userdata 之前和BootComplete
之前調用。
如果不存在活動的檢查點更新,則此方法無效。
中止更改()
強制重啟並恢復到檢查點。放棄自第一次重新啟動以來的所有用戶數據修改。
框架在重新啟動後但在commitChanges
之前調用此方法。調用此方法時, retry_counter
會減少。生成日誌條目。
布爾需要回滾()
確定是否需要回滾。
在非檢查點設備上,返回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
標誌添加到 fstab 的<fs_mgr_flags>
部分,用於安裝在/data
的設備。
非 F2FS 系統
對於非 F2FS 系統,必須在內核配置中啟用dm-bow
。
將checkpoint=block
標誌添加到 fstab 的<fs_mgr_flags>
部分,用於安裝在/data
的設備。
檢查日誌
調用 Checkpoint API 時會生成日誌條目。
驗證
要測試您的 UDC 實施,請運行VtsKernelCheckpointTest
一組 VTS 測試。
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
位於設備和文件系統之間。當一個分區被掛載時,會發出一個 trim 導致文件系統對所有空閒塊發出 trim 命令。 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
UDC 功能使用檢查點 API。對於 UDC 使用的其他 API,請參閱IVoid.aidl
。
無效的開始檢查點(整數重試)
創建一個檢查點。
框架在準備好開始更新時調用此方法。檢查點是在檢查點文件系統(如用戶數據)在重新啟動後以 R/W 方式掛載之前創建的。如果重試計數為正,API 處理跟踪重試,更新程序調用needsRollback
以檢查是否需要回滾更新。如果重試計數為-1
,則 API 將遵循 A/B 引導加載程序的判斷。
進行正常 A/B 更新時不會調用此方法。
無效的 commitChanges()
提交更改。
當更改準備好提交時,框架會在重新啟動後調用此方法。這在數據(例如圖片、視頻、短信、服務器回執)寫入 userdata 之前和BootComplete
之前調用。
如果不存在活動的檢查點更新,則此方法無效。
中止更改()
強制重啟並恢復到檢查點。放棄自第一次重新啟動以來的所有用戶數據修改。
框架在重新啟動後但在commitChanges
之前調用此方法。調用此方法時, retry_counter
會減少。生成日誌條目。
布爾需要回滾()
確定是否需要回滾。
在非檢查點設備上,返回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
標誌添加到 fstab 的<fs_mgr_flags>
部分,用於安裝在/data
的設備。
非 F2FS 系統
對於非 F2FS 系統,必須在內核配置中啟用dm-bow
。
將checkpoint=block
標誌添加到 fstab 的<fs_mgr_flags>
部分,用於安裝在/data
的設備。
檢查日誌
調用 Checkpoint API 時會生成日誌條目。
驗證
要測試您的 UDC 實施,請運行VtsKernelCheckpointTest
一組 VTS 測試。