가상 A/B 구현 - 패치

다음 패치를 선택하여 다음과 같은 알려진 문제를 해결하세요.

사이드로드 시 할당 가능한 공간 정확히 확인

*2 * 합계(업데이트 그룹 크기)*보다 크기가 작은 super 파티션이 있는 가상 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를 방지하기 위해 소멸 시 대기 중인 작업이 취소됩니다.

다음 변경사항이 Android 11 소스 트리에 있는지 확인하여 병합 중에 update_engine에서 발생하는 SIGSEGV 비정상 종료 문제를 해결합니다.

  • CL 1439792(CL 1439372 전제 조건)
  • CL 1439372(CleanupPreviousUpdateAction: 소멸 시 대기 중인 작업 취소)
  • CL 1663460 (markSlotSuccessful이 늦게 제공될 경우의 잠재적 와일드 포인터 오류 수정)

OTA 업데이트 후 VAB의 올바르지 않은 슬롯 전환 수정

Android 11 이상에서 OTA 업데이트 후 기기의 슬롯 스위치를 동기화하지 못하는 경우 기기를 사용할 수 없게 될 수 있습니다. IBootControl HAL의 슬롯 전환 구현이 쓰기를 수행하는 경우 이러한 쓰기를 즉시 플러시해야 합니다. 쓰기가 플러시되지 않고, 병합을 시작했지만 하드웨어가 슬롯 전환 쓰기를 플러시할 수 있게 되기 전에 기기를 재부팅하면 기기가 이전 슬롯으로 돌아가고 부팅에 실패할 수 있습니다.

코드 솔루션의 예는 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 없이 모든 verity 모드(예: AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE)를 사용하도록 구성된 부트로더

이 기기 설정에서 verity 오류가 발생하면 vbmeta 파티션이 손상되고 비 A/B 기기는 작동하지 않게 렌더링됩니다. 마찬가지로 병합이 시작되면 A/B 기기도 작동하지 않을 수 있습니다. AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO verity 모드만 사용하세요.

  1. 커널에서 CONFIG_DM_VERITY_AVB=n을 설정합니다.
  2. 대신 AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO 모드를 사용하도록 기기를 구성합니다.

자세한 내용과 실습에 관해서는 verity 문서: dm-verity 오류 처리를 참고하세요.

긴급 시스템 종료 중 I/O 오류에 응답하여 verity 작업 건너뛰기

Android 11 이상에서는 긴급 시스템 종료가 호출되면(열 종료의 경우와 마찬가지로) dm 기기는 활성 상태일 수 있지만 블록 기기는 I/O 요청을 더 이상 처리할 수 없습니다. 이 상태에서 I/O 오류를 새 dm 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 이상에서는 코드가 삭제되고 구성 옵션을 사용할 수 없습니다.

병합된 파일이 올바르게 구성되었는지 확인

시스템 이미지와 공급업체 이미지를 따로 빌드한 다음 merge_target_files를 사용하여 병합하면 병합 프로세스 중에 가상 A/B 구성이 잘못 삭제될 수 있습니다. 병합된 타겟 파일에서 가상 A/B 구성이 올바른지 확인하려면 CL 2084183 패치(동적 파티션 정보에서 동일한 키/값 쌍 병합)를 적용합니다.

필수 구성요소 업데이트

Android 13부터 snapuserd가 공급업체 램디스크에서 일반 램디스크로 이동되었습니다. 기기가 Android 13으로 업그레이드되는 경우 공급업체 램디스크와 일반 램디스크에 모두 snapuserd의 사본이 포함될 수 있습니다. 이 경우에 가상 A/B에 snapuserd의 시스템 사본이 필요합니다. snapuserd의 올바른 사본이 배치되도록 하려면 CL 2031243(first_stage_ramdisk에 snapuserd 복사)을 적용합니다.