가상 A/B 구현 - 패치

다음 패치를 선택하여 다음 알려진 문제를 해결하십시오.

사이드로딩할 때 할당 가능한 공간을 올바르게 확인하십시오.

*2 * sum(업데이트 그룹 크기)*보다 작은 크기의 슈퍼 파티션이 있는 가상 A/B 장치에서 전체 OTA 패키지를 테스트용 로드하면 복구 로그 /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 은 폐기 시 보류 중인 작업을 취소합니다. 메시지 루프에서 보류 중인 작업의 작업 ID를 추적하는 변수를 유지 관리합니다. 파괴 시 segfault를 피하기 위해 보류 중인 작업이 취소됩니다.

병합하는 동안 update_engine 에서 SIGSEGV 충돌을 수정하려면 Android 11 소스 트리에 다음 변경 사항이 있는지 확인하세요.

  • 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_engineScheduleWaitMarkBootSuccessful()WaitForMergeOrSchedule() 을 호출합니다. 병합 프로세스가 시작됩니다. 그러나 장치가 이전 슬롯으로 재부팅됩니다. 병합이 이미 시작되었기 때문에 장치가 부팅되지 않고 작동하지 않게 됩니다.

소스 트리에 다음 변경 사항을 추가합니다. CL 1664859는 선택 사항입니다.

  • CL 1439792 (CL 1439372의 전제 조건).
  • CL 1439372 ( CleanupPreviousUpdateAction : 폐기 시 보류 중인 작업 취소)
  • CL 1663460 ( markSlotSuccessful 이 늦게 올 때 잠재적인 와일드 포인터 오류 수정)
  • CL 1664859 (선택 사항 - CleanupPreviousUpdateAction 에 대한 unittest 추가)

건너뛴 메타데이터로 인한 데이터 손실 또는 손상 방지

Android 11 이상에서 저장 장치에 휘발성 쓰기 되돌림 캐시가 있는 경우 특정 조건에서 완료된 병합의 메타데이터를 건너뛰어 데이터 손실 또는 손상이 발생합니다.

정황:

  1. 한 세트의 예외에 대한 병합 작업을 완료한 후 merge_callback() 이 호출되었습니다.
  2. 병합 완료를 추적하는 COW 장치에서 메타데이터가 업데이트되었습니다. (COW 장치에 대한 이 업데이트는 깔끔하게 플러시됩니다.)

결과: 최근 병합의 저장 장치 캐시가 플러시되지 않아 시스템이 충돌했습니다.

해결 방법을 구현하려면 다음을 참조하세요.

올바른 dm-verity 구성 확인

Android 11 이상에서는 다음 dm-verity 옵션을 사용하여 기기를 실수로 구성할 수 있습니다.

  • 커널의 CONFIG_DM_VERITY_AVB=y
  • AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO 없이 모든 검증 모드(예: AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE )를 사용하도록 구성된 부트로더입니다.

이 장치 구성을 사용하면 모든 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 모드를 사용하도록 장치를 구성하십시오.

더 많은 정보를 원하고 실무상 verity 문서를 참조하십시오. Handling dm-verity Errors .

긴급 시스템 종료 시 I/O 오류 발생 시 Verity 작업 건너뛰기

Android 11 이상에서 긴급 시스템 종료가 호출되면(열적 종료의 경우와 같이) 블록 장치가 더 이상 I/O 요청을 처리할 수 없는 동안 dm 장치는 활성 상태일 수 있습니다. 이 상태에서 새 dm I/O 요청 또는 이미 진행 중인 요청에 의해 처리된 I/O 오류는 오판인 verity 손상 상태로 이어질 수 있습니다.

시스템이 종료될 때 I/O 오류에 대한 응답으로 verity 작업을 건너뛰려면 다음을 사용합니다.

CL 1847875 (종료 중 I/O 오류에 대한 응답으로 verity 작업 건너뛰기)

DM_ANDROID_VERITY_AT_MOST_ONCE_DEFAULT_ENABLED가 꺼져 있는지 확인

4.19 커널 이하를 실행하는 Android Go 기기는 커널 구성에 DM_ANDROID_VERITY_AT_MOST_ONCE_DEFAULT_ENABLED=y 가 있을 수 있습니다. 이 설정은 가상 A/B와 호환되지 않으며 두 가지를 함께 사용하는 경우 드문 페이지 손상 문제를 일으키는 것으로 알려져 있습니다.

커널 4.19 및 이전 버전의 경우 커널 구성에서 CONFIG_DM_ANDROID_VERITY_AT_MOST_ONCE_DEFAULT_ENABLED=n 을 설정하여 비활성화합니다.

커널 5.4 이상의 경우 코드가 제거되었으며 구성 옵션을 사용할 수 없습니다.