HAL_PART_LIST_FILE="background_copy.list"
CONFIG_FILE="update.cfg"
SET_UPGRADE_STATUS="/usr/bin/device_board_set_upgrade_status"
+GET_UPGRADE_STATUS="/usr/bin/device_board_get_upgrade_status"
DO_RW_UPDATE_FILE="$FOTA_UPDATE_PREFIX/opt/.do_rw_update"
TRUE=0
FALSE=1
RESIZE_DYNPARTS="/bin/resize-dynparts"
fi
+if [ -z "$COPY_BLOCKDEV" ]; then
+ COPY_BLOCKDEV="/bin/copy-blockdev"
+fi
+
upgrade_log_init() {
if [ ! -d "$UPGRADE_LOG_DIR" ]; then
mkdir -p "$UPGRADE_LOG_DIR"
background_copy() {
log "[Info] Background copying A|B partitions for update..."
start_duration=$(date +%s)
+
+ local partitions=()
+ local progress_to=100
+ local total_size=0
+ local curr_progress_from=0
+ local curr_progress_from_int=0
+ local curr_progress_to=0
+ local curr_progress_to_int=0
+ local range=0
+ local update=""
+
+ if [ "$#" -eq 1 ]; then
+ if ! curr_progress_from="$($GET_UPGRADE_STATUS)"; then
+ log "[Error] Cannot check upgrade status value"
+ exit_error
+ fi
+ progress_to=$1
+ update="--update"
+ fi
+
+ range=$((progress_to - curr_progress_from))
+
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 )); } || \
continue
fi
+ CURRENT_PARTITION="/dev/mapper/${partition_name}_${CURRENT_AB}"
+ CURRENT_PARTITION_SIZE="$(blockdev --getsize64 $CURRENT_PARTITION)"
+
if { [ "$partition_name" == "rootfs" ] && (( ROOTFS_NEXT_SIZE == 0 )); } || \
{ [ "$partition_name" == "hal" ] && (( HAL_NEXT_SIZE == 0 )); }; then
log "[Error] Unable to find: $partition_name next partition on $EMMC_DEVICE device on $NEXT_AB slot"
continue
fi
- CURRENT_PARTITION="/dev/mapper/${partition_name}_${CURRENT_AB}"
NEXT_PARTITION="/dev/mapper/${partition_name}_${NEXT_AB}"
+ NEXT_PARTITION_SIZE="$(blockdev --getsize64 $NEXT_PARTITION)"
else
if ! CURRENT_PARTITION="$("$BLKID_PRINT" "$EMMC_DEVICE" "$partition_name" "$CURRENT_AB")"; then
log "[Error] Unable to find: $partition_name current partition on $EMMC_DEVICE device on $CURRENT_AB slot"
continue
fi
+ CURRENT_PARTITION_SIZE="$(calculate_size $CURRENT_PARTITION)"
+
if ! NEXT_PARTITION="$("$BLKID_PRINT" "$EMMC_DEVICE" "$partition_name" "$NEXT_AB")"; then
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_SIZE="$(calculate_size $NEXT_PARTITION)"
fi
if [ "$CURRENT_PARTITION" == "" ] || [ "$NEXT_PARTITION" == "" ]; then
log "[Error] current: $CURRENT_PARTITION or next: $NEXT_PARTITION partition is empty on $EMMC_DEVICE device"
log "[Info] $partition_name partition current and next are the same: $CURRENT_PARTITION on $EMMC_DEVICE device"
continue
fi
- 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
- 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
+ BYTES_TO_COPY=0
+
+ if [ "$NEXT_PARTITION_SIZE" -lt "$CURRENT_PARTITION_SIZE" ]; then
+ BYTES_TO_COPY="$NEXT_PARTITION_SIZE"
else
- PART_SIZE="$(calculate_size "$CURRENT_PARTITION")"
- head -c "$PART_SIZE" "$CURRENT_PARTITION" > "$NEXT_PARTITION"
+ BYTES_TO_COPY="$CURRENT_PARTITION_SIZE"
fi
- log "[Info] Finished background copy $partition_name from $CURRENT_PARTITION to $NEXT_PARTITION"
+
+ total_size=$((total_size + BYTES_TO_COPY))
+ partitions+=("$partition_name $CURRENT_PARTITION $NEXT_PARTITION $BYTES_TO_COPY")
+ done
+
+ for partition in "${partitions[@]}"; do
+ read -r partition_name CURRENT_PARTITION NEXT_PARTITION BYTES_TO_COPY <<< "${partition}"
+
+ # calculate progress in % (float) in the given range
+ curr_progress_to="$(echo "$curr_progress_from" "$range" "$BYTES_TO_COPY" "$total_size" | awk '{print $1 + $2*($3/$4)}')"
+ # round to the nearest integer
+ curr_progress_from_int="$(printf "%.*f\n" 0 "$curr_progress_from")"
+ curr_progress_to_int="$(printf "%.*f\n" 0 "$curr_progress_to")"
+ check_sha1=""
if [ "$partition_name" == "rootfs" ]; then
- 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}')
- 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=$(head -c "$PART_SIZE" "$CURRENT_PARTITION" | sha1sum | awk '{print $1}')
- NEXT_SHA1=$(head -c "$PART_SIZE" "$NEXT_PARTITION" | sha1sum | awk '{print $1}')
- fi
+ check_sha1="--sha1"
+ fi
- if [ "$CUR_SHA1" == "$NEXT_SHA1" ]; then
- log "[Info] Partition $partition_name was cloned correctly"
- else
- log "[Error] Checksums are different: $CUR_SHA1 != $NEXT_SHA1"
- exit_error
- fi
+ log "[Info] Background copy $partition_name, from: $CURRENT_PARTITION to $NEXT_PARTITION"
+ if ! "$COPY_BLOCKDEV" "$CURRENT_PARTITION" "$NEXT_PARTITION" --cnt "$BYTES_TO_COPY" $update $check_sha1 --progress-from $curr_progress_from_int --progress-to $curr_progress_to_int; then
+ log "[Error] Couldn't copy $CURRENT_PARTITION to $NEXT_PARTITION"
+ exit_error
fi
+ log "[Info] Finished background copy $partition_name from $CURRENT_PARTITION to $NEXT_PARTITION"
+
+ curr_progress_from=$curr_progress_to
done
end_duration=$(date +%s)
totaltime=$((end_duration - start_duration))
fi
PROGRESS_AFTER_RO=80
+PROGRESS_AFTER_CLONING=20
PATH=/bin:/usr/bin:/sbin:/usr/sbin
FOTA_DIR="/opt/usr/data/fota"
SCRIPT_UPGRADE_FOTA="upgrade-fota.sh"
BLKID_PRINT_FILE="blkid-print"
RESIZE_DYNPARTS_FILE="resize-dynparts"
+COPY_BLOCKDEV_FILE="copy-blockdev"
FLOCK_PATH="/var/lock/clone_partitions.lock"
export BLKID_PRINT="$FOTA_DIR/$BLKID_PRINT_FILE"
export RESIZE_DYNPARTS="$FOTA_DIR/$RESIZE_DYNPARTS_FILE"
+export COPY_BLOCKDEV="$FOTA_DIR/$COPY_BLOCKDEV_FILE"
prepare_fota_dir() {
if [ -d "$FOTA_DIR" ]; then
unpack_file "${DOWNLOAD_DELTA}" "${RESIZE_DYNPARTS_FILE}"
chmod +x "$FOTA_DIR/$RESIZE_DYNPARTS_FILE"
+ unpack_file "${DOWNLOAD_DELTA}" "${COPY_BLOCKDEV_FILE}"
+ chmod +x "$FOTA_DIR/$COPY_BLOCKDEV_FILE"
+
unpack_file "$DOWNLOAD_DELTA" "$CONFIG_FILE"
if [ "$(device_board_get_partition_ab_cloned)" -eq 0 ]; then
unpack_file "${DOWNLOAD_DELTA}" "${SCRIPT_UPGRADE_PREPARE_PARTITIONS}"
- run_script "${FOTA_DIR}/${SCRIPT_UPGRADE_PREPARE_PARTITIONS}"
+ run_script "${FOTA_DIR}/${SCRIPT_UPGRADE_PREPARE_PARTITIONS} $PROGRESS_AFTER_CLONING"
if [ $RET -ne 0 ]; then
exit_error
fi
else
log "[Info] Partitions already cloned"
+ set_upgrade_status $PROGRESS_AFTER_CLONING
fi
- set_upgrade_status 20
-
# In the next steps the content of the partitions of the second slot will
# be modified, so they will not be a clone of the current partitions
device_board_clear_partition_ab_cloned