동적 파티션 구현

동적 파티션 나누기는 Linux 커널의 dm 선형 기기 매퍼 모듈을 사용하여 구현됩니다. super 파티션에는 super 내에 있는 각 동적 파티션의 이름과 블록 범위가 나열된 메타데이터가 포함됩니다. 1단계 init에서 이 메타데이터는 파싱 및 검증되며 각 동적 파티션을 나타내는 가상 블록 기기가 생성됩니다.

OTA를 적용할 때는 동적 파티션이 필요에 따라 자동으로 생성되고 크기가 변경되며 삭제됩니다. A/B 기기의 경우 두 가지의 메타데이터 사본이 있으며, 변경사항이 대상 슬롯을 나타내는 사본에만 적용됩니다.

동적 파티션은 사용자 공간에 구현됩니다. 따라서 부트로더에 의해 요구되는 파티션을 동적으로 만들 수 없습니다. 예를 들어 boot, dtbovbmeta는 부트로더에 의해 판독되므로 물리적 파티션으로 유지되어야 합니다.

각 동적 파티션은 업데이트 그룹에 속할 수 있습니다. 이러한 그룹은 그룹의 파티션에서 소비할 수 있는 최대 공간을 제한합니다. 예를 들어 systemvendorsystemvendor의 총 크기를 제한하는 그룹에 속할 수 있습니다.

새 기기에 동적 파티션 구현

이 섹션에서는 Android 10 이상으로 출시되는 새로운 기기에 동적 파티션을 구현하는 방법에 관해 자세히 설명합니다. 기존 기기를 업데이트하는 방법은 Android 기기 업그레이드를 참고하세요.

파티션 변경사항

Android 10으로 출시되는 기기의 경우 super라는 파티션을 만듭니다. super 파티션은 내부적으로 A/B 슬롯을 처리하므로 A/B 기기에는 별도의 super_asuper_b 파티션이 필요 없습니다. 부트로더에 의해 사용되지 않는 모든 읽기 전용 AOSP 파티션은 동적이어야 하며 GPT(GUID 파티션 테이블)에서 제거해야 합니다. 공급업체별 파티션은 동적일 필요가 없으며 GPT에 삽입 가능합니다.

super의 크기를 예상하려면 GPT에서 삭제되고 있는 파티션의 크기를 추가합니다. A/B 기기의 경우 여기에 두 슬롯의 크기를 포함해야 합니다. 그림 1에는 동적 파티션으로 전환하기 전과 후의 파티션 테이블 예시가 나와 있습니다.

파티션 테이블 레이아웃
그림 1. 동적 파티션으로 전환 시의 새로운 물리적 파티션 테이블 레이아웃

지원되는 동적 파티션은 다음과 같습니다.

  • 시스템
  • 공급업체
  • 제품
  • 시스템 Ext
  • ODM

Android 10으로 출시되는 기기의 경우 명령어 sysprop ro.boot.super_partition이 비어 있도록 커널 명령줄 옵션 androidboot.super_partition이 비어 있어야 합니다.

파티션 정렬

super 파티션이 제대로 정렬되지 않으면 기기 매퍼 모듈의 작동 효율이 떨어질 수 있습니다. super 파티션은 블록 레이어에 의해 결정된 최소 I/O 요청 크기에 맞게 정렬되어야 합니다. 기본적으로 빌드 시스템은 (super 파티션 이미지를 생성하는 lpmake를 통해) 1MiB 정렬이 모든 동적 파티션에 충분하다고 가정합니다. 하지만 공급업체는 super 파티션이 제대로 정렬되었는지 확인해야 합니다.

sysfs를 검사하여 블록 기기의 최소 요청 크기를 확인할 수 있습니다. 예:

# ls -l /dev/block/by-name/super
lrwxrwxrwx 1 root root 16 1970-04-05 01:41 /dev/block/by-name/super -> /dev/block/sda17
# cat /sys/block/sda/queue/minimum_io_size
786432

super 파티션의 정렬도 비슷한 방식으로 확인할 수 있습니다.

# cat /sys/block/sda/sda17/alignment_offset

정렬 오프셋은 0이어야 합니다.

기기 구성 변경사항

동적 파티션 나누기를 사용 설정하려면 device.mk에 다음 플래그를 추가합니다.

PRODUCT_USE_DYNAMIC_PARTITIONS := true

보드 구성 변경사항

super 파티션의 크기를 설정해야 합니다.

BOARD_SUPER_PARTITION_SIZE := <size-in-bytes>

A/B 기기에서는 동적 파티션 이미지의 총 크기가 super 파티션 크기의 절반을 초과할 경우 빌드 시스템에서 오류를 생성합니다.

동적 파티션 목록은 다음과 같이 구성할 수 있습니다. 업데이트 그룹을 사용하는 기기의 경우 그룹을 BOARD_SUPER_PARTITION_GROUPS 변수에 나열합니다. 그런 다음 각 그룹 이름에는 BOARD_group_SIZEBOARD_group_PARTITION_LIST 변수가 포함됩니다. A/B 기기의 경우 그룹의 최대 크기가 한 개의 슬롯만 덮어야 합니다. 이는 그룹 이름이 내부적으로 슬롯 접미사 형식을 취하기 때문입니다.

다음은 모든 파티션을 example_dynamic_partitions라는 그룹에 배치하는 기기의 예입니다.

BOARD_SUPER_PARTITION_GROUPS := example_dynamic_partitions
BOARD_EXAMPLE_DYNAMIC_PARTITIONS_SIZE := 6442450944
BOARD_EXAMPLE_DYNAMIC_PARTITIONS_PARTITION_LIST := system vendor product

다음은 시스템 및 제품 서비스를 group_foo에, vendor, product, odmgroup_bar에 삽입하는 기기의 예입니다.

BOARD_SUPER_PARTITION_GROUPS := group_foo group_bar
BOARD_GROUP_FOO_SIZE := 4831838208
BOARD_GROUP_FOO_PARTITION_LIST := system product_services
BOARD_GROUP_BAR_SIZE := 1610612736
BOARD_GROUP_BAR_PARTITION_LIST := vendor product odm
  • 가상 A/B 출시 기기의 경우 모든 그룹의 최대 크기를 합한 값은 다음 값을 넘지 않아야 합니다.
    BOARD_SUPER_PARTITION_SIZE - 오버헤드
    가상 A/B 구현을 확인하세요.
  • A/B 출시 기기의 경우 모든 그룹의 최대 크기를 합산한 값이 다음과 같아야 합니다.
    BOARD_SUPER_PARTITION_SIZE / 2 - 오버헤드
  • A/B 외의 기기 및 재구성된 A/B 기기의 경우 모든 그룹의 최대 크기를 합산한 값이 다음과 같아야 합니다.
    BOARD_SUPER_PARTITION_SIZE - 오버헤드
  • 빌드 시에는 업데이트 그룹 내 각 파티션 이미지의 크기를 합산한 값이 그룹의 최대 크기를 초과하면 안 됩니다.
  • 메타데이터, 정렬 등을 감안하려면 계산에 오버헤드가 필요합니다. 적당한 오버헤드는 4MiB이지만 기기의 필요에 따라 더 큰 오버헤드를 선택할 수도 있습니다.

동적 파티션 크기

동적 파티션 이전에는 향후 업데이트를 위한 공간이 충분하도록 파티션 크기가 과할당되었습니다. 실제 크기는 그대로 선택되었고, 대부분의 읽기 전용 파티션은 파일 시스템에 어느 정도의 여유 공간이 있었습니다. 동적 파티션에서는 이러한 여유 공간을 사용할 수 없으며 OTA 도중 파티션을 확장하는 데 사용할 수 있습니다. 파티션이 공간을 낭비하지 않도록 하고 가능한 최소 크기에 할당되도록 하는 것이 중요합니다.

읽기 전용 ext4 이미지의 경우 빌드 시스템에서 자동으로 최소 크기를 할당합니다(하드코딩된 파티션 크기가 지정되지 않은 경우). 빌드 시스템은 파일 시스템의 미사용 공간이 최소화되도록 이미지 크기를 맞춥니다. 그러면 기기에서 OTA에 사용 가능한 공간을 낭비하지 않습니다.

또한 블록 수준 중복 삭제를 통해 ext4 이미지를 추가 압축할 수 있습니다. 이를 사용 설정하려면 다음 구성을 사용하세요.

BOARD_EXT4_SHARE_DUP_BLOCKS := true

파티션 최소 크기의 자동 할당을 원하지 않는 경우 두 가지 방법으로 파티션 크기를 제어할 수 있습니다. BOARD_partitionIMAGE_PARTITION_RESERVED_SIZE를 사용하여 최소 여유 공간을 지정하거나 BOARD_partitionIMAGE_PARTITION_SIZE를 지정하여 동적 파티션을 특정 크기로 강제 적용할 수 있습니다. 필요한 경우가 아니라면 두 방식 모두 권장되지 않습니다.

예:

BOARD_PRODUCTIMAGE_PARTITION_RESERVED_SIZE := 52428800

이렇게 하면 product.img의 파일 시스템에 50MiB의 미사용 공간이 확보됩니다.

system-as-root 변경사항

Android 10으로 출시된 기기는 system-as-root를 사용하면 안 됩니다.

동적 파티션을 포함하는 기기는 동적 파티션과 함께 출시되거나 동적 파티션이 새로 추가되는지 여부와 상관없이 system-as-root를 사용하면 안 됩니다. Linux 커널은 super 파티션을 해석할 수 없으므로 system 자체를 마운트할 수 없습니다. system은 이제 램디스크에 있는 1단계 init에 의해 마운트됩니다.

BOARD_BUILD_SYSTEM_ROOT_IMAGE 설정 안 함 Android 10에서 BOARD_BUILD_SYSTEM_ROOT_IMAGE 플래그는 시스템이 커널에서 마운트되는지 또는 램디스크에서 1단계 init를 통해 마운트되는지 구분하는 데만 사용됩니다.

BOARD_BUILD_SYSTEM_ROOT_IMAGEtrue로 설정하면 PRODUCT_USE_DYNAMIC_PARTITIONStrue일 때 빌드 오류가 발생합니다.

BOARD_USES_RECOVERY_AS_BOOT를 true로 설정하면 복구 이미지가 복구의 램디스크를 포함하는 boot.img로 빌드됩니다. 이전에는 bootloader가 skip_initramfs 커널 명령줄 매개변수를 사용하여 부팅 모드를 결정했습니다. Android 10 기기의 경우 부트로더는 skip_initramfs를 커널 명령줄에 전달하면 안 됩니다. 대신 부트로더는 androidboot.force_normal_boot=1을 전달하여 복구를 건너뛰고 일반 Android를 부팅해야 합니다. Android 12 이상으로 출시되는 기기는 bootconfig를 사용하여 androidboot.force_normal_boot=1을 전달해야 합니다.

AVB 구성 변경사항

Android 자체 검사 부팅 2.0을 사용할 때는 기기에서 연계된 파티션 설명자를 사용하지 않는 경우 변경할 필요가 없습니다. 연계된 파티션을 사용 중이지만 인증된 파티션 중 하나가 동적인 경우에는 변경이 필요합니다.

다음은 systemvendor 파티션에 대해 vbmeta를 연결하는 기기의 구성 예시입니다.

BOARD_AVB_SYSTEM_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem
BOARD_AVB_SYSTEM_ALGORITHM := SHA256_RSA2048
BOARD_AVB_SYSTEM_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)
BOARD_AVB_SYSTEM_ROLLBACK_INDEX_LOCATION := 1

BOARD_AVB_VENDOR_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem
BOARD_AVB_VENDOR_ALGORITHM := SHA256_RSA2048
BOARD_AVB_VENDOR_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)
BOARD_AVB_VENDOR_ROLLBACK_INDEX_LOCATION := 1

이 구성에서는 부트로더가 systemvendor 파티션 끝에서 vbmeta 바닥글을 찾을 수 있을 것으로 예상합니다. 이러한 파티션은 더 이상 부트로더에 표시되지 않으므로(super에 상주함) 두 가지를 변경해야 합니다.

  • vbmeta_systemvbmeta_vendor 파티션을 기기의 파티션 테이블에 추가합니다. A/B 기기의 경우 vbmeta_system_a, vbmeta_system_b, vbmeta_vendor_avbmeta_vendor_b를 추가합니다. 이러한 파티션을 한 개 이상 추가하는 경우 파티션은 vbmeta 파티션의 크기와 동일해야 합니다.
  • VBMETA_를 추가하여 구성 플래그 이름을 바꾸고 다음으로 연계 확장되는 파티션을 지정합니다.
    BOARD_AVB_VBMETA_SYSTEM := system
    BOARD_AVB_VBMETA_SYSTEM_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem
    BOARD_AVB_VBMETA_SYSTEM_ALGORITHM := SHA256_RSA2048
    BOARD_AVB_VBMETA_SYSTEM_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)
    BOARD_AVB_VBMETA_SYSTEM_ROLLBACK_INDEX_LOCATION := 1
    
    BOARD_AVB_VBMETA_VENDOR := vendor
    BOARD_AVB_VBMETA_VENDOR_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem
    BOARD_AVB_VBMETA_VENDOR_ALGORITHM := SHA256_RSA2048
    BOARD_AVB_VBMETA_VENDOR_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)
    BOARD_AVB_VBMETA_VENDOR_ROLLBACK_INDEX_LOCATION := 1
    

기기에서는 이러한 파티션을 하나만 사용하거나 둘 다 사용하거나 아예 사용하지 않을 수 있습니다. 논리 파티션으로 연계하는 경우에만 변경이 필요합니다.

AVB 부트로더 변경사항

부트로더가 libavb를 삽입한 경우 다음과 같은 패치를 포함합니다.

연계 파티션을 사용 중인 경우 다음 패치를 포함합니다.

  • 49936b4c0109411fdd38bd4ba3a32a01c40439a9 — "libavb: 파티션 시작 부분에서 vbmeta blob 지원"

커널 명령줄 변경사항

새 매개변수인 androidboot.boot_devices를 커널 명령줄에 추가해야 합니다. init에서 /dev/block/by-name 심볼릭 링크를 사용 설정하는 데 사용됩니다. 이는 ueventd에서 만든 기본 이름별 심볼릭 링크(/dev/block/platform/device-path/by-name/partition-name)로 연결되는 기기 경로 구성요소여야 합니다. Android 12 이상으로 출시되는 기기는 bootconfig를 사용하여 androidboot.boot_devicesinit에 전달해야 합니다.

예를 들어 super 파티션 이름별 심볼릭 링크가 /dev/block/platform/soc/100000.ufshc/by-name/super면 다음과 같이 BoardConfig.mk 파일에 명령줄 매개변수를 추가할 수 있습니다.

BOARD_KERNEL_CMDLINE += androidboot.boot_devices=soc/100000.ufshc
다음과 같이 BoardConfig.mk 파일에 bootconfig 매개변수를 추가할 수 있습니다.
BOARD_BOOTCONFIG += androidboot.boot_devices=soc/100000.ufshc

fstab 변경사항

기기 트리 및 기기 트리 오버레이에는 fstab 항목을 추가하면 안 됩니다. 램디스크의 일부가 될 fstab 파일을 사용하세요.

논리 파티션의 fstab 파일을 변경해야 합니다.

  • fs_mgr 플래그 필드에는 파티션이 1단계에서 마운트되어야 함을 나타내는 Android 10에 도입된 logical 플래그와 first_stage_mount 플래그가 포함되어야 합니다.
  • 파티션은 avb=vbmeta partition namefs_mgr 플래그로 지정한 후 지정된 vbmeta 파티션은 마운트를 시도하기 전에 1단계 init에 의해 초기화됩니다. 기기에서 사용할 수 있습니다.
  • dev 필드는 파티션 이름이어야 합니다.

다음 fstab 항목은 위의 규칙에 따라 시스템, 공급업체 및 제품을 논리 파티션으로 설정합니다.

#<dev>  <mnt_point> <type>  <mnt_flags options> <fs_mgr_flags>
system   /system     ext4    ro,barrier=1        wait,slotselect,avb=vbmeta,logical,first_stage_mount
vendor   /vendor     ext4    ro,barrier=1        wait,slotselect,avb,logical,first_stage_mount
product  /product    ext4    ro,barrier=1        wait,slotselect,avb,logical,first_stage_mount

fstab 파일을 1단계 램디스크에 복사합니다.

SELinux 변경사항

super 파티션 블록 기기는 super_block_device 라벨로 표시되어야 합니다. 예를 들어 슈퍼 파티션 이름별 심볼릭 링크가 /dev/block/platform/soc/100000.ufshc/by-name/super이면 file_contexts에 다음 줄을 추가합니다.

/dev/block/platform/soc/10000\.ufshc/by-name/super   u:object_r:super_block_device:s0

fastbootd

동적 파티션을 이해할 수 없는 부트로더(또는 사용자 공간 외 플래싱 도구)는 동적 파티션을 플래시할 수 없습니다. 이를 해결하려면 기기에 fastbootd라 불리는 fastboot 프로토콜의 사용자 공간 구현을 사용해야 합니다.

자세한 fastbootd 구현 방법은 Fastboot를 사용자 공간으로 이동을 참고하세요.

adb를 다시 마운트

eng 또는 userdebug 빌드를 사용 중인 개발자의 경우 adb remount가 빠른 반복에 매우 유용합니다. 동적 파티션은 각 파일 시스템 내에 더 이상 여유 공간이 없기 때문에 adb remount에 문제가 발생합니다. 이를 해결하려면 기기에서 overlayfs를 사용 설정할 수 있어야 합니다. super 파티션 내에 여유 공간만 있으면 adb remount는 자동으로 임시 동적 파티션을 만들고 overlayfs를 쓰기에 사용합니다. 임시 파티션의 이름은 scratch이므로 다른 파티션에 이 이름을 사용하지 마세요.

overlayfs를 사용 설정하는 자세한 방법은 AOSP에서 overlayfs README를 참고하세요.

Android 기기 업그레이드

기기를 Android 10으로 업그레이드하고 OTA에 동적 파티션 지원을 포함하고 싶은 경우에는 내장된 파티션 테이블을 변경할 필요가 없습니다. 몇몇 추가적인 구성이 필요합니다.

기기 구성 변경사항

동적 파티션 나누기를 새로 추가하려면 다음 플래그를 device.mk에 추가합니다.

PRODUCT_USE_DYNAMIC_PARTITIONS := true
PRODUCT_RETROFIT_DYNAMIC_PARTITIONS := true

보드 구성 변경사항

다음과 같은 보드 변수를 설정해야 합니다.

  • 동적 파티션 확장을 저장하는 데 사용된 블록 기기 목록에 BOARD_SUPER_PARTITION_BLOCK_DEVICES를 설정합니다. 이는 기기에 있는 기존 물리 파티션의 이름 목록입니다.
  • BOARD_SUPER_PARTITION_partition_DEVICE_SIZE를 각각 BOARD_SUPER_PARTITION_BLOCK_DEVICES에 있는 각 블록 기기의 크기로 설정합니다. 이는 기기에 있는 기존 물리 파티션의 크기 목록입니다. 일반적으로 기존 보드 구성에서는 BOARD_partitionIMAGE_PARTITION_SIZE입니다.
  • BOARD_SUPER_PARTITION_BLOCK_DEVICES의 모든 파티션에 대해 기존 BOARD_partitionIMAGE_PARTITION_SIZE를 설정 해제합니다.
  • BOARD_SUPER_PARTITION_SIZEBOARD_SUPER_PARTITION_partition_DEVICE_SIZE의 합계로 설정합니다.
  • BOARD_SUPER_PARTITION_METADATA_DEVICE를 동적 파티션 메타데이터가 저장된 블록 기기에 설정합니다. BOARD_SUPER_PARTITION_BLOCK_DEVICES 중 하나여야 합니다. 일반적으로 system으로 설정됩니다.
  • BOARD_SUPER_PARTITION_GROUPS, BOARD_group_SIZE, BOARD_group_PARTITION_LIST를 각각 설정합니다. 자세한 내용은 새 기기의 보드 구성 변경사항 을 참조하세요.

예를 들어 기기에 이미 시스템과 공급업체 파티션이 있고 이를 업데이트 중에 동적 파티션으로 전환하고 새 제품 파티션을 추가하고 싶은 경우에는 이를 보드 구성으로 설정합니다.

BOARD_SUPER_PARTITION_BLOCK_DEVICES := system vendor
BOARD_SUPER_PARTITION_METADATA_DEVICE := system

# Rename BOARD_SYSTEMIMAGE_PARTITION_SIZE to BOARD_SUPER_PARTITION_SYSTEM_DEVICE_SIZE.
BOARD_SUPER_PARTITION_SYSTEM_DEVICE_SIZE := <size-in-bytes>

# Rename BOARD_VENDORIMAGE_PARTITION_SIZE to BOARD_SUPER_PARTITION_VENDOR_DEVICE_SIZE
BOARD_SUPER_PARTITION_VENDOR_DEVICE_SIZE := <size-in-bytes>

# This is BOARD_SUPER_PARTITION_SYSTEM_DEVICE_SIZE + BOARD_SUPER_PARTITION_VENDOR_DEVICE_SIZE
BOARD_SUPER_PARTITION_SIZE := <size-in-bytes>

# Configuration for dynamic partitions. For example:
BOARD_SUPER_PARTITION_GROUPS := group_foo
BOARD_GROUP_FOO_SIZE := <size-in-bytes>
BOARD_GROUP_FOO_PARTITION_LIST := system vendor product

SELinux 변경사항

super 파티션 블록 기기는 속성 super_block_device_type로 표시해야 합니다. 예를 들어 기기에 이미 systemvendor 파티션이 있는 경우 이를 파티션 파티션으로 사용하여 동적 파티션의 공간을 저장하는 것이 좋으며, 이름별 심볼릭 링크는 {로 표시됩니다 101} system_block_device:

/dev/block/platform/soc/10000\.ufshc/by-name/system   u:object_r:system_block_device:s0
/dev/block/platform/soc/10000\.ufshc/by-name/vendor   u:object_r:system_block_device:s0

그런 다음 device.te에 다음 줄을 추가합니다.

typeattribute system_block_device super_block_device_type;

다른 구성은 새 기기에 동적 파티션 구현을 참고하세요.

재구성 업데이트에 관한 자세한 내용은 동적 파티션이 없는 A/B 기기의 OTA 를 참고하세요.

공장 출고 시 이미지

동적 파티션 지원이 포함된 기기 출시의 경우 사용자 fastboot를 사용하여 공장 출고 시 이미지를 플래시하지 않는 것이 좋습니다. 이는 사용자 공간에 대한 부팅이 다른 플래싱 메소드보다 느리기 때문입니다.

이를 해결하기 위해 make dist는 이제 super 파티션에 직접 플래시할 수 있는 추가 super.img 이미지를 빌드합니다. 이 경우 super 파티션 메타데이터 외에도 system.imgvendor.img 등이 포함된 논리 파티션의 콘텐츠가 자동으로 포함됩니다. 이 이미지는 추가적인 도구나 fastbootd를 사용하여 super 파티션에 직접 플래싱할 수 있습니다. 빌드 후에는 super.img${ANDROID_PRODUCT_OUT}에 배치됩니다.

동적 파티션으로 출시되는 A/B 기기의 경우 super.img에 A 슬롯의 이미지가 포함됩니다. super 이미지를 직접 플래시한 후에는 기기를 재부팅하기 전에 슬롯 A를 부팅 가능으로 표시합니다.

재구성 기기의 경우 make dist는 상응하는 물리적 파티션에 직접 플래시할 수 있는 super_*.img 이미지 세트를 빌드합니다. 예를 들어 BOARD_SUPER_PARTITION_BLOCK_DEVICES가 시스템 공급업체이면 make distsuper_system.imgsuper_vendor.img를 빌드합니다. 이러한 이미지는 target_files.zip의 OTA 폴더에 배치됩니다.

기기 매퍼 저장 기기 조정

동적 파티션 나누기는 여러 비확정 기기 매퍼 객체를 수용합니다. 이러한 인스턴스들이 예상대로 인스턴스화되지 않을 수도 있으므로 모든 마운트를 추적하고 연결된 모든 파티션의 Android 속성을 기본 저장소 기기로 업데이트해야 합니다.

init 내부의 메커니즘은 마운트를 추적하고 Android 속성을 비동기식으로 업데이트합니다. 이 기간이 걸리는 시간은 특정 기간에 속하지 않으므로, 모든 on property 트리거가 응답할 수 있을 만큼 충분한 시간을 제공해야 합니다. 속성은 dev.mnt.blk.<partition>이며, 여기서 <partition>root, system, data 또는 vendor입니다. 다음 예시와 같이 각 속성은 기본 스토리지 기기 이름과 연결됩니다.

taimen:/ % getprop | grep dev.mnt.blk
[dev.mnt.blk.data]: [sda]
[dev.mnt.blk.firmware]: [sde]
[dev.mnt.blk.metadata]: [sde]
[dev.mnt.blk.persist]: [sda]
[dev.mnt.blk.root]: [dm-0]
[dev.mnt.blk.vendor]: [dm-1]

blueline:/ $ getprop | grep dev.mnt.blk
[dev.mnt.blk.data]: [dm-4]
[dev.mnt.blk.metadata]: [sda]
[dev.mnt.blk.mnt.scratch]: [sda]
[dev.mnt.blk.mnt.vendor.persist]: [sdf]
[dev.mnt.blk.product]: [dm-2]
[dev.mnt.blk.root]: [dm-0]
[dev.mnt.blk.system_ext]: [dm-3]
[dev.mnt.blk.vendor]: [dm-1]
[dev.mnt.blk.vendor.firmware_mnt]: [sda]

init.rc 언어를 사용하면 Android 속성을 규칙의 일부로 확장할 수 있으며 다음과 같이 명령어를 사용해 저장소 기기를 조정할 수 있습니다.

write /sys/block/${dev.mnt.blk.root}/queue/read_ahead_kb 128
write /sys/block/${dev.mnt.blk.data}/queue/read_ahead_kb 128

2단계 init에서 명령어 처리가 시작되면 epoll loop이 활성화되고 값 업데이트가 시작됩니다. 그러나 속성 트리거가 init까지 지연되지 않으므로 초기 부팅 단계에서 root, system 또는 vendor init.rc 데몬이 early-fs에서 재정의될 수 있을 때까지 커널 기본 read_ahead_kb이 충분할 것으로 예상됩니다 (다양한 데몬과 시설이 시작될 때). 따라서 on property 기능을 sys.read_ahead_kb와 같은 init.rc 제어 속성과 함께 사용하여 작업 시점을 처리하고 경합 상태를 방지하는 것이 좋습니다. 을 사용합니다.

on property:dev.mnt.blk.root=* && property:sys.read_ahead_kb=*
    write /sys/block/${dev.mnt.blk.root}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048}

on property:dev.mnt.blk.system=* && property:sys.read_ahead_kb=*
    write /sys/block/${dev.mnt.blk.system}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048}

on property:dev.mnt.blk.vendor=* && property:sys.read_ahead_kb=*
    write /sys/block/${dev.mnt.blk.vendor}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048}

on property:dev.mnt.blk.product=* && property:sys.read_ahead_kb=*
    write /sys/block/${dev.mnt.blk.system_ext}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048}

on property:dev.mnt.blk.oem=* && property:sys.read_ahead_kb=*
    write /sys/block/${dev.mnt.blk.oem}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048}

on property:dev.mnt.blk.data=* && property:sys.read_ahead_kb=*
    write /sys/block/${dev.mnt.blk.data}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048}

on early-fs:
    setprop sys.read_ahead_kb ${ro.read_ahead_kb.boot:-2048}

on property:sys.boot_completed=1
   setprop sys.read_ahead_kb ${ro.read_ahead_kb.bootcomplete:-128}