自 2025 年 3 月 27 日起,我們建議您使用 android-latest-release
而非 aosp-main
建構及貢獻 AOSP。詳情請參閱「Android 開放原始碼計畫變更」。
實作虛擬 A/B 版本修補程式
透過集合功能整理內容
你可以依據偏好儲存及分類內容。
挑選下列修補程式來解決下列已知問題。
側載時正確檢查可用空間
在虛擬 A/B 裝置上側載完整 OTA 套件 (該裝置的超級分區大小小於 *2 * sum(size of update groups)*) 可能會失敗,並在復原記錄 /tmp/recovery.log
中顯示以下內容:
The maximum size of all groups with suffix _b (...) has exceeded half of allocatable space for dynamic partitions ...
以下是記錄的範例:
[INFO:dynamic_partition_control_android.cc(1020)] Will overwrite existing partitions. Slot A may be unbootable until update finishes!
[...]
[ERROR:dynamic_partition_control_android.cc(803)] The maximum size of all groups with suffix _b (2147483648) has exceeded half of allocatable space for dynamic partitions 1073741824.
如果遇到這個問題,請精選 CL 1399393,並在裝置未使用 recovery 做為啟動時,重新建構及閃記啟動分割區或復原分割區。
修正合併期間的區隔錯誤
套用 OTA 更新後,在 VAB 合併程序期間,呼叫 update_engine_client --cancel
會導致 CleanupPreviousUpdateAction
當機。markSlotSuccessful
延遲到達時,也可能會發生野指標錯誤。
我們已透過新增 StopActionInternal
函式解決這個問題。CleanupPreviousUpdateAction
會在銷毀時取消待處理的工作。它會維護一個變數,用於追蹤訊息迴圈中待處理工作的工作 ID。在銷毀時,系統會取消待處理的工作,以免發生分段錯誤。
請確認您的 Android 11 來源樹狀結構中包含下列變更,以便修正合併期間 update_engine
中的 SIGSEGV
當機問題:
防止 update_engine 過早合併
裝置啟動 (Android 11 以上版本) 並完成啟動程序後,update_engine
會呼叫 ScheduleWaitMarkBootSuccessful()
和 WaitForMergeOrSchedule()
。這麼做會啟動合併程序。不過,裝置會重新啟動至舊的插槽。由於合併作業已開始,裝置無法啟動,因此無法運作。
將下列變更加入來源樹狀結構。請注意,CL 1664859 為選用。
確認 dm-verity 設定正確無誤
在 Android 11 以上版本中,裝置可能會不小心設定下列 dm-verity 選項:
- 核心中的
CONFIG_DM_VERITY_AVB=y
- 系統啟動載入程式已設定為使用任何 verity 模式 (例如
AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE
),但沒有 AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO
。
在這種裝置設定下,任何驗證錯誤都會導致 vbmeta 分區損毀,並使非 A/B 裝置無法運作。同樣地,如果合併已開始,A/B 裝置也可能無法運作。只使用 AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO
驗證模式。
- 在核心中設定
CONFIG_DM_VERITY_AVB=n
。
- 請改為設定裝置使用
AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO
模式。
詳情請參閱 verity 說明文件:處理 dm-verity 錯誤。
如果您分別建構系統映像檔和供應商映像檔,然後使用 merge_target_files
合併這些映像檔,虛擬 A/B 設定可能會在合併程序中遭到誤刪。如要驗證合併目標檔案中的虛擬 A/B 設定是否正確,請套用下列修補程式:CL 2084183 (在動態分割區資訊中合併相同的鍵/值組合)
更新必要元件
自 Android 13 起,snapuserd
已從供應商 RAM 磁碟移至通用 RAM 磁碟。如果裝置升級至 Android 13,供應商 RAM 磁碟和一般 RAM 磁碟都可能包含 snapuserd
的副本。在這種情況下,Virtual A/B 需要 snapuserd
的系統副本。為確保 snapuserd
的正確副本已就位,請套用 CL 2031243 (將 snapuserd
複製到 first_stage_ramdisk)。
這個頁面中的內容和程式碼範例均受《內容授權》中的授權所規範。Java 與 OpenJDK 是 Oracle 和/或其關係企業的商標或註冊商標。
上次更新時間:2025-07-27 (世界標準時間)。
[[["容易理解","easyToUnderstand","thumb-up"],["確實解決了我的問題","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["缺少我需要的資訊","missingTheInformationINeed","thumb-down"],["過於複雜/步驟過多","tooComplicatedTooManySteps","thumb-down"],["過時","outOfDate","thumb-down"],["翻譯問題","translationIssue","thumb-down"],["示例/程式碼問題","samplesCodeIssue","thumb-down"],["其他","otherDown","thumb-down"]],["上次更新時間:2025-07-27 (世界標準時間)。"],[],[],null,["# Implement Virtual A/B - patches\n\nCherry-pick the following patches to address the following known issues.\n\n### Check allocatable space correctly when sideloading\n\nSideloading a full OTA package on a Virtual A/B device that has a super\npartition with a size smaller than \\*2 \\* sum(size of update groups)\\* may fail\nwith the following in recovery log `/tmp/recovery.log`: \n\n The maximum size of all groups with suffix _b (...) has exceeded half of allocatable space for dynamic partitions ...\n\nHere is an example of the log: \n\n [INFO:dynamic_partition_control_android.cc(1020)] Will overwrite existing partitions. Slot A may be unbootable until update finishes!\n [...]\n [ERROR:dynamic_partition_control_android.cc(803)] The maximum size of all groups with suffix _b (2147483648) has exceeded half of allocatable space for dynamic partitions 1073741824.\n\nIf you encounter this issue, cherry pick [CL\n1399393](https://android-review.googlesource.com/1399393), rebuild, and flash\nthe boot partition or recovery partition if the device doesn't use recovery as\nboot.\n\n### Fix segmentation fault during merge\n\nAfter applying an OTA update, during the VAB merge process, a call to\n`update_engine_client --cancel` causes `CleanupPreviousUpdateAction` to crash. A\npotential wild pointer error also exists when `markSlotSuccessful` comes late.\n\nThis was resolved by adding the `StopActionInternal` function.\n`CleanupPreviousUpdateAction` cancels pending tasks on destroy. It maintains a\nvariable that tracks the task ID of the pending task in the message loop. On\ndestroy, the pending task is canceled to avoid segfault.\n\nEnsure the following changes are in your Android 11 source tree to fix `SIGSEGV`\ncrashes in `update_engine` during merge:\n\n- [CL 1439792](https://android-review.googlesource.com/1439792) (a prerequisite to CL 1439372)\n- [CL 1439372](https://android-review.googlesource.com/1439372) (`CleanupPreviousUpdateAction`: cancel pending tasks on destroy)\n- [CL 1663460](https://android-review.googlesource.com/1663460) (fix the potential wild pointer error when `markSlotSuccessful` comes late)\n\n### Prevent update_engine premature merge\n\nWhen a device boots (Android 11 and higher), and the boot completes, the\n`update_engine` calls `ScheduleWaitMarkBootSuccessful()`, and\n`WaitForMergeOrSchedule()`. This starts the merge process. However, the device\nreboots to the old slot. Because the merge already started, the device fails to\nboot and becomes inoperable.\n\nAdd the following changes to your source tree. Note that CL 1664859 is optional.\n\n- [CL 1439792](https://android-review.googlesource.com/1439792) (a prerequisite to CL 1439372)\n- [CL 1439372](https://android-review.googlesource.com/1439372) (`CleanupPreviousUpdateAction`: cancel pending tasks on destroy)\n- [CL 1663460](https://android-review.googlesource.com/1663460) (fix the potential wild pointer error when `markSlotSuccessful` comes late)\n- [CL 1664859](https://android-review.googlesource.com/1664859) (optional - add `unittest` for `CleanupPreviousUpdateAction`)\n\n### Ensure the correct dm-verity configuration\n\nIn Android 11 and higher, devices can be inadvertently configured with the\nfollowing dm-verity options:\n\n- `CONFIG_DM_VERITY_AVB=y` in the kernel\n- The bootloader configured to use any verity mode, (such as `AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE`), without `AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO`.\n\nWith this device configuration, any verity error causes the vbmeta partition to\nbecome corrupted, and renders non-A/B devices inoperable. Similarly, if a merge\nhas started, A/B devices might also become inoperable. Only use the\n`AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO` verity mode.\n\n1. Set `CONFIG_DM_VERITY_AVB=n` in the kernel.\n2. Configure devices to use the `AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO` mode instead.\n\nFor more information reference the verity documentation: [Handling dm-verity\nErrors](https://android.googlesource.com/platform/external/avb/+/android16-release/README.md#Handling-dm_verity-Errors).\n\n### Confirm the merged file is correctly configured\n\nIf you are building system images and vendor images separately, then using\n`merge_target_files` to merge them, Virtual A/B configurations might be\nincorrectly dropped during the merge process. To verify that Virtual A/B\nconfigurations are correct in the merged target file, apply the following\npatches: [CL\n2084183](https://android-review.googlesource.com/c/platform/build/+/2084183/)\n(merge identical key/val pairs in dynamic partition info)\n\n### Update necessary components\n\nAs of Android 13, `snapuserd` has been moved from vendor ramdisk to generic\nramdisk. If your device is upgrading to Android 13, it is possible that both\nvendor ramdisk and generic ramdisk contain a copy of `snapuserd`. In this\nsituation, Virtual A/B requires the system copy of `snapuserd`. To ensure that\nthe correct copy of `snapuserd` is in place, apply [CL\n2031243](https://android-review.googlesource.com/c/platform/system/core/+/2031243/)\n(copy `snapuserd` to first_stage_ramdisk)."]]