Реализация виртуального A/B-тестирования – исправления

Чтобы устранить известные проблемы, выборочно скопируйте изменения из следующих исправлений.

Проверка выделяемого пространства при установке из неизвестного источника

При загрузке полного пакета OTA на виртуальное устройство A/B с суперразделом, размер которого меньше, чем *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, пересоберите и прошейте раздел загрузки или раздел восстановления, если устройство не использует восстановление в качестве загрузки.

Исправлена ошибка сегментации при объединении.

После применения беспроводного обновления во время процесса объединения VAB вызов update_engine_client --cancel приводит к сбою CleanupPreviousUpdateAction. Если markSlotSuccessful появляется поздно, также может возникнуть ошибка с указателем.

Эта проблема была решена путем добавления функции StopActionInternal. CleanupPreviousUpdateAction отменяет ожидающие задачи при уничтожении. Он поддерживает переменную, которая отслеживает идентификатор ожидающей задачи в цикле сообщений. При уничтожении объекта ожидающая задача отменяется, чтобы избежать ошибки сегментирования.

Чтобы устранить сбои SIGSEGV в update_engine во время объединения, убедитесь, что в дереве исходного кода Android 11 есть следующие изменения:

  • CL 1439792 (необходимо для CL 1439372)
  • CL 1439372 (CleanupPreviousUpdateAction: отмена ожидающих задач при уничтожении)
  • CL 1663460 (исправлена потенциальная ошибка с указателем при позднем получении markSlotSuccessful).

Как предотвратить преждевременное объединение update_engine

Когда устройство загружается (Android 11 и более поздние версии) и загрузка завершается, update_engine вызывает ScheduleWaitMarkBootSuccessful() и WaitForMergeOrSchedule(). Начнется процесс объединения. Однако устройство перезагружается в старый слот. Поскольку объединение уже началось, устройство не загружается и становится неработоспособным.

Добавьте в дерево источников следующие изменения. Обратите внимание, что CL 1664859 – необязательный параметр.

  • CL 1439792 (необходимо для CL 1439372)
  • CL 1439372 (CleanupPreviousUpdateAction: отмена ожидающих задач при уничтожении)
  • CL 1663460 (исправлена потенциальная ошибка с указателем при позднем получении markSlotSuccessful).
  • CL 1664859 (необязательно – добавьте unittest для CleanupPreviousUpdateAction)

Убедитесь, что конфигурация 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.

При такой конфигурации устройства любая ошибка verity приводит к повреждению раздела vbmeta и делает неработоспособными устройства, не поддерживающие A/B-обновления. Аналогично, если объединение уже началось, устройства A/B также могут стать неработоспособными. Используйте только режим проверки AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO.

  1. Задайте CONFIG_DM_VERITY_AVB=n в ядре.
  2. Настройте устройства так, чтобы на них использовался режим AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO.

Подробнее о том, как устранять ошибки dm-verity…

Убедитесь, что объединенный файл настроен правильно

Если вы создаете образы системы и поставщика отдельно, а затем объединяете их с помощью merge_target_files, настройки виртуального A/B-тестирования могут быть неправильно удалены в процессе объединения. Чтобы проверить, правильно ли настроена виртуальная система A/B в объединенном целевом файле, примените следующие исправления: CL 2084183 (объединение одинаковых пар "ключ/значение" в информации о динамическом разделе).

Обновите необходимые компоненты

В Android 13 файл snapuserd был перенесен из ramdisk поставщика в общий ramdisk. Если ваше устройство обновляется до Android 13, возможно, что и в ramdisk поставщика, и в общем ramdisk есть копия snapuserd. В этом случае виртуальной системе A/B требуется системная копия snapuserd. Чтобы убедиться, что используется правильная копия snapuserd, примените CL 2031243 (скопируйте snapuserd в first_stage_ramdisk).