HAL_CURR_SIZE=0
HAL_NEXT_SIZE=0
+UPGRADE_LOG_DIR="/opt/var/log/fota"
+UPGRADE_LOG_FILE="$UPGRADE_LOG_DIR/upgrade.log"
+UPGRADE_SUPPORT_SCRIPT_NAMES=("upgrade-prepare-partitions.sh" "upgrade-trigger.sh" \
+ "upgrade-partial.sh" "upgrade-fota.sh")
+
if [ -z $BLKID_PRINT ]; then
BLKID_PRINT="/usr/bin/blkid-print"
fi
RESIZE_DYNPARTS="/bin/resize-dynparts"
fi
-#------------------------------------------------
-# critical_log msg [file]
-#------------------------------------------------
-critical_log() {
- # log format: [script_name][tag]actual_log
- LOG="[${SCRIPT_NAME}]$1"
- dlogsend -k "$LOG"
- if [ "$2" != "" ]; then
- echo "[$(date +"%d/%m/%Y %H:%M:%S")]" "$LOG" >> "$2"
+upgrade_log_init() {
+ if [ ! -d "$UPGRADE_LOG_DIR" ]; then
+ mkdir -p "$UPGRADE_LOG_DIR"
fi
- echo "$LOG"
- return 0
+ if [ -e "$UPGRADE_LOG_FILE" ]; then
+ rm "$UPGRADE_LOG_FILE"
+ touch "$UPGRADE_LOG_FILE"
+ fi
+
+ echo "[Info] Logging to $UPGRADE_LOG_FILE"
}
-critical_flog() {
- critical_log "$1" "$LOG_FILE"
+# Call this function every time a new script is run
+set_script_name_and_log_file() {
+ SCRIPT_NAME="$(basename "$1")"
+ LOG_FILE="/dev/null"
+
+ for name in "${UPGRADE_SUPPORT_SCRIPT_NAMES[@]}"
+ do
+ if [ "$name" == "$SCRIPT_NAME" ]; then
+ LOG_FILE="$UPGRADE_LOG_FILE"
+ break
+ fi
+ done
}
-#------------------------------------------------
-# log msg [file]
-#------------------------------------------------
log() {
# log format: [script_name][tag]actual_log
LOG="[${SCRIPT_NAME}]$1"
- if [ "$2" != "" ]; then
- echo "[$(date +"%d/%m/%Y %H:%M:%S")]" "$LOG" >> "$2"
+ LOG_DATE="[$(date +"%d/%m/%Y %H:%M:%S")]"
+
+ if [ $# -ge 2 ] && [ "$2" == "critical" ]; then
+ dlogsend -k "$LOG"
fi
- echo "$LOG"
- return 0
+ echo "$LOG_DATE" "$LOG" | tee -a "$LOG_FILE"
}
-flog() {
- log "$1" "$LOG_FILE"
+critical_log() {
+ log "$1" "critical"
}
untrap() {
trap 'echo "Aborting due to errexit on ${0##*/}:$LINENO. Exit code: $?" >&2' ERR
}
-verify_file() {
+verify_file_internal() {
FILE_NAME="$1"
FILE_PATH="$FOTA_DIR/$FILE_NAME"
VALID_CHECKSUM=$(awk "\$2 ~ /^$FILE_NAME\$/ {print \$1}" "$FOTA_DIR/checksum.SHA1")
if [ "$VALID_CHECKSUM" == "" ]; then
- echo "[Error] No $FILE_NAME in checksum.SHA1"
+ log "[Error] No $FILE_NAME in checksum.SHA1"
return $FALSE
fi
if ! echo "$VALID_CHECKSUM $FILE_PATH" | sha1sum --check --status; then
- echo "[Error] Checksum for file $FILE_NAME is invalid"
+ log "[Error] Checksum for file $FILE_NAME is invalid"
return $FALSE
fi
- echo "[Info] Checksum of $FILE_NAME is OK"
+ log "[Info] Checksum of $FILE_NAME is OK"
return $TRUE
}
FILE_NAME="$2"
tar xpf "${ARCHIVE_NAME}" -C "${FOTA_DIR}" "${FILE_NAME}" 2> /dev/null
if [ ! -e "${FOTA_DIR}/${FILE_NAME}" ]; then
- flog "[Error] There is no ${FILE_NAME}"
+ log "[Error] There is no ${FILE_NAME}"
fi
- if ! verify_file "$FILE_NAME"; then
+ if ! verify_file_internal "$FILE_NAME"; then
exit_error
fi
}
verify_img() {
DELTA_FILE="$1"
if [ -e "$IMG_VERIFIER" ]; then
- log "[Info] Package verifier is found. Verify $DELTA_FILE" "$LOG_FILE"
+ log "[Info] Package verifier is found. Verify $DELTA_FILE"
if ! "$IMG_VERIFIER" -i "$DELTA_FILE" -l "/opt/var/log/last_iv.log"; then
- log "[Error] Update package verification FAILED..." "$LOG_FILE"
+ log "[Error] Update package verification FAILED..."
echo 5 > "$STATUS_DIR"/result
exit_error
else
- log "[Info] Update package verification PASSED!" "$LOG_FILE"
+ log "[Info] Update package verification PASSED!"
fi
fi
}
echo "/dev/mapper/$part_name"
return 0
else
- echo "WARNING : SUPER FOUND BUT $part_name NOT FOUND" >&2
+ log "[Warning] : SUPER FOUND BUT $part_name NOT FOUND"
return 1
fi
}
check_if_super() {
- if SUPERFS="$("$BLKID_PRINT" "$EMMC_DEVICE" super a)"; then
+ if SUPERFS="$(("$BLKID_PRINT" "$EMMC_DEVICE" super a) 2>/dev/null)"; then
local MAPPED_DEVICES=""
MAPPED_DEVICES=$(dmsetup ls)
if ! EMMC_DEVICE="/dev/$(/bin/lsblk -ndo pkname "${ROOTFS_DEVICE}")" ||\
[ "$EMMC_DEVICE" == "/dev/" ]; then
- flog "[Error] Unable to find used block device: $EMMC_DEVICE, for /"
+ log "[Error] Unable to find used block device: $EMMC_DEVICE, for /"
exit_error
fi
}
background_copy() {
- flog "[Info] Background copying A|B partitions for update..."
+ log "[Info] Background copying A|B partitions for update..."
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"
+ log "[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"
+ log "[Error] Unable to find: $partition_name next partition on $EMMC_DEVICE device on $NEXT_AB slot"
check_optional_partition "$partition_name" 1
continue
fi
NEXT_PARTITION="/dev/mapper/${partition_name}_${NEXT_AB}"
else
if ! CURRENT_PARTITION="$("$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"
+ log "[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="$("$BLKID_PRINT" "$EMMC_DEVICE" "$partition_name" "$NEXT_AB")"; then
- flog "[Error] Unable to find: $partition_name next partition on $EMMC_DEVICE device on $NEXT_AB slot"
+ log "[Error] Unable to find: $partition_name next partition on $EMMC_DEVICE device on $NEXT_AB slot"
check_optional_partition "$partition_name" 1
continue
fi
fi
if [ "$CURRENT_PARTITION" == "" ] || [ "$NEXT_PARTITION" == "" ]; then
- flog "[Error] current: $CURRENT_PARTITION or next: $NEXT_PARTITION partition is empty on $EMMC_DEVICE device"
+ log "[Error] current: $CURRENT_PARTITION or next: $NEXT_PARTITION partition is empty on $EMMC_DEVICE device"
return $FALSE
fi
if [ "$CURRENT_PARTITION" == "$NEXT_PARTITION" ]; then
- flog "[Info] $partition_name partition current and next are the same: $CURRENT_PARTITION on $EMMC_DEVICE device"
+ log "[Info] $partition_name partition current and next are the same: $CURRENT_PARTITION on $EMMC_DEVICE device"
continue
fi
- flog "[Info] Background copy $partition_name, from: $CURRENT_PARTITION to $NEXT_PARTITION"
+ log "[Info] Background copy $partition_name, from: $CURRENT_PARTITION to $NEXT_PARTITION"
if [ -n "$SUPERFS" ] && { [ "$partition_name" == "rootfs" ] || [ "$partition_name" == "hal" ]; }; then
if [ "$partition_name" == "rootfs" ]; then
if (( ROOTFS_NEXT_SIZE < ROOTFS_CURR_SIZE )); then
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"
+ log "[Info] Finished background copy $partition_name from $CURRENT_PARTITION to $NEXT_PARTITION"
if [ "$partition_name" == "rootfs" ]; then
- flog "[Info] Checksum verification for $partition_name"
+ log "[Info] Checksum verification for $partition_name"
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}')
fi
if [ "$CUR_SHA1" == "$NEXT_SHA1" ]; then
- flog "[Info] Partition $partition_name was cloned correctly"
+ log "[Info] Partition $partition_name was cloned correctly"
else
- flog "[Error] Checksums are different: $CUR_SHA1 != $NEXT_SHA1"
+ log "[Error] Checksums are different: $CUR_SHA1 != $NEXT_SHA1"
exit_error
fi
fi
done
end_duration=$(date +%s)
totaltime=$((end_duration - start_duration))
- flog "[Info] Finished Background copying A|B partitions for update...Total Time : $totaltime sec"
+ log "[Info] Finished Background copying A|B partitions for update...Total Time : $totaltime sec"
return $TRUE
}
upgrade_images() {
DELTA_TAR="$1"
- flog "[Info] Flash images for update..."
+ log "[Info] Flash images for update..."
LABEL_MAP_PATH=${HAL_UPGRADE_CFG_DIR}/${HAL_}
while read LABEL PARTLABEL; do
fi
if ! /bin/tar tf "$DELTA_TAR" "$DELTA_NAME"; then
- flog "[Error] There is no delta $DELTA_NAME for label $LABEL_NAME from part $PART_NAME"
+ log "[Error] There is no delta $DELTA_NAME for label $LABEL_NAME from part $PART_NAME"
exit_error
fi
CURR_PARTITION="$("$BLKID_PRINT" "$EMMC_DEVICE" "$PART_NAME" "$CURRENT_AB")"
fi
- flog "[Info] Flashing $DELTA_NAME... to $NEXT_PARTITION"
+ log "[Info] Flashing $DELTA_NAME... to $NEXT_PARTITION"
local UP_RES
untrap
retrap
case $UP_RES in
0)
- flog "[Info] Finished flashing $DELTA_NAME... to $NEXT_PARTITION"
+ log "[Info] Finished flashing $DELTA_NAME... to $NEXT_PARTITION"
;;
*)
- flog "[Info] Flashing error $DELTA_NAME... to $NEXT_PARTITION"
+ log "[Info] Flashing error $DELTA_NAME... to $NEXT_PARTITION"
return $FALSE
;;
esac
SETUP_SCRIPT_PATH=$FOTA_DIR/$SETUP_SCRIPT_NAME
/bin/tar xvfp "$DELTA_TAR" -C "$FOTA_DIR" "$SETUP_SCRIPT_NAME" 2>/dev/null ||\
- (log "[Info] setup.sh does not exist, skipping." "$LOG_FILE" && return)
+ (log "[Info] setup.sh does not exist, skipping." && return)
if [ -e "$SETUP_SCRIPT_PATH" ]; then
/bin/sh "$SETUP_SCRIPT_PATH"
set_upgrade_status() {
VALUE="$1"
- ${SET_UPGRADE_STATUS} ${VALUE}
+ ${SET_UPGRADE_STATUS} ${VALUE} &>/dev/null
if [ $? -eq 0 ]; then
- critical_log "set_upgrade_status success: ${VALUE}" "$LOG_FILE"
+ critical_log "[Info] set_upgrade_status success: status is ${VALUE}"
else
- critical_log "set_upgrade_status failed: ${VALUE}" "$LOG_FILE"
+ critical_log "[Info] set_upgrade_status failed: status is ${VALUE}"
fi
}
exit_error() {
set_upgrade_status -1
- LOG_DIR="/var/log/fota"
-
- if [ ! -d "$LOG_DIR" ]; then
- /usr/bin/mkdir -p "$LOG_DIR"
- fi
-
- if [ -e /tmp/upgrade-prepare-partitions.log ]; then
- /usr/bin/mv /tmp/upgrade-prepare-partitions.log $LOG_DIR/
- fi
-
- if [ -e /tmp/upgrade-trigger.log ]; then
- /usr/bin/mv /tmp/upgrade-trigger.log $LOG_DIR/
- fi
-
- if [ -e /tmp/upgrade-partial.log ]; then
- /usr/bin/mv /tmp/upgrade-partial.log $LOG_DIR/
- fi
-
- if [ -e /tmp/update-fota.log ]; then
- /usr/bin/mv /tmp/update-fota.log $LOG_DIR/
- fi
-
exit 1
}
local MOUNT_OPTIONS="$3"
local SRC
if ! SRC="$("$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"
+ log "[Error] Unable to find $GPT_LABEL partition on $EMMC_DEVICE device for $NEXT_AB slot"
return 1
fi
local MOUNTED="$(/bin/findmnt -n -o TARGET "$SRC" | /bin/head -n 1 || echo "")"
SRC="$MOUNTED"
fi
if ! /bin/mkdir -p "$DST"; then
- flog "[Error] Unable to mkdir for mount destination: $DST"
+ log "[Error] Unable to mkdir for mount destination: $DST"
return 1
fi
if ! /bin/mount -o "$MOUNT_OPTIONS" "$SRC" "$DST"; then
- flog "[Error] Unable to mount $SRC to $DST, options: $MOUNT_OPTIONS"
+ log "[Error] Unable to mount $SRC to $DST, options: $MOUNT_OPTIONS"
return 1
fi
CLEANUP_PARTITION+=("$DST")
for (( idx=${#CLEANUP_PARTITION[@]}-1 ; idx>=0 ; idx-- )) ; do
local DST="${CLEANUP_PARTITION[idx]}"
if [ "$DST" == "" ]; then
- flog "[Error] Partition for cleanup is empty, idx: $idx, partition count: ${#CLEANUP_PARTITION[@]}"
+ log "[Error] Partition for cleanup is empty, idx: $idx, partition count: ${#CLEANUP_PARTITION[@]}"
continue
fi
if ! /bin/umount "$DST"; then
- flog "[Error] Unable to umount $DST"
+ log "[Error] Unable to umount $DST"
fi
done
FOTA_DIR="/opt/usr/data/fota"
STATUS_DIR="/opt/data/update"
DOWNLOAD_DELTA="$1"
-SCRIPT_NAME="upgrade-trigger.sh"
-LOG_FILE="/tmp/upgrade-trigger.log"
SCRIPT_UPGRADE_PREPARE_PARTITIONS="upgrade-prepare-partitions.sh"
SCRIPT_UPGRADE_PARTIAL="upgrade-partial.sh"
SCRIPT_UPGRADE_FOTA="upgrade-fota.sh"
BLKID_PRINT_FILE="blkid-print"
RESIZE_DYNPARTS_FILE="resize-dynparts"
FLOCK_PATH="/var/lock/clone_partitions.lock"
-DELTA_VERIFIER="/usr/bin/delta-verifier"
export BLKID_PRINT="$FOTA_DIR/$BLKID_PRINT_FILE"
export RESIZE_DYNPARTS="$FOTA_DIR/$RESIZE_DYNPARTS_FILE"
# If provided delta is from outside the FOTA_DIR delete everything
rm -rf -- "$FOTA_DIR/*"
fi
+ # `echo` commands below are intentional as upgrade-common.inc is not sourced yet (no access to logging functions)
else
- log "[Info] Create fota dir..." "$LOG_FILE"
+ echo "[Info] Create fota dir..."
mkdir -p "$FOTA_DIR"
fi
if [ ! -d "$STATUS_DIR" ]; then
- log "[Info] Create status dir..." "$LOG_FILE"
+ echo "[Info] Create status dir..."
mkdir -p "$STATUS_DIR"
fi
}
-log() {
- # log format: [script_name][tag]actual_log
- LOG="[${SCRIPT_NAME}]$1"
- if [ "$2" != "" ]; then
- echo "[$(date +"%d/%m/%Y %H:%M:%S")]" "$LOG" >> "$2"
- fi
- echo "$LOG"
-
- return 0
-}
-
is_ab_upgrade() {
if grep -q partition_ab= /proc/cmdline; then
return $TRUE
return $FALSE
}
+run_script() {
+ log "[Info] Running $1"
+ $1
+ RET=$?
+}
+
do_update() {
if is_ab_upgrade; then
set_upgrade_status 5
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"
+ log "[Info] Starting to prepare the partitions for upgrade.."
unpack_file "${DOWNLOAD_DELTA}" "${SCRIPT_UPGRADE_PREPARE_PARTITIONS}"
- if ! "${FOTA_DIR}/${SCRIPT_UPGRADE_PREPARE_PARTITIONS}"; then
+
+ run_script "${FOTA_DIR}/${SCRIPT_UPGRADE_PREPARE_PARTITIONS}"
+ if [ $RET -ne 0 ]; then
exit_error
fi
else
- echo "[Info] Partitions already cloned"
+ log "[Info] Partitions already cloned"
fi
set_upgrade_status 20
unpack_file "${DOWNLOAD_DELTA}" "${SCRIPT_UPGRADE_PARTIAL}"
unpack_file "${DOWNLOAD_DELTA}" "${SCRIPT_UPGRADE_FOTA}"
- if ! "${FOTA_DIR}/${SCRIPT_UPGRADE_PARTIAL}" "${DOWNLOAD_DELTA}"; then
- log "[Error] Failed to run $SCRIPT_UPGRADE_PARTIAL ${DOWNLOAD_DELTA}"
+ run_script ""${FOTA_DIR}/${SCRIPT_UPGRADE_PARTIAL}" "${DOWNLOAD_DELTA}""
+
+ if [ $RET -ne 0 ] ; then
+ log "[Error] Failed to run $SCRIPT_UPGRADE_PARTIAL ${DOWNLOAD_DELTA}" "$LOG_FILE"
exit_error
fi
# script will be aborted. We don't want this to be treated as an error.
untrap
set -u errexit
- if ! "${FOTA_DIR}/${SCRIPT_UPGRADE_FOTA}"; then
+ run_script "${FOTA_DIR}/${SCRIPT_UPGRADE_FOTA}"
+ if ! [ $RET -ne 0 ]; then
# We want to check if we are here becasue the reboot interrupted the
# execution of ${SCRIPT_UPGRADE_FOTA} or for some other reason.
# If a reboot is currently in progress then /proc/1/exe will point to
exit_error
else
set_upgrade_status 80
- echo "[Info] RO update: $SCRIPT_NAME success"
+ log "[Info] RO update: $SCRIPT_NAME success"
fi
fi
else
- echo "[Error] Non-A/B upgrade is unsupported"
+ log "[Error] Non-A/B upgrade is unsupported"
device_board_set_upgrade_status -1
exit 1
fi
VALID_CHECKSUM=$(awk "\$2 ~ /^$FILE_NAME\$/ {print \$1}" "$FOTA_DIR/checksum.SHA1")
if [ "$VALID_CHECKSUM" == "" ]; then
- echo "[Error] No $FILE_NAME in checksum.SHA1"
+ log "[Error] No $FILE_NAME in checksum.SHA1"
device_board_set_upgrade_status -1
exit 1
fi
if ! echo "$VALID_CHECKSUM $FILE_PATH" | sha1sum --check --status; then
- echo "[Error] Checksum for file $FILE_NAME is invalid"
+ log "[Error] Checksum for file $FILE_NAME is invalid"
device_board_set_upgrade_status -1
exit 1
fi
- echo "[Info] Checksum of $FILE_NAME is OK"
+ log "[Info] Checksum of $FILE_NAME is OK"
}
(
flock 9
-rm -f "$LOG_FILE" && touch "$LOG_FILE"
-
if [ "$#" != "1" ] || [ ! -f "$1" ]; then
- log "[Error] Usage: $0 path_to_delta.tar[.gz]" "$LOG_FILE"
+ echo "[Error] Usage: $0 path_to_delta.tar[.gz]"
exit 1
fi
-log "[Info] Triggered upgrade.." "$LOG_FILE"
-log "[Info] Using <$DOWNLOAD_DELTA> delta file." "$LOG_FILE"
-
prepare_fota_dir
+
tar xfp "$DOWNLOAD_DELTA" -C "$FOTA_DIR" checksum.SHA1
-verify_file "$0"
+
tar xfp "$DOWNLOAD_DELTA" -C "$FOTA_DIR" upgrade-common.inc
+
+. "$FOTA_DIR"/upgrade-common.inc
+upgrade_log_init
+set_script_name_and_log_file "${BASH_SOURCE[0]}"
+
verify_file "$FOTA_DIR/upgrade-common.inc"
+
+verify_file "$0"
tar xfp "$DOWNLOAD_DELTA" -C "$FOTA_DIR" update-info.ini
verify_file "$FOTA_DIR/update-info.ini"
tar xfp "$DOWNLOAD_DELTA" -C "$FOTA_DIR" delta-verifier
fi
log "[Info] Delta verification success"
-. "$FOTA_DIR"/upgrade-common.inc
-
set_upgrade_status 1
verify_img "${DOWNLOAD_DELTA}"
do_update