Вишневый выбор следующих исправлений для решения следующих известных проблем.
Правильно проверяйте выделяемое пространство при боковой загрузке
Неопубликованная загрузка полного пакета 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 и более поздних версиях, если устройство хранения имеет энергозависимый кэш обратной записи, при определенных условиях метаданные завершенного слияния пропускаются, что приводит к потере или повреждению данных.
Условия:
- После завершения операции слияния одного набора исключений
merge_callback()
. - Метаданные были обновлены в устройстве 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
.
- Установите
CONFIG_DM_VERITY_AVB=n
в ядре - Вместо этого настройте устройства для использования режима
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 и более поздних версий код был удален, а параметр конфигурации недоступен.