Dynamic Partitions: allow partition resizing 27/305427/5
authorJacek Kryszyn <j.kryszyn@samsung.com>
Wed, 31 Jan 2024 14:34:03 +0000 (15:34 +0100)
committerJacek Kryszyn <j.kryszyn@samsung.com>
Mon, 12 Feb 2024 14:53:55 +0000 (15:53 +0100)
This patch modifies scripts launched during upgrade/partition
cloning by allowing modification of metadata stored on a super
partition in order to resize dynamic partitions.

Change-Id: I338f383d34553f04429c77f85c0720f8c992c94e

scripts/clone_partitions/clone_partitions.sh
scripts/upgrade-support/upgrade-common.inc
scripts/upgrade-support/upgrade-partial.sh
scripts/upgrade-support/upgrade-trigger.sh

index 167394d..e122b99 100644 (file)
@@ -41,10 +41,12 @@ do_clone() {
        load_background_copy_list
        if background_copy; then
                device_board_set_partition_ab_cloned
+               unmap_next_dynamic_partitions
                log "[Info] Partitions have been cloned"
                return 0
        else
                critical_log "[Error] Partitions have not been cloned"
+               unmap_next_dynamic_partitions
                return 1
        fi
 }
index 98cad56..f429e4c 100644 (file)
@@ -9,6 +9,10 @@ DO_RW_UPDATE_FILE="$FOTA_UPDATE_PREFIX/opt/.do_rw_update"
 TRUE=0
 FALSE=1
 SUPERFS=""
+ROOTFS_CURR_SIZE=0
+ROOTFS_NEXT_SIZE=0
+HAL_CURR_SIZE=0
+HAL_NEXT_SIZE=0
 
 if [ -z $BLKID_PRINT ]; then
        BLKID_PRINT="/usr/bin/blkid-print"
@@ -116,10 +120,25 @@ check_ab_partition_scheme() {
        fi
 }
 
+unmap_next_dynamic_partitions () {
+       if [ -n "$SUPERFS" ]; then
+               local MAPPED_DEVICES=""
+               MAPPED_DEVICES=$(dmsetup ls)
+
+               if [[ $MAPPED_DEVICES = *"rootfs_${NEXT_AB}"* ]]; then
+                       dmsetup remove rootfs_"${NEXT_AB}"
+               fi
+
+               if [[ $MAPPED_DEVICES = *"hal_${NEXT_AB}"* ]]; then
+                       dmsetup remove hal_"${NEXT_AB}"
+               fi
+       fi
+}
+
 map_from_super() {
     local part_name="$1"
     local part_table="$2"
-    echo "$part_table" | /usr/sbin/dmsetup create "$part_name" &>/dev/null
+    echo -e "$part_table" | /usr/sbin/dmsetup create "$part_name" &>/dev/null
     if [ $? = 0 ]; then
         echo "/dev/mapper/$part_name"
         return 0
@@ -134,20 +153,34 @@ check_if_super() {
                local MAPPED_DEVICES=""
                MAPPED_DEVICES=$(dmsetup ls)
 
-               # if dynamic partitions are used, only partitions from the current
-               # slot are mapped on boot. dmsetup will list only *_{CURRENT_AB}
-               # partitions. This check allows to tell which partitions are mapped
-               # and which have to be mapped in order to perform upgrade.
+               # only partitions from CURRENT_AB slot are mapped on boot in case of
+               # Tizen with dynamic partitions. dmsetup ls invoked after boot will
+               # list only those partitions. In this case map NEXT_AB partitions to
+               # allow upgrade/copying in background. Do not map again otherwise.
                if [[ $MAPPED_DEVICES != *"rootfs_${NEXT_AB}"* ]]; then
+                       # CONFIG_FILE exists only during upgrade. In this case use it to
+                       # modify metadata of NEXT_AB slot partitions on super. Otherwise we
+                       # are copying partitions in background. In this case modify size of
+                       # NEXT_AB partitions to match size of CURRENT_AB partitions.
+                       if [ -f "${FOTA_DIR}/${CONFIG_FILE}" ]; then
+                               /bin/resize-dynparts "${SUPERFS}" "${NEXT_AB}" "${FOTA_DIR}/${CONFIG_FILE}"
+                       else
+                               /bin/resize-dynparts "${SUPERFS}" "${NEXT_AB}"
+                       fi
+
                        PARSE_DYNPARTS=`/usr/sbin/parse-dynparts "$SUPERFS" --list-tables`
 
                        while read -r part_name part_table; do
                                if [ "$part_name" = "rootfs_${NEXT_AB}" ]; then
                                        map_from_super "$part_name" "$part_table"
+                                       ROOTFS_CURR_SIZE="$(blockdev --getsize64 /dev/mapper/rootfs_${CURRENT_AB})"
+                                       ROOTFS_NEXT_SIZE="$(blockdev --getsize64 /dev/mapper/rootfs_${NEXT_AB})"
                                fi
 
                                if [ "$part_name" = "hal_${NEXT_AB}" ]; then
                                        map_from_super "$part_name" "$part_table"
+                                       HAL_CURR_SIZE="$(blockdev --getsize64 /dev/mapper/hal_${CURRENT_AB})"
+                                       HAL_NEXT_SIZE="$(blockdev --getsize64 /dev/mapper/hal_${NEXT_AB})"
                                fi
                        done <<< "$PARSE_DYNPARTS"
                fi
@@ -179,6 +212,20 @@ background_copy() {
        start_duration=$(date +%s)
        for partition_name in ${PARTITION_LIST}; do
                if { [ "$partition_name" == "rootfs" ] || [ "$partition_name" == "hal" ]; } && [ -n "$SUPERFS" ]; then
+                       if { [ "$partition_name" == "rootfs" ] && (( ROOTFS_CURR_SIZE == 0 )); } || \
+                               { [ "$partition_name" == "hal" ] && (( HAL_CURR_SIZE == 0 )); }; then
+                               flog "[Error] Unable to find: $partition_name current partition on $EMMC_DEVICE device on $CURRENT_AB slot"
+                               check_optional_partition "$partition_name" 1
+                               continue
+                       fi
+
+                       if { [ "$partition_name" == "rootfs" ] && (( ROOTFS_NEXT_SIZE == 0 )); } || \
+                               { [ "$partition_name" == "hal" ] && (( HAL_NEXT_SIZE == 0 )); }; then
+                               flog "[Error] Unable to find: $partition_name next partition on $EMMC_DEVICE device on $NEXT_AB slot"
+                               check_optional_partition "$partition_name" 1
+                               continue
+                       fi
+
                        CURRENT_PARTITION="/dev/mapper/${partition_name}_${CURRENT_AB}"
                        NEXT_PARTITION="/dev/mapper/${partition_name}_${NEXT_AB}"
                else
@@ -189,7 +236,7 @@ background_copy() {
                        fi
 
                        if ! NEXT_PARTITION="$("$BLKID_PRINT" "$EMMC_DEVICE" "$partition_name" "$NEXT_AB")"; then
-                               flog "[Error] Unable to find: $partition_name next partition on $EMMC_DEVICE device on $CURRENT_AB slot"
+                               flog "[Error] Unable to find: $partition_name next partition on $EMMC_DEVICE device on $NEXT_AB slot"
                                check_optional_partition "$partition_name" 1
                                continue
                        fi
@@ -203,13 +250,42 @@ background_copy() {
                        continue
                fi
                flog "[Info] Background copy $partition_name, from: $CURRENT_PARTITION to $NEXT_PARTITION"
-               /bin/dd if="$CURRENT_PARTITION" of="$NEXT_PARTITION" bs=4096
+               if [ -n "$SUPERFS" ] && { [ "$partition_name" == "rootfs" ] || [ "$partition_name" == "hal" ]; }; then
+                       if [ "$partition_name" == "rootfs" ]; then
+                               if (( ROOTFS_NEXT_SIZE < ROOTFS_CURR_SIZE )); then
+                                       head -c "$ROOTFS_NEXT_SIZE" "$CURRENT_PARTITION" > "$NEXT_PARTITION"
+                               else
+                                       head -c "$ROOTFS_CURR_SIZE" "$CURRENT_PARTITION" > "$NEXT_PARTITION"
+                               fi
+                       fi
+
+                       if [ "$partition_name" == "hal" ]; then
+                               if (( HAL_NEXT_SIZE < HAL_CURR_SIZE )); then
+                                       head -c "$HAL_NEXT_SIZE" "$CURRENT_PARTITION" > "$NEXT_PARTITION"
+                               else
+                                       head -c "$HAL_CURR_SIZE" "$CURRENT_PARTITION" > "$NEXT_PARTITION"
+                               fi
+                       fi
+               else
+                       /bin/dd if="$CURRENT_PARTITION" of="$NEXT_PARTITION" bs=4096
+               fi
                flog "[Info] Finished background copy $partition_name from $CURRENT_PARTITION to $NEXT_PARTITION"
 
                if [ "$partition_name" == "rootfs" ]; then
                        flog "[Info] Checksum verification for $partition_name"
-                       CUR_SHA1=$(sha1sum "$CURRENT_PARTITION" | awk '{print $1}')
-                       NEXT_SHA1=$(sha1sum "$NEXT_PARTITION" | awk '{print $1}')
+                       if [ -n "$SUPERFS" ]; then
+                               if (( ROOTFS_NEXT_SIZE < ROOTFS_CURR_SIZE )); then
+                                       CUR_SHA1=$(head -c "$ROOTFS_NEXT_SIZE" "$CURRENT_PARTITION" | sha1sum | awk '{print $1}')
+                                       NEXT_SHA1=$(sha1sum "$NEXT_PARTITION" | awk '{print $1}')
+                               else
+                                       CUR_SHA1=$(sha1sum "$CURRENT_PARTITION" | awk '{print $1}')
+                                       NEXT_SHA1=$(head -c "$ROOTFS_CURR_SIZE" "$NEXT_PARTITION" | sha1sum | awk '{print $1}')
+                               fi
+                       else
+                               CUR_SHA1=$(sha1sum "$CURRENT_PARTITION" | awk '{print $1}')
+                               NEXT_SHA1=$(sha1sum "$NEXT_PARTITION" | awk '{print $1}')
+                       fi
+
                        if [ "$CUR_SHA1" == "$NEXT_SHA1" ]; then
                                flog "[Info] Partition $partition_name was cloned correctly"
                        else
index 258673f..af090d8 100755 (executable)
@@ -46,7 +46,6 @@ prepare_fota_update_dir
 check_ab_partition_scheme
 check_used_block_device
 check_args "$@"
-unpack_file "$DELTA_TAR" "$CONFIG_FILE"
 unpack_file "$DELTA_TAR" "upgrade-apply"
 /bin/chmod +x "$FOTA_DIR/upgrade-apply"
 unpack_file "$DELTA_TAR" "upgrade-apply-deltafs"
index 656e0d8..4084f65 100644 (file)
@@ -69,6 +69,8 @@ do_update() {
                unpack_file "${DOWNLOAD_DELTA}" "${BLKID_PRINT_FILE}"
                chmod +x "$FOTA_DIR/$BLKID_PRINT_FILE"
 
+               unpack_file "$DOWNLOAD_DELTA" "$CONFIG_FILE"
+
                if [ "$(device_board_get_partition_ab_cloned)" -eq 0 ]; then
                        log "Starting to prepare the partitions for upgrade.." "$LOG_FILE"