Allow upgrade of Tizen with dynamic partitions 74/302774/3 accepted/tizen_unified_riscv accepted/tizen/unified/20240112.154553 accepted/tizen/unified/riscv/20240115.113650
authorJacek Kryszyn <j.kryszyn@samsung.com>
Fri, 8 Dec 2023 09:53:42 +0000 (10:53 +0100)
committerJacek Kryszyn <j.kryszyn@samsung.com>
Thu, 14 Dec 2023 14:32:36 +0000 (15:32 +0100)
This change adds support of dynamic partitions mapped from super
partition during upgrade. blkid-print was modified in order to
a) print usage and error messages on stderr instead of stdout
b) return output in a form which was extracted using sed anyway

Change-Id: Ibef751fd011dc3baf09df753cc4e8b81a583a0c2

scripts/upgrade-support/upgrade-common.inc
src/blkid-print/blkid-print.c

index 2426c11..229ac6b 100644 (file)
@@ -8,6 +8,7 @@ SET_UPGRADE_STATUS="/usr/bin/device_board_set_upgrade_status"
 DO_RW_UPDATE_FILE="$FOTA_UPDATE_PREFIX/opt/.do_rw_update"
 TRUE=0
 FALSE=1
+SUPERFS=""
 
 #------------------------------------------------
 #       critical_log msg [file]
@@ -111,6 +112,44 @@ check_ab_partition_scheme() {
        fi
 }
 
+map_from_super() {
+    local part_name="$1"
+    local part_table="$2"
+    echo "$part_table" | /usr/sbin/dmsetup create "$part_name" &>/dev/null
+    if [ $? = 0 ]; then
+        echo "/dev/mapper/$part_name"
+        return 0
+    else
+        echo "WARNING : SUPER FOUND BUT $part_name NOT FOUND" >&2
+        return 1
+    fi
+}
+
+check_if_super() {
+       if SUPERFS="$(/usr/bin/blkid-print "$EMMC_DEVICE" super a)"; then
+               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.
+               if [[ $MAPPED_DEVICES != *"rootfs_${NEXT_AB}"* ]]; then
+                       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"
+                               fi
+
+                               if [ "$part_name" = "hal_${NEXT_AB}" ]; then
+                                       map_from_super "$part_name" "$part_table"
+                               fi
+                       done <<< "$PARSE_DYNPARTS"
+               fi
+       fi
+}
+
 check_used_block_device() {
        local MAPPER_MATCH_REGEX='.*/dev/mapper.*'
        ROOTFS_DEVICE="$(findmnt / -no SOURCE)"
@@ -127,27 +166,31 @@ check_used_block_device() {
                flog "[Error] Unable to find used block device: $EMMC_DEVICE, for /"
                exit_error
        fi
+
+       check_if_super
 }
 
 background_copy() {
        flog "[Info] Background copying A|B partitions for update..."
        start_duration=$(date +%s)
        for partition_name in ${PARTITION_LIST}; do
-               # echo is there to suspend abort when partition will not be found e.g. hal
-               if ! CURRENT_PARTITION="$(/usr/bin/blkid-print "$EMMC_DEVICE" "$partition_name" "$CURRENT_AB" |\
-                       sed -E 's|(part_nr: [0-9]+ )\((.*)\): (.*)|\3|' || echo "__FALSE__")" || \
-                       [ "$CURRENT_PARTITION" == "__FALSE__" ]; 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 ! NEXT_PARTITION="$(/usr/bin/blkid-print "$EMMC_DEVICE" "$partition_name" "$NEXT_AB" |\
-                       sed -E 's|(part_nr: [0-9]+ )\((.*)\): (.*)|\3|')"; then
-                       flog "[Error] Unable to find: $partition_name next partition on $EMMC_DEVICE device on $CURRENT_AB slot"
-                       check_optional_partition "$partition_name" 1
-                       continue
+               if { [ "$partition_name" == "rootfs" ] || [ "$partition_name" == "hal" ]; } && [ -n "$SUPERFS" ]; then
+                       CURRENT_PARTITION="/dev/mapper/${partition_name}_${CURRENT_AB}"
+                       NEXT_PARTITION="/dev/mapper/${partition_name}_${NEXT_AB}"
+               else
+                       if ! CURRENT_PARTITION="$(/usr/bin/blkid-print "$EMMC_DEVICE" "$partition_name" "$CURRENT_AB")"; 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 ! NEXT_PARTITION="$(/usr/bin/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"
+                               check_optional_partition "$partition_name" 1
+                               continue
+                       fi
                fi
-               if [ "$CURRENT_PARTITION" == "" ] || [ "$NEXT_PARTITION" = "" ]; then
+               if [ "$CURRENT_PARTITION" == "" ] || [ "$NEXT_PARTITION" == "" ]; then
                        flog "[Error] current: $CURRENT_PARTITION or next: $NEXT_PARTITION partition is empty on $EMMC_DEVICE device"
                        return $FALSE
                fi
@@ -214,10 +257,16 @@ upgrade_images() {
                        exit_error
                fi
 
-               local NEXT_PARTITION="$(/usr/bin/blkid-print "$EMMC_DEVICE" "$PART_NAME" "$NEXT_AB" |\
-                       /bin/sed -E 's|(part_nr: [0-9]+ )\((.*)\): (.*)|\3|')"
-               local CURR_PARTITION="$(/usr/bin/blkid-print "$EMMC_DEVICE" "$PART_NAME" "$CURRENT_AB" |\
-                       /bin/sed -E 's|(part_nr: [0-9]+ )\((.*)\): (.*)|\3|')"
+               local CURR_PARTITION=""
+               local NEXT_PARTITION=""
+
+               if { [ "$PART_NAME" == "rootfs" ] || [ "$PART_NAME" == "hal" ]; } && [ x$SUPERFS != "x" ]; then
+                       NEXT_PARTITION="/dev/mapper/${PART_NAME}_${NEXT_AB}"
+                       CURR_PARTITION="/dev/mapper/${PART_NAME}_${CURRENT_AB}"
+               else
+                       NEXT_PARTITION="$(/usr/bin/blkid-print "$EMMC_DEVICE" "$PART_NAME" "$NEXT_AB")"
+                       CURR_PARTITION="$(/usr/bin/blkid-print "$EMMC_DEVICE" "$PART_NAME" "$CURRENT_AB")"
+               fi
 
                flog "[Info] Flashing $DELTA_NAME... to $NEXT_PARTITION"
 
@@ -339,8 +388,7 @@ mount_partition() {
        local DST="$2"
        local MOUNT_OPTIONS="$3"
        local SRC
-       if ! SRC="$(/usr/bin/blkid-print "$EMMC_DEVICE" "$GPT_LABEL" "$NEXT_AB" |\
-               /bin/sed -E 's|(part_nr: [0-9]+ )\((.*)\): (.*)|\3|')"; then
+       if ! SRC="$(/usr/bin/blkid-print "$EMMC_DEVICE" "$GPT_LABEL" "$NEXT_AB")"; then
                flog "[Error] Unable to find $GPT_LABEL partition on $EMMC_DEVICE device for $NEXT_AB slot"
                return 1
        fi
index 17addaf..4da1e7d 100644 (file)
 
 void usage(const char* msg) {
        if (msg) {
-               printf("%s\n", msg);
+               fprintf(stderr, "%s\n", msg);
        }
-       printf("USAGE: blkid-print device_name partition_label suffix\n"
+       fprintf(stderr, "USAGE: blkid-print device_name partition_label suffix [verbose]\n"
        "device_name: block device e.g. /dev/mmcblk0\n"
        "partition_label: partiton label to search for e.g. rootfs,ramdisk etc.\n"
-       "suffix: a|b partiton slot\n");
+       "suffix: a|b partiton slot\n"
+       "verbose: optional, prints part_nr: part_nr (part_label): part_path instead of part_path only\n");
 }
 
 blkid_partition partition_for(char *device_name, char *part_name, char *new_slot) {
        char part_name_with_slot[MAX_PARTNAME_LEN];
        int found_part_n = -1;
        if (!device_name || !part_name || !new_slot){
-               printf("partition_for: one or more argument is NULL\n");
+               fprintf(stderr, "partition_for: one or more argument is NULL\n");
                return NULL;
        }
        if (snprintf(part_name_with_slot, MAX_PARTNAME_LEN, "%s_%s", part_name, new_slot) < 0) {
@@ -44,19 +45,19 @@ blkid_partition partition_for(char *device_name, char *part_name, char *new_slot
        }
        blkid_probe pr = blkid_new_probe_from_filename(device_name);
        if (pr == NULL) {
-               printf("ERROR: blkid error for %s\n", device_name);
+               fprintf(stderr, "ERROR: blkid error for %s\n", device_name);
                usage(NULL);
                return NULL;
        }
        blkid_partlist ls = blkid_probe_get_partitions(pr);
        if (!ls) {
-               printf("ERROR: unable to probe partitions.\n");
+               fprintf(stderr, "ERROR: unable to probe partitions.\n");
                blkid_free_probe(pr);
                return NULL;
        }
        int nparts = blkid_partlist_numof_partitions(ls);
        if (nparts == -1) {
-               printf("ERROR: unable to get partition count\n");
+               fprintf(stderr, "ERROR: unable to get partition count\n");
                blkid_free_probe(pr);
                return NULL;
        }
@@ -91,13 +92,16 @@ const char *get_part_label(blkid_partlist ls, int part_nr) {
 
 int main(int argc, char *argv[]) {
        char device_name_path[PATH_MAX];
-       if (argc != 4) {
+       if (argc < 4 || argc > 5 || (argc == 5 && strcmp(argv[4], "verbose")) ) {
                usage("Please specify correct argument number\n");
                return 1;
        }
+
+       int verbose = (argc == 5) ? 1 : 0;
+
        char *device_name = realpath(argv[1], device_name_path);
        if (!device_name) {
-               printf("ERROR: Unable to determine realpath for: %s\n", argv[1]);
+               fprintf(stderr, "ERROR: Unable to determine realpath for: %s\n", argv[1]);
                usage(NULL);
                return 1;
        }
@@ -105,13 +109,13 @@ int main(int argc, char *argv[]) {
        char *suffix = argv[3];
        blkid_partition part = partition_for(device_name, partition_label, suffix);
        if (part == NULL) {
-               printf("ERROR: Partition '%s' not found.\n", partition_label);
+               fprintf(stderr, "ERROR: Partition '%s' not found.\n", partition_label);
                usage(NULL);
                return 2;
        }
        int part_nr = blkid_partition_get_partno(part);
        if (part_nr < 0) {
-               printf("ERROR: Partition '%s' not found", partition_label);
+               fprintf(stderr, "ERROR: Partition '%s' not found", partition_label);
                return 3;
        }
        const char *part_label = blkid_partition_get_name(part);
@@ -122,7 +126,10 @@ int main(int argc, char *argv[]) {
                snprintf(part_path, PATH_MAX, "%s%d", device_name, part_nr);
        else
                snprintf(part_path, PATH_MAX, "%sp%d", device_name, part_nr);
-       printf("part_nr: %d (%s): %s\n", part_nr, part_label, part_path);
-               return 0;
-}
 
+       if (verbose)
+               printf("part_nr: %d (%s): %s\n", part_nr, part_label, part_path);
+       else
+               printf("%s\n", part_path);
+       return 0;
+}