diff --git a/scripts/asic_config_check b/scripts/asic_config_check new file mode 100755 index 000000000000..23be6b97421e --- /dev/null +++ b/scripts/asic_config_check @@ -0,0 +1,86 @@ +#!/bin/bash -e + +# Exit codes +ASIC_CONFIG_UNCHANGED=0 +ASIC_CONFIG_CHANGED=1 +SRC_ASIC_CONFIG_NOT_FOUND=2 +DST_ASIC_CONFIG_NOT_FOUND=3 + +# Logging utilities +function error() +{ + logger -p user.err "$@" +} + +function debug() +{ + logger -p user.info "$@" +} + +# Retrieve the source ASIC config checksum from the source image +# Exits with error SRC_ASIC_CONFIG_NOT_FOUND if the checksum is not found +function GetSourceASICConfigChecksum() +{ + if [[ ! -f "/etc/sonic/asic_config_checksum" ]]; then + error "ASIC config not found in src image, can't verify changes" + exit "${SRC_ASIC_CONFIG_NOT_FOUND}" + fi +} + +# Retrieve the destination ASIC config checksum from the destination image +# Exits with error DST_ASIC_CONFIG_NOT_FOUND if the checksum is not found +function GetDestinationASICConfigChecksum() +{ + DST_IMAGE_PATH="/host/image-${DST_SONIC_IMAGE#SONiC-OS-}" + FS_PATH="${DST_IMAGE_PATH}/fs.squashfs" + FS_MOUNTPOINT="/tmp/image-${DST_SONIC_IMAGE#SONiC-OS-}-fs" + + # Verify that the destination image exists + if [[ ! -d ${DST_IMAGE_PATH} ]]; then + error "ASIC config not found in dst image, can't verify changes" + exit "${DST_ASIC_CONFIG_NOT_FOUND}" + fi + + mkdir "${FS_MOUNTPOINT}" + mount -t squashfs "${FS_PATH}" "${FS_MOUNTPOINT}" + + if [[ ! -f "${FS_MOUNTPOINT}/etc/sonic/asic_config_checksum" ]]; then + error "ASIC config not found in dst image, can't verify changes" + umount "${FS_MOUNTPOINT}" + rm -rf "${FS_MOUNTPOINT}" + exit "${DST_ASIC_CONFIG_NOT_FOUND}" + fi + + cp "${FS_MOUNTPOINT}/etc/sonic/asic_config_checksum" /tmp/dst_asic_config_checksum + umount "${FS_MOUNTPOINT}" + rm -rf "${FS_MOUNTPOINT}" +} + +# Confirm that the src and dst ASIC config checksums match +# Exits with ASIC_CONFIG_CHANGED if the checksums differ +function ConfirmASICConfigChecksumsMatch() +{ + SRC_CONFIG_CHECKSUM=$(cat /etc/sonic/asic_config_checksum) + DST_CONFIG_CHECKSUM=$(cat /tmp/dst_asic_config_checksum) + if [[ "${SRC_CONFIG_CHECKSUM}" != "${DST_CONFIG_CHECKSUM}" ]]; then + error "ASIC config may have changed, checksum failed" + exit "${ASIC_CONFIG_CHANGED}" + fi +} + +# Main starts here +debug "Checking that ASIC configuration has not changed" + +SRC_SONIC_IMAGE="$(sonic_installer list | grep "Current: " | cut -f2 -d' ')" +DST_SONIC_IMAGE="$(sonic_installer list | grep "Next: " | cut -f2 -d' ')" +if [[ "${SRC_SONIC_IMAGE}" == "${DST_SONIC_IMAGE}" ]]; then + debug "ASIC config unchanged, src and dst SONiC version are the same" + exit "${ASIC_CONFIG_UNCHANGED}" +fi + +GetSourceASICConfigChecksum +GetDestinationASICConfigChecksum +ConfirmASICConfigChecksumsMatch + +debug "ASIC config unchanged, checksum passed" +exit "${ASIC_CONFIG_UNCHANGED}" diff --git a/scripts/fast-reboot b/scripts/fast-reboot index 8b05650e5671..d503c755ac85 100755 --- a/scripts/fast-reboot +++ b/scripts/fast-reboot @@ -250,6 +250,23 @@ function reboot_pre_check() debug "Next image ${NEXT_SONIC_IMAGE} doesn't exist ..." exit ${EXIT_NEXT_IMAGE_NOT_EXISTS} fi + + # Make sure ASIC configuration has not changed between images + ASIC_CONFIG_CHECK_SCRIPT="/usr/bin/asic_config_check" + ASIC_CONFIG_CHECK_SUCCESS=0 + if [[ "$REBOOT_TYPE" = "warm-reboot" || "$REBOOT_TYPE" = "fastfast-reboot" ]]; then + ASIC_CONFIG_CHECK_EXIT_CODE=0 + ${ASIC_CONFIG_CHECK_SCRIPT} || ASIC_CONFIG_CHECK_EXIT_CODE=$? + + if [[ "${ASIC_CONFIG_CHECK_EXIT_CODE}" != "${ASIC_CONFIG_CHECK_SUCCESS}" ]]; then + if [[ x"${FORCE}" == x"yes" ]]; then + debug "Ignoring ASIC config checksum failure..." + else + error "ASIC config may have changed: errno=${ASIC_CONFIG_CHECK_EXIT_CODE}" + exit "${EXIT_FAILURE}" + fi + fi + fi } function unload_kernel() diff --git a/setup.py b/setup.py index d12d9880b89d..a4bdf7089ef1 100644 --- a/setup.py +++ b/setup.py @@ -52,6 +52,7 @@ }, scripts=[ 'scripts/aclshow', + 'scripts/asic_config_check', 'scripts/boot_part', 'scripts/coredump-compress', 'scripts/db_migrator.py',