Android 10 supports dynamic partitions, a userspace partitioning system that can create, resize, and destroy partitions during over-the-air (OTA) updates.
This page describes how OTA clients resize dynamic partitions during an update for A/B devices that launched without dynamic partitions support and how OTA clients upgrade to Android 10.
Background
        During an update of an A/B device to support dynamic partitions, the
        GUID partition table (GPT) on the device is preserved, so there's no
        super partition on the device. Metadata is stored at
        system_a and system_b, but this can be
        customized by changing BOARD_SUPER_PARTITION_METADATA_DEVICE.
      
        In each of the block devices, there are two metadata slots. Only one
        metadata slot in each block device is used. For example, Metadata 0 at
        system_a and Metadata 1 at system_b
        correspond to partitions at the A and B slots, respectively. At
        runtime, it doesn't matter which slot is being updated.
      
        In this page, the metadata slots are called Metadata S
        (source) and Metadata T (target). Similarly, partitions are referred
        to as system_s, vendor_t, and so on.
      
For more information about build system configurations, see Upgrading devices.
For more information about how partitions belong to update groups, see Board configuration changes for new devices.
An example of metadata on a device is:
- Physical block device system_a- Metadata 0
              - Group foo_a- Logical (dynamic) partition system_a
- Logical (dynamic) partition
                      product_services_a
- Other partitions updated by Foo
 
- Logical (dynamic) partition 
 - Group bar_a- Logical (dynamic) partition vendor_a
- Logical (dynamic) partition
                      product_a
- Other partitions updated by Bar
 
- Logical (dynamic) partition 
 
- Group 
- Metadata 1 (not used)
 
- Metadata 0
              
- Physical block device system_b- Metadata 0 (not used)
- Metadata 1
              - Group foo_b
                  - Logical (dynamic) partition
                      system_b
- Logical (dynamic) partition
                      product_services_b
- Other partitions updated by Foo
 
- Logical (dynamic) partition
                      
- Group bar_b
                  - Logical (dynamic) partition
                      vendor_b
- Logical (dynamic) partition
                      product_b
- Other partitions updated by Bar
 
- Logical (dynamic) partition
                      
 
- Group foo_b
                  
 
        You can use the lpdump tool under
        system/extras/partition_tools to dump the metadata on
        your device. For example:
      
lpdump --slot 0 /dev/block/by-name/system_alpdump --slot 1 /dev/block/by-name/system_b
Retrofit an update
On devices running Android 9 and lower, the OTA client on the device doesn't support mapping dynamic partitions before the update. An additional set of patches is created so that mapping can be applied directly to the existing physical partitions.
        The OTA generator builds the final super.img file that
        contains the content of all dynamic partitions, then splits the image
        into multiple images matching the sizes of the physical block devices
        corresponding to system, vendor, and so on. These images are named
        super_system.img, super_vendor.img, and so on.
        The OTA client applies these images to the physical partitions, rather
        than applying the images for the logical (dynamic) partitions.
      
Because the OTA client doesn't know how to map dynamic partitions, all post-install steps are disabled automatically for these partitions when the update package is generated. See Configuring post-installation for more details.
The update flow is the same as in Android 9.
Before the update:
ro.boot.dynamic_partitions= ro.boot.dynamic_partitions_retrofit=
After the update:
ro.boot.dynamic_partitions=true ro.boot.dynamic_partitions_retrofit=true
Future updates after retrofit
After the retrofit update, the OTA client is updated to work with dynamic partitions. The extents for source partitions never span across target physical partitions.
Update flow using a regular update package
- Initialize the superpartition metadata.- 
                Construct new metadata M from Metadata S (source metadata).
                For example, if Metadata S uses [system_s,vendor_s,product_s] as block devices, then the new metadata M uses [system_t,vendor_t,product_t] as block devices. All groups and partitions are discarded in M.
- 
                Add target groups and partitions according to the
                dynamic_partition_metadatafield in the update manifest. The size of each partition can be found innew_partition_info.
- Write M to Metadata T.
- Map the added partitions on the device mapper as writable.
 
- 
                Construct new metadata M from Metadata S (source metadata).
                For example, if Metadata S uses [
- Apply the update on the block devices.
            - If necessary, map the source partitions on the device mapper as read only. This is necessary for sideloading because the source partitions aren't mapped prior to the update.
- Apply a full or delta update to all block devices at the target slot.
- Mount the partitions to run the post-install script, and then unmount the partitions.
 
- Unmap the target partitions.
Update flow using a retrofit update package
          If the retrofit update package is applied on a device that already
          enables dynamic partitions, the OTA client applies the split
          super.img file on block devices directly. The update
          flow is similar to a retrofit update. See
          Retrofitting an update
          for details.
        
For example, assume the following:
- Slot A is the active slot.
- 
            system_acontains the active metadata at slot 0.
- 
            system_a,vendor_a, andproduct_aare used as block devices.
          When the OTA client receives a retrofit update package, it applies
          super_system.img on physical system_b,
          super_vendor.img on physical vendor_b, and
          super_product.img on physical product_b.
          The physical block device system_b contains the correct
          metadata to map the logical system_b,
          vendor_b, and product_b at boot time.
        
Generate update packages
Incremental OTA
          When generating incremental OTAs for retrofit devices, the updates
          depend on whether or not the base build defines
          PRODUCT_USE_DYNAMIC_PARTITIONS and
          PRODUCT_RETROFIT_DYNAMIC_PARTITIONS.
        
- 
            If the base build doesn't define the variables, this is a
            retrofitting update. The update package contains the split
            super.imgfile and disables the post-install step.
- If the base build does define the variables, this is the same as a typical update with dynamic partitions. The update package contains the images for logical (dynamic) partitions. The post-install step can be enabled.
Full OTA
Two full OTA packages are generated for retrofit devices.
- 
            $(PRODUCT)-ota-retrofit-$(TAG).zipalways contains splitsuper.imgand disables the post-install step for retrofitting update.- 
                It's generated with an additional argument
                --retrofit_dynamic_partitionsto theota_from_target_filesscript.
- It can be applied to all builds.
 
- 
                It's generated with an additional argument
                
- 
            $(PRODUCT)-ota-$(TAG).zipcontains logical images for future updates.- Apply this only to builds with dynamic partitions enabled. See details below on enforcing this.
 
Reject nonretrofit update on old builds
Apply the regular full OTA package only to builds with dynamic partitions enabled. If the OTA server is configured incorrectly and pushes these packages to devices running Android 9 or lower, devices fail to boot. The OTA client on Android 9 and lower can't tell the difference between a retrofit OTA package and a regular full OTA package, so the client won't reject the full package.
To prevent the device from accepting the full OTA package, you can require a post-install step to check the existing device configuration. For example:
        device/device_name/dynamic_partitions/check_dynamic_partitions
      
#!/system/bin/sh DP_PROPERTY_NAME="ro.boot.dynamic_partitions" DP_RETROFIT_PROPERTY_NAME="ro.boot.dynamic_partitions_retrofit" DP_PROPERTY=$(getprop ${DP_PROPERTY_NAME}) DP_RETROFIT_PROPERTY=$(getprop ${DP_RETROFIT_PROPERTY_NAME}) if [ "${DP_PROPERTY}" != "true" ] || [ "${DP_RETROFIT_PROPERTY}" != "true" ] ; then echo "Error: applied non-retrofit update on build without dynamic" \ "partitions." echo "${DP_PROPERTY_NAME}=${DP_PROPERTY}" echo "${DP_RETROFIT_PROPERTY_NAME}=${DP_RETROFIT_PROPERTY}" exit 1 fi
        device/device_name/dynamic_partitions/Android.mk
      
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE:= check_dynamic_partitions LOCAL_MODULE_TAGS := optional LOCAL_MODULE_CLASS := EXECUTABLES LOCAL_SRC_FILES := check_dynamic_partitions LOCAL_PRODUCT_MODULE := true include $(BUILD_PREBUILT)
        device/device_name/device.mk
      
PRODUCT_PACKAGES += check_dynamic_partitions # OPTIONAL=false so that the error in check_dynamic_partitions will be # propagated to OTA client. AB_OTA_POSTINSTALL_CONFIG += \ RUN_POSTINSTALL_product=true \ POSTINSTALL_PATH_product=bin/check_dynamic_partitions \ FILESYSTEM_TYPE_product=ext4 \ POSTINSTALL_OPTIONAL_product=false \
        When the regular OTA package is applied on a device without dynamic
        partitions enabled, the OTA client runs
        check_dynamic_partitions as a post-install step and
        rejects the update.