Внедрение виртуального A/B — патчи

Вишневый выбор следующих исправлений для решения следующих известных проблем.

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

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

Исправить ошибку сегментации во время слияния

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

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

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

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

Исправить неправильное переключение слотов VAB, опубликовать OTA-обновление

В Android 11 и более поздних версиях сбой синхронизации слот-переключателя на устройстве после обновления OTA может привести устройство в непригодное для использования состояние. Если реализация переключения слотов вашего IBootControl HAL выполняет запись, вы должны немедленно очистить эти записи. Если записи не сбрасываются и устройство перезагружается после начала слияния, но до того, как аппаратное обеспечение сможет сбросить запись переключения слота, устройство может вернуться к предыдущему слоту и не загрузиться.

Пример решения кода см. в этом CL: CL 1535570 .

Предотвратить преждевременное слияние update_engine

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

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

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

Предотвращение потери или повреждения данных из-за пропуска метаданных

В Android 11 и более поздних версиях, если устройство хранения имеет энергозависимый кэш обратной записи, при определенных условиях метаданные завершенного слияния пропускаются, что приводит к потере или повреждению данных.

Условия:

  1. После завершения операции слияния одного набора исключений merge_callback() .
  2. Метаданные были обновлены в устройстве COW, которое отслеживает завершение слияния. (Это обновление для устройства COW полностью очищается.)

Результат: произошел сбой системы из-за того, что кэш устройства хранения недавнего слияния не был очищен.

См. следующее, чтобы реализовать решение:

Убедитесь в правильности конфигурации dm-verity.

В Android 11 и более поздних версиях устройства могут быть непреднамеренно настроены со следующими параметрами dm-verity:

  • CONFIG_DM_VERITY_AVB=y в ядре
  • Загрузчик настроен на использование любого режима проверки подлинности (например, 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 .

  1. Установите CONFIG_DM_VERITY_AVB=n в ядре
  2. Вместо этого настройте устройства для использования режима AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO .

Для получения дополнительной информации и практики обратитесь к документации Verity: Обработка ошибок dm-verity .

Пропустить истинную работу в ответ на ошибку ввода-вывода во время аварийного завершения работы системы

В Android 11 и более поздних версиях, если вызывается аварийное отключение системы (как в случае теплового отключения), устройство dm может быть активным, в то время как блочное устройство больше не может обрабатывать запросы ввода-вывода. В этом состоянии ошибки ввода-вывода, обработанные новыми запросами ввода-вывода dm или теми, которые уже находятся в процессе выполнения, могут привести к состоянию истинного повреждения, что является ошибочным суждением.

Чтобы пропустить истинную работу в ответ на ошибку ввода-вывода при завершении работы системы, используйте следующее:

CL 1847875 (пропускает верную работу в ответ на ошибку ввода-вывода во время завершения работы)

Убедитесь, что параметр DM_ANDROID_VERITY_AT_MOST_ONCE_DEFAULT_ENABLED отключен.

Устройства Android Go с ядром 4.19 или более ранней версии могут иметь DM_ANDROID_VERITY_AT_MOST_ONCE_DEFAULT_ENABLED=y в конфигурации ядра. Этот параметр несовместим с Virtual A/B и, как известно, вызывает редкие проблемы с повреждением страницы, когда оба включены вместе.

Для ядер 4.19 и более ранних отключите его, установив CONFIG_DM_ANDROID_VERITY_AT_MOST_ONCE_DEFAULT_ENABLED=n в конфигурации ядра.

Для ядер 5.4 и более поздних версий код был удален, а параметр конфигурации недоступен.