Allow for up to two deltas to be given to upgrade scripts. 73/311573/8
authorAntoni <a.adaszkiewi@samsung.com>
Tue, 21 May 2024 14:13:52 +0000 (16:13 +0200)
committerMichal Bloch <m.bloch@samsung.com>
Wed, 5 Jun 2024 11:25:54 +0000 (11:25 +0000)
If a single delta is provided, it has to be either delta-platform or
regular delta. The second delta is optional, and it has to be
delta-boot. The script does not check the type of deltas, it is up
to the script user.

Change-Id: Ia112cc2f95e41a06a337dc0a3a504ab953436208

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

index 3b304b82dc8ea83cfd1fbed20751970c329def05..5bf1ea869e410884aa9548a2207bee128961ce2c 100644 (file)
@@ -84,8 +84,8 @@ retrap() {
 }
 
 check_if_file_in_archive() {
-       ARCHIVE_NAME="$1"
-       FILE_NAME="$2"
+       local ARCHIVE_NAME="$1"
+       local FILE_NAME="$2"
        local RET=0
        tar tf "${ARCHIVE_NAME}" "${FILE_NAME}" >/dev/null 2>&1 || RET=$?
 
@@ -96,33 +96,55 @@ check_if_file_in_archive() {
        fi
 }
 
+merge_config_files_and_delete() {
+       local FILE_A="$1"
+       local FILE_B="$2"
+       local FILE_OUT="$3"
+
+       cat "$FILE_A" > "$FILE_OUT"
+       cat "$FILE_B" >> "$FILE_OUT"
+
+       rm -f "$FILE_A" "$FILE_B"
+}
+
 verify_file_internal() {
        FILE_NAME="$1"
-       FILE_PATH="$FOTA_DIR/$FILE_NAME"
-       VALID_CHECKSUM=$(awk "\$2 ~ /^$FILE_NAME\$/ {print \$1}" "$FOTA_DIR/checksum.SHA1")
+       FILE_PATH="$2"
+       local CHECKSUM_FILE_PATH="$3"
+       VALID_CHECKSUM=$(awk "\$2 ~ /^$FILE_NAME\$/ {print \$1}" "$CHECKSUM_FILE_PATH")
        if [ "$VALID_CHECKSUM" == "" ]; then
-               log "[Error] No $FILE_NAME in checksum.SHA1"
+               critical_log "[Error] No $FILE_NAME in $CHECKSUM_FILE_PATH"
                return $FALSE
        fi
 
        if ! echo "$VALID_CHECKSUM  $FILE_PATH" | sha1sum --check --status; then
-               log "[Error] Checksum for file $FILE_NAME is invalid"
+               critical_log "[Error] Checksum for file $FILE_NAME is invalid [$CHECKSUM_FILE_PATH]"
                return $FALSE
        fi
 
-       log "[Info] Checksum of $FILE_NAME is OK"
+       log "[Info] Checksum of $FILE_NAME is OK [$CHECKSUM_FILE_PATH]"
        return $TRUE
 }
 
+# Default dir to unpack is FOTA_DIR (pass anon-empty 4th param to override)
 unpack_file() {
-       ARCHIVE_NAME="$1"
-       FILE_NAME="$2"
-       tar xpf "${ARCHIVE_NAME}" -C "${FOTA_DIR}" "${FILE_NAME}" 2> /dev/null
-       if [ ! -e "${FOTA_DIR}/${FILE_NAME}" ]; then
-               log "[Error] There is no ${FILE_NAME}"
+       local ARCHIVE_PATH="$1"
+       local FILE_NAME="$2"
+       local CHECKSUM_FILE_A_PATH="$3"
+       local UNPACK_DIR="$4"
+
+       if [ -z "$UNPACK_DIR" ]; then
+               UNPACK_DIR="$FOTA_DIR"
+       fi
+
+       local FILE_PATH="$UNPACK_DIR/$FILE_NAME"
+
+       tar xpf "${ARCHIVE_PATH}" -C "${UNPACK_DIR}" "${FILE_NAME}" 2> /dev/null
+       if [ ! -e "$FILE_PATH" ]; then
+               log "[Error] There is no $FILE_NAME in $ARCHIVE_PATH"
        fi
 
-       if ! verify_file_internal "$FILE_NAME"; then
+       if ! verify_file_internal "$FILE_NAME" "$FILE_PATH" "$CHECKSUM_FILE_A_PATH"; then
                exit_error
        fi
 }
@@ -400,11 +422,14 @@ load_background_copy_list() {
 run_upgrade_binary() {
        log "[Info] Running $1"
        $1 2>&1 | tee -a "$LOG_FILE"
-       return ${PIPESTATUS[0]}
+       return "${PIPESTATUS[0]}"
 }
 
 upgrade_images() {
-       DELTA_TAR="$1"
+       DELTA_TAR_A="$1"
+       DELTA_TAR_B="$2"
+       local TARGET_ARCHIVE
+
        log "[Info] Flash images for update..."
 
        LABEL_MAP_PATH=${HAL_UPGRADE_CFG_DIR}/${HAL_}
@@ -412,7 +437,7 @@ upgrade_images() {
                declare "LABEL_MAP_${LABEL}=${PARTLABEL}"
        done < <(sed -e '/^#/d' -e '/^$/d' "${LABEL_MAP_PATH}/${HAL_PART_MAP_FILE}")
 
-       local PROGRESS_INFO_FILE_PATH="$2"
+       local PROGRESS_INFO_FILE_PATH="$3"
        local PROGRESS_INFO_FILE_ARG
        if [ -n "$PROGRESS_INFO_FILE_PATH" ]; then
                PROGRESS_INFO_FILE_ARG="--progress-info-file $PROGRESS_INFO_FILE_PATH"
@@ -439,11 +464,23 @@ upgrade_images() {
                        continue
                fi
 
-               if ! /bin/tar tf "$DELTA_TAR" "$DELTA_NAME"; then
-                       log "[Error] There is no delta $DELTA_NAME for label $LABEL_NAME from part $PART_NAME"
-                       exit_error
+               if [ -n "$DELTA_TAR_B" ]; then
+                       if check_if_file_in_archive "$DELTA_TAR_A" "$DELTA_NAME"; then
+                               TARGET_ARCHIVE="$DELTA_TAR_A"
+                       elif check_if_file_in_archive "$DELTA_TAR_B" "$DELTA_NAME"; then
+                               TARGET_ARCHIVE="$DELTA_TAR_B"
+                       else
+                               critical_log "[Error] There is no delta $DELTA_NAME for label $LABEL_NAME from part $PART_NAME in either archive"
+                               exit_error
+                       fi
+               else
+                       # If there is only one archive delta has to be found
+                       if ! check_if_file_in_archive "$DELTA_TAR_A" "$DELTA_NAME"; then
+                               critical_log "[Error] There is no delta $DELTA_NAME for label $LABEL_NAME from part $PART_NAME"
+                               exit_error
+                       fi
+                       TARGET_ARCHIVE="$DELTA_TAR_A"
                fi
-
                local CURR_PARTITION=""
                local NEXT_PARTITION=""
 
@@ -462,7 +499,7 @@ upgrade_images() {
                case "${TYPE_S[0]}" in
                        FULL_IMAGE)
                                run_upgrade_binary "$FOTA_DIR/upgrade-apply "`
-                                                                       `"--archive $DELTA_TAR "`
+                                                                       `"--archive $TARGET_ARCHIVE "`
                                                                        `"--dest $NEXT_PARTITION "`
                                                                        `"--dest-size $NEW_SIZE "`
                                                                        `"--archive-file $DELTA_NAME "`
@@ -472,7 +509,7 @@ upgrade_images() {
                                ;;
                        DELTA_IMAGE)
                                run_upgrade_binary "$FOTA_DIR/upgrade-apply "`
-                                                                       `"--archive $DELTA_TAR "`
+                                                                       `"--archive $TARGET_ARCHIVE "`
                                                                        `"--dest $NEXT_PARTITION "`
                                                                        `"--dest-size $NEW_SIZE "`
                                                                        `"--archive-file $DELTA_NAME "`
@@ -488,7 +525,7 @@ upgrade_images() {
                                mount "$NEXT_PARTITION" "$FOTA_DIR/partition_mnt"
 
                                run_upgrade_binary "$FOTA_DIR/upgrade-apply-deltafs "`
-                                                                       `"--archive $DELTA_TAR "`
+                                                                       `"--archive $TARGET_ARCHIVE "`
                                                                        `"--dest $FOTA_DIR/partition_mnt "`
                                                                        `"--archive-file $DELTA_NAME/"
                                UP_RES=$?
index 04c16d57c70b4a5118576199c16d023568dcdd96..98b550cc6a3d19f97283663d6b57f4ef84347520 100755 (executable)
@@ -11,6 +11,9 @@ fi
 PATH=/bin:/usr/bin:/sbin:/usr/sbin
 FOTA_DIR="/opt/usr/data/fota"
 
+DELTA_A_DIR="$FOTA_DIR/delta_a"
+DELTA_B_DIR="$FOTA_DIR/delta_b"
+
 . "$FOTA_DIR"/upgrade-common.inc
 set_script_name_and_log_file "${BASH_SOURCE[0]}"
 
@@ -28,6 +31,11 @@ cleanup_files() {
        rm -f -- "$FOTA_DIR/$CONFIG_FILE"
        rm -f -- "$FOTA_DIR/upgrade-trigger.sh"
        rm -f -- "$FOTA_DIR/checksum.SHA1"
+       rm -rf -- "$DELTA_A_DIR"
+
+       if [ -d "$DELTA_B_DIR" ]; then
+               rm -rf -- "$DELTA_B_DIR"
+       fi
 }
 
 mount() {
index 22826a9e5fc22defbc12b3b446052982c43288e0..0001baedfad6026b647bf52216c6484282aa64a4 100755 (executable)
@@ -9,18 +9,35 @@ fi
 
 PATH=/bin:/usr/bin:/sbin:/usr/sbin
 FOTA_DIR="/opt/usr/data/fota"
+DELTA_A_DIR="$FOTA_DIR/delta_a"
+DELTA_B_DIR="$FOTA_DIR/delta_b"
+DELTA_A_CHECKSUM_FILE="$DELTA_A_DIR/checksum.SHA1"
+DELTA_B_CHECKSUM_FILE="$DELTA_B_DIR/checksum.SHA1"
 
 . "$FOTA_DIR"/upgrade-common.inc
 set_script_name_and_log_file "${BASH_SOURCE[0]}"
 
 check_args() {
-       DELTA_TAR="$1"
-       if [ ! -f "$DELTA_TAR" ]; then
-               log "[Error] Usage: $0 path_to_delta.tar[.gz]"
+       DELTA_TAR_A="$1"
+       DELTA_TAR_B="$2"
+
+       SINGLE_DELTA=true
+       if [ -n "$DELTA_TAR_B" ]; then
+               SINGLE_DELTA=false
+       fi
+
+       if [[ (( $SINGLE_DELTA = true ) && ( ! -f "$DELTA_TAR_A" )) || \
+               (( $SINGLE_DELTA = false ) && (( ! -f "$DELTA_TAR_A" ) || ( ! -f "$DELTA_TAR_B"))) ]]; then
+               log "[Error] Usage: $0 path_to_delta.tar[.gz] [path_to_second_delta.tar[.gz]]"
                exit 1
        fi
 
-       log "[Info] Using <$DELTA_TAR> delta file."
+       if [ $SINGLE_DELTA = true ]; then
+               log "[Info] Using <$DELTA_TAR_A> delta file."
+               DELTA_B_CHECKSUM_FILE=""
+       else
+               log "[Info] Using <$DELTA_TAR_A> and <$DELTA_TAR_B> delta files."
+       fi
 }
 
 FOTA_UPDATE_PREFIX="/run/upgrade-sysroot"
@@ -31,8 +48,18 @@ cleanup() {
 }
 
 cleanup_files() {
-       rm -f -- "$DELTA_TAR"
+       rm -f -- "$DELTA_TAR_A"
+
+       if [ $SINGLE_DELTA = false ]; then
+               rm -f -- "$DELTA_TAR_B"
+       fi
+
+       if [ -f "$FOTA_DIR/update-progress-info.ini" ]; then
+               rm -f -- "$FOTA_DIR/update-progress-info.ini"
+       fi
+
        rm -f -- "$FOTA_DIR/upgrade-apply"
+       rm -f -- "$FOTA_DIR/upgrade-apply-deltafs"
        rm -f -- "$FOTA_DIR/$SCRIPT_NAME"
 }
 
@@ -44,26 +71,51 @@ prepare_fota_update_dir
 check_ab_partition_scheme
 check_used_block_device
 check_args "$@"
-
-unpack_file "$DELTA_TAR" "upgrade-apply"
+unpack_file "$DELTA_TAR_A" "upgrade-apply" "$DELTA_A_CHECKSUM_FILE" ""
 /bin/chmod +x "$FOTA_DIR/upgrade-apply"
-unpack_file "$DELTA_TAR" "upgrade-apply-deltafs"
+unpack_file "$DELTA_TAR_A" "upgrade-apply-deltafs" "$DELTA_A_CHECKSUM_FILE" ""
 /bin/chmod +x "$FOTA_DIR/upgrade-apply-deltafs"
 
-if check_if_file_in_archive "$DELTA_TAR" "update-progress-info.ini"; then
-       unpack_file "$DELTA_TAR" "update-progress-info.ini"
-       PROGRESS_INFO_FILE_PATH="$FOTA_DIR/update-progress-info.ini"
+if [ $SINGLE_DELTA = true ]; then
+       if check_if_file_in_archive "$DELTA_TAR_A" "update-progress-info.ini"; then
+               unpack_file "$DELTA_TAR_A" "update-progress-info.ini" "$DELTA_A_CHECKSUM_FILE" ""
+               PROGRESS_INFO_FILE_PATH="$FOTA_DIR/update-progress-info.ini"
+       else
+               PROGRESS_INFO_FILE_PATH=""
+       fi
 else
-       PROGRESS_INFO_FILE_PATH=""
+       FOUND_IN_DELTA_A=false
+       FOUND_IN_DELTA_B=false
+
+       if check_if_file_in_archive "$DELTA_TAR_A" "update-progress-info.ini"; then
+               unpack_file "$DELTA_TAR_A" "update-progress-info.ini" "$DELTA_A_CHECKSUM_FILE" "$DELTA_A_DIR"
+               FOUND_IN_DELTA_A=true
+       fi
+
+       if check_if_file_in_archive "$DELTA_TAR_B" "update-progress-info.ini"; then
+               unpack_file "$DELTA_TAR_B" "update-progress-info.ini" "$DELTA_B_CHECKSUM_FILE" "$DELTA_B_DIR"
+               FOUND_IN_DELTA_B=true
+       fi
+
+       PROGRESS_INFO_FILE_PATH="$FOTA_DIR/update-progress-info.ini"
+       if [ $FOUND_IN_DELTA_A = true ] && [ $FOUND_IN_DELTA_B = true ]; then
+               merge_config_files_and_delete "$DELTA_A_DIR/update-progress-info.ini" "$DELTA_B_DIR/update-progress-info.ini" "$FOTA_DIR/update-progress-info.ini"
+       elif [ $FOUND_IN_DELTA_A = true ]; then
+               mv "$DELTA_A_DIR/update-progress-info.ini" "$FOTA_DIR/update-progress-info.ini"
+       elif [ $FOUND_IN_DELTA_B = true ]; then
+               mv "$DELTA_B_DIR/update-progress-info.ini" "$FOTA_DIR/update-progress-info.ini"
+       else
+               PROGRESS_INFO_FILE_PATH=""
+       fi
 fi
 
-if ! upgrade_images "$DELTA_TAR" "$PROGRESS_INFO_FILE_PATH"; then
+if ! upgrade_images "$DELTA_TAR_A" "$DELTA_TAR_B" "$PROGRESS_INFO_FILE_PATH"; then
        critical_log "[Error] Unable to upgrade_images"
        cleanup
        exit_error
 fi
 
-if ! run_setup_script "$DELTA_TAR"; then
+if ! run_setup_script "$DELTA_TAR_A"; then
        critical_log "[Error] Unable to run_setup_script"
        cleanup
        exit_error
index 4f4f0197c750f04c3d47e667badd966b6a430cdb..d29876f4717f5d67cd50efd66d0536aaa6f86f95 100644 (file)
@@ -16,10 +16,15 @@ ERR_FINISH_BEFORE_RO_UPDATE_COMPLETE=3
 
 PATH=/bin:/usr/bin:/sbin:/usr/sbin
 FOTA_DIR="/opt/usr/data/fota"
+DELTA_A_DIR="$FOTA_DIR/delta_a"
+DELTA_B_DIR="$FOTA_DIR/delta_b"
+DELTA_A_CHECKSUM_FILE="$DELTA_A_DIR/checksum.SHA1"
+DELTA_B_CHECKSUM_FILE="$DELTA_B_DIR/checksum.SHA1"
 STATUS_DIR="/opt/data/update"
 SCRIPT_UPGRADE_PREPARE_PARTITIONS="upgrade-prepare-partitions.sh"
 SCRIPT_UPGRADE_PARTIAL="upgrade-partial.sh"
 SCRIPT_UPGRADE_FOTA="upgrade-fota.sh"
+SCRIPT_UPGRADE_TRIGGER="upgrade-trigger.sh"
 BLKID_PRINT_FILE="blkid-print"
 RESIZE_DYNPARTS_FILE="resize-dynparts"
 COPY_BLOCKDEV_FILE="copy-blockdev"
@@ -29,22 +34,47 @@ export RESIZE_DYNPARTS="$FOTA_DIR/$RESIZE_DYNPARTS_FILE"
 export COPY_BLOCKDEV="$FOTA_DIR/$COPY_BLOCKDEV_FILE"
 
 prepare_fota_dir() {
+       # Cleanup FOTA dir. If provided delta(s) are inside, keep them
+       # This could delete the deltas if they are placed in DELTA_X_DIR. But since the script
+       # creates/deletes them (and doesn't place them there), it is unlikely. Some vital scripts
+       # and files (like this <upgrade-trigger.sh> script or checksum file) will be deleted, but
+       # it's not an issue since they will be exctraced again later.
        if [ -d "$FOTA_DIR" ]; then
-               # Cleanup FOTA_DIR
-               if [ "$(dirname "$DOWNLOAD_DELTA")" = "$FOTA_DIR" ]; then
-                       # If provided delta is from inside the FOTA_DIR, delete everything else
-                       DELTA_FILE_NAME=$(basename "$DOWNLOAD_DELTA")
-                       rm -rf -- "$FOTA_DIR/!($DELTA_FILE_NAME)"
+               local DELTA_A_PARENT_DIR="$(readlink -e "$(dirname "$DELTA_A")")"
+
+               if [ $SINGLE_DELTA = true ]; then
+                       if [ "$DELTA_A_PARENT_DIR" = "$FOTA_DIR" ]; then
+                               find "$FOTA_DIR" -maxdepth 1 -not -wholename "$FOTA_DIR" -not -wholename "$(readlink -e "$DELTA_A")" -exec rm -r "{}" \;
+                       else
+                               rm -rf -- ${FOTA_DIR:?}/*
+                       fi
                else
-                       # If provided delta is from outside the FOTA_DIR delete everything
-                       rm -rf -- "${FOTA_DIR:?}/*"
+                       local DELTA_B_PARENT_DIR="$(readlink -e "$(dirname "$DELTA_B")")"
+
+                       if [ "$DELTA_A_PARENT_DIR" = "$FOTA_DIR" ] && [ "$DELTA_B_PARENT_DIR" = "$FOTA_DIR" ]; then
+                               find "$FOTA_DIR" -maxdepth 1 -not -wholename "$FOTA_DIR" -not -wholename "$(readlink -e "$DELTA_A")" \
+                                       -not -wholename "$(readlink -e "$DELTA_B")" -exec rm -r "{}" \;
+                       elif [ "$DELTA_A_PARENT_DIR" = "$FOTA_DIR" ]; then
+                               find "$FOTA_DIR" -maxdepth 1 -not -wholename "$FOTA_DIR" -not -wholename "$(readlink -e "$DELTA_A")" -exec rm -r "{}" \;
+                       elif [ "$DELTA_B_PARENT_DIR" = "$FOTA_DIR" ]; then
+                               find "$FOTA_DIR" -maxdepth 1 -not -wholename "$FOTA_DIR" -not -wholename "$(readlink -e "$DELTA_B")" -exec rm -r "{}" \;
+                       else
+                               rm -rf -- ${FOTA_DIR:?}/*
+                       fi
                fi
-       # `echo` commands below are intentional as upgrade-common.inc is not sourced yet (no access to logging functions)
        else
-               echo "[Info] Create fota dir..."
+               echo "[Info] Create FOTA dir..."
                mkdir -p "$FOTA_DIR"
        fi
 
+       echo "[Info] Create subdir for delta..."
+       mkdir "$DELTA_A_DIR"
+
+       if [ $SINGLE_DELTA = false ]; then
+               echo "[Info] Create subdir for second delta..."
+               mkdir "$DELTA_B_DIR"
+       fi
+
        if [ ! -d "$STATUS_DIR" ]; then
                echo "[Info] Create status dir..."
                mkdir -p "$STATUS_DIR"
@@ -68,21 +98,27 @@ do_update() {
        if is_ab_upgrade; then
                set_upgrade_status 5
 
-               unpack_file "${DOWNLOAD_DELTA}" "${BLKID_PRINT_FILE}"
+               unpack_file "${DELTA_A}" "${BLKID_PRINT_FILE}" "${DELTA_A_CHECKSUM_FILE}" ""
                chmod +x "$FOTA_DIR/$BLKID_PRINT_FILE"
 
-               unpack_file "${DOWNLOAD_DELTA}" "${RESIZE_DYNPARTS_FILE}"
+               unpack_file "${DELTA_A}" "${RESIZE_DYNPARTS_FILE}" "${DELTA_A_CHECKSUM_FILE}" ""
                chmod +x "$FOTA_DIR/$RESIZE_DYNPARTS_FILE"
 
-               unpack_file "${DOWNLOAD_DELTA}" "${COPY_BLOCKDEV_FILE}"
+               unpack_file "${DELTA_A}" "${COPY_BLOCKDEV_FILE}" "${DELTA_A_CHECKSUM_FILE}" ""
                chmod +x "$FOTA_DIR/$COPY_BLOCKDEV_FILE"
 
-               unpack_file "$DOWNLOAD_DELTA" "$CONFIG_FILE"
+               if [ $SINGLE_DELTA = false ]; then
+                       unpack_file "$DELTA_A" "$CONFIG_FILE" "$DELTA_A_CHECKSUM_FILE" "$DELTA_A_DIR"
+                       unpack_file "$DELTA_B" "$CONFIG_FILE" "$DELTA_B_CHECKSUM_FILE" "$DELTA_B_DIR"
+                       merge_config_files_and_delete "$DELTA_A_DIR/$CONFIG_FILE" "$DELTA_B_DIR/$CONFIG_FILE" "$FOTA_DIR/$CONFIG_FILE"
+               else
+                       unpack_file "$DELTA_A" "$CONFIG_FILE" "$DELTA_A_CHECKSUM_FILE" ""
+               fi
 
                if [ "$(device_board_get_partition_ab_cloned)" -eq 0 ]; then
                        log "[Info] Starting to prepare the partitions for upgrade.."
 
-                       unpack_file "${DOWNLOAD_DELTA}" "${SCRIPT_UPGRADE_PREPARE_PARTITIONS}"
+                       unpack_file "${DELTA_A}" "${SCRIPT_UPGRADE_PREPARE_PARTITIONS}" "${DELTA_A_CHECKSUM_FILE}" ""
 
                        run_script "${FOTA_DIR}/${SCRIPT_UPGRADE_PREPARE_PARTITIONS} $PROGRESS_AFTER_CLONING"
                        if [ $RET -ne 0 ]; then
@@ -98,7 +134,7 @@ do_update() {
                device_board_clear_partition_ab_cloned
 
 
-               run_script "${FOTA_DIR}/${SCRIPT_UPGRADE_PARTIAL} ${DOWNLOAD_DELTA}"
+               run_script "${FOTA_DIR}/${SCRIPT_UPGRADE_PARTIAL} ${DELTA_A} ${DELTA_B}"
 
                if [ $RET -ne 0 ] ; then
                        log "[Error] Failed to run $SCRIPT_UPGRADE_PARTIAL ${DOWNLOAD_DELTA}" "$LOG_FILE"
@@ -144,26 +180,41 @@ do_finish() {
 verify_file() {
        FILE_PATH="$1"
        FILE_NAME=$(basename "$FILE_PATH")
+       local CHECKSUM_FILE="$2"
 
-       VALID_CHECKSUM=$(awk "\$2 ~ /^$FILE_NAME\$/ {print \$1}" "$FOTA_DIR/checksum.SHA1")
+       VALID_CHECKSUM=$(awk "\$2 ~ /^$FILE_NAME\$/ {print \$1}" "$CHECKSUM_FILE")
        if [ "$VALID_CHECKSUM" == "" ]; then
-               log "[Error] No $FILE_NAME in checksum.SHA1"
+               log "[Error] No $FILE_NAME in $CHECKSUM_FILE"
                device_board_set_upgrade_status -1
                exit 1
        fi
 
        if ! echo "$VALID_CHECKSUM  $FILE_PATH" | sha1sum --check --status; then
-               log "[Error] Checksum for file $FILE_NAME is invalid"
+               log "[Error] Checksum for file $FILE_NAME is invalid [$CHECKSUM_FILE]"
                device_board_set_upgrade_status -1
                exit 1
        fi
 
-       log "[Info] Checksum of $FILE_NAME is OK"
+       log "[Info] Checksum of $FILE_NAME is OK [$CHECKSUM_FILE]"
 }
 
 MODE_RO_UPDATE=false
 MODE_FINISH_UPDATE=false
 
+# DELTA_A variable will be the path to the delta containing all binaries/scripts
+# neccessary to perform upgrade. This could either be a "platform" delta, or a
+# "platform" + "boot" delta. If two deltas are to be used, the script has to be
+# given this delta first. Calling this script with "boot" delta only or giving it
+# the "boot" delta as first path parameter is not recommended and it is up to
+# the caller to ensure this doesn't happen.
+SINGLE_DELTA=true
+DELTA_A=""
+DELTA_B=""
+
+printf "[Start] Running %s: " "$0"
+printf "[%s] " "$@"
+printf "\n"
+
 while [[ $# -gt 0 ]]; do
        case "$1" in
                --ro-update)
@@ -172,8 +223,20 @@ while [[ $# -gt 0 ]]; do
                --finish)
                        MODE_FINISH_UPDATE=true
                        ;;
+               --ro-update-and-finish)
+                       MODE_RO_UPDATE=true
+                       MODE_FINISH_UPDATE=true
+                       ;;
+               # Just a precausion
+               "")
+                       ;;
                *)
-                       DOWNLOAD_DELTA="$1"
+                       if [ -z "$DELTA_A" ]; then
+                               DELTA_A="$1"
+                       else
+                               DELTA_B="$1"
+                               SINGLE_DELTA=false
+                       fi
                        ;;
        esac
        shift
@@ -184,12 +247,12 @@ if [ $MODE_RO_UPDATE = false ] && [ $MODE_FINISH_UPDATE = false ]; then
        MODE_FINISH_UPDATE=true
 fi
 
-if [ $MODE_RO_UPDATE = true ] && [ ! -f "$DOWNLOAD_DELTA" ]; then
-       echo "[Error] Usage: $0 [--ro_update <path_to_delta.tar[.gz]>] [--finish]"
+if [[ ( $MODE_RO_UPDATE = true ) && ((( $SINGLE_DELTA = true ) && ( ! -f "$DELTA_A" )) \
+       || (( $SINGLE_DELTA = false ) && (( ! -f "$DELTA_A" ) || ( ! -f "$DELTA_B" )))) ]]; then
+       echo "[Error] Usage: $0 [--ro_update <path_to_delta.tar[.gz]> [<path_to_second_delta.tar[.gz]>] ] [--finish]"
        exit 1
 fi
 
-
 (
 if [ $MODE_RO_UPDATE = false ] && [ $MODE_FINISH_UPDATE = true ]; then
        if ! flock -n 9; then
@@ -200,37 +263,53 @@ else
        flock 9
 fi
 
-# if [ "$#" != "1" ] || [ ! -f "$1" ]; then
-#   echo "[Error] Usage: $0 path_to_delta.tar[.gz]"
-#   exit 1
-# fi
 if [ $MODE_RO_UPDATE = true ]; then
        prepare_fota_dir
 
-       tar xfp "$DOWNLOAD_DELTA" -C "$FOTA_DIR" checksum.SHA1
+       tar xfp "$DELTA_A" -C "$DELTA_A_DIR" checksum.SHA1
+       # Copy in case script is later called in "--finish" mode (prepare_fota_dir() deletes it)
+       cp "$DELTA_A_DIR/checksum.SHA1" "$FOTA_DIR/checksum.SHA1"
+
+       # Untar this file in case script is later called in "--finish mode" (prepare_fota_dir() deletes it)
+       if [ ! -f "$FOTA_DIR/$SCRIPT_UPGRADE_TRIGGER" ]; then
+               tar xfp "$DELTA_A" -C "$FOTA_DIR" "$SCRIPT_UPGRADE_TRIGGER"
+       fi
 
-       tar xfp "$DOWNLOAD_DELTA" -C "$FOTA_DIR" upgrade-common.inc
+       tar xfp "$DELTA_A" -C "$FOTA_DIR" upgrade-common.inc
+
+       if [ $SINGLE_DELTA = false ]; then
+               tar xfp "$DELTA_B" -C "$DELTA_B_DIR" checksum.SHA1
+       else
+               DELTA_B_CHECKSUM_FILE=""
+       fi
 fi
 
 if [ ! -f "$FOTA_DIR/upgrade-common.inc" ]; then
-       echo "[Error] upgrade-common.inc not exist"
+       echo "[Error] upgrade-common.inc does not exist"
        device_board_set_upgrade_status -1
        exit 1
 fi
 
-       . "$FOTA_DIR"/upgrade-common.inc
+. "$FOTA_DIR"/upgrade-common.inc
 
 if [ $MODE_RO_UPDATE = true ]; then
        upgrade_log_init
-       set_script_name_and_log_file "${BASH_SOURCE[0]} $*"
+       set_script_name_and_log_file "${BASH_SOURCE[0]}"
+
+       verify_file "$FOTA_DIR/upgrade-common.inc" "$DELTA_A_CHECKSUM_FILE"
+       verify_file "$0" "$DELTA_A_CHECKSUM_FILE"
 
-       verify_file "$FOTA_DIR/upgrade-common.inc"
+       unpack_file "${DELTA_A}" delta-verifier "$DELTA_A_CHECKSUM_FILE" ""
+       unpack_file "${DELTA_A}" "${SCRIPT_UPGRADE_PARTIAL}" "$DELTA_A_CHECKSUM_FILE" ""
+       unpack_file "${DELTA_A}" "${SCRIPT_UPGRADE_FOTA}" "$DELTA_A_CHECKSUM_FILE" ""
 
-       verify_file "$0"
-       unpack_file "${DOWNLOAD_DELTA}" update-info.ini
-       unpack_file "${DOWNLOAD_DELTA}" delta-verifier
-       unpack_file "${DOWNLOAD_DELTA}" "${SCRIPT_UPGRADE_PARTIAL}"
-       unpack_file "${DOWNLOAD_DELTA}" "${SCRIPT_UPGRADE_FOTA}"
+       if [ $SINGLE_DELTA = false ]; then
+               unpack_file "${DELTA_A}" update-info.ini "$DELTA_A_CHECKSUM_FILE" "$DELTA_A_DIR"
+               unpack_file "${DELTA_B}" update-info.ini "$DELTA_B_CHECKSUM_FILE" "$DELTA_B_DIR"
+               merge_config_files_and_delete "$DELTA_A_DIR/update-info.ini" "$DELTA_B_DIR/update-info.ini" "$FOTA_DIR/update-info.ini"
+       else
+               unpack_file "${DELTA_A}" update-info.ini "$DELTA_A_CHECKSUM_FILE" ""
+       fi
 
        log "[Info] Begin delta verification"
        RET=0
@@ -247,15 +326,22 @@ if [ $MODE_RO_UPDATE = true ]; then
        log "[Info] Delta verification success"
 
        set_upgrade_status 1
-       verify_img "${DOWNLOAD_DELTA}"
+
+       verify_img "$DELTA_A"
+       if [ $SINGLE_DELTA = false ]; then
+               verify_img "$DELTA_B"
+       fi
+
        do_update
 fi
 
 if [ $MODE_FINISH_UPDATE = true ]; then
        set_script_name_and_log_file "${BASH_SOURCE[0]}"
 
-       verify_file "$0"
-       verify_file "$FOTA_DIR/upgrade-common.inc"
+       # Even if there are two deltas, verifying with one is enough as if there was some
+       # mismatch we wouldn't have reached this point
+       verify_file "$0" "$DELTA_A_CHECKSUM_FILE"
+       verify_file "$FOTA_DIR/upgrade-common.inc" "$DELTA_A_CHECKSUM_FILE"
        do_finish
 
 fi