From: Jacek Kryszyn Date: Fri, 8 Dec 2023 09:53:42 +0000 (+0100) Subject: Allow upgrade of Tizen with dynamic partitions X-Git-Tag: accepted/tizen/unified/20240112.154553^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3bb122d7654d38e9b547a48aae7654e1eaba1e37;p=platform%2Fcore%2Fsystem%2Fupgrade.git Allow upgrade of Tizen with dynamic partitions 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 --- diff --git a/scripts/upgrade-support/upgrade-common.inc b/scripts/upgrade-support/upgrade-common.inc index 2426c11..229ac6b 100644 --- a/scripts/upgrade-support/upgrade-common.inc +++ b/scripts/upgrade-support/upgrade-common.inc @@ -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 diff --git a/src/blkid-print/blkid-print.c b/src/blkid-print/blkid-print.c index 17addaf..4da1e7d 100644 --- a/src/blkid-print/blkid-print.c +++ b/src/blkid-print/blkid-print.c @@ -24,19 +24,20 @@ 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; +}