#!/bin/bash

# ********************************************** ***************************** #
# File Name: os_system_update.sh
# Description: update the system
# **************************************************************************** #

#包含头脚本
source /OSM/script/os_load_base.sh
# --------------------------  variables  ------------------------------------- #
#变量定义
G_ERROR=1
G_ERROR_NOT_ENOUGH_MEM_AND_COFFERDATA=2
G_ERROR_NOT_ENOUGH_MEM=2
G_ERROR_PKG_INVALIDE=3
G_ERROR_PKG_INEXISTENCE=4
G_ERROR_IMAGE_CAPACITY_NOT_ENOUGH=5
G_ERROR_BOOT_LINK_ERROR=6
G_PROMPT=false
G_BIOS_NEED_REBOOT=false
G_ERROR_ASL_NOT_INSTALL=0
G_ERROR_ASL_REINSTALL=9

G_PRODUCT_TYPE_LIST=(S3900 S6900 S2600T PANGEA_V2R1C00 PANGEA_V2R1C01 PANGEA_V2R1C10 PANGEA_V2R3C01 PANGEA_V2R5C00 PANGEA_V2R5C00_2U)
#产品型号
G_PRODUCT_TYPE=$(grep "Product Name is" /proc/osp/bsp | cut -d' ' -f4 | tr 'a-z' 'A-Z')
G_TYPE_S2600T="S2600T"
G_TYPE_S3900="S3900"
G_TYPE_S6900="S6900"
G_TYPE_PANGEA_V2R1C00="PANGEA_V2R1C00"
G_TYPE_PANGEA_V2R1C01="PANGEA_V2R1C01"
G_TYPE_PANGEA_V2R2C10="PANGEA_V2R2C10"
G_S3900_VERS_CONF="product_versions.S3900.conf"
G_S6900_VERS_CONF="product_versions.S6900.conf"
G_S2600T_VERS_CONF="product_versions.S2600T.conf"
G_PANGEA_V2R1C01_VERS_CONF="product_versions.PANGEA_V2R1C01.conf"
G_PANGEA_V2R1C00_VERS_CONF="product_versions.PANGEA_V2R1C00.conf"
G_PANGEA_V2R2C10_VERS_CONF="product_versions.PANGEA_V2R2C10.conf"

MAX_TRY_TIMES=3
G_SYS_PKG_DIR_IN_COFFER_DATA=/OSM/coffer_data/update
G_MEM_NEEDED_WHEN_CP_PKG=400

#内存最小值
G_MIN_MEM=280
G_TAR_PACKAGE_MIN_MEM=80
G_IMG_DIR=/startup_disk/image
G_UPDATE_BOOT_DIR=/startup_disk/image/boot_osp
G_UPDATE_TMP_DIR=/startup_disk/image/boot_osp_tmp
G_BOOT_OSP_BAK_DIR=/startup_disk/image/boot_osp_bak
G_COFFER_DATA_TMP=/OSM/coffer_data/update/tmp
G_UPDATE_DIR=/OSM/update
G_MD5_CHECK_FILE_NAME=md5sum_sync
G_SHA256_CHECK_FILE_NAME=sha256sum_sync
G_CUR_VERSION_FILE=/OSM/conf/versions.conf
G_PKG_VERSION_FILENAME=versions.conf
G_BIOS_UPDATE_KO_NAME=updatebios.ko
G_BIOS_UPDATE_KO_FILE=update_pkg/${G_PRODUCT_TYPE}/bios/updatebios.ko
G_BIOS_UPDATE_ROM_NAME=update_pkg/${G_PRODUCT_TYPE}/bios/bios.ROM

G_BIOS_UPDATE_DIR=/OSM/update
G_BIOS_UPDATE_PKG_DIR=/OSM/modules
G_BIOS_RUNNING_PKG_DIR=/startup_disk/image/boot
G_PRODUCT_BIOS_UPDATE_FILE_NAME=BIOSUpgradePackageName
G_UPDATE_PKG_PATH=/OSM/update/SYS_software.tgz
G_BIOS_PKG_DIR=bios
MESSAGE=/OSM/log/cur_debug/messages
G_SYNC_SOURCE_IP=""

BACKUP_DIR=/OSM/ccdb/store/soft_backup
BACKUP_BOOT_OSP_DIR=$BACKUP_DIR/boot_osp

#将PCIE版本文件放到硬盘，防止重启丢失
G_PCIE_PKG_VERSION_FILE=/startup_disk/conf/conf_local/pcie_version.conf
G_PCIE_PACKEG_VERSION_FILE=/OSM/update/pcie_version_pkg

#升级状态文件目录及文件名
G_UPDATE_STATE_DIR=/startup_disk/conf/conf_local
G_UPDATE_STATE_FILE=state_upd.lua
G_UPGRADE_FILE=UpgradeFile.xml
G_BAY_CONFIG_FILE=/startup_disk/conf/conf_local/bay_config.ini
G_BIOS_UPDATE_FAIL_ITEMNAME=BiosUpdateFailFile



G_PRODUCT_CFG_FILE=/OSM/conf/product.ini
G_DISK_UTIL_THRESHOLD=DiskUsageThrehold
G_PRODUCT_IMAGE_CAPACITY_ITEMNAME=UpgradeSysImageAvailableByte
G_SYS_PKG_NAME_ITEMNAME=SysUpgradePackageName
G_SYS_PKG_DIR_ITEMNAME=UpgradePackageDir
G_PRODUCT_UPDATE_INTF_SH=$G_UPDATE_PKG_DIR/product_update_intf.sh
G_PRODUCT_FIRE_SH=/OSM/script/product_upgrade_for_old.sh
#boot连接
G_BOOT_LINK=/startup_disk/image/boot
#备份目录
G_BOOT_OSP_BAK_DIR=/startup_disk/image/boot_osp_bak

#product_is_same_R_version.sh 当前系统待升级包中的系统版本
#脚本返回0表示在同一R版本，脚本返回1表示不在同一个R版本
G_PRODUCT_JUDGE_IS_SAME_R_SH=/OSM/script/product_is_same_R_version.sh

G_UPGRADE_OUTPUT_DETAIL_FILE_NAME=CmdOutputDetailFile

#热补丁相关
G_OS_HP_DIR="/OSM/coffer_bin/hotpatch"
G_HOT_PATCH_BOOT_DIR="/OSM/coffer_bin"
G_UPG_HP_PATCH_VER_CONF="$G_OS_HP_DIR/patch_version"
G_UPG_HP_START_PATCH_CONF="/startup_disk/conf/hotpatch_version_bak.conf"
#热补丁相关


#异构支持包相关全局变量

##异构支持包解压的目录
G_ASL_UPDATE_TMP_DIR=/startup_disk/image/boot/Asl_New
##异构支持包解压需要的磁盘空间
G_PRODUCT_ASL_IMAGE_CAPACITY_ITEMNAME=UpgradeAslPatchImageAvailableByte
##异构支持包解压需要的内存
G_ASL_TAR_PACKAGE_MIN_MEM=80
##异构包的配置文件
ASL_VERS_CONF=patch.conf
##异构包的校验文件
G_ASL_SHA256_CHECK_FILE_NAME=patch.sha256sum
##当前系统中异构支持包的配置文件
G_ASL_CONFIG_FILE_NAME=asl.conf
##当前系统中异构支持包的配置文件的目录
G_ASL_CONFIG_FILE_DIR=/OSM/conf
##系统的版本文件
G_SYS_CONFIG_FILE=/OSM/conf/versions.conf
##异构支持包安装目录
G_ASL_INSTALL_DIR=/startup_disk/image/boot/Asl
##异构支持包临时安装目录
G_ASL_TEMP_INSTALL_DIR=/startup_disk/image/boot/Asl_bak
##从远端拷贝过来的异构支持包配置文件存放位置
G_ASL_COPY_TEMP_FILE=/tmp/asl.conf
##上传包的目录
G_UploadPath=/OSM/update

G_TMP_FILE="/tmp/md1status"
G_INQ_TIMES=6
G_BOOTLOADER=`ls -l $G_IMG_DIR|grep grub |awk '{print $9}'`
# --------------------------  functions  ----------------------- ------------- #
UPD_ECHO()
{
    OS_echo "UPGRADE_SH: [`basename $0`] $1"
}

OS_UpdateHelp()
{
    UPD_ECHO "Usage: [ -f ] [-w] [-r] [ -c ]  [ -p package name ] [ -l ] "
    exit 1
}

OS_SaveLog()
{
    /OSM/script/os_coffer_main.sh -e
    if [ 0 != $? ] ; then
        OS_echo "UPGRADE_SH: --- os save log error! ---">/dev/null
    fi

    OS_echo "UPGRADE_SH: --- os save log sucessful! ---">/dev/null
}

# **************************************************************************** #
# Function Name: OS_UPGRADE_FORCE_FREEMEM is to force free mem
# Description:
# Parameter:
# Return: fail exit 1, succ return 0
# **************************************************************************** #
OS_UPGRADE_FORCE_FREEMEM()
{
    declare -i FREE_TIMES
    declare -i FREE_MEMORY

    FREE_TIMES=0
    FREE_MEMORY=0
    while true;do
        echo 3 > /proc/sys/vm/drop_caches
        let FREE_TIMES=$FREE_TIMES+1
        if [ $FREE_TIMES -gt 3 ];then
            OS_echo "[OS_UPGRADE_FORCE_FREEMEM] It has test $FREE_TIMES times"
            return 0
        fi

        FREE_MEMORY=`free -m|grep ^Mem|awk '{print $4}'`
        if [ $FREE_MEMORY -gt "${G_MIN_MEM}" ];then
            OS_echo "[OS_UPGRADE_FORCE_FREEMEM] It has reached $G_MIN_MEM memory"
            return 0
        fi
    done

    return 0
}

# **************************************************************************** #
# Function Name: OS_Confirm is check is the cmd need to been confirmed
# Description:
# Parameter:
# Return: fail exit 1, succ return 0
# **************************************************************************** #
OS_Confirm()
{
    if [ "$G_PROMPT" = "true" ] ; then
        return 0
    fi
    echo "Are you sure[Yy/Nn]?"
    L_GO=start
    while [ -n "$L_GO" ]
    do
        read L_WORK
        if [[ "$L_WORK" = [Yy] ]] ; then
            L_GO=""
        elif [[ "$L_WORK" = [Nn] ]] ; then
            exit 1
        fi
    done

    return 0
}

# **************************************************************************** #
# Function Name:
# Description:
# Parameter:
# Return:
# **************************************************************************** #
OS_CHECK_FREE_MEM_ENOUGH()
{
    L_NEED_MEM=$1

    #check memory is enough
    echo 3 >/proc/sys/vm/drop_caches

    FREE_MEM=`free -m|grep ^Mem|awk '{print $4}'`
    if [ "${FREE_MEM}" -lt "${L_NEED_MEM}" ];then
        OS_echo "[OS_CreatePolicy] Force free memory"
        return 1
    fi

    return 0
}

# **************************************************************************** #
# Function Name:
# Description:
# Parameter:
# Return:
# **************************************************************************** #
OS_CHECK_TAR_PACKAGE_MEM_ENOUGH()
{
    #check memory is enough
    echo 3 >/proc/sys/vm/drop_caches

    FREE_MEM=`free -m|grep ^Mem|awk '{print $4}'`
    if [ "${FREE_MEM}" -lt "${G_TAR_PACKAGE_MIN_MEM}" ];then
        declare -i FREE_TIMES
        declare -i FREE_MEMORY

        FREE_TIMES=0
        FREE_MEMORY=0
        while [ true ];do
            echo 3 > /proc/sys/vm/drop_caches
            let FREE_TIMES=$FREE_TIMES+1
            if [ $FREE_TIMES -gt 3 ];then
                return 1
            fi

            FREE_MEMORY=`free -m|grep ^Mem|awk '{print $4}'`
            if [ $FREE_MEMORY -gt "${G_TAR_PACKAGE_MIN_MEM}" ];then
                return 0
            fi
        done
    fi

    return 0
}

CHECK_PACKAGE_MD5()
{
    local pkg_dir=$1
    cd $pkg_dir
    if [ ! -f $G_MD5_CHECK_FILE_NAME ] ; then
        OS_echo "UPGRADE_SH: $G_MD5_CHECK_FILE_NAME not exist, can not md5check, return 1" >/dev/null
        return 1
    fi

    #check md5
    L_OK_NUM=`cat $G_MD5_CHECK_FILE_NAME |wc -l`
    L_OK_MD5=`md5sum -c $G_MD5_CHECK_FILE_NAME |grep "OK"|wc -l `
    OS_echo "UPGRADE_SH: L_OK_NUM = [$L_OK_NUM], L_OK_MD5 = [$L_OK_MD5]" >/dev/null

    if [ "$L_OK_NUM" != "$L_OK_MD5" ] ; then
        OS_echo "UPGRADE_SH: md5 check error, the total ok is $L_OK_NUM, but there only $L_OK_MD5 ok" >/dev/null
        L_FAIL=`md5sum -c $G_MD5_CHECK_FILE_NAME |grep "FAILED"|cut -d ':' -f 1`
        OS_echo "UPGRADE_SH: $L_FAIL check error" >/dev/null
        cd - &>/dev/null
        return 1
    fi
    OS_echo "UPGRADE_SH: md5sum -c $G_MD5_CHECK_FILE_NAME success" >/dev/null
    return 0
}

CHECK_PACKAGE_SHA256()
{
    local pkg_dir=$1
    cd $pkg_dir

    #check sha256
    L_OK_NUM=`cat $G_SHA256_CHECK_FILE_NAME |wc -l`
    L_OK_SHA256=`sha256sum -c $G_SHA256_CHECK_FILE_NAME |grep "OK"|wc -l `
    OS_echo "UPGRADE_SH: L_OK_NUM = [$L_OK_NUM], L_OK_SHA256 = [$L_OK_SHA256]" >/dev/null

    if [ "$L_OK_NUM" != "$L_OK_SHA256" ] ; then
        OS_echo "UPGRADE_SH: sha256 check error, the total ok is $L_OK_NUM, but there only $L_OK_SHA256 ok" >/dev/null
        L_FAIL=`sha256sum -c $G_SHA256_CHECK_FILE_NAME |grep "FAILED"|cut -d ':' -f 1`
        OS_echo "UPGRADE_SH: $L_FAIL check error" >/dev/null
        cd - &>/dev/null
        return 1
    fi
    OS_echo "UPGRADE_SH: sha256sum -c $G_SHA256_CHECK_FILE_NAME success" >/dev/null
    return 0
}

CHECK_PACKAGE()
{
    local pkg_dir=$1
        
    if [ -f $pkg_dir/$G_SHA256_CHECK_FILE_NAME ] ; then
        OS_echo "UPGRADE_SH: $G_SHA256_CHECK_FILE_NAME exist, check it" >/dev/null
        CHECK_PACKAGE_SHA256 $pkg_dir
        if [ "$?" == "0" ] ; then
        return 0    
        fi 
    fi      
    if [ -f $pkg_dir/$G_MD5_CHECK_FILE_NAME ] ; then
        OS_echo "UPGRADE_SH: $G_MD5_CHECK_FILE_NAME exist, check it" >/dev/null
        CHECK_PACKAGE_MD5 $pkg_dir
        if [ "$?" == "0" ] ; then            
            return 0 
        fi
    fi  
    return $G_ERROR_PKG_INVALIDE
}

# **************************************************************************** # 
# Function Name: Check_file_md5 
# Description: 检查文件的md5 
# Parameter: 
# Return:  
# **************************************************************************** # 
Check_file_md5() 
{ 
    local pkg_dir=$1 
    local file_name=$2 
    cd $pkg_dir 
     
    local realvalue=`md5sum $file_name | awk '{print $1}'` 
    if [ -z "$realvalue" ] ; then 
        OS_echo "UPGRADE_SH: check $file_name failed." >/dev/null 
        cd - &>/dev/null
        return 1     
    fi 
     
    local configvaule=`cat md5sum_sync | grep "$file_name" | awk '{print $1}'` 
    if [ -z "$configvaule" ] ; then 
        OS_echo "UPGRADE_SH: no $file_name in check file." >/dev/null 
        cd - &>/dev/null
        return 1     
    fi 
    
    cd - &>/dev/null
    OS_echo "UPGRADE_SH: $file_name md5 realvalue is $realvalue, and configvaule is $configvaule." >/dev/null 
    if [ "$realvalue" != "$configvaule" ];then 
        return 1 
    fi 
     
    return 0 
} 
# **************************************************************************** # 
# Function Name: Check_file_sha256 
# Description: 检查文件的sha256 
# Parameter: 
# Return:  
# **************************************************************************** # 
Check_file_sha256() 
{ 
    local pkg_dir=$1 
    local file_name=$2 
    cd $pkg_dir 
     
    local realvalue=`sha256sum $file_name | awk '{print $1}'` 
    if [ -z "$realvalue" ] ; then 
        OS_echo "UPGRADE_SH: check $file_name failed." >/dev/null 
        cd - &>/dev/null
        return 1     
    fi 
    local configvaule=`cat sha256sum_sync | grep "$file_name" | awk '{print $1}'` 
    if [ -z "$configvaule" ] ; then 
        OS_echo "UPGRADE_SH: no $file_name in check file." >/dev/null 
        cd - &>/dev/null
        return 1     
    fi 
     
    cd - &>/dev/null
    OS_echo "UPGRADE_SH: $file_name sha256 realvalue is $realvalue, and configvaule is $configvaule." >/dev/null 
    if [ "$realvalue" != "$configvaule" ];then 
        return 1 
    fi 
    return 0 
} 
# **************************************************************************** # 
# Function Name: Check_Initrd_and_Bzimage 
# Description: 升级重启前再校验一次initrd和bzimage，防止损坏无法引导系统。 
###########    不再校验整个目录，整个目录的改动无法管控 
# Parameter: 
# Return:  
# **************************************************************************** # 
Check_Initrd_and_Bzimage() 
{ 
    local pkg_dir=$1 
    local initrd_file=initrd 
    local bzimage_file=bzImage 
     
    if [ -f $pkg_dir/$G_SHA256_CHECK_FILE_NAME ] ; then 
        OS_echo "UPGRADE_SH: $G_SHA256_CHECK_FILE_NAME exist, check it" >/dev/null 
        Check_file_sha256 $pkg_dir $initrd_file 
        if [ "$?" != "0" ];then 
            return 1 
        fi 
        Check_file_sha256 $pkg_dir $bzimage_file 
        if [ "$?" != "0" ];then 
            return 1 
        fi 
        return 0 
    fi 
    if [ -f $pkg_dir/$G_MD5_CHECK_FILE_NAME ] ; then 
        OS_echo "UPGRADE_SH: $G_MD5_CHECK_FILE_NAME exist, check it" >/dev/null 
        Check_file_md5 $pkg_dir $initrd_file 
        if [ "$?" != "0" ];then 
            return 1 
        fi 
        Check_file_md5 $pkg_dir $bzimage_file 
        if [ "$?" != "0" ];then 
            return 1 
        fi 
        return 0 
    fi 
         
    return 1 
} 
# **************************************************************************** # 
# Function Name: Del_DM_in_Checksum 
# Description: 删除校验文件中的DM校验。 
# Parameter: 
# Return:  
# **************************************************************************** # 
Del_DM_in_Checksum() 
{ 
    local TMP_DIR=$1 
    cd $TMP_DIR 
     
    if [ -f ${G_SHA256_CHECK_FILE_NAME} ]; then 
        OS_echo "UPGRADE_SH: Del ism in $G_SHA256_CHECK_FILE_NAME." >/dev/null 
        sed -i '/ism_cs_full.tgz/d' ${G_SHA256_CHECK_FILE_NAME}  
        return 0 
    elif [ -f ${G_MD5_CHECK_FILE_NAME} ]; then 
        OS_echo "UPGRADE_SH: Del ism in $G_MD5_CHECK_FILE_NAME." >/dev/null 
        sed -i '/ism_cs_full.tgz/d' ${G_MD5_CHECK_FILE_NAME}  
        return 0 
    fi 
     
    return 1 
} 

PRODUCE_MD5_FOR_DIR()
{
    local TMP_DIR=$1
    cd $TMP_DIR
        
    rm -f md5sum_sync
    tree -ifa . | while read LINE
    do
        if [ -n "${LINE}" ] ; then
            if [ -f "${LINE}" ] ; then
                md5sum "${LINE}" >> md5sum_sync
            fi
        fi
    done
        
    return 0;
}

PRODUCE_SHA256_FOR_DIR()
{
    local TMP_DIR=$1
    cd $TMP_DIR
        
    rm -f sha256sum_sync
    tree -ifa . | while read LINE
    do
        if [ -n "${LINE}" ] ; then
            if [ -f "${LINE}" ] ; then
                sha256sum "${LINE}" >> sha256sum_sync
            fi
        fi
    done
    
    return 0;
}

PRODUCE_CHECKSUM_FOR_DIR()
{
    local TMP_DIR=$1
    cd $TMP_DIR
    
    if [ -f ${G_SHA256_CHECK_FILE_NAME} ]; then
        PRODUCE_SHA256_FOR_DIR $TMP_DIR
        ret=$?
        if [ "0" != "$ret" ]; then
            OS_echo "UPGRADE_SH: Failed to produce ${G_SHA256_CHECK_FILE_NAME} for ${TMP_DIR}." >/dev/null
        fi
        return $ret
    elif [ -f ${G_MD5_CHECK_FILE_NAME} ]; then
        PRODUCE_MD5_FOR_DIR $TMP_DIR
        ret=$?
        if [ "0" != "$ret" ]; then
            OS_echo "UPGRADE_SH: Failed to produce ${G_MD5_CHECK_FILE_NAME} for ${TMP_DIR}." >/dev/null
        fi
        return $ret
    fi
    
    return 0
}

# **************************************************************************** #
# Function Name: UPD_CLEAR_USELESS_FIRMWARE
# Description:删除产品包中无用的小固件包
# Parameter:产品型号，通过/proc/osp/bsp获取
# Return:NA
# **************************************************************************** #
UPD_CLEAR_USELESS_FIRMWARE()
{
    local ProductType=$1
    local FindFlag=false
    local PkgPath=$2
    
    #BEGIN: S3900老版本特殊处理，后续禁止增加
    if [ ${ProductType} == "S3900" ] && [ -d ${PkgPath}/update_pkg/S6900 ] ; then
        mv ${PkgPath}/update_pkg/S6900/pcie_pkg/*PCIE*.tgz ${PkgPath}/update_pkg/
    fi
    #END
    
    for pdt in "${G_PRODUCT_TYPE_LIST[@]}"
    do
        if [ ${ProductType} != "${pdt}" ]; then
            rm -rf ${PkgPath}/update_pkg/$pdt
        else
            FindFlag=true
        fi
    done
    
    #BEGIN: S3900老版本特殊处理，后续禁止增加
    if [ ${ProductType} == "S3900" ] ; then
        local pciePkgPath=${PkgPath}/update_pkg/S6900/pcie_pkg/
        for file in ${PkgPath}/update_pkg/*PCIE*.tgz
        do
            [ -e "$file" ] && mkdir -p ${pciePkgPath} && mv $file ${pciePkgPath}
        done
    fi
    #END
    
    if [ false == $FindFlag ]; then
        UPD_ECHO "Clear useless update_pkg failed, cause the product type ${ProductType} is unknown."
    fi
}


# **************************************************************************** #
# Function Name: UPD_PREHANDLE_FOR_VMMS
# Description: 升级/回退前调用vmms脚本修改menu.lst
# Parameter:NA
# Return:NA
# **************************************************************************** #
UPD_PREHANDLE_FOR_VMMS()
{
    local L_CUR_KER_VER=$1
    local L_PKG_VERSION=$2
    local L_PRODUCT_TYPE=`cat "$G_PRODUCT_CFG_FILE" | awk '/ProductName =/ {print $(NF-1)}'`
    
    if [ ! -f /OSM/script/vmms_change_menu_when_upgrade.sh ];then
        OS_echo "UPGRADE_SH: no vmms script!" >/dev/null
        return 0
    fi
    
    sh /OSM/script/vmms_change_menu_when_upgrade.sh $L_CUR_KER_VER $L_PKG_VERSION $G_UPDATE_TMP_DIR
    if [ "0" != "$?" ];then
        OS_echo "UPGRADE_SH: Change menulst failed!" >/dev/null
        return 1
    fi
    
    return 0
}

# **************************************************************************** #
# Function Name: OS_CHECK_PACKAGE
# Description:
# Parameter:
# Return:
# **************************************************************************** #
OS_CHECK_PACKAGE()
{
    cd $G_UPDATE_TMP_DIR

    #check the product id
    L_CUR_VERSION=`cat $G_CUR_VERSION_FILE |grep -m 1 Version |awk -F"=" '{print $2}'`
    L_PKG_VERSION=`cat $G_UPDATE_TMP_DIR/$G_PKG_VERSION_FILENAME |grep -m 1 Version |awk -F"=" '{print $2}'`
    OS_echo "UPGRADE_SH: Cur Version=$L_CUR_VERSION, Pkg Version=$L_PKG_VERSION" >/dev/null

    L_CUR_PDT=`echo $L_CUR_VERSION |awk -F. '{print $2}'`
    if [ -z "$L_CUR_PDT" ];then
        L_CUR_PDT=`echo ${L_CUR_VERSION:0:3}`
    fi

    L_PKG_PDT=`echo $L_PKG_VERSION |awk -F. '{print $2}'`
    if [ -z "$L_PKG_PDT" ];then
        L_PKG_PDT=`echo ${L_PKG_VERSION:0:3}`
    fi

    OS_echo "UPGRADE_SH: [CheckTheVersion] cur product id = $L_CUR_PDT, package product id = $L_PKG_PDT." >/dev/null
    if [ "$L_PKG_PDT" == "" ] || [ $L_CUR_PDT != $L_PKG_PDT ] ; then
        OS_echo "UPGRADE_SH: [CheckTheVersion]Error, package not compatible." >/dev/null
        cd - &>/dev/null
        return 1
    fi

    cd - &>/dev/null
        
    #为虚拟机预修改menu.lst
    UPD_PREHANDLE_FOR_VMMS $L_CUR_VERSION $L_PKG_VERSION
    ret=$?
    if [ "0" != "$ret" ];then
        return $ret
    fi 

    #重新生成校验文件
    PRODUCE_CHECKSUM_FOR_DIR ${G_UPDATE_TMP_DIR}
    if [ "$?" != "0" ]; then
        return 1
    fi
    
    return 0
}

# **************************************************************************** #
# Function Name: OM_RelinkBoot
# Description: relink the boot link
# Parameter: 1-link to dir
# Return:
# **************************************************************************** #
OM_ClearResetTimes()
{
    if [ -f "/sys/kernel/nvram/info" ] ; then
        echo "Clean NVRAM" >/sys/kernel/nvram/info
    else
        OS_echo "[OM_ClearResetTimes]/sys/kernel/nvram/info does not exist, can't Clean NVRAM!"
        return 1
    fi
    return 0
}


# **************************************************************************** #
# Function Name: OM_RelinkBoot
# Description: relink the boot link
# Parameter: 1-link to dir
# Return:
# **************************************************************************** #
OM_Rollback()
{
    L_Clear_Flag=$1
    mount -o remount,rw,async $G_DISK_MOUNT_IMAGE &>/dev/kmsg

    mv $G_UPDATE_BOOT_DIR $G_UPDATE_TMP_DIR &>/dev/kmsg

    mv $G_BOOT_OSP_BAK_DIR $G_UPDATE_BOOT_DIR &>/dev/kmsg

    mv $G_UPDATE_TMP_DIR $G_BOOT_OSP_BAK_DIR &>/dev/kmsg

    if [ "$L_Clear_Flag" = "true" ] ; then
        OM_ClearResetTimes
    fi

    cd /
    mount -o remount,ro,sync $G_DISK_MOUNT_IMAGE &>/dev/kmsg
    return 0
}

# **************************************************************************** #
# Function Name:OS_UPDATE_PACKAGE
# Description:
# Parameter:
# Return:
# **************************************************************************** #
OS_UPDATE_PACKAGE()
{
    OS_echo "UPGRADE_SH: OS_UPDATE_PACKAGE Begin" >/dev/null

    # check current system
    L_BOOT_TYPE=`cat /boot/boot_type`
    if [ "$L_BOOT_TYPE" != "os_boot_osp" ] ; then
        OS_echo "UPGRADE_SH: Warning!!!System in $L_BOOT_TYPE type, not os_boot_osp." >/dev/null
        OS_echo "UPGRADE_SH: Warning!!!It is dangerous to update in $L_BOOT_TYPE type." >/dev/null
    fi

    OS_echo "UPGRADE_SH: cd $G_DISK_MOUNT_IMAGE" >/dev/null

    cd $G_DISK_MOUNT_IMAGE

    OS_echo "UPGRADE_SH: rm -rf boot_osp_bak" >/dev/null
    rm -rf boot_osp_bak/* &>/dev/kmsg

    OS_echo "UPGRADE_SH: mv -f boot_osp_tmp boot_osp_bak" >/dev/null
    mv boot_osp_tmp/* boot_osp_bak &>/dev/kmsg
    rm -rf boot_osp_tmp &>/dev/kmsg

    OS_echo "UPGRADE_SH: cd $G_DISK_MOUNT_IMAGE/boot_osp_bak" >/dev/null
    cd $G_DISK_MOUNT_IMAGE/boot_osp_bak &>/dev/kmsg
    OS_echo "UPGRADE_SH: ln -s ../$G_BOOTLOADER $G_BOOTLOADER" >/dev/null
    ln -s ../$G_BOOTLOADER $G_BOOTLOADER &>/dev/kmsg

    #清除nvram
    OS_echo "UPGRADE_SH: OS_ClearResetTimes" >/dev/null
    OS_ClearResetTimes

    OS_echo "UPGRADE_SH: OS_UPDATE_PACKAGE Exist" >/dev/null

    sync
    echo 3 >/proc/sys/vm/drop_caches

    FREE_MEM=`free -m|grep ^Mem|awk '{print $4}'`
    if [ "${FREE_MEM}" -lt "${G_MIN_MEM}" ];then
        OS_echo "[OS_CreatePolicy] Force free memory"
        OS_UPGRADE_FORCE_FREEMEM
    fi

    return 0
}

# **************************************************************************** #
# Function Name:
# Description:
# Parameter:
# Return:
# **************************************************************************** #
OM_COVERT_BOOT_OSP_BAK_TO_BOOT_OSP()
{
    OS_echo "UPGRADE_SH: covert boot_osp and boot_osp_bak">/dev/null
    cd $G_DISK_MOUNT_IMAGE
    rm -fr boot &>/dev/kmsg
    if [ "0" != "$?" ] ; then
        OS_SET_DISK_RW
        rm -fr boot &>/dev/kmsg
        if [ "0" != "$?" ] ; then
            OS_echo "UPGRADE_SH: rm boot point failed">/dev/null
            exit 1
        fi
    fi
    OS_echo "UPGRADE_SH: rm boot point success">/dev/null

    mv $G_UPDATE_BOOT_DIR $G_UPDATE_TMP_DIR &>/dev/kmsg

    mv $G_BOOT_OSP_BAK_DIR $G_UPDATE_BOOT_DIR &>/dev/kmsg

    mv $G_UPDATE_TMP_DIR $G_BOOT_OSP_BAK_DIR &>/dev/kmsg

    ln -s boot_osp boot &>/dev/kmsg
    if [ 0 != $? ] ; then
        OS_echo "UPGRADE_SH: relink boot point to boot_osp failed">/dev/null
        exit 1
    fi
    OS_echo "UPGRADE_SH: relink boot point to boot_osp success">/dev/null

    return 0
}

# **************************************************************************** #
# Function Name:
# Description:
# Parameter:
# Return:
# **************************************************************************** #
OS_MODIFY_LINK_TO_BAK()
{
    OS_echo "UPGRADE_SH: rm boot and relink boot point to boot_osp_bak">/dev/null
    cd $G_DISK_MOUNT_IMAGE
    rm -fr boot &>/dev/kmsg
    if [ "0" != "$?" ] ; then
        OS_SET_DISK_RW
        rm -fr boot &>/dev/kmsg
        if [ "0" != "$?" ] ; then
            OS_echo "UPGRADE_SH: rm boot point failed">/dev/null
            exit 1
        fi
    fi
    OS_echo "UPGRADE_SH: rm boot point success">/dev/null

    ln -s boot_osp_bak boot &>/dev/kmsg
    if [ 0 != $? ] ; then
        OS_echo "UPGRADE_SH: relink boot point to boot_osp_bak failed">/dev/null
        exit 1
    fi
    OS_echo "UPGRADE_SH: relink boot point to boot_osp_bak success">/dev/null
    cd /OSM

    return 0
}
# **************************************************************************** #
# Function Name:
# Description:
# Parameter:
# Return:
# **************************************************************************** #
OS_ROLLBACK_CHANGE_LINK()
{
    L_LINK_DIR=`ls -l /startup_disk/image/boot |awk '{print $11}'`
    if [ -z $L_LINK_DIR ];then
        OS_echo "UPGRADE_SH: get the link of boot point fail"
        exit 1
    fi
    OS_echo "UPGRADE_SH: the link of boot point is (boot->$L_LINK_DIR)"

    cd $G_DISK_MOUNT_IMAGE
    rm -fr boot &>/dev/kmsg
    if [ "0" != "$?" ];then
        OS_SET_DISK_RW
        rm -fr boot &>/dev/kmsg
        if [ "0" != "$?" ] ; then
            OS_echo "UPGRADE_SH: rm boot point failed">/dev/null
            exit 1
        fi
    fi
    OS_echo "UPGRADE_SH: rm boot point success">/dev/null

    if [ "boot_osp" == $L_LINK_DIR ];then
        OS_echo "UPGRADE_SH: Need change the link boot point to boot_osp_bak for rollback"
        ln -s boot_osp_bak boot &>/dev/kmsg
        if [ 0 != $? ] ; then
            OS_echo "UPGRADE_SH: relink boot point to boot_osp_bak failed">/dev/null
            exit 1
        fi
    elif [ "boot_osp_bak" == $L_LINK_DIR ];then
        OS_echo "UPGRADE_SH: Need change the link boot point to boot_osp for rollback"
        ln -s boot_osp boot &>/dev/kmsg
        if [ 0 != $? ] ; then
            OS_echo "UPGRADE_SH: relink boot point to boot_osp failed">/dev/null
            exit 1
        fi
    else
        OS_echo "UPGRADE_SH: the link of boot point(boot->$L_LINK_DIR) is error!">/dev/null
        exit 1
    fi
    OS_echo "UPGRADE_SH: relink boot point for rollback success">/dev/null

    return 0
}
# **************************************************************************** #
# Function Name:
# Description:
# Parameter:
# Return:
# **************************************************************************** #
OS_CHECK_IMAGE_CAPACITY_ENOUGH()
{
    local L_PACKAGE_NAME=$1
    L_NEED_SIZE=`du -k $L_PACKAGE_NAME | awk '{print $1}'`
    let L_NEED_SIZE=$L_NEED_SIZE+80*1024
    
    #先判断保险箱盘的空间,保险箱和启动盘都不够返2，保险箱够返0，启动盘够返1
    L_AVAILABLE_SIZE=`df /OSM/coffer_data/ |grep /OSM/coffer_data |awk '{print $4}'`
    OS_echo "UPGRADE_SH: Cur coffer_data Capacity(byte) = $L_AVAILABLE_SIZE,  Needed = $L_NEED_SIZE" >/dev/null
    if [[ $L_AVAILABLE_SIZE -lt $L_NEED_SIZE ]] ; then
        OS_echo "UPGRADE_SH: coffer_data Capacity Not Enough" >/dev/null
        L_AVAILABLE_SIZE=`df /startup_disk/image/ |grep /startup_disk/image |awk '{print $4}'`
        OS_echo "UPGRADE_SH: Cur Medium Capacity(byte) = $L_AVAILABLE_SIZE,  Needed = $L_NEED_SIZE" >/dev/null
        if [[ $L_AVAILABLE_SIZE -lt $L_NEED_SIZE ]] ; then
            OS_echo "UPGRADE_SH: Medium Capacity Not Enough" >/dev/null
            return 2
        else
            return 1
        fi
    else
        OS_echo "UPGRADE_SH: Medium Capacity Enough" >/dev/null
        return 0
    fi
}

UPD_CHOOSE_CONF_FILE()
{
    local ProductType=$1
    local VERSIONS_CONF=product_versions.${ProductType}.conf
    local MENU_LST=menu_${G_PRODUCT_TYPE}.lst
    local GRUB_CFG=grub_${G_PRODUCT_TYPE}.cfg
    
    UPD_ECHO "Production type is ${ProductType}" >/dev/null
    if [ -f ${VERSIONS_CONF} ]; then
        cp -f ${VERSIONS_CONF} versions.conf
    else
        UPD_ECHO "Product type(${ProductType}) without conf($VERSIONS_CONF)!" >/dev/null
        return 1
    fi
    
    cd ${G_UPDATE_TMP_DIR}/conf
    if [ -f ${MENU_LST} ]; then
        cp -af ${MENU_LST} menu.lst
        #SHA256
        if [ -f $G_UPDATE_TMP_DIR/$G_SHA256_CHECK_FILE_NAME ] ; then
            L_SHA256_RET=`sha256sum menu.lst | awk '{print $1}'`
            sed -i "s/^.*menu\.lst.*$/${L_SHA256_RET}  \.\/conf\/menu\.lst/g" ../sha256sum_sync
        elif [ -f $G_UPDATE_TMP_DIR/$G_MD5_CHECK_FILE_NAME ] ; then
            L_MD5_RET=`md5sum menu.lst | awk '{print $1}'`
            sed -i "s/^.*menu\.lst.*$/${L_MD5_RET}  \.\/conf\/menu\.lst/g" ../md5sum_sync
        fi
    else
        UPD_ECHO "Product type(${ProductType}) without menu.lst($MENU_LST)!" >/dev/null
    fi
    if [ -f ${GRUB_CFG} ]; then
        cp -af ${GRUB_CFG} grub.cfg
        #SHA256
        if [ -f $G_UPDATE_TMP_DIR/$G_SHA256_CHECK_FILE_NAME ] ; then
            L_SHA256_RET=`sha256sum grub.cfg | awk '{print $1}'`
            sed -i "s/^.*grub\.cfg.*$/${L_SHA256_RET}  \.\/conf\/grub\.cfg/g" ../sha256sum_sync
        elif [ -f $G_UPDATE_TMP_DIR/$G_MD5_CHECK_FILE_NAME ] ; then
            L_MD5_RET=`md5sum grub.cfg | awk '{print $1}'`
            sed -i "s/^.*grub\.cfg.*$/${L_MD5_RET}  \.\/conf\/grub\.cfg/g" ../md5sum_sync
        fi
    else
        UPD_ECHO "Product type(${ProductType}) without grub.cfg($GRUB_CFG)!" >/dev/null
    fi
    return 0
}

# **************************************************************************** #
# Function Name:
# Description:
# Parameter:
# Return:
# **************************************************************************** #
OS_TAR_UPDATE_PACKAGE()
{
    L_PACKAGE_PATH_NAME=$1
    local L_MD5_RET=""
    local L_SHA256_RET=""
    if [ ! -f $L_PACKAGE_PATH_NAME ] ; then
        OS_echo "UPGRADE_SH: $L_PACKAGE_PATH_NAME is not exist, exit $G_ERROR_PKG_INEXISTENCE" >/dev/null
        exit $G_ERROR_PKG_INEXISTENCE
    fi
    
    #清除预处理补丁 ，释放空间
    ClearPreprocessPatch
 
    if [ -d $G_UPDATE_TMP_DIR ];then
        rm -fr $G_UPDATE_TMP_DIR &>/dev/kmsg
    fi
    mkdir -p $G_UPDATE_TMP_DIR
    #给other组用户增加读权限，防止以该目录无法进行网络引导
    chmod 775 $G_UPDATE_TMP_DIR

    local l_bootLink=$(ls -l $G_BOOT_LINK | awk '{print $11}')
    if [ "$l_bootLink" == "boot_osp_bak" ]; then
        OS_echo "UPGRADE_SH: boot link(boot->$l_bootLink) is already point to boot_osp_bak."
        exit $G_ERROR_BOOT_LINK_ERROR
    fi

    if [ -d $G_BOOT_OSP_BAK_DIR ];then
        rm -fr $G_BOOT_OSP_BAK_DIR &>/dev/kmsg
    fi
    mkdir -p $G_BOOT_OSP_BAK_DIR &>/dev/kmsg
    chmod 775 $G_BOOT_OSP_BAK_DIR

    if [ -d $G_COFFER_DATA_TMP ];then
        rm -fr $G_COFFER_DATA_TMP &>/dev/kmsg
    fi
    mkdir -p $G_COFFER_DATA_TMP &>/dev/kmsg
    chmod 750 $G_COFFER_DATA_TMP >/dev/null 2>&1
    
    #check tar upgrade package memory is enough
    OS_CHECK_TAR_PACKAGE_MEM_ENOUGH
    if [ "0" != $? ];then
        OS_echo "UPGRADE_SH: tar upgrade package memory is not enough, exit $G_ERROR_NOT_ENOUGH_MEM" >/dev/null
        rm -f $L_PACKAGE_PATH_NAME  &>/dev/kmsg
        exit $G_ERROR_NOT_ENOUGH_MEM
    fi
    
    #check image capacity is enough
    OS_CHECK_IMAGE_CAPACITY_ENOUGH $L_PACKAGE_PATH_NAME
    local ret=$?
    if [ "2" == "$ret" ];then
        OS_echo "UPGRADE_SH: image capacity is not enough, exit $G_ERROR_IMAGE_CAPACITY_NOT_ENOUGH" >/dev/null
        rm -f $L_PACKAGE_PATH_NAME  &>/dev/kmsg
        exit $G_ERROR_IMAGE_CAPACITY_NOT_ENOUGH
    elif [ "0" == "$ret" ];then
        #先解压到保险箱盘，删除不需要的文件后，再拷贝到boot_osp_tmp
        OS_echo "UPGRADE_SH: tar -xzf $L_PACKAGE_PATH_NAME -C $G_COFFER_DATA_TMP Begin">/dev/null
        tar -xzf $L_PACKAGE_PATH_NAME -C $G_COFFER_DATA_TMP 1>/dev/null 2>/dev/null
        if [ "$?" != "0" ] ; then
            OS_echo "UPGRADE_SH: tar -xzf $L_PACKAGE_PATH_NAME -C $G_COFFER_DATA_TMP error, exit $G_ERROR_PKG_INVALIDE" >/dev/null
            rm -f $L_PACKAGE_PATH_NAME  &>/dev/kmsg
            exit $G_ERROR_PKG_INVALIDE
        fi
        OS_echo "UPGRADE_SH: tar -xzf $L_PACKAGE_PATH_NAME -C $G_COFFER_DATA_TMP End">/dev/null
        #校验包
                
        CHECK_PACKAGE $G_COFFER_DATA_TMP
        if [ "$?" != "0" ] ; then
            rm -f $L_PACKAGE_PATH_NAME  &>/dev/kmsg
            exit $G_ERROR_PKG_INVALIDE
        fi
                       
        ClearUnusedFileInPkg $G_COFFER_DATA_TMP
        mv $G_COFFER_DATA_TMP/* $G_UPDATE_TMP_DIR &>/dev/kmsg
    else
        OS_echo "UPGRADE_SH: tar -xzf $L_PACKAGE_PATH_NAME -C $G_UPDATE_TMP_DIR Begin">/dev/null
        tar -xzf $L_PACKAGE_PATH_NAME -C $G_UPDATE_TMP_DIR 1>/dev/null 2>/dev/null
        if [ "$?" != "0" ] ; then
            rm -f $L_PACKAGE_PATH_NAME  &>/dev/kmsg
            exit $G_ERROR_PKG_INVALIDE
        fi
        OS_echo "UPGRADE_SH: tar -xzf $L_PACKAGE_PATH_NAME -C $G_UPDATE_TMP_DIR End">/dev/null

        CHECK_PACKAGE $G_UPDATE_TMP_DIR
        if [ "$?" != "0" ] ; then
            rm -f $L_PACKAGE_PATH_NAME  &>/dev/kmsg
            exit $G_ERROR_PKG_INVALIDE
        fi
        
        ClearUnusedFileInPkg $G_UPDATE_TMP_DIR
    fi
    OS_echo "UPGRADE_SH: tar -xzf $L_PACKAGE_PATH_NAME -C $G_UPDATE_TMP_DIR End">/dev/null

    rm -f $L_PACKAGE_PATH_NAME &>/dev/kmsg
    echo 3 >/proc/sys/vm/drop_caches

    FREE_MEM=`free -m|grep ^Mem|awk '{print $4}'`
    if [ "${FREE_MEM}" -lt "${G_MIN_MEM}" ];then
        OS_echo "[OS_CreatePolicy] Force free memory"
        OS_UPGRADE_FORCE_FREEMEM
    fi

    #bak conf file to update disk dir
    if [ ! -d $G_UPDATE_DIR ] && [ ! -h $G_UPDATE_DIR ];then
        mkdir -p $G_UPDATE_DIR &>/dev/kmsg
    fi
    cd $G_UPDATE_TMP_DIR
    
    UPD_CHOOSE_CONF_FILE ${G_PRODUCT_TYPE}
    if [ "0" != "$?" ]; then
        exit $G_ERROR_PKG_INVALIDE
    fi

    local L_PKG_VERSION=`cat $G_UPDATE_TMP_DIR/$G_PKG_VERSION_FILENAME |grep -m 1 Version |awk -F"=" '{print $2}'`
    #R版本降级场景，构造兼容不同版本的固件配套表
    isDowngradeAndRebuildVerconf $L_PKG_VERSION
    
    cd $G_UPDATE_TMP_DIR
    cp *.conf $G_UPDATE_DIR/ &>/dev/kmsg
    cd - &>/dev/null
    
    # PCIE 交换机目录及文件名
    local tmppath=`cat $G_PRODUCT_CFG_FILE | grep -m 1 UpdPcieSwFilePath | awk -F"=" '{print $2}'`
    G_PCIE_PKG_PATH=${G_UPDATE_TMP_DIR}/${tmppath}
    if [ -d $G_PCIE_PKG_PATH ];then
        cd $G_PCIE_PKG_PATH
        L_NAME_PCIE=$(ls $G_PCIE_PKG_PATH | grep PCIE)
        L_NAME_PCIE_FOLDER=${L_NAME_PCIE%.*}

        echo "$G_PCIE_PKG_PATH/$L_NAME_PCIE" > $G_PCIE_PACKEG_VERSION_FILE
        chmod 644 $G_PCIE_PACKEG_VERSION_FILE >/dev/null 2>&1

        tar -zxf $L_NAME_PCIE $L_NAME_PCIE_FOLDER/dsw_version.conf >/dev/null 2>&1
        mv $L_NAME_PCIE_FOLDER/dsw_version.conf $G_PCIE_PKG_VERSION_FILE >/dev/null 2>&1
        chmod 644 $G_PCIE_PKG_VERSION_FILE >/dev/null 2>&1
        [ -d $L_NAME_PCIE_FOLDER ] && rm -rf $L_NAME_PCIE_FOLDER
        OS_echo "${UPGRADE_SH}: Exe unzip package success!" >/dev/null
        cd - &>/dev/null
    fi
    return 0
}


# **************************************************************************** #
# Description:解压硬盘FW的包,预留80M空间给解包用
# Parameter:
# Return:
# **************************************************************************** #
UPGRADE_TAR_UPDATE_DISK_PACKAGE()
{
    local L_DISKFW_PATH_NAME=$1
    local L_UPDATE_DISK_DIR_TMP=/startup_disk/image/boot/update_pkg/diskfirmware/tmp
    local L_pkgsize
    local L_avaible_size
    local L_ADD_SIZE_AFTER_TAR=81920
    
    OS_echo "UPGRADE_SH: begin to unzip $L_DISKFW_PATH_NAME !">/dev/null
    if [ ! -f $L_DISKFW_PATH_NAME ];then
        OS_echo "UPGRADE_SH: $L_DISKFW_PATH_NAME is not exist">/dev/null
        return $G_ERROR_PKG_INEXISTENCE
    fi
    
    if [ -d $L_UPDATE_DISK_DIR_TMP ];then
        rm -fr $L_UPDATE_DISK_DIR_TMP &>/dev/kmsg
    fi
    mkdir -p $L_UPDATE_DISK_DIR_TMP &>/dev/kmsg
    chmod 750 $L_UPDATE_DISK_DIR_TMP >/dev/null 2>&1

    L_pkgsize=`stat $L_DISKFW_PATH_NAME | grep Size: | awk '{print $2}'`
    let L_pkgsize=$L_pkgsize/1024+$L_ADD_SIZE_AFTER_TAR  
    L_avaible_size=`df /startup_disk/image/ |grep /startup_disk/image |awk '{print $4}'`
    OS_echo "UPGRADE_SH: Cur Medium Capacity(byte) = $L_avaible_size,  Needed = $L_pkgsize" >/dev/null
    if [[ $L_avaible_size -lt $L_pkgsize ]] ; then
        OS_echo "UPGRADE_SH: Medium Capacity Not Enough" >/dev/null
        return $G_ERROR_IMAGE_CAPACITY_NOT_ENOUGH
    fi
    
    tar -xzf $L_DISKFW_PATH_NAME -C $L_UPDATE_DISK_DIR_TMP 1>/dev/null 2>/dev/null
    if [ "$?" != "0" ] ; then
        OS_echo "UPGRADE_SH: tar -xzf $L_DISKFW_PATH_NAME -C $L_UPDATE_DISK_DIR_TMP error, exit $G_ERROR_PKG_INVALIDE" >/dev/null
        rm -f $L_DISKFW_PATH_NAME  &>/dev/kmsg
        return $G_ERROR_PKG_INVALIDE
    fi
    
    rm -f $L_DISKFW_PATH_NAME  &>/dev/kmsg
    return 0
}
# **************************************************************************** #
# Description:检查硬盘FW的包的完整性 
# Parameter:
# Return:
# **************************************************************************** #
UPGRADE_CHECK_DISK_PACKAGE()
{
    local L_UPDATE_DISK_DIR_TMP=/startup_disk/image/boot/update_pkg/diskfirmware/tmp
    local L_UPDATE_DISK_DIR=/startup_disk/image/boot/update_pkg/diskfirmware
    local L_SHA256_CHECK_FILE_NAME="sha256sum_sync"
    local L_HDDFW_CHECK_FILE_NAME="hddfw.conf"

    if [ ! -f $L_UPDATE_DISK_DIR_TMP/$L_HDDFW_CHECK_FILE_NAME ] ; then
        OS_echo "UPGRADE_SH: $L_HDDFW_CHECK_FILE_NAME not exist." >/dev/null   
        rm -rf $L_UPDATE_DISK_DIR_TMP
        return $G_ERROR_PKG_INVALIDE
    fi
    
    if [ -f $L_UPDATE_DISK_DIR_TMP/$L_SHA256_CHECK_FILE_NAME ] ; then
        OS_echo "UPGRADE_SH: $G_SHA256_CHECK_FILE_NAME exist, check it." >/dev/null
        CHECK_PACKAGE_SHA256 $L_UPDATE_DISK_DIR_TMP
        if [ "$?" == "0" ] ; then
            mv $L_UPDATE_DISK_DIR_TMP/* $L_UPDATE_DISK_DIR 1>/dev/null 2>/dev/null
            rm -rf $L_UPDATE_DISK_DIR_TMP
            return 0
        fi 
    else
        OS_echo "UPGRADE_SH: $L_SHA256_CHECK_FILE_NAME not exist." >/dev/null
    fi  
    
    rm -rf $L_UPDATE_DISK_DIR_TMP
    return $G_ERROR_PKG_INVALIDE
}

# **************************************************************************** #
# Description:升级完成删除导入的FW包 
# Parameter:
# Return:
# **************************************************************************** #
UPGRADE_DEL_DISK_PACKAGE()
{
    local L_UPDATE_DISK_DIR="/startup_disk/image/boot/update_pkg/diskfirmware"
    
    cd $L_UPDATE_DISK_DIR
    OS_SET_DISK_RW
    ls | grep -vw "\." | grep -vw "hddfw.conf" | xargs -d "\n" rm -rf
    OS_SET_DISK_RO
    
    cd - &>/dev/null
    return 0
}
# **************************************************************************** #
# Description:从主控同步红黑榜
# Parameter:
# Return:
# **************************************************************************** #
UPGRADE_SYNC_DISK_PACKAGE()
{
    local master_ip=$1
    local L_UPDATE_DISK_DIR="/startup_disk/image/boot/update_pkg/diskfirmware"
    
    ##如果已经指向boot_osp_bak，表明已经同步了大系统，不再处理。
    local l_boot_link=`ls -l $G_DISK_MOUNT_IMAGE | grep -a "boot ->" | awk '{print $11}'`
    if [ "$l_boot_link" == "boot_osp_bak" ] ; then
        OS_echo "UPGRADE_SH: boot is linked to boot_osp_bak, no need sync." >/dev/null
        return 0
    fi
    
    if [ -f $L_UPDATE_DISK_DIR/hddfw.conf ];then
        OS_echo "UPGRADE_SH: --- $disk file is exist! ---">/dev/null
        return 0
    fi
    
    /OSM/script/upgrade_trans_file.sh $L_UPDATE_DISK_DIR/hddfw.conf $L_UPDATE_DISK_DIR GET_FILE $master_ip
    if [ "$?" != "0" ];then
        OS_echo "UPGRADE_SH:Sync disk file from master failed." >/dev/null
        return 1
    fi
 
    return 0
}
# **************************************************************************** #
# Description:单控备份红黑榜到CCDB目录 
# Parameter:
# Return:
# **************************************************************************** #
UPGRADE_BACKUP_DISK_FILE_TO_CCDB()
{
    local L_UPDATE_DISK_DIR="/startup_disk/image/boot/update_pkg/diskfirmware"
    local L_BACKUP_BOOT_OSP_DIR="/OSM/ccdb/store/soft_backup/boot_osp"
    
    
    if [ ! -f $L_UPDATE_DISK_DIR/hddfw.conf ];then
        OS_echo "UPGRADE_SH: --- disk file is no exist! ---">/dev/null
        return 0
    fi
    
    if [ ! -d $L_BACKUP_BOOT_OSP_DIR ];then
        OS_echo "UPGRADE_SH: --- backup dir is no exist! ---">/dev/null
        return 0
    fi
    
    cp $L_UPDATE_DISK_DIR/hddfw.conf $L_BACKUP_BOOT_OSP_DIR/update_pkg/diskfirmware/
     
    return 0
}

# **************************************************************************** #
# Function Name:
# Description:
# Parameter:
# Return:
# **************************************************************************** #
OS_CHECK_TAR_ASL_PACKAGE_MEM_ENOUGH()
{
    #check memory is enough
    echo 3 >/proc/sys/vm/drop_caches

    FREE_MEM=`free -m|grep ^Mem|awk '{print $4}'`
    if [ "${FREE_MEM}" -lt "${G_ASL_TAR_PACKAGE_MIN_MEM}" ];then
        declare -i FREE_TIMES
        declare -i FREE_MEMORY

        FREE_TIMES=0
        FREE_MEMORY=0
        while [ true ];do
            echo 3 > /proc/sys/vm/drop_caches
            let FREE_TIMES=$FREE_TIMES+1
            if [ $FREE_TIMES -gt 3 ];then
                return 1
            fi

            FREE_MEMORY=`free -m|grep ^Mem|awk '{print $4}'`
            if [ $FREE_MEMORY -gt "${G_ASL_TAR_PACKAGE_MIN_MEM}" ];then
                return 0
            fi
        done
    fi

    return 0
}


# **************************************************************************** #
# Function Name:
# Description:
# Parameter:
# Return:
# **************************************************************************** #
OS_CHECK_ASL_IMAGE_CAPACITY_ENOUGH()
{
    L_NEED_SIZE=`cat $G_PRODUCT_CFG_FILE | grep $G_PRODUCT_ASL_IMAGE_CAPACITY_ITEMNAME | head -1 | cut -d '=' -f 2`
    if [ -z $L_NEED_SIZE ];then
        OS_echo "UPGRADE_SH: get image capacity item value fail, user default vaule=200" >/dev/null
        L_NEED_SIZE=204800
    fi

    L_AVAILABLE_SIZE=`df /startup_disk/image/ |grep /startup_disk/image |awk '{print $4}'`

    OS_echo "UPGRADE_SH: Cur Medium Capacity(byte) = $L_AVAILABLE_SIZE,  AslPatch Needed = $L_NEED_SIZE" >/dev/null
    if [[ $L_AVAILABLE_SIZE -lt $L_NEED_SIZE ]] ; then
        OS_echo "UPGRADE_SH:AslPatch Needed Capacity Not Enough" >/dev/null
        return 1
    fi

    OS_echo "UPGRADE_SH: AslPatch Needed Capacity Enough" >/dev/null
    return 0
}

# **************************************************************************** #
# Function Name:
# Description:
# Parameter:
# Return:
# **************************************************************************** #
OS_TAR_ASL_UPDATE_PACKAGE()
{
    L_ASL_PACKAGE_PATH_NAME=$1
    local L_MD5_RET=""
    if [ ! -f $L_ASL_PACKAGE_PATH_NAME ] ; then
        OS_echo "UPGRADE_SH: $L_ASL_PACKAGE_PATH_NAME is not exist, exit $G_ERROR_PKG_INEXISTENCE" >/dev/null
        exit $G_ERROR_PKG_INEXISTENCE
    fi

    if [ -d $G_ASL_UPDATE_TMP_DIR ];then
        rm -fr $G_ASL_UPDATE_TMP_DIR &>/dev/kmsg
    fi
    mkdir -p $G_ASL_UPDATE_TMP_DIR

    #check image capacity is enough
    OS_CHECK_ASL_IMAGE_CAPACITY_ENOUGH
    if [ "0" != $? ];then
        OS_echo "UPGRADE_SH: AslPatch image capacity is not enough, exit $G_ERROR_IMAGE_CAPACITY_NOT_ENOUGH" >/dev/null
        rm -f $L_ASL_PACKAGE_PATH_NAME  &>/dev/kmsg
        exit $G_ERROR_IMAGE_CAPACITY_NOT_ENOUGH
    fi

    #check tar upgrade package memory is enough
    OS_CHECK_TAR_ASL_PACKAGE_MEM_ENOUGH
    if [ "0" != $? ];then
        OS_echo "UPGRADE_SH: tar asl patch upgrade package memory is not enough, exit $G_ERROR_NOT_ENOUGH_MEM" >/dev/null
        rm -f $L_ASL_PACKAGE_PATH_NAME  &>/dev/kmsg
        exit $G_ERROR_NOT_ENOUGH_MEM
    fi

    OS_echo "UPGRADE_SH: tar -xzf $L_ASL_PACKAGE_PATH_NAME -C $G_ASL_UPDATE_TMP_DIR Begin" >/dev/null
    tar -xzf $L_ASL_PACKAGE_PATH_NAME -C $G_ASL_UPDATE_TMP_DIR 1>/dev/null 2>/dev/null
    if [ "$?" != "0" ] ; then
        OS_echo "UPGRADE_SH: tar -xzf $L_ASL_PACKAGE_PATH_NAME -C $G_ASL_UPDATE_TMP_DIR error, exit $G_ERROR_PKG_INVALIDE" >/dev/null
        rm -f $L_ASL_PACKAGE_PATH_NAME  &>/dev/kmsg
        exit $G_ERROR_PKG_INVALIDE
    fi
    OS_echo "UPGRADE_SH: tar -xzf $L_ASL_PACKAGE_PATH_NAME -C $G_ASL_UPDATE_TMP_DIR End" >/dev/null

    rm -f $L_ASL_PACKAGE_PATH_NAME &>/dev/kmsg
    echo 3 >/proc/sys/vm/drop_caches

    FREE_MEM=`free -m|grep ^Mem|awk '{print $4}'`
    if [ "${FREE_MEM}" -lt "${G_MIN_MEM}" ];then
        OS_echo "[OS_CreatePolicy] Force free memory" >/dev/null
        OS_UPGRADE_FORCE_FREEMEM
    fi

    cd $G_ASL_UPDATE_TMP_DIR
    if [ -f ${ASL_VERS_CONF} ]; then
        cp -f ${ASL_VERS_CONF} /OSM/update/versions.conf
    fi

    return 0
}

# **************************************************************************** #
# Function Name: OS_CHECK_ASL_PACKAGE
# Description:
# Parameter:
# Return:
# **************************************************************************** #
OS_CHECK_ASL_PACKAGE()
{
    cd $G_ASL_UPDATE_TMP_DIR
    if [ ! -f $G_ASL_SHA256_CHECK_FILE_NAME ] ; then
        OS_echo "UPGRADE_SH: $G_ASL_SHA256_CHECK_FILE_NAME not exist, can not sha256 check, return 1" >/dev/null
        return 1
    fi

    #check sha256
    L_OK_NUM=`cat $G_ASL_SHA256_CHECK_FILE_NAME |wc -l`
    L_OK_SHA256=`sha256sum -c $G_ASL_SHA256_CHECK_FILE_NAME |grep "OK"|wc -l `
    OS_echo "UPGRADE_SH: L_OK_NUM = [$L_OK_NUM], L_OK_SHA256 = [$L_OK_SHA256]" >/dev/null

    if [ "$L_OK_NUM" != "$L_OK_SHA256" ] ; then
        OS_echo "UPGRADE_SH: sha256sum check error, the total ok is $L_OK_NUM, but there only $L_OK_SHA256 ok" >/dev/null
        cd - &>/dev/null
        return 1
    fi
    OS_echo "UPGRADE_SH: sha256sum -c $G_ASL_SHA256_CHECK_FILE_NAME success" >/dev/null

    return 0
}

# **************************************************************************** #
# Function Name: OS_CHECK_ASL_REINSTALL
# Description:
# Parameter:
# Return:-1=check error
#        0=the asl package is not installed
#        1=the asl package is installed
# **************************************************************************** #
OS_CHECK_ASL_REINSTALL()
{
    if [ ! -d $G_ASL_CONFIG_FILE_DIR ] || [ ! -f $G_ASL_CONFIG_FILE_DIR/$G_ASL_CONFIG_FILE_NAME ]; then
        OS_echo "UPGRADE_SH: OS_CHECK_ASL_REINSTALL $G_ASL_CONFIG_FILE_DIR or
            $G_ASL_CONFIG_FILE_DIR/$G_ASL_CONFIG_FILE_NAME is not exist, return -1" >/dev/null
        OS_FREE_MEM_FUC
        return $G_ERROR_PKG_INVALIDE
    fi

    if [ ! -d $G_ASL_UPDATE_TMP_DIR ] || [ ! -f $G_ASL_UPDATE_TMP_DIR/$ASL_VERS_CONF ]; then
        OS_echo "UPGRADE_SH: OS_CHECK_ASL_REINSTALL $G_ASL_UPDATE_TMP_DIR or
            $G_ASL_UPDATE_TMP_DIR/$ASL_VERS_CONF is not exist, return -1" >/dev/null
        OS_FREE_MEM_FUC
        return $G_ERROR_PKG_INVALIDE
    fi

    # 读取升级目录下的配置文件，获取ASL名称
    cd $G_ASL_UPDATE_TMP_DIR
    CONFIG_FILE=`ls | grep ".conf"`
    ASL_NAME=`awk -F ' ' '$1=="Asl_Name" {print $2}' $CONFIG_FILE`
    ASL_VERSION=`awk -F ' ' '$1=="Asl_Version" {print $2}' $CONFIG_FILE`
    ASL_PRODUCT_VERSION=`awk -F ' ' '$1=="Product_Fw_Version" {print $2}' $CONFIG_FILE`
    if [ "" == "${ASL_NAME}" ] || [ "" == "${ASL_VERSION}" ] || [ "" == "${ASL_PRODUCT_VERSION}" ]; then
        OS_FREE_MEM_FUC
        OS_echo "UPGRADE_SH: OS_CHECK_ASL_REINSTALL The $G_ASL_UPDATE_TMP_DIR/$ASL_VERS_CONF is error," >/dev/null
        return $G_ERROR_PKG_INVALIDE
    fi
    OS_echo "UPGRADE_SH:OS_CHECK_ASL_REINSTALL, get productversion=$ASL_PRODUCT_VERSION aslname=$ASL_NAME, aslversion=$ASL_VERSION in $G_ASL_UPDATE_TMP_DIR/$ASL_VERS_CONF" >/dev/null
    cd - &>/dev/null

    ##对比系统中的大包版本是否与配置文件中的一致
    if [ ! -f $G_PRODUCT_CFG_FILE ]; then
        OS_echo "UPGRADE_SH: OS_CHECK_ASL_REINSTALL $G_PRODUCT_CFG_FILE file not found." >/dev/null
        OS_FREE_MEM_FUC
        return $G_ERROR_PKG_INVALIDE
    fi
    SYS_PRODUCT_VERSION=`awk -F '=' '$1=="SpcVersion" {print $2}' $G_SYS_CONFIG_FILE`
    if [ "" == $SYS_PRODUCT_VERSION ]; then
        OS_FREE_MEM_FUC
        OS_echo "UPGRADE_SH: OS_CHECK_ASL_REINSTALL get SpcVersion fail in $SYS_PRODUCT_VERSION" >/dev/null
        return $G_ERROR_PKG_INVALIDE
    fi

    if [ $SYS_PRODUCT_VERSION != $ASL_PRODUCT_VERSION ]; then
        OS_FREE_MEM_FUC
        OS_echo "UPGRADE_SH: OS_CHECK_ASL_REINSTALL $SYS_PRODUCT_VERSION is not equal $ASL_PRODUCT_VERSION" >/dev/null
        return 8;
    fi

    ## 对比系统中是否已经安装了当前安装的异构支持包
    G_ASL_MEN=$G_ASL_CONFIG_FILE_DIR/$G_ASL_CONFIG_FILE_NAME
    ASL_VERSION_MEM=`awk -F ' ' -v asl_name="${ASL_NAME}" '$1==asl_name {print $2}' $G_ASL_MEN`
    if [ "" != $ASL_VERSION_MEM ] && [ $ASL_VERSION == $ASL_VERSION_MEM ]; then
        OS_FREE_MEM_FUC
        OS_echo "UPGRADE_SH: OS_CHECK_ASL_REINSTALL $ASL_NAME $ASL_VERSION have already installed." >/dev/null
        return 9;
    fi

    OS_FREE_MEM_FUC
    OS_echo "UPGRADE_SH: [os_system_update.sh -D] The Asl package $ASL_NAME $ASL_VERSION is not installed." >/dev/null
    return 0;
}

CopyAslConfFromOtherNid()
{
    local L_SRC_IP=$1
    local L_SRC_FILE=${G_ASL_CONFIG_FILE_DIR}/${G_ASL_CONFIG_FILE_NAME}
    local L_TEMP_DIR="/tmp"

    #判断文件是否存在
    if [ -f ${G_ASL_COPY_TEMP_FILE} ]; then
        rm -rf ${G_ASL_COPY_TEMP_FILE}  &>/dev/null
    fi

    #从源 IP 拷贝版本
    /OSM/script/os_get_file.sh ${L_SRC_IP} ${L_SRC_FILE} ${L_TEMP_DIR}
    if [ "0" != "$?" ]; then
        OS_echo "UPGRADE_SH: copy ${L_SRC_IP}:${G_ASL_COPY_TEMP_FILE} to local failed." > /dev/null
        return 1
    fi

    if [ ! -f ${G_ASL_COPY_TEMP_FILE} ]; then
        OS_echo "UPGRADE_SH: ${G_ASL_COPY_TEMP_FILE} is not exist, copy failed." > /dev/null
        return 1
    fi

    OS_echo "UPGRADE_SH: copy ${L_SRC_IP}:${G_ASL_COPY_TEMP_FILE} to local success." > /dev/null

    return 0

}

SelectOneConnectedIp()
{
    local L_SOURCE_IP_LIST=$1
    local L_SOURCE_IP_1=$(echo $L_SOURCE_IP_LIST |cut -d ',' -f1)
    local L_SOURCE_IP_2=$(echo $L_SOURCE_IP_LIST |cut -d ',' -f2)

    OS_echo "UPGRADE_SH: The source ip list is ($L_SOURCE_IP_LIST), the first ip is ($L_SOURCE_IP_1) and second is ($L_SOURCE_IP_2)." > /dev/null

    # 检查传入IP是否连通
    CheckIpConnection $L_SOURCE_IP_1
    if [ "$?" == "0" ]; then
        G_SYNC_SOURCE_IP=$L_SOURCE_IP_1
        OS_echo "UPGRADE_SH: The source ip ($L_SOURCE_IP_1) is connected." > /dev/null
        return 0
    fi

    # 检查该网段是否连通
    CheckIpConnection $L_SOURCE_IP_2
    if [ "$?" == "0" ]; then
        G_SYNC_SOURCE_IP=$L_SOURCE_IP_2
        OS_echo "UPGRADE_SH: The other ip ($L_SOURCE_IP_2) is connected." > /dev/null
        return 0
    fi

    OS_echo "UPGRADE_SH: The both ($L_SOURCE_IP_1) and ($L_SOURCE_IP_2) are disconnected, exit 1." > /dev/null
    exit 1
}

CopyAnythingWithRetry()
{
    local L_SOURCE_IP=$1
    local L_SOURCE_TYPE=$2
    local L_TRY_TIMES=0
    local L_SYNC_FILE_TIMES=5
    OS_echo "UPGRADE_SH: The source ip is ${L_SOURCE_IP}." > /dev/null

    while [ true ]; do
        if [ $L_TRY_TIMES -ge $L_SYNC_FILE_TIMES ];then
            OS_echo "UPGRADE_SH: It has reached $L_TRY_TIMES times to try to sync file." > /dev/null
            return 1
        fi
        OS_echo "UPGRADE_SH: It has try $L_TRY_TIMES times." > /dev/null
        let L_TRY_TIMES=$L_TRY_TIMES+1

        # 检测L_SOURCE_IP是否连通 否则转换之
        SelectOneConnectedIp $L_SOURCE_IP
        if [ "$?" != "0" ]; then
            OS_echo "UPGRADE_SH: All of the ip is disconnected." > /dev/null
            return 1
        fi

        if [ "${L_SOURCE_TYPE}" == "ASL_SYNC" ]; then
            CopyAslPatchFromOtherNid $G_SYNC_SOURCE_IP
            if [ "0" == "$?" ];then
                rm -rf touch /OSM/bin/asl_reboot_flag
                touch /OSM/bin/asl_reboot_flag
                OS_echo "UPGRADE_SH: Copy asl patch package From [$G_SYNC_SOURCE_IP] to Local Success!" > /dev/null
                return 0
            fi
        elif [ "${L_SOURCE_TYPE}" == "ASL_COPY" ]; then
            CopyAslConfFromOtherNid $G_SYNC_SOURCE_IP
            if [ "0" == "$?" ];then
                OS_echo "UPGRADE_SH: Copy asl.conf From [$G_SYNC_SOURCE_IP] to Local Success!" > /dev/null
                return 0
            fi
        else
            OS_echo "UPGRADE_SH: CopyAnythingWithRetry input copy type is not known!" > /dev/null
        fi

        sleep 5
    done

}

# **************************************************************************** #
# Function Name:OS_ASL_ENCODE_VERSION
# Description: get asl package version
# Parameter:
# Return:
# **************************************************************************** #
OS_ASL_ENCODE_VERSION()
{
    local L_ASL_CONF_FILE=$1
    if [ ! -r  "${L_ASL_CONF_FILE}" ]; then
        OS_echo "UPGRADE_SH:the ${L_ASL_CONF_FILE} is not exist, and OS_ASL_ENCODE_VERSION failed" >/dev/null
        return 1
    fi

    local L_TEMP_CONF=`mktemp` &> /dev/null
    sed '/^ *$/d' $L_ASL_CONF_FILE  | awk '{print $1$2$3}' | sort > $L_TEMP_CONF
    if [ ! -f "$L_TEMP_CONF" ] ; then
        OS_echo "UPGRADE_SH: ${L_TEMP_CONF} is not exist, OS_ASL_ENCODE_VERSION failed" >/dev/null
        return 1
    fi

    ASL_ENCODED_VER=`sha256sum -t  $L_TEMP_CONF | awk '{print $1}'`
    rm -rf $L_TEMP_CONF

    echo ${ASL_ENCODED_VER}
    return 0
}

# **************************************************************************** #
# Function Name:  OS_CHECK_ASL_VERSION
# Description: check asl version, if the asl version is not same
# Parameter:
# Return: 0 the asl version is same; 1 the asl version is not same; other error 2
# **************************************************************************** #
OS_CHECK_ASL_VERSION()
{
    local L_IN_PARA=$1
    local L_SRC_IP=${L_IN_PARA%,*}
    local L_MASTER_VER=${L_IN_PARA##*,}
    local L_Local_ASLVER

    ##获取本地的异构支持包编码  /OSM/conf/asl.conf
    L_Local_ASLVER=`OS_ASL_ENCODE_VERSION  ${G_ASL_CONFIG_FILE_DIR}/${G_ASL_CONFIG_FILE_NAME}`
    if [ 0 != "$?" ]; then
        OS_echo "UPGRADE_SH: get the local asl patch encoded version failed" >/dev/null
        return 1
    fi

    OS_echo "UPGRADE_SH: the local asl encoded version is (${L_Local_ASLVER}) and the master asl encoded version is (${L_MASTER_VER})" >/dev/null

    ##直接比较本控上异构支持包版本信息与入参带入的主控的异构包版本信息
    if [ "" != "${L_MASTER_VER}" ];then
        if [ "${L_MASTER_VER}" == "${L_Local_ASLVER}" ];then
            OS_echo "UPGRADE_SH: the local asl version is same to the master asl version, and return success." >/dev/null
            return 0
        else
            OS_echo "UPGRADE_SH: the local asl version is not same to the master asl version, and need sync asl." >/dev/null
            return 1
        fi
    fi

    ##获取L_SRC_IP的内存中的异构支持包文件
    CopyAnythingWithRetry $L_SRC_IP "ASL_COPY"
    if [ 0 != "$?" ]; then
        OS_echo "UPGRADE_SH: get the src[${L_SRC_IP}] asl patch encoded version failed" >/dev/null
        return 2
    fi

    ##获取远端的异构支持包编码
    L_MASTER_VER=`OS_ASL_ENCODE_VERSION  $G_ASL_COPY_TEMP_FILE`
    if [ 0 != "$?" ]; then
        OS_echo "UPGRADE_SH: get the src[${L_SRC_IP}] asl patch encoded version failed" >/dev/null
        rm $G_ASL_COPY_TEMP_FILE &>/dev/kmsg
        return 2
    fi
    rm $G_ASL_COPY_TEMP_FILE &>/dev/kmsg

    ##比较主控上的异构支持包版本信息与本控的异构支持包版本信息是否一致
    OS_echo "UPGRADE_SH: the master asl encode version:${L_MASTER_VER}" >/dev/null
    if [ "${L_MASTER_VER}" == "${L_Local_ASLVER}" ]; then
        OS_echo "UPGRADE_SH: the local asl version is same to the master asl version" >/dev/null
        return 0
    fi

    OS_echo "UPGRADE_SH: the local asl version is not same to the master asl version, need sync asl." >/dev/null
    return 1

}



# **************************************************************************** #
# Function Name: CopyAslPatchFromOtherNid
# Description: copy  /startup_disk/image/boot/Asl from src_ip to local /startup_disk/image/boot/Asl
# Parameter:
# Return: 0 sync asl patch success; 1 sync asl patch failed
# **************************************************************************** #
CopyAslPatchFromOtherNid()
{
    local L_SRC_IP=$1
    local L_SRC_DIR=${G_ASL_INSTALL_DIR}
    local L_BAK_DIR="/startup_disk/image/boot/Asl_bak"
    local L_TEMP_DIR="/startup_disk/image/boot/Asl_temp"

    #设置目录可读写
    OS_SET_DISK_RW

    #判断目录是否存在
    if [ -d ${L_TEMP_DIR} -o -d ${L_BAK_DIR} ]; then
        rm -rf ${L_TEMP_DIR}  &>/dev/null
        rm -rf ${L_BAK_DIR}  &>/dev/null
    fi

    mkdir -p ${L_TEMP_DIR} &>/dev/null

    #从源 IP 拷贝版本
    /OSM/script/os_get_dir.sh ${L_SRC_IP} ${L_SRC_DIR} ${L_TEMP_DIR}
    if [ "0" != "$?" ]; then
        OS_echo "UPGRADE_SH: copy ${L_SRC_IP}:${L_SRC_DIR} to local failed." > /dev/null
        rm -rf ${L_TEMP_DIR} &>/dev/null
        OS_SET_DISK_RO
        return 1
    fi

    mv ${L_SRC_DIR}  ${L_BAK_DIR}  &>/dev/kmsg
    mv ${L_TEMP_DIR}/Asl ${L_SRC_DIR}  &>/dev/kmsg
    rm -rf ${L_TEMP_DIR}  &>/dev/kmsg

    #设置异构支持包软链接
    cd ${G_ASL_INSTALL_DIR}  &>/dev/kmsg

    tree -ifa -L 1 ./ | grep "./" | while read ASL_DIR
    do
        cd ${G_ASL_INSTALL_DIR}/${ASL_DIR} &>/dev/kmsg
        if [ ! -h ${G_ASL_INSTALL_DIR}/${ASL_DIR}/asl ];then
            OS_echo "UPGRADE_SH:Asl patch link(asl->Asl_Lib) not exist, need create." >/dev/null
            OS_echo "UPGRADE_SH:create asl patch link ${ASL_DIR}/asl->${ASL_DIR}/Asl_New"  >/dev/null
            if [ ! -d ${G_ASL_INSTALL_DIR}/${ASL_DIR}/Asl_Lib ]; then
                OS_echo "$G_ASL_INSTALL_DIR/$ASL_DIR/Asl_Lib is not exist" >/dev/null
                OS_SET_DISK_RO
                return 1
            fi
            ln -s Asl_Lib  asl  &>/dev/kmsg
            if [ 0 != $? ];then
                OS_echo "Creat asl patch link(${ASL_DIR}/asl->${ASL_DIR}/Asl_New) fail,exit." >/dev/null
                OS_SET_DISK_RO
                return 1
            fi
        fi
    done

    cd -  &>/dev/kmsg

    rm -rf ${L_BAK_DIR}  &>/dev/kmsg

    sync

    OS_SET_DISK_RO
    OS_echo "UPGRADE_SH: copy ${L_SRC_IP}:${L_SRC_DIR} to local success." > /dev/null
    return 0

}

# **************************************************************************** #
# Function Name:
# Description:
# Parameter: path + package name
# Return:
# **************************************************************************** #
OS_GET_UPDATE_PACKAGE_VERSION()
{
    L_PACKAGE_PATH_NAME=$1

    if [ ! -f $L_PACKAGE_PATH_NAME ] ; then
        OS_echo "UPGRADE_SH: $L_PACKAGE_PATH_NAME is not exist, tar update package for version error, exit 1" >/dev/null
        exit 1
    fi

    if [ ! -d $G_UPDATE_DIR ] ; then
        OS_echo "UPGRADE_SH: create /OSM/update dir" >/dev/null
        mkdir -p $G_UPDATE_DIR
    fi

    OS_echo "UPGRADE_SH: tar -xzf $L_PACKAGE_PATH_NAME -C $G_UPDATE_DIR $G_PKG_VERSION_FILENAME Begin">/dev/null
    tar -xzf $L_PACKAGE_PATH_NAME -C $G_UPDATE_DIR $G_PKG_VERSION_FILENAME upgrade_command_execute.sh  --wildcards *.xml 1>/dev/null 2>/dev/null
    if [ ! -f $G_UPDATE_DIR/$G_PKG_VERSION_FILENAME ] ; then
        OS_echo "UPGRADE_SH: tar update package for version error, exit 1" >/dev/null
        exit 1
    fi
    #check the product id
    L_CUR_VERSION=`cat $G_CUR_VERSION_FILE |grep -m 1 Version |awk -F"=" '{print $2}'`
    L_PKG_VERSION=`cat $G_UPDATE_DIR/$G_PKG_VERSION_FILENAME |grep -m 1 Version |awk -F"=" '{print $2}'`
    OS_echo "UPGRADE_SH: Cur Version=$L_CUR_VERSION, Pkg Version=$L_PKG_VERSION" >/dev/null

    L_CUR_PDT=`echo $L_CUR_VERSION |awk -F. '{print $2}'`
    if [ -z "$L_CUR_PDT" ];then
        L_CUR_PDT=`echo ${L_CUR_VERSION:0:3}`
    fi

    L_PKG_PDT=`echo $L_PKG_VERSION |awk -F. '{print $2}'`
    if [ -z "$L_PKG_PDT" ];then
        L_PKG_PDT=`echo ${L_PKG_VERSION:0:3}`
    fi

    OS_echo "UPGRADE_SH: [CheckTheVersion] cur product id = $L_CUR_PDT, package product id = $L_PKG_PDT." >/dev/null
    if [ "$L_PKG_PDT" == "" ] || [ $L_CUR_PDT != $L_PKG_PDT ] ; then
        OS_echo "UPGRADE_SH: [CheckTheVersion]Error, package not compatible." >/dev/null
        return $G_ERROR_PKG_INVALIDE
    fi

    OS_echo "UPGRADE_SH: tar -xzf $L_PACKAGE_PATH_NAME -C $G_UPDATE_DIR $G_PKG_VERSION_FILENAMES End">/dev/null
    return 0
}

function UPGRADE_RESTART_OMM_UPD_SERVER_AND_AGENT()
{
    if [ -f /startup_disk/conf/conf_local/upd_need_restart ];then
        OS_echo "Need restart server and agent"
        rm -f /startup_disk/conf/conf_local/upd_need_restart
        sleep 60
        local pid=$(ps -ww -eo pid,cmd | grep "/OSM/bin/omm_upd_server.bin" | grep -v grep | awk '{print $1}')
        OS_echo "upgrade server oldPid: $pid"
        if [ "$pid" = "" ]; then
            return
        else
            OS_echo "upgrade server will be killed."
            kill -9 $pid
            sleep 1
            local pid=$(ps -ww -eo pid,cmd | grep "/OSM/bin/omm_upd_server.bin" | grep -v grep | awk '{print $1}')
            OS_echo "upgrade server newPid: $pid"
            if [ "$pid" = "" ]; then
                OS_echo "upgrade server restart failed"
                return
            fi  
        fi
        
        local pid=$(ps -ww -eo pid,cmd | grep "/OSM/bin/omm_upd_agent.bin" | grep -v grep | awk '{print $1}')
        OS_echo "upgrade agent oldPid: $pid"
        if [ "$pid" = "" ]; then
            return
        else
            OS_echo "upgrade agent will be killed."
            kill -9 $pid
            sleep 1
            local pid=$(ps -ww -eo pid,cmd | grep "/OSM/bin/omm_upd_agent.bin" | grep -v grep | awk '{print $1}')
            OS_echo "upgrade agent newPid: $pid"
            if [ "$pid" = "" ]; then
                OS_echo "upgrade agent restart failed"
                return
            fi  
        fi
    else
        OS_echo "no restart flag."
    fi
    return
}
# **************************************************************************** #
# Function Name: OS_DEL_ALL_FILES_IN_UPDATE
# Description: delete all files in update dir
# Parameter:
# Return:
# **************************************************************************** #
OS_DEL_ALL_FILES_IN_UPDATE()
{
    local L_IS_HOTPATCH=$1 
    L_DEL_DIR=/OSM/update
    #delete memory update dir content
    if [ -d $L_DEL_DIR ] ; then
        cd $L_DEL_DIR
        rm -rf * &>/dev/kmsg
        cd - &>/dev/null
    fi
    #delete upgrade state file
    if [ -d $G_UPDATE_STATE_DIR ];then
        cd $G_UPDATE_STATE_DIR
        rm  $G_UPDATE_STATE_FILE &>/dev/kmsg
        rm  $G_UPGRADE_FILE &>/dev/kmsg
        cd - &>/dev/null
    fi
    #delete /startup_disk/image/boot_osp_tmp
    #download hotpatch in upgrading,do not delete G_UPDATE_TMP_DIR
    #download hotpatch in upgrading,do not delete G_UPDATE_TMP_DIR
    if [ $L_IS_HOTPATCH != "upgrade_and_hotpatch" ];then
        rm -f /tmp/upgrade_and_hotpatch.txt
        rm -f /tmp/upd_hotpatch_resume.log
        if [ -d $G_UPDATE_TMP_DIR ];then
            rm -rf $G_UPDATE_TMP_DIR &>/dev/kmsg
        fi
    else #touch the upgrade-and-hotpatch file flag
        OS_echo "UPGRADE_SH: upgrade_and_hotpatch,touch the file flag." >/dev/null      
        touch /tmp/upgrade_and_hotpatch.txt
    fi
    
    #chmod /startup_disk/image/boot_osp
    if [ -d $G_UPDATE_BOOT_DIR ];then
        chmod 755 $G_UPDATE_BOOT_DIR &>/dev/kmsg
    fi
    
    #chmod /startup_disk/image/boot_osp_bak
    if [ -d $G_BOOT_OSP_BAK_DIR ];then
        chmod 755 $G_BOOT_OSP_BAK_DIR &>/dev/kmsg
    fi
    #delete /startup_disk/image/boot/Asl_New
    if [ -d $G_ASL_UPDATE_TMP_DIR ];then
        rm -rf $G_ASL_UPDATE_TMP_DIR &>/dev/kmsg
    fi
    echo "expect_success"
    return 0
}

# **************************************************************************** #
# Function Name: OS_DEL_FILES_IN_UPDATE_DIR
# Description: delete files in /OSM/update
# Parameter:
# Return:
# **************************************************************************** #
OS_DEL_FILES_IN_UPDATE_DIR()
{
    #delete medium update dir content
    if [ -d $G_UPDATE_DIR ] ;then
        cd $G_UPDATE_DIR
        rm -rf * &>/dev/kmsg
        cd - &>/dev/null
    fi
    return 0
}

# **************************************************************************** #
# Function Name:
# Description:
# Parameter:
# Return:
# **************************************************************************** #
OS_SET_HOTPATCH_DISK_RW()
{
    OS_echo "UPGRADE_SH: Disk Boot Dir = [$G_HOT_PATCH_BOOT_DIR], Set Disk Boot Dir RW Begin" >/dev/null

    mount -o remount,rw,async $G_HOT_PATCH_BOOT_DIR
    if [ 0 != $? ] ; then
        OS_echo "UPGRADE_SH: Set Disk Boot Dir RW Error" >/dev/null
        exit 1
    fi

    OS_echo "UPGRADE_SH: Set Disk Boot Dir RW Success" >/dev/null
    return 0
}

# **************************************************************************** #
# Function Name:
# Description:
# Parameter:
# Return:
# **************************************************************************** #
OS_SET_HOTPATCH_DISK_RO()
{
    OS_echo "UPGRADE_SH: Disk Boot Dir = [$G_HOT_PATCH_BOOT_DIR], Set Disk Boot Dir RO Begin" >/dev/null

    for((i=0;i<3;i++))
    do
        mount -o remount,ro,sync $G_HOT_PATCH_BOOT_DIR
        if [ 0 = $? ] ; then
            break
        fi
        OS_echo "UPGRADE_SH:Remount hotpatch RO failed, i=$i"
        sleep 5
    done

    if [ $i -ge 3 ] ; then
        OS_echo "UPGRADE_SH: Set Disk Boot Dir RO Error" >/dev/null
        return 1
    else
        OS_echo "UPGRADE_SH: Set Disk Boot Dir RO Success" >/dev/null
        return 0
    fi

    return 0
}

# **************************************************************************** #
# Function Name:
# Description:
# Parameter:
# Return:
# **************************************************************************** #
OS_SET_DISK_RW()
{
    L_DISK_BOOT=`cat /proc/mounts |grep $G_DISK_MOUNT_IMAGE |awk '{print $1}'`
    if [ -z "$L_DISK_BOOT" ] ; then
        L_DISK_BOOT=$G_DISK_BOOT
    else
        L_DISK_BOOT=${L_DISK_BOOT%[0-9]}
    fi

    OS_echo "UPGRADE_SH: Disk Boot Dir = [$L_DISK_BOOT], Set Disk Boot Dir RW Begin" >/dev/null

    OS_SetStartUpDiskProperty $L_DISK_BOOT rw
    if [ 0 != $? ] ; then
        OS_echo "UPGRADE_SH: Set Disk Boot Dir RW Error" >/dev/null
        exit 1
    fi

    OS_echo "UPGRADE_SH: Set Disk Boot Dir RW Success" >/dev/null
    return 0
}

# **************************************************************************** #
# Function Name:
# Description:
# Parameter:
# Return:
# **************************************************************************** #
OS_SET_DISK_RO()
{
    L_DISK_BOOT=`cat /proc/mounts |grep $G_DISK_MOUNT_IMAGE |awk '{print $1}'|awk -F 1 '{print $1}'`
    if [ -z "$L_DISK_BOOT" ] ; then
        L_DISK_BOOT=$G_DISK_BOOT
    else
        L_DISK_BOOT=${L_DISK_BOOT%[0-9]}
    fi

    OS_echo "UPGRADE_SH: Disk Boot Dir = [$L_DISK_BOOT], Set Disk Boot Dir RO Begin" >/dev/null

    for((i=0;i<3;i++))
    do
        OS_SetStartUpDiskProperty $L_DISK_BOOT ro
        if [ 0 = $? ] ; then
            break
        fi
        OS_echo "UPGRADE_SH:Remount image RO failed, i=$i"
        sleep 5
    done

    if [ $i -ge 3 ] ; then
        OS_echo "UPGRADE_SH: Set Disk Boot Dir RO Error" >/dev/null
        return 1
    else
        OS_echo "UPGRADE_SH: Set Disk Boot Dir RO Success" >/dev/null
        return 0
    fi

    return 0
}


# **************************************************************************** #
# Function Name:
# Description:
# Parameter:
# Return:
# **************************************************************************** #
OS_CHECK_IS_BOOT_FROM_USB()
{
     if [ -f /OSM/conf/bootfromusb.txt ] ; then
        OS_echo "UPGRADE_SH: Boot From USB" >/dev/null
        exit 1
     else
        OS_echo "UPGRADE_SH: Not boot from USB" >/dev/null
        exit 0
     fi
}

# **************************************************************************** #
# Function Name:
# Description:
# Parameter:
# Return: 0, false; 1, need
# **************************************************************************** #
OS_CHECK_IS_NEED_FIRE_DISK()
{
    #获取系统软件包名
    L_SYS_PKG_NAME=`cat $G_PRODUCT_CFG_FILE |grep $G_SYS_PKG_NAME_ITEMNAME |cut -d '=' -f 2`
    L_SYS_PKG_DIR=`cat $G_PRODUCT_CFG_FILE |grep $G_SYS_PKG_DIR_ITEMNAME |cut -d '=' -f 2`

    if [ ! -f $L_SYS_PKG_DIR/$L_SYS_PKG_NAME ];then
        OS_echo "UPGRADE_SH: Pkg[$L_SYS_PKG_DIR/$L_SYS_PKG_NAME] is inexistent, need not fire disk, exit 0" >/dev/null
        return 0
    fi

    #获取版本文件versions.conf, 2600R2的包中的版本文件为osp_versions.conf
    L_OSP_VERSIONS_CONF=`tar -tzf $L_SYS_PKG_DIR/$L_SYS_PKG_NAME |grep osp_versions.conf`
    if [ -n "$L_OSP_VERSIONS_CONF" ];then
        tar -xzf $L_SYS_PKG_DIR/$L_SYS_PKG_NAME -C $L_SYS_PKG_DIR osp_versions.conf 1>/dev/null 2>/dev/null
        mv $L_SYS_PKG_DIR/osp_versions.conf $L_SYS_PKG_DIR/versions.conf
    else
        tar -xzf $L_SYS_PKG_DIR/$L_SYS_PKG_NAME -C $L_SYS_PKG_DIR versions.conf 1>/dev/null 2>/dev/null
    fi

    #判断版本文件获取是否正确
    if [ ! -f $L_SYS_PKG_DIR/versions.conf ];then
        OS_echo "UPGRADE_SH: tar $L_SYS_PKG_DIR/$L_SYS_PKG_NAME For Getting Version File Failed" >/dev/null
        return 0
    else
        OS_echo "UPGRADE_SH: tar $L_SYS_PKG_DIR/$L_SYS_PKG_NAME For Getting Version File Success" >/dev/null
    fi

    #检查包是否与当前系统处于同一个R版本
    L_CUR_VERSION=`cat $G_CUR_VERSION_FILE |grep Version |awk '{print $2}' | sed 's/[.T]//g'`
    L_PKG_VERSION=`cat $L_SYS_PKG_DIR/versions.conf |grep Version |awk '{print $2}' | sed 's/[.T]//g'`
    OS_echo "UPGRADE_SH: Cur Version=$L_CUR_VERSION, Pkg Version=$L_PKG_VERSION" >/dev/null

    #调用产品提供的脚本判断是否处于同一个R版本
    if [ ! -f $G_PRODUCT_JUDGE_IS_SAME_R_SH ];then
        OS_echo "UPGRADE_SH: $G_PRODUCT_JUDGE_IS_SAME_R_SH inexistent, Needn't Fire For Update" >/dev/null
        return 0
    fi

    #R版本间的版本回退需要烧盘升级
    $G_PRODUCT_JUDGE_IS_SAME_R_SH $L_CUR_VERSION $L_PKG_VERSION
    retval=$?
    if [ "0" == "$retval" ];then
        OS_echo "UPGRADE_SH: [$G_PRODUCT_JUDGE_IS_SAME_R_SH $L_CUR_VERSION $L_PKG_VERSION] Return: R Version Same" >/dev/null
        OS_echo "UPGRADE_SH: Needn't Fire For Update" >/dev/null
        return 0
    elif [ "2" == "$retval" ];then
        OS_echo "UPGRADE_SH: Sys package not compatible" >/dev/null
        return 2
    else
        OS_echo "UPGRADE_SH: [$G_PRODUCT_JUDGE_IS_SAME_R_SH $L_CUR_VERSION $L_PKG_VERSION] Return: R Version Diff" >/dev/null

        #比较是否是R版本间的回退
        if [ "$L_PKG_VERSION" -lt "$L_CUR_VERSION" ];then
            OS_echo "UPGRADE_SH: R Version Revert, Need Fire For Update">/dev/null
            return 1
        else
            OS_echo "UPGRADE_SH: R Version Upgrade, Needn't Fire For Update" >/dev/null
            return 0
        fi
    fi
}

# **************************************************************************** #
# Function Name:
# Description:
# Parameter:
# Return:
# **************************************************************************** #
OS_EXEC_UNZIP_PKG_NEXT_PRETREATMENT()
{
    if [ ! -f "$G_PRODUCT_UPDATE_INTF_SH" ];then
        OS_echo "UPGRADE_SH: $G_PRODUCT_UPDATE_INTF_SH inexist, Needn't Exec Unzip Pkg Next Pretreatment" >/dev/null
    else
        OS_echo "UPGRADE_SH: Exec Unzip Pkg Next Pretreatment" >/dev/null
        dos2unix $G_PRODUCT_UPDATE_INTF_SH >/dev/null
        chmod +x $G_PRODUCT_UPDATE_INTF_SH >/dev/null
        $G_PRODUCT_UPDATE_INTF_SH -a
        if [ 0 != $? ]; then
            OS_echo "UPGRADE_SH: Exec Unzip Pkg Next Pretreatment Fail" >/dev/null
            exit 1
        fi
    fi

    return 0
}

# **************************************************************************** #
# Function Name: OM_IS_SERIOUS_RESET
# Description: 判断是否是严重复位
# Parameter: none
# Return: 0-no 1-yes
# **************************************************************************** #
OM_IS_SERIOUS_RESET()
{
    RESET_TYPE=$1
    case $RESET_TYPE in
        watchDog)
            return 1
            ;;
        oops)
            return 1
            ;;
        oom)
            return 1
            ;;
        unknown)
            return 1
            ;;
        panic)
            return 1
            ;;
        kernel)
            return 1
            ;;
        mce)
            return 1
            ;;
        bspwatchdog)
            return 1
            ;;
        ecc)
            return 1
            ;;
        *)
        ;;
    esac

    return 0
}
# **************************************************************************** #
# Function Name: OM_LAST_AND_SECLAST_BOOT_ISNOT_SERIOUS
# Description: 判断最近两次重启是否都是严重复位(用于回退系统版本)
# Parameter: none
# Return: 0-no 1-yes
# **************************************************************************** #
OM_LAST_AND_SECLAST_BOOT_ISNOT_SERIOUS()
{   
    dmesg -c > /dev/null
    echo "Reset inform" >/sys/kernel/nvram/info
    LastReset=`dmesg -c |grep "NO.* reset"`
    LastResetType=`echo $LastReset|grep -oP "(?<=NO.1 reset is )\w+"`
    SecLastResetType=`echo $LastReset|grep -oP "(?<=NO.2 reset is )\w+"`
    OS_echo "The lastest boot reason is $LastResetType"
    OS_echo "The second lastest boot reason is $SecLastResetType"
    OM_IS_SERIOUS_RESET $LastResetType
    ret1=$?
    OM_IS_SERIOUS_RESET $SecLastResetType
    ret2=$?
    if [ $ret1 = 1 -a $ret2 = 1 ] ; then
        return 1
    fi
    return 0
}

# **************************************************************************** #
# Function Name:
# Description:
# Parameter:
# Return:
# **************************************************************************** #
OM_VER_SELECT()
{
    L_TMP=`ls -l $G_DISK_MOUNT_IMAGE | grep -a "boot ->" |awk '{print $11}'`
    local L_VERSION_STR
    if [ "$L_TMP" = "boot_osp_bak" ] ; then
        OS_echo ">>>>>>>>>> Now System In Update Mode >>>>>>>>>"
        OM_LAST_AND_SECLAST_BOOT_ISNOT_SERIOUS
        if [ "$?" = "1" ] ; then
            #防止在C99升级C00时回退
            L_VERSION_STR=`cat /startup_disk/image/boot_osp/versions.conf |grep -m 1 Version |awk -F= '{print $2}'`
            OS_echo "The system version of boot_osp is [$L_VERSION_STR]."
            OS_echo "****System fail in upgrade,Rollback. Relink boot to boot_osp"
            OM_Rollback true
            OS_SaveLog
            reboot -f
            return $?
        fi
        OS_echo "--- System is in normal update status,no need Rollback"
        return 1
    fi
}

# **************************************************************************** #
# Function Name:
# Description:
# Parameter:
# Return:
# **************************************************************************** #
SYNC_SYSTEM()
{
    L_BOOT_LINK=`ls -l $G_DISK_MOUNT_IMAGE | grep -a "boot ->" |awk '{print $11}'`
    if [ "$L_BOOT_LINK" == "boot_osp_bak" ] ; then
        OS_echo "[$G_CUR_SH_NAME]: system is updating status, covert osp and osp_back if sync peer system. ">/dev/null
        OM_COVERT_BOOT_OSP_BAK_TO_BOOT_OSP
    fi

    if [ -d $G_BOOT_OSP_BAK_DIR ];then
        rm -fr $G_BOOT_OSP_BAK_DIR
    fi
    mkdir -p $G_BOOT_OSP_BAK_DIR

    L_SYNC_PEER_RESULT=1
    declare -i L_START_TIME=`date +%s`
    declare -i L_CURRENT_TIME=`date +%s`
    declare -i L_TRIAL_TIME=1200
    declare -i L_TIME_INTERVAL=$L_CURRENT_TIME-$L_START_TIME
    while [ "$L_TIME_INTERVAL" -lt "$L_TRIAL_TIME" ] && [ "$L_SYNC_PEER_RESULT" != "0" ]
    do
        OS_echo "[$G_CUR_SH_NAME]: L_TIME_INTERVAL=$L_TIME_INTERVAL">/dev/null
        /OSM/script/os_sync_peer_dir.sh $G_BOOT_LINK boot $G_BOOT_OSP_BAK_DIR >/dev/null 2>&1
        if [ "0" != "$?" ];then
            OS_echo "[$G_CUR_SH_NAME]: Exec /OSM/script/os_sync_peer_dir.sh $G_BOOT_LINK boot $G_BOOT_OSP_BAK_DIR fail">/dev/null
            sleep 10
            L_CURRENT_TIME=`date +%s`
            L_TIME_INTERVAL=$L_CURRENT_TIME-$L_START_TIME
        else
            OS_echo "[$G_CUR_SH_NAME]: Exec /OSM/script/os_sync_peer_dir.sh $G_BOOT_LINK boot $G_BOOT_OSP_BAK_DIR successful">/dev/null
            L_SYNC_PEER_RESULT=0
        fi
    done

    if [ "0" != "$L_SYNC_PEER_RESULT" ];then
        OS_echo "[$G_CUR_SH_NAME]: sync peer dir failed after 1200s trial!">/dev/null
        return 1
    fi

    #修改链接
    OS_echo "[$G_CUR_SH_NAME]: call to OS_MODIFY_LINK_TO_BAK modify link.">/dev/null
    OS_MODIFY_LINK_TO_BAK
    if [ "0" != "$?" ];then
        OS_echo "[$G_CUR_SH_NAME]: Relint boot to boot_osp_bak fail">/dev/null
        return 1
    fi

    #刷盘
    sync

    OS_SaveLog

    #重启
    reboot -f

    return 0
}

OS_FREE_MEM_FUC()
{
    OS_echo "[UPGRADE_FREE_MEM]free memory begin!"
    sync
    echo 3 >/proc/sys/vm/drop_caches
    FREE_MEM=`free -m|grep ^Mem|awk '{print $4}'`
    if [ "${FREE_MEM}" -lt "${G_MIN_MEM}" ];then
        OS_echo "[OS_CreatePolicy] Force free memory"
        OS_UPGRADE_FORCE_FREEMEM
    fi
}

# **************************************************************************** #
# Function Name: execute process scritp
# Description:
# Parameter: ./sh (execute path) (script exist path) (script name)
# Return:
# **************************************************************************** #
OS_EXECUTE_UPGRADE_SCRIPT()
{
    L_EXEC_PATH=`echo $1 |awk '{print $1}'`
    L_SCRIPT_FILE_PATH=`echo $1 |awk '{print $2}'`
    L_SCRIPT_FILE_NAME=`echo $1 |awk '{print $3}'`

    mkdir $L_EXEC_PATH

    if [ ! -d $L_EXEC_PATH ] ; then
       OS_echo "UPGRADE_SH: create upgrade script run path" >/dev/null
       mkdir $L_EXEC_PATH
    fi

    cp -f $L_SCRIPT_FILE_PATH $L_EXEC_PATH

    cd $L_EXEC_PATH

    ./$L_SCRIPT_FILE_NAME
    L_RET=$?

    rm -Rf *

    return $L_RET
}

# **************************************************************************** #
# Function Name: OS_RMMOD_BIOS_KO
# Description:
# Parameter: none
# Return: 0-succ 1-fail
# **************************************************************************** #
OS_RMMOD_BIOS_KO()
{
    L_TMP="updatebios"
    L_INSMOD=`lsmod |grep "$L_TMP" |awk '{print $1}'`
    if [ -z "$L_INSMOD" ] ; then
        return 0
    fi

    rmmod -f $G_BIOS_UPDATE_KO_NAME
    if [ 0 != $? ] ; then
        OS_echo "UPGRADE_SH: --- rmmod $G_BIOS_UPDATE_KO_NAME Failed ---">/dev/null
        return 1
    fi

    return 0
}

# **************************************************************************** #
# Function Name:
# Description:
# Parameter: none
# Return: 0-succ 1-fail
# **************************************************************************** #
OS_INSMOD_BIOS_KO()
{
    L_BIOS_UPDATE_FILE_TMP=$1

    cd $G_BIOS_UPDATE_DIR
    OS_echo "UPGRADE_SH: insmod $G_BIOS_UPDATE_KO_NAME fname=$L_BIOS_UPDATE_FILE_TMP Begin">/dev/null
    insmod "$G_BIOS_UPDATE_KO_NAME" fname=$L_BIOS_UPDATE_FILE_TMP
    if [ "0" != "$?" ];then
        OS_echo "UPGRADE_SH: insmod $G_BIOS_UPDATE_KO_NAME fname=$L_BIOS_UPDATE_FILE_TMP fail">/dev/null
        return 1
    else
        OS_echo "UPGRADE_SH: insmod $G_BIOS_UPDATE_KO_NAME fname=$L_BIOS_UPDATE_FILE_TMP success">/dev/null
        return 0
    fi
}

# **************************************************************************** #
# Function Name: OS_EXECUTE_UPDATE_BIOS
# Description: execute to update the bios
# Parameter: none
# Return: 0-do not need update  1-fail 2-success 3-warn
# **************************************************************************** #
OS_EXECUTE_UPDATE_BIOS()
{
    L_BIOS_UPDATE_FILE_PATH=$1

    OS_RMMOD_BIOS_KO
    if [ 0 != $? ] ; then
        rm -f $L_BIOS_UPDATE_FILE_PATH &>/dev/kmsg
        rm -f $G_BIOS_UPDATE_DIR/$G_BIOS_UPDATE_KO_NAME &>/dev/kmsg
        OS_echo "UPGRADE_SH: --- OS_RMMOD_BIOS_KO failed ---">/dev/null
        exit 1
    fi

    #clear log
    dmesg -c >/dev/null

    OS_INSMOD_BIOS_KO $L_BIOS_UPDATE_FILE_PATH
    if [ "0" != "$?" ];then
        rm -f $L_BIOS_UPDATE_FILE_PATH &>/dev/kmsg
        rm -f $G_BIOS_UPDATE_DIR/$G_BIOS_UPDATE_KO_NAME &>/dev/kmsg
        OS_echo "UPGRADE_SH: --- OS_INSMOD_BIOS_KO failed ---">/dev/null
        exit 1
    fi

    local TRY_DMESG_TIMES=1
    while [ true ];do

        OS_echo "UPGRADE_SH: Try $TRY_DMESG_TIMES to dmesg bios keyword">/dev/null
        L_OK=$(dmesg | grep "bios:reboot")
        if [ -n  "$L_OK"  ] ; then
            OS_echo "UPGRADE_SH: --- Update BIOS success ---">/dev/null
            return 2
        fi

        L_SAME=$(dmesg | grep "bios:same")
        if [ -n  "$L_SAME"  ] ; then
            OS_echo "UPGRADE_SH: --- BIOS ver same, don't need update BIOS ---">/dev/null
            return 0
        fi

        L_WARN=$(dmesg | grep "bios:warn")
        if [ -n  "$L_WARN"  ] ; then
            OS_echo "UPGRADE_SH: update BIOS fail, current running BIOS ver is same with sys config.">/dev/null
            return 3
        fi

        let TRY_DMESG_TIMES=$TRY_DMESG_TIMES+1
        if [ $TRY_DMESG_TIMES -gt $MAX_TRY_TIMES ];then
            OS_echo "UPGRADE_SH: It has reached $MAX_TRY_TIMES times to try to demsg bios keyword"
            break
        fi
        sleep 5
    done
    local TRY_CAT_TIMES=1
    while [ true ];do
        if [ ! -f $MESSAGE ] ; then
            OS_echo "UPGRADE_SH: $MESSAGE is not exist">/dev/null
            return 1
        fi

        OS_echo "UPGRADE_SH: Try $TRY_CAT_TIMES to cat bios keyword">/dev/null
        L_OK=$(cat $MESSAGE | grep "bios:reboot")
        if [ -n  "$L_OK"  ] ; then
            OS_echo "UPGRADE_SH: --- Update BIOS success ---">/dev/null
            return 2
        fi

        L_SAME=$(cat $MESSAGE | grep "bios:same")
        if [ -n  "$L_SAME"  ] ; then
            OS_echo "UPGRADE_SH: --- BIOS ver same, don't need update BIOS ---">/dev/null
            return 0
        fi

        L_WARN=$(cat $MESSAGE | grep "bios:warn")
        if [ -n  "$L_WARN"  ] ; then
            OS_echo "UPGRADE_SH: update BIOS fail, current running BIOS ver is same with sys config.">/dev/null
            return 3
        fi
        let TRY_CAT_TIMES=$TRY_CAT_TIMES+1
        if [ $TRY_CAT_TIMES -gt $MAX_TRY_TIMES ] ; then
            OS_echo "UPGRADE_SH: It has reached $MAX_TRY_TIMES times to try to cat bios keyword."
            break
        fi
        sleep 5
    done
    #bios:fail
    return 1
}

# **************************************************************************** #
# Function Name: OS_UPDATE_BIOS
# Description: update the bios
# Parameter: none
# Return: 0-succ 1-fail
# **************************************************************************** #
OS_UPDATE_BIOS()
{
    local L_BIOS_UPDATE_FAIL_FILE=""
    L_BIOS_UPDATE_FAIL_FILE=`cat $G_PRODUCT_CFG_FILE |grep $G_BIOS_UPDATE_FAIL_ITEMNAME |cut -d '=' -f 2`

    if [ -z $L_BIOS_UPDATE_FAIL_FILE ];then
        L_BIOS_UPDATE_FAIL_FILE="/tmp/biosupgradefail"
    fi

    L_BIOS_UPDATE_ROM_NAME="bios.ROM"


    rm -f $G_BIOS_UPDATE_DIR/$L_BIOS_UPDATE_ROM_NAME &>/dev/kmsg
    rm -f $G_BIOS_UPDATE_DIR/$G_BIOS_UPDATE_KO_NAME &>/dev/kmsg

    L_BOOT_LINK=`ls -l $G_DISK_MOUNT_IMAGE | grep -a "boot ->" |awk '{print $11}'`
    if [ "$L_BOOT_LINK" != "boot_osp_bak" ] ; then
        OS_echo "UPGRADE_SH: system is not in updating status, update BIOS with running version.">/dev/null
        L_UPGRADE_STATUS=false
    else
        OS_echo "UPGRADE_SH: system is in updating status, update BIOS with new version.">/dev/null
        L_UPGRADE_STATUS=true
    fi
    
    if [ ! -f $G_BOOT_LINK/$G_BIOS_UPDATE_ROM_NAME ] ; then
        OS_echo "UPGRADE_SH: BIOS update file:$G_BOOT_LINK/$G_BIOS_UPDATE_ROM_NAME is not exist" >/dev/null
        exit 0
    fi

    if [ ! -f $G_BIOS_UPDATE_PKG_DIR/$G_BIOS_UPDATE_KO_NAME ] ; then
        OS_echo "UPGRADE_SH: BIOS update file:$G_BIOS_RUNNING_PKG_DIR/$G_BIOS_UPDATE_KO_NAME is not exist" >/dev/null
        exit 0
    fi
        
    OS_echo "UPGRADE_SH: cp $G_BOOT_LINK/$G_BIOS_UPDATE_ROM_NAME to $G_BIOS_UPDATE_DIR">/dev/null
    cp $G_BOOT_LINK/$G_BIOS_UPDATE_ROM_NAME $G_BIOS_UPDATE_DIR &>/dev/kmsg

    OS_echo "UPGRADE_SH: cp $G_BIOS_UPDATE_PKG_DIR/$G_BIOS_UPDATE_KO_NAME to $G_BIOS_UPDATE_DIR">/dev/null
    cp $G_BIOS_UPDATE_PKG_DIR/$G_BIOS_UPDATE_KO_NAME $G_BIOS_UPDATE_DIR &>/dev/kmsg

    OS_echo "UPGRADE_SH: Begin to upgrade BIOS.">/dev/null
    OS_EXECUTE_UPDATE_BIOS $G_BIOS_UPDATE_DIR/$L_BIOS_UPDATE_ROM_NAME
    L_BIOS_UPDATE_RET=$?
    if [ "0" == "$L_BIOS_UPDATE_RET" ] ; then
        OS_echo "UPGRADE_SH: Both BIOS are new version, now start work.">/dev/null
        OS_RMMOD_BIOS_KO
        rm -f $G_BIOS_UPDATE_DIR/$L_BIOS_UPDATE_ROM_NAME &>/dev/kmsg
        rm -f $G_BIOS_UPDATE_DIR/$G_BIOS_UPDATE_KO_NAME &>/dev/kmsg
        return 0
    elif [ "2" == "$L_BIOS_UPDATE_RET" ] ; then
        OS_RMMOD_BIOS_KO
        rm -f $G_BIOS_UPDATE_DIR/$L_BIOS_UPDATE_ROM_NAME &>/dev/kmsg
        rm -f $G_BIOS_UPDATE_DIR/$G_BIOS_UPDATE_KO_NAME &>/dev/kmsg
        G_BIOS_NEED_REBOOT=true
        return 0
    #BIOS upgrade failed, but the current BIOS is same with config ver.
    elif [ "3" == "$L_BIOS_UPDATE_RET" ] ; then
        #非升级过程中，则正常开工后发告警.
        OS_echo "UPGRADE_SH: BIOS upgrade failed but the current BIOS is new version, start work now.">/dev/null
        OS_RMMOD_BIOS_KO
        rm -f $G_BIOS_UPDATE_DIR/$L_BIOS_UPDATE_ROM_NAME &>/dev/kmsg
        rm -f $G_BIOS_UPDATE_DIR/$G_BIOS_UPDATE_KO_NAME &>/dev/kmsg
        OS_echo "1" >$L_BIOS_UPDATE_FAIL_FILE
        return 0
    #BIOS upgrade failed, and the current BIOS is different from config ver.
    else
        #非升级过程中，则开工失败.
        if [ "$L_UPGRADE_STATUS" = "false" ] ; then
            OS_echo "UPGRADE_SH: BIOS upgrade failed and current BIOS is not new ver and not in upgrading status, start work fail.">/dev/null
            OS_RMMOD_BIOS_KO
            rm -f $G_BIOS_UPDATE_DIR/$L_BIOS_UPDATE_ROM_NAME &>/dev/kmsg
            rm -f $G_BIOS_UPDATE_DIR/$G_BIOS_UPDATE_KO_NAME &>/dev/kmsg
            return 1
        #升级过程中，则回滚.
        else
            #BIOS upgrade failed, but in upgrading status, rollback system version and reboot
            OS_echo "UPGRADE_SH: BIOS upgrade failed and current BIOS is not new ver and in upgrading status, rollback system version.">/dev/null
            OM_Rollback false
            OS_SaveLog
            reboot -f
            exit 1
        fi
    fi
}

# **************************************************************************** #
# Function Name: OS_UPDATE_BIOS_BEFORE_REBOOT
# Description: update the bios before upgrade reboot
# Parameter: none
# Return: 0-succ 1-fail
# **************************************************************************** #
OS_UPDATE_BIOS_BEFORE_REBOOT()
{
    local l_dstVersion="$1"
    local l_ospVersion="1"
    local l_bakVersion="1"
    local l_tmpVersion="1"
    local l_curVersion="1"
    
    local L_BIOS_UPDATE_FAIL_FILE=""
    L_BIOS_UPDATE_FAIL_FILE=`cat $G_PRODUCT_CFG_FILE |grep $G_BIOS_UPDATE_FAIL_ITEMNAME |cut -d '=' -f 2`
    
    ##版本号获取后，如果存在补丁版本号，版本号部分将包含SPH或者SPC的补丁版本号，需要去掉，只获取前10位，否则将无法匹配到versions.conf
    l_dstVersion=`echo ${l_dstVersion:0:10}`
    OS_echo "UPGRADE_SH: dstVersion=$l_dstVersion " >/dev/null
    
    if [ -z $L_BIOS_UPDATE_FAIL_FILE ];then
        L_BIOS_UPDATE_FAIL_FILE="/tmp/biosupgradefail"
    fi
    L_BIOS_UPDATE_ROM_NAME="bios.ROM"
    
    rm -f $G_BIOS_UPDATE_DIR/$L_BIOS_UPDATE_ROM_NAME &>/dev/kmsg
    rm -f $G_BIOS_UPDATE_DIR/$G_BIOS_UPDATE_KO_NAME &>/dev/kmsg

    #获取三个目录下的版本
    [ -f $G_UPDATE_BOOT_DIR/$G_PKG_VERSION_FILENAME ] \
            && { l_ospVersion=$(grep -m 1 Version $G_UPDATE_BOOT_DIR/$G_PKG_VERSION_FILENAME | awk -F"=" '{print $2}'); }
    [ -f $G_BOOT_OSP_BAK_DIR/$G_PKG_VERSION_FILENAME ] \
            && { l_bakVersion=$(grep -m 1 Version $G_BOOT_OSP_BAK_DIR/$G_PKG_VERSION_FILENAME | awk -F"=" '{print $2}'); }
    [ -f $G_UPDATE_TMP_DIR/$G_PKG_VERSION_FILENAME ] \
            && { l_tmpVersion=$(grep -m 1 Version $G_UPDATE_TMP_DIR/$G_PKG_VERSION_FILENAME | awk -F"=" '{print $2}'); }
    #获取当前的版本
    [ -f $G_CUR_VERSION_FILE ] \
            && { l_curVersion=$(grep -m 1 Version $G_CUR_VERSION_FILE | awk -F"=" '{print $2}'); }
            
    #如果是降级到老版本，则直接不升级BIOS返回成功   
    if [ -n "$(echo $l_dstVersion | grep "^35003")" -a  $l_dstVersion -lt 3500320101 ] \
    || [ -n "$(echo $l_dstVersion | grep "^31803")" -a  $l_dstVersion -lt 3180320101 ] \
    || [ -n "$(echo $l_dstVersion | grep "^32003")" -a  $l_dstVersion -lt 3200320101 ] \
    || [ -n "$(echo $l_dstVersion | grep "^32001")" ] \
    || [ -n "$(echo $l_dstVersion | grep "^31801")" ]; then
        OS_echo "UPGRADE_SH: curVersion=$l_curVersion dstVersion=$l_dstVersion don't upgrade BIOS of old version." >/dev/null
        return 0
    fi

    #检查升级目标版本在哪个目录下
    if [ "$l_ospVersion" == "$l_dstVersion" ]; then
        #如果升级目标版本在boot_osp下，则用boot_osp中的BIOS固件升级
        OS_echo "UPGRADE_SH: Upgrade bios dst version is in boot_osp." >/dev/null

        OS_echo "UPGRADE_SH: cp $G_UPDATE_BOOT_DIR/$G_BIOS_UPDATE_ROM_NAME to $G_BIOS_UPDATE_DIR">/dev/null
        if [ ! -f $G_UPDATE_BOOT_DIR/$G_BIOS_UPDATE_ROM_NAME ] ; then
        OS_echo "UPGRADE_SH: Bios.rom is not exist, upgrade bios later">/dev/null
        return 0
    fi
        cp $G_UPDATE_BOOT_DIR/$G_BIOS_UPDATE_ROM_NAME $G_BIOS_UPDATE_DIR &>/dev/kmsg
    elif [ "$l_bakVersion" == "$l_dstVersion" ]; then
        #如果升级目标版本已经在boot_osp_bak下，则OK
        OS_echo "UPGRADE_SH: Upgrade bios dst version is already in boot_osp_bak." >/dev/null
        
        OS_echo "UPGRADE_SH: cp $G_BOOT_OSP_BAK_DIR/$G_BIOS_UPDATE_ROM_NAME to $G_BIOS_UPDATE_DIR">/dev/null
    if [ ! -f $G_BOOT_OSP_BAK_DIR/$G_BIOS_UPDATE_ROM_NAME ] ; then
        OS_echo "UPGRADE_SH: Bios.rom is not exist, upgrade bios later">/dev/null
        return 0
    fi
        cp $G_BOOT_OSP_BAK_DIR/$G_BIOS_UPDATE_ROM_NAME $G_BIOS_UPDATE_DIR &>/dev/kmsg
        
    elif [ "$l_tmpVersion" == "$l_dstVersion" ]; then
        #如果升级目标版本已经在boot_osp_tmp下，则需要将其文件放到boot_osp_bak下
        OS_echo "UPGRADE_SH: Upgrade bios dst version is already in boot_osp_tmp." >/dev/null
        
        OS_echo "UPGRADE_SH: cp $G_UPDATE_TMP_DIR/$G_BIOS_UPDATE_ROM_NAME to $G_BIOS_UPDATE_DIR">/dev/null
    if [ ! -f $G_UPDATE_TMP_DIR/$G_BIOS_UPDATE_ROM_NAME ] ; then
        OS_echo "UPGRADE_SH: Bios.rom is not exist, upgrade bios later">/dev/null
        return 0
    fi
        cp $G_UPDATE_TMP_DIR/$G_BIOS_UPDATE_ROM_NAME $G_BIOS_UPDATE_DIR &>/dev/kmsg

    else
        #如果升级目标版本三个目录均没有，则返回失败
        OS_echo "UPGRADE_SH: Upgrade bios dst version is not in boot_osp, boot_osp_bak and boot_osp_tmp." >/dev/null
        return 1;
    fi
    
    OS_echo "UPGRADE_SH: cp $G_BIOS_UPDATE_PKG_DIR/$G_BIOS_UPDATE_KO_NAME to $G_BIOS_UPDATE_DIR">/dev/null
    cp $G_BIOS_UPDATE_PKG_DIR/$G_BIOS_UPDATE_KO_NAME $G_BIOS_UPDATE_DIR &>/dev/kmsg
    
    #判读是否处于升级状态
    L_BOOT_LINK=`ls -l $G_DISK_MOUNT_IMAGE | grep -a "boot ->" |awk '{print $11}'`
    if [ "$L_BOOT_LINK" != "boot_osp_bak" ] ; then
        OS_echo "UPGRADE_SH: system is not in updating status or in upgrading before rebooting, update BIOS with running or new version.">/dev/null
        L_UPGRADE_STATUS=false
    else
        OS_echo "UPGRADE_SH: system is in updating status, update BIOS with new version.">/dev/null
        L_UPGRADE_STATUS=true
    fi
    
    #开始升级bios
    OS_echo "UPGRADE_SH: Begin to upgrade BIOS.">/dev/null
    OS_EXECUTE_UPDATE_BIOS $G_BIOS_UPDATE_DIR/$L_BIOS_UPDATE_ROM_NAME
    L_BIOS_UPDATE_RET=$?
    if [ "0" == "$L_BIOS_UPDATE_RET" ] ; then
        OS_echo "UPGRADE_SH: Both BIOS are new version, now start work.">/dev/null
        OS_RMMOD_BIOS_KO
        rm -f $G_BIOS_UPDATE_DIR/$L_BIOS_UPDATE_ROM_NAME &>/dev/kmsg
        rm -f $G_BIOS_UPDATE_DIR/$G_BIOS_UPDATE_KO_NAME &>/dev/kmsg
        return 0
    elif [ "2" == "$L_BIOS_UPDATE_RET" ] ; then
        OS_RMMOD_BIOS_KO
        rm -f $G_BIOS_UPDATE_DIR/$L_BIOS_UPDATE_ROM_NAME &>/dev/kmsg
        rm -f $G_BIOS_UPDATE_DIR/$G_BIOS_UPDATE_KO_NAME &>/dev/kmsg
        G_BIOS_NEED_REBOOT=true
        return 2
    #BIOS upgrade failed, but the current BIOS is same with config ver.
    elif [ "3" == "$L_BIOS_UPDATE_RET" ] ; then
        #非升级过程中.
        OS_echo "UPGRADE_SH: BIOS upgrade failed but the current BIOS is new version.">/dev/null
        OS_RMMOD_BIOS_KO
        rm -f $G_BIOS_UPDATE_DIR/$L_BIOS_UPDATE_ROM_NAME &>/dev/kmsg
        rm -f $G_BIOS_UPDATE_DIR/$G_BIOS_UPDATE_KO_NAME &>/dev/kmsg

        OS_echo "1" >$L_BIOS_UPDATE_FAIL_FILE
        return 0
    #BIOS upgrade failed, and the current BIOS is different from config ver.
    else
        OS_echo "UPGRADE_SH: BIOS upgrade failed and current BIOS is not new ver and not in upgrading status.">/dev/null
        OS_RMMOD_BIOS_KO
        rm -f $G_BIOS_UPDATE_DIR/$L_BIOS_UPDATE_ROM_NAME &>/dev/kmsg
        rm -f $G_BIOS_UPDATE_DIR/$G_BIOS_UPDATE_KO_NAME &>/dev/kmsg
        return 1
    fi
}


# **************************************************************************** #
# Function Name:
# Description:
# Parameter: none
# Return: 0-succ 1-fail
# **************************************************************************** #
OS_REBOOT_SYSTEM()
{
    if [ "$G_BIOS_NEED_REBOOT" = "true" ] ; then
        OS_SaveLog
        reboot -f
    fi
}

# **************************************************************************** #
# Function Name: OS_TAR_UPGRADE_OUTPUT_FILE
# Description:   tar upgrade output detail file
# Parameter:     output file path
# Return:
# **************************************************************************** #
OS_TAR_UPGRADE_OUTPUT_FILE()
{
    L_OUTPUT_FILE=$1
    L_PEER_IP=`OS_GetRemoteIBCIP`
    L_UPGRADE_DETAIL_FILE=`cat $G_PRODUCT_CFG_FILE |grep $G_UPGRADE_OUTPUT_DETAIL_FILE_NAME |cut -d '=' -f 2`
    L_TMP_LOCAL=upgrade_detail_a
    L_TMP_PEER=upgrade_detail_b

    cd $G_UPDATE_DIR &>/dev/null

    if [ -f $L_OUTPUT_FILE ];then
        rm -fr $L_OUTPUT_FILE &>/dev/null
    fi

    cp -fr $L_UPGRADE_DETAIL_FILE upgrade_detail_a &>/dev/null
    scp ibc_os_hs@$L_PEER_IP:$L_UPGRADE_DETAIL_FILE upgrade_detail_b &>/dev/null

    if [ -f $L_TMP_LOCAL ] && [ -f $L_TMP_PEER ];then
        OS_echo "UPGRADE_SH: tar -czf tmp.tgz $L_TMP_LOCAL $L_TMP_PEER." >/dev/null
        tar -czf tmp.tgz $L_TMP_LOCAL $L_TMP_PEER &>/dev/null
    elif [ -f $L_TMP_LOCAL ];then
        OS_echo "UPGRADE_SH: tar -czf tmp.tgz $L_TMP_LOCAL." >/dev/null
        tar -czf tmp.tgz $L_TMP_LOCAL &>/dev/null
    elif [ -f $L_TMP_PEER ];then
        OS_echo "UPGRADE_SH: tar -czf tmp.tgz $L_TMP_PEER." >/dev/null
        tar -czf tmp.tgz $L_TMP_PEER &>/dev/null
    else
        OS_echo "UPGRADE_SH: upgrade output detail file is not exist in local and peer controller." >/dev/null
        cd - &>/dev/null
        return 1
    fi

    mv tmp.tgz $1 &>/dev/null
    scp $1 ibc_os_hs@$L_PEER_IP:$1 &>/dev/null

    if [ -f $L_TMP_LOCAL ];then
        rm -fr $L_TMP_LOCAL &>/dev/null
    fi

    if [ -f $L_TMP_PEER ];then
        rm -fr $L_TMP_PEER &>/dev/null
    fi

    if [ -f $L_OUTPUT_FILE ];then
        OS_echo "UPGRADE_SH: tar upgrade output file $L_OUTPUT_FILE success." >/dev/null
    else
        OS_echo "UPGRADE_SH: tar upgrade output file $L_OUTPUT_FILE fail." >/dev/null
    fi

    cd - &>/dev/null

    return 0
}
# **************************************************************************** #
# Function Name: UPGRADE_CHECK_IS_HOT_DIR_CHANGE
# Description: 判断补丁目录是否变化coffer_bin
# Parameter:
# Return: 
# **************************************************************************** #
UPGRADE_CHECK_IS_HOT_DIR_CHANGE()
{
    l_ver_file=$1
    
    l_ver=`cat $l_ver_file | grep -m 1 Version  | awk -F"=" '{print $2}'`
    if [ -z $l_ver ];then
        OS_echo "UPGRADE_SH no version." >/dev/null
        return 1
    fi
            
    #如果是老版本，则没有coffer_bin/hotpatch目录   
    if [ -n "$(echo $l_ver | grep "^620071")" -a  "$((l_ver))" -lt "6200710215" ] \
    || [ -n "$(echo $l_ver | grep "^618071")" -a  "$((l_ver))" -lt "6180710215" ] \
    || [ -n "$(echo $l_ver | grep "^650071")" -a  "$((l_ver))" -lt "6500710215" ] \
    || [ -n "$(echo $l_ver | grep "^3200")" -a  "$((l_ver))" -lt "3200630215" ] \
    || [ -n "$(echo $l_ver | grep "^3500")" -a  "$((l_ver))" -lt "3500630215" ] \
    || [ -n "$(echo $l_ver | grep "^3100")" -a  "$((l_ver))" -lt "3100630215" ] \
    || [ -n "$(echo $l_ver | grep "^3180")" -a  "$((l_ver))" -lt "3180630215" ];then
        OS_echo "UPGRADE_SH: peerVersion=$l_ver, has not change dir." >/dev/null
        return 1
    fi
    
    return 0
}
#*********************************************************************#
# Function Name: upgrade_ReleaseSpaceInBootRescue
# Description: 释放备件boot_rescue下的空间
# Usage: syncDirPromPeer
# Parameter:
# Return:
#*********************************************************************#
function upgrade_ReleaseSpaceInBootRescue()
{
    local BOOT_RESCUE_DIR="/startup_disk/image/boot_rescue/"
    local BOOT_RESCUE_UPDATE="/startup_disk/image/boot_rescue/update_pkg"
    local BOOT_RESCUE_INITRD="/startup_disk/image/boot_rescue/initrd"
    local BOOT_RESCUE_BZIMAGE="/startup_disk/image/boot_rescue/bzImage"
    
    if [ -d $BOOT_RESCUE_UPDATE ] ; then
        OS_echo "UPGRADE_SH: exist boot_rescue updatepkg.">/dev/null
        rm -rf $BOOT_RESCUE_UPDATE
        if [ 0 != $? ] ; then
            OS_echo "UPGRADE_SH: remove boot_rescue updatepkg failed.">/dev/null
            return 1
        fi
    fi
    
    if [ ! -h $BOOT_RESCUE_INITRD ] ; then
        OS_echo "UPGRADE_SH: exist boot_rescue initrd.">/dev/null
        rm -f $BOOT_RESCUE_INITRD
        cd $BOOT_RESCUE_DIR
        ln -s ../boot_osp/initrd /startup_disk/image/boot_rescue/initrd
        if [ 0 != $? ] ; then
            OS_echo "UPGRADE_SH: make initrd link failed.">/dev/null
            cd - &>/dev/null
            return 1
        fi
    fi
    if [ ! -h $BOOT_RESCUE_BZIMAGE ] ; then
        OS_echo "UPGRADE_SH: exist boot_rescue bzImage.">/dev/null
        rm -f $BOOT_RESCUE_BZIMAGE
        cd $BOOT_RESCUE_DIR
        ln -s ../boot_osp/bzImage /startup_disk/image/boot_rescue/bzImage
        if [ 0 != $? ] ; then
            OS_echo "UPGRADE_SH: make bzImage link failed.">/dev/null
            cd - &>/dev/null
            return 1
        fi
    fi

    cd - &>/dev/null
    return 0
}

# **************************************************************************** #
# Function Name: OS_JUDGE_DIR_EXIST
# Description: 创建和清理同步的目录
# Parameter:
# Return: 
# **************************************************************************** #
OS_JUDGE_DIR_EXIST()
{
    local checkDir=$G_BOOT_OSP_BAK_DIR

    if [ -d $G_UPDATE_TMP_DIR ]; then
        OS_echo "UPGRADE_SH: rm boot_osp_tmp dir" > /dev/null
        rm -rf $G_UPDATE_TMP_DIR
    fi
    
    upgrade_ReleaseSpaceInBootRescue

    if [ -d $G_OS_HP_DIR ];then
         rm -rf $G_OS_HP_DIR
         OS_echo "UPGRADE_SH: rm hotpatch update dir" > /dev/null
    fi
    
    ClearPreprocessPatch
    
    [ ! -d ${checkDir} ] && { mkdir -p ${checkDir}; return 0; }

    [ -n "$(ls -A ${checkDir})" ] && rm -rf ${checkDir}/*

    return 0
}

# **************************************************************************** #
# Function Name: CopySoftwareFromOtherNid
# Description: 同步系统软件目录和补丁目录
# Parameter:
# Return: 
# **************************************************************************** #
CopySoftwareFromOtherNid()
{
    local L_SOURCE_IP=$1
    local local rettmp=0

    #设置目录可读写
    OS_SET_DISK_RW
    OS_SET_HOTPATCH_DISK_RW

    #判断目录是否存在 以及存在是否为空
    OS_JUDGE_DIR_EXIST

    #从源 IP 拷贝版本
    /OSM/script/os_get_dir.sh ${L_SOURCE_IP} /startup_disk/image/boot_osp /startup_disk/image/boot_osp_bak
    if [ "0" != "$?" ]; then
        OS_echo "UPGRADE_SH: copy software from $L_SOURCE_IP failed." > /dev/null
        OS_SET_DISK_RO
        return 1
    fi
    # 校验拷贝过来的软件版本boot_osp_bak/boot_osp
    Check_Initrd_and_Bzimage /startup_disk/image/boot_osp_bak/boot_osp
    if [ "$?" != "0" ] ; then
        OS_echo "UPGRADE_SH: check system software failed">/dev/null
        OS_SET_DISK_RO
        return 1
    fi

    #os_get_dir.sh 脚本是拷贝整个文件夹 移动文件并删除多余的 boot_osp 目录
    mv /startup_disk/image/boot_osp_bak/boot_osp/* /startup_disk/image/boot_osp_bak/
    rm -rf /startup_disk/image/boot_osp_bak/boot_osp

    if [ ! -h $G_DISK_MOUNT_IMAGE/boot_osp_bak/$G_BOOTLOADER ]; then
        OS_echo "$G_BOOTLOADER link not exit, need to recreat." > /dev/null

        cd $G_DISK_MOUNT_IMAGE/boot_osp_bak &> /dev/kmsg
        OS_echo "UPGRADE_SH: ln -s ../$G_BOOTLOADER $G_BOOTLOADER" > /dev/null

        ln -s ../$G_BOOTLOADER $G_BOOTLOADER &>/dev/kmsg
        if [ "0" != "$?" ];then
            OS_echo "Creat $G_BOOTLOADER link failed,exit." > /dev/null
            OS_SET_DISK_RO
            return 1
        fi
    fi

    #从源IP拷贝热补丁，如果对端是老版本则忽略此失败，coffer_bin没有hotpatch目录
    if [ -f /startup_disk/image/boot_osp_bak/versions.conf ];then
        UPGRADE_CHECK_IS_HOT_DIR_CHANGE "/startup_disk/image/boot_osp_bak/versions.conf"
        rettmp=$?        
    fi
    
    /OSM/script/os_get_dir.sh ${L_SOURCE_IP} $G_OS_HP_DIR $G_HOT_PATCH_BOOT_DIR
    if [ "0" != "$?" ]; then
        OS_echo "UPGRADE_SH copy hotpatch from $L_SOURCE_IP failed." > /dev/null
        if [ "0" == "$rettmp" ];then
            OS_SET_DISK_RO    
            OS_SET_HOTPATCH_DISK_RO
            return 1
        fi
    fi
    
    #设置热补丁软连接，如果通过172.16网段传输文件，由于SFTP协议限制，无法传输软链接，需要传输后手动恢复
    if [ -d $G_OS_HP_DIR/patch_cur ];then
        if [ ! -h $G_OS_HP_DIR/patch ];then
            OS_echo "UPGRADE_SH Hot patch link(patch->hotpatch_cur) not exist,need create.">/dev/null
            cd $G_OS_HP_DIR &>/dev/kmsg
            ln -s patch_cur patch &>/dev/kmsg
            if [ 0 != $? ];then
                OS_echo "UPGRADE_SH Creat hot patch link(patch->hotpatch_cur)fail,exit.">/dev/null
                OS_SET_DISK_RO
                OS_SET_HOTPATCH_DISK_RO
                return 1
            fi
        fi
    elif [ -d $G_OS_HP_DIR/patch_bak ];then
        if [ ! -h $G_OS_HP_DIR/patch ];then
            OS_echo "UPGRADE_SH Hot patch link(patch->hotpatch_bak) not exist,need create.">/dev/null
            cd $G_OS_HP_DIR &>/dev/kmsg
            ln -s patch_bak patch &>/dev/kmsg
            if [ 0 != $? ];then
                OS_echo "UPGRADE_SH Creat hot patch link(patch->hotpatch_bak) fail,exit.">/dev/null
                OS_SET_DISK_RO
                OS_SET_HOTPATCH_DISK_RO
                return 1
            fi
        fi
    fi
    #如果是老版本阵列，当前待扩容节点为新版本，需要处理从老版本拷贝软件包丢软链接的场景
    if [ -d $G_DISK_MOUNT_IMAGE/boot_osp_bak/hotpatch/patch_cur ];then
        if [ ! -h $G_DISK_MOUNT_IMAGE/boot_osp_bak/hotpatch/patch ];then
            OS_echo "[$G_CUR_SH_NAME]: Hot patch link(patch->hotpatch_cur) not exist,need create.">/dev/null
            cd $G_DISK_MOUNT_IMAGE/boot_osp_bak/hotpatch &>/dev/kmsg
            ln -s patch_cur patch &>/dev/kmsg
            if [ 0 != $? ];then
                OS_echo "Creat hot patch link(patch->hotpatch_cur)fail,exit.">/dev/null
                OS_SET_DISK_RO
                return 1
            fi
        fi
    elif [ -d $G_DISK_MOUNT_IMAGE/boot_osp_bak/hotpatch/patch_bak ];then
        if [ ! -h $G_DISK_MOUNT_IMAGE/boot_osp_bak/hotpatch/patch ];then
            OS_echo "[$G_CUR_SH_NAME]: Hot patch link(patch->hotpatch_bak) not exist,need create.">/dev/null
            cd $G_DISK_MOUNT_IMAGE/boot_osp_bak/hotpatch &>/dev/kmsg
            ln -s patch_bak patch &>/dev/kmsg
            if [ 0 != $? ];then
                OS_echo "Creat hot patch link(patch->hotpatch_bak) fail,exit.">/dev/null
                OS_SET_DISK_RO
                return 1
            fi
        fi
    fi

    #设置port链接
    if [ ! -e "$G_DISK_MOUNT_IMAGE/boot_osp_bak/update_pkg/${G_PRODUCT_TYPE}/port" ]; then
        OS_echo "[$G_CUR_SH_NAME]: port symbolic link does not exist, need create."
        cd "$G_DISK_MOUNT_IMAGE/boot_osp_bak/update_pkg/${G_PRODUCT_TYPE}"
        ln -s ../port port
        if [ 0 != $? ]; then
            OS_echo "[$G_CUR_SH_NAME]: Failed to create port symbolic link."
        fi
    fi
    #设置diskfirmware链接
    if [ ! -e "$G_DISK_MOUNT_IMAGE/boot_osp_bak/update_pkg/${G_PRODUCT_TYPE}/diskfirmware" ]; then
        OS_echo "[$G_CUR_SH_NAME]: diskfirmware symbolic link does not exist, need create."
        cd "$G_DISK_MOUNT_IMAGE/boot_osp_bak/update_pkg/${G_PRODUCT_TYPE}"
        ln -s ../diskfirmware diskfirmware
        if [ 0 != $? ]; then
            OS_echo "[$G_CUR_SH_NAME]: Failed to create diskfirmware symbolic link."
        fi
    fi
    #修改 boot 链接 指向 bak
    OS_MODIFY_LINK_TO_BAK
    if [ "0" != "$?" ]; then
        OS_echo "UPGRADE_SH: Relint boot to boot_osp_bak fail" > /dev/null
        OS_SET_DISK_RO
        if [ "0" == "$rettmp" ];then
            OS_SET_HOTPATCH_DISK_RO
        fi
        return 1
    fi

    if [ -d $G_ASL_INSTALL_DIR ];then
        OS_echo "$G_ASL_INSTALL_DIR is exist" >/dev/null
        #设置异构支持包软链接
        cd $G_ASL_INSTALL_DIR  &>/dev/kmsg

        tree -ifa -L 1 ./ | grep "./" | while read ASL_DIR
        do
            cd $G_ASL_INSTALL_DIR/$ASL_DIR &>/dev/kmsg
            if [ ! -d $G_ASL_INSTALL_DIR/$ASL_DIR/Asl_Lib -o ! -f $G_ASL_INSTALL_DIR/$ASL_DIR/Asl_Lib/patch.conf ]; then
                OS_echo "$G_ASL_INSTALL_DIR/$ASL_DIR/Asl_Lib or patch.conf is not exist" >/dev/null
                OS_SET_DISK_RO
                if [ "0" == "$rettmp" ];then
                    OS_SET_HOTPATCH_DISK_RO
                fi
                return 1
            fi
            cd $G_ASL_INSTALL_DIR/$ASL_DIR/Asl_Lib &>/dev/kmsg

            cd $G_ASL_INSTALL_DIR/$ASL_DIR &>/dev/kmsg
            if [ ! -h $G_ASL_INSTALL_DIR/$ASL_DIR/asl ];then
                OS_echo "[$G_CUR_SH_NAME]:Asl patch link(asl->Asl_Lib) not exist, need create." >/dev/null
                OS_echo "[$G_CUR_SH_NAME]:create asl patch link ${ASL_DIR}/asl->${ASL_DIR}/Asl_New"  >/dev/null
                ln -s Asl_Lib  asl  &>/dev/kmsg
                if [ 0 != $? ];then
                    OS_echo "Creat asl patch link(${ASL_DIR}/asl->${ASL_DIR}/Asl_New) fail,exit." >/dev/null
                    OS_SET_DISK_RO
                    if [ "0" == "$rettmp" ];then
                        OS_SET_HOTPATCH_DISK_RO
                    fi
                    return 1
                fi
            fi
        done

        cd -  &>/dev/kmsg
    else
        OS_echo "$G_ASL_INSTALL_DIR is not exist" >/dev/null
    fi

    #给other组用户增加读权限，防止以该目录无法进行网络引导(OS网络引导权限要求，但是通过OS脚本get的目录，会将other组用户权限剔除)
    chmod o+r $G_DISK_MOUNT_IMAGE/boot_osp_bak/*

    #刷盘
    sync
    OS_echo "UPGRADE_SH: copy software from $L_SOURCE_IP successed." > /dev/null
    OS_SET_DISK_RO
    if [ "0" == "$rettmp" ];then
        OS_SET_HOTPATCH_DISK_RO
    fi
    return 0
}

CheckIpConnection()
{
    local L_CheckIp=$1

    if [ -z $L_CheckIp ];then
        OS_echo "${G_SCRIPT_NAME}: ip ${L_CheckIp} is null" > /dev/null
        return 1
    fi

    result=`ping -c 3 -w 5 -q $L_CheckIp 2>/dev/stdout`
    OS_echo "UPGRADE_SH: The result of ping commond is $result." > /dev/null
    tmp=`echo $result | egrep '100% packet loss|Network is unreachable'`
    if [ -n "$tmp" ];then
        return 1
    fi

    return 0
}

GetConnectedIp()
{
    local L_SRC_IP=$1

    # 检查传入IP是否连通
    CheckIpConnection $L_SRC_IP
    if [ "$?" == "0" ]; then
        G_SYNC_SOURCE_IP=$L_SRC_IP
        OS_echo "UPGRADE_SH: The source ip ($L_SRC_IP) is connected." > /dev/null
        return 0
    fi

    # 判断传入IP是否为心跳
    if [ "127.127.127" == "${L_SRC_IP%.*}" ]; then
        OS_echo "UPGRADE_SH: The bond ip ($L_SRC_IP) is disconnected." > /dev/null
        return 1 # 心跳IP不通 T双控
    fi

    # 根据产品型号 获取内部两个IP
    L_PRODUCT_NAME=$(cat $G_PRODUCT_CFG_FILE | grep -m 1 ProductName | awk -F "=" '{print $2}' | grep -E '(HVS|18500|18800|18800F)')
    if [ -n "$L_PRODUCT_NAME" ];then
        L_IP1=$(ifconfig eth2 | grep -oE "inet addr:([0-9]+.){3}[0-9]+" | grep -oE "([0-9]+.){3}[0-9]+")
        L_IP2=$(ifconfig eth3 | grep -oE "inet addr:([0-9]+.){3}[0-9]+" | grep -oE "([0-9]+.){3}[0-9]+")
    else
        L_IP1=$(ifconfig eth2:in | grep -oE "inet addr:([0-9]+.){3}[0-9]+" | grep -oE "([0-9]+.){3}[0-9]+")
        L_IP2=$(ifconfig eth3:in | grep -oE "inet addr:([0-9]+.){3}[0-9]+" | grep -oE "([0-9]+.){3}[0-9]+")
    fi
    OS_echo "UPGRADE_SH: L_PRODUCT_NAME ($L_PRODUCT_NAME), L_SRC_IP ($L_SRC_IP), L_IP1 ($L_IP1), L_IP2 ($L_IP2)." > /dev/null

    # 用另外一个网段的IP
    if [ "${L_SRC_IP%.*}" == "${L_IP1%.*}" ] && [ "" != "${L_IP2}" ]; then
        Diff=$((${L_IP1##*.} - ${L_SRC_IP##*.}))
        G_SYNC_SOURCE_IP=${L_IP2%.*}.$((${L_IP2##*.} - ${Diff}))
    elif [ "${L_SRC_IP%.*}" == "${L_IP2%.*}" ] && [ "" != "${L_IP1}" ]; then
        Diff=$((${L_IP2##*.} - ${L_SRC_IP##*.}))
        G_SYNC_SOURCE_IP=${L_IP1%.*}.$((${L_IP1##*.} - ${Diff}))
    else
        OS_echo "UPGRADE_SH: Source ip segment maybe error." > /dev/null
        return 1
    fi

    # 检查该网段是否连通
    CheckIpConnection $G_SYNC_SOURCE_IP
    if [ "$?" != "0" ]; then
        OS_echo "UPGRADE_SH: The other ip ($G_SYNC_SOURCE_IP) is also disconnected." > /dev/null
        return 1
    fi

    OS_echo "UPGRADE_SH: The source ip ($L_SRC_IP) is disconnected, transform it to ($G_SYNC_SOURCE_IP)." > /dev/null
    return 0
}

CopySoftwareWithRetry()
{
    local L_SOURCE_IP=$1
    local L_TRY_TIMES=0
    local L_SYNC_FILE_TIMES=5
    OS_echo "UPGRADE_SH: The source ip is $L_SOURCE_IP." > /dev/null

    while [ true ]; do
        if [ $L_TRY_TIMES -ge $L_SYNC_FILE_TIMES ];then
            OS_echo "UPGRADE_SH: It has reached $L_TRY_TIMES times to try to sync file."
            return 1
        fi
        OS_echo "UPGRADE_SH: It has try $L_TRY_TIMES times."
        let L_TRY_TIMES=$L_TRY_TIMES+1

        # 检查传入IP是否连通
        CheckIpConnection $L_SOURCE_IP
        if [ "$?" != "0" ]; then
            OS_echo "UPGRADE_SH: The source ip ($L_SOURCE_IP) is not connected." > /dev/null
            return 1
        fi

        CopySoftwareFromOtherNid $L_SOURCE_IP
        if [ "0" == "$?" ];then
            OS_echo "UPGRADE_SH: Copy Software From [$L_SOURCE_IP] to Local Success!"
            touch /OSM/update/syncreboot
            return 0
        fi
        sleep 5
    done

}

OS_UPG_HP_IS_NEED_ROLLBACK()
{
    local L_TEMP=
    local L_RET=
    local L_CUR_KER_VER=0
    local L_INACTIVE_VER=0

    OS_echo "Starting estimating hotpach is need rollback or not."
    
    #升级过程中安装补丁失败，需要回退补丁
	if [ -f /tmp/upd_hotpatch_resume.log ];then
        OS_echo "There is upgrade hotpatch in upgrading,need rollback."
        rm -f /tmp/upd_hotpatch_resume.log
		return 1;
	fi
    
    #获取内核态版本信息
    if [ ! -f $G_UPG_HP_PATCH_VER_CONF ];then
        #获取热补丁内核版本为空或者失败，认为内核中不存在热补丁，无需回退
        OS_echo "There is no hotpatch in kernel, need not rollback."
        return 0
    else
        #内核存在热补丁，获取版本信息
        L_CUR_KER_VER=`cat ${G_UPG_HP_PATCH_VER_CONF}`
        if [ -z "${L_CUR_KER_VER}" ];then
            OS_echo "The version is null, need not rollback."
            return 0
        fi
        OS_echo "Hotpatch version of kernel is ${L_CUR_KER_VER}."
    fi

    #若/startup_disk/conf/下的hotpatch_version.conf版本文件不存在，无需回退
    if [ ! -e $G_UPG_HP_START_PATCH_CONF ]; then
        OS_echo "There is no hotpatch_version.conf in tmp dir, need not rollback."
        return 0
    fi

    #获取需要激活的版本信息
    L_INACTIVE_VER=`cat ${G_UPG_HP_START_PATCH_CONF} | grep "^Version" | tail -n 1 | awk -F'=' '{print $2}' 2>/dev/kmsg`
    OS_echo "Hotpatch inactive version is ${L_INACTIVE_VER}."

    #比较内核中的版本和需要激活的版本的一致性，不相同为不需要回退
    if [ "${L_CUR_KER_VER}" != "${L_INACTIVE_VER}" ]; then
        OS_echo "Hotpatch inactive version is not the same as running kernel version and hotpacth need not rollback."
        return 0
    fi

    OS_echo "Hotpatch inactive version is the same as running kernel version and hotpacth need rollback."
    return 1
}

function ChangeLinkToDIR()
{
    local L_link=$1
    rm -rf $L_link
    mkdir -p $L_link
    chmod 775 $L_link
    return 0
}
function HandleDIRAfterTarSYSPkg()
{
    if [ ! -h $G_UPDATE_DIR ]; then
        return 0
    fi
    ChangeLinkToDIR $G_UPDATE_DIR
    if [ "`ls -A $G_SYS_PKG_DIR_IN_COFFER_DATA`" != "" ]; then
        mv $G_SYS_PKG_DIR_IN_COFFER_DATA/* $G_UPDATE_DIR
    fi
    return 0
}
function LinkToCofferData()
{
    rm -rf $G_SYS_PKG_DIR_IN_COFFER_DATA/*
    L_COFFERDATA_MEM=`df -m $G_SYS_PKG_DIR_IN_COFFER_DATA | tail -n1|awk '{print $4}'`
    OS_echo "UPGRADE_SH: L_COFFERDATA_MEM is $L_COFFERDATA_MEM." > /dev/null
    
    if [ $L_COFFERDATA_MEM -ge $G_MEM_NEEDED_WHEN_CP_PKG ]; then
        rm -rf $G_UPDATE_DIR
        ln -s $G_SYS_PKG_DIR_IN_COFFER_DATA $G_UPDATE_DIR
    else
        L_FTDS_MEM=`du -m /OSM/coffer_data/ftds/tracefile/ | grep -oE [0-9]+`
        OS_echo "UPGRADE_SH: L_FTDS_MEM is $L_FTDS_MEM." > /dev/null
        
        let L_COFFERDATA_MEM=$L_COFFERDATA_MEM+$L_FTDS_MEM
        if [ $L_COFFERDATA_MEM -ge $G_MEM_NEEDED_WHEN_CP_PKG ] ; then
            rm -rf /OSM/coffer_data/ftds/tracefile/*
            rm -rf $G_UPDATE_DIR
            ln -s $G_SYS_PKG_DIR_IN_COFFER_DATA $G_UPDATE_DIR
            return 0
        fi
               
        OS_echo "UPGRADE_SH: The space of the ${G_SYS_PKG_DIR_IN_COFFER_DATA} is not enough to save the PKG" > /dev/null
        #upgrade_startwork_fail.sh远程调用该脚本通过以下打印获取执行结果
        echo "Mem not enough"
        exit $G_ERROR_NOT_ENOUGH_MEM_AND_COFFERDATA
    fi
    
    return 0
}

function CopyAtomStateFile()
{
    local ip=$1
    local ismaster=$(IsMaster; echo $?)
    local tmpdir=/tmp/upd_state_atoms/
    local atomfile=upd_state_atoms.lua

    [ -d $tmpdir ] && rm -rf $tmpdir
    mkdir -p $tmpdir

    if [ "$ismaster" == 1 ]; then
        cp $G_UPDATE_STATE_DIR/$atomfile $tmpdir
        cp $G_UPDATE_STATE_DIR/upd_state_flows.lua $tmpdir
        return 0
    fi

    os_get_file.sh $ip $G_UPDATE_STATE_DIR/$atomfile $tmpdir
    if [ "0" != "$?" ]; then
        return 1
    fi

    cp $G_UPDATE_STATE_DIR/upd_state_flows.lua $tmpdir
    return 0
}

function AGname2AGindex()
{
    local error=11
    local AGname=$(grep -oP "(?<=\[\"AtomGroup\"\] = \").*(?=\",)" upd_state_atoms.lua)

    ## 添加AG后请同步刷新此处
    declare -a OfflineAtomGroup=( UploadPackageWhenOfflineUpgrade PrepareForUpdateWhenOfflineUpgrade UpgradePcieSw UpgradeSystemWhenOfflineUpgrade RebootWhenOfflineUpgrade OfflineSysCompatibleAfterReboot )

    for ((i=0;i<${#OfflineAtomGroup[@]};i++))
    do
        if [ ${OfflineAtomGroup[$i]} == "$AGname" ]; then
            return $(($i + 1))
        fi
    done

    return $error
}

function GetAtomResultForResume()
{
    local INIT=11; local SUCC=0;
    local FAIL=2;  local RBK=3;

    step=$(grep -oP "(?<=\[\"Step\"\] = \").*(?=\",)" upd_state_atoms.lua)

    if [ -z "$step" ]; then
        return $INIT
    elif [ $step == "#SuccExit" ]; then
        return $SUCC
    elif [ $step == "#SuccRbk" ]; then
        return $FAIL
    elif [ $step == "#FailExit" ]; then
        return $RBK
    else
        return $INIT
    fi
}

function FlowIdIsTheSame()
{
    local SAME=0; local DIFF=1;

    local AgentFlowId=$(grep -oP "(?<=\[\"FlowId\"\] = ).*(?=,)" upd_state_atoms.lua)
    local ServerFlowId=$(grep -oP "(?<=\[\"FlowId\"\] = ).*(?=,)" upd_state_flows.lua)

    if [ "$AgentFlowId" == "$ServerFlowId" ]; then
        return $SAME
    fi

    return $DIFF
}

function AnalyseAtomStateFile()
{
    local param=$1; local error=11; local ret=$error;

    cd /tmp/upd_state_atoms/

    if [ ! -f upd_state_atoms.lua ] || [ ! -f upd_state_flows.lua ]; then
        OS_echo "Analyse state file, state file not exist." >/dev/null
        cd - &>/dev/null
        return $error
    fi

    if [ "$param" == "flowid" ]; then
        FlowIdIsTheSame; ret=$?

    elif [ "$param" == "agindex" ]; then
        AGname2AGindex; ret=$?

    elif [ "$param" == "result" ]; then
        GetAtomResultForResume; ret=$?

    else
        OS_echo "Analyse state file, unknown param." >/dev/null
    fi

    cd - &>/dev/null

    [ -z $ret ] && ret=$error
    OS_echo "Analyse state file, param $param, exist $ret." >/dev/null
    return $ret
}

function IsMaster()
{
    local L_CheckCmd="sys showcls"
    local L_TempFile="/OSM/update/diagnoseinfo"
    local L_LocalNid
    local L_MasterNid
(
diagnose --auto <<EOF
${L_CheckCmd}
quit
EOF
) >>${L_TempFile}

    L_LocalNid=`awk '/local node id/{print $NF}' ${L_TempFile}`
    L_MasterNid=`grep -v ":" ${L_TempFile} | awk '/master/{print $1}'`
    OS_echo "UPGRADE_SH: Check the local node(${L_LocalNid}) is or not the master(${L_MasterNid})." >/dev/null
    if [ "" != "${L_LocalNid}" -a "" != "${L_MasterNid}" -a "${L_LocalNid}" == "${L_MasterNid}" ]; then
       OS_echo "UPGRADE_SH: The local node is the master." >/dev/null
       rm ${L_TempFile}
       return 1;
    fi
    OS_echo "UPGRADE_SH: The local node is not the master." >/dev/null
    rm ${L_TempFile}
    return 0;
}

function CheckIsPrePkg()
{
    local L_PkgPath=$1
    local L_PkgConfFile="patch.conf"
    local L_IsSpeScript

    OS_echo "UPGRADE_SH: Begin to check the type of preprocess package before system upgrade." >/dev/null

    if [ ! -f ${L_PkgPath} ]; then
        OS_echo "UPGRADE_SH: ${L_PkgPath} is not exist, and return 3." >/dev/null
        return 3
    fi

    cd ${G_UploadPath} >/dev/null 2>&1
    tar -xzf ${L_PkgPath}  ${L_PkgConfFile} -C ${G_UploadPath}  >/dev/null 2>&1
    if [ 0 != "$?" -o ! -f ${G_UploadPath}/${L_PkgConfFile} ]; then
        OS_echo "UPGRADE_SH: Tar ${L_PkgConfFile} in ${L_PkgPath} failed, and return 3." >/dev/null
        rm -rf ${G_UploadPath}/${L_PkgConfFile}
        cd - &>/dev/kmsg
        return 3
    fi
    cd - >/dev/null 2>&1

    L_IsSpeScript=`cat ${G_UploadPath}/${L_PkgConfFile} | grep -i "Type=" | wc -l`
    if [ "0" != "${L_IsSpeScript}" ]; then
        OS_echo "UPGRADE_SH: The Package is preprocess package, and return 1." >/dev/null
        rm -rf ${G_UploadPath}/${L_PkgConfFile}
        return 1
    fi

    OS_echo "UPGRADE_SH: The Package is not preprocess package, and return 0." >/dev/null
    rm -rf ${G_UploadPath}/${L_PkgConfFile}
    return 0
}

function ExecutePreScript()
{
    local L_PkgPath="/OSM/update/hotpatch.tgz"
    local L_PkgConfFile="patch.conf"
    local L_ScriptName
    local L_ScriptType

    OS_echo "UPGRADE_SH: Begin to execute preprocess script before system upgrade." >/dev/null

    if [ ! -f ${L_PkgPath} ]; then
        OS_echo "UPGRADE_SH: ${L_PkgPath} is not exist, and finish the preprocess." >/dev/null
        return 3
    fi

    tar -xzf ${L_PkgPath} -C ${G_UploadPath}   >/dev/null 2>&1
    if [ 0 != "$?" -o ! -f ${G_UploadPath}/${L_PkgConfFile} ]; then
        OS_echo "UPGRADE_SH: Tar ${L_PkgConfFile} in ${L_PkgPath} failed, and finish the preprocess." >/dev/null
        rm -rf ${G_UploadPath}/*
        return 3
    fi
    dos2unix ${G_UploadPath}/${L_PkgConfFile}   >/dev/null 2>&1

    L_ScriptName=`cat ${G_UploadPath}/${L_PkgConfFile} | grep -i "Script=" | awk -F= '{print $2}'`
    L_ScriptType=`cat ${G_UploadPath}/${L_PkgConfFile} | grep -i "Type=" | awk -F= '{print $2}'`
    if [ "" == "${L_ScriptName}" -o "" == "${L_ScriptType}" -o ! -f "${G_UploadPath}/${L_ScriptName}" ]; then
        OS_echo "UPGRADE_SH:   ${G_UploadPath}/${L_PkgConfFile} is error, and finish the preprocess." >/dev/null
        rm -rf ${G_UploadPath}/*
        return 3
    fi

    chmod +x ${G_UploadPath}/${L_ScriptName} >/dev/null 2>&1
    if [ "$?" != 0 ]; then
        OS_echo "UPGRADE_SH: Chmod the preprocess script failed and finish the preprocess." >/dev/null
        rm -rf ${G_UploadPath}/*
        return 3
    fi

    #判断脚本包只在主控执行，以及本控是否在主控
    if [ "master" == ${L_ScriptType} ] ; then
        IsMaster
        if [ "$?" == "0" ]; then
            OS_echo "UPGRADE_SH: The preprocess script is only do in master , local controller is not master and finish the preprocess." >/dev/null
            rm -rf ${G_UploadPath}/*
            return 0
        fi
    elif [ "all" == ${L_ScriptType} ]; then
        OS_echo "UPGRADE_SH: Execute the preprocess script do in all controller." >/dev/null
    else
        OS_echo "UPGRADE_SH: The ${L_ScriptType} is not defined and finish the preprocess." >/dev/null
        rm -rf ${G_UploadPath}/*
        return 3
    fi

    ${G_UploadPath}/${L_ScriptName} >/dev/null 2>&1
    if [ "$?" != 0 ]; then
        OS_echo "UPGRADE_SH: Execute the preprocess script package failed and finish the preprocess." >/dev/null
        rm -rf ${G_UploadPath}/*
        return 3
    fi

    rm -rf ${G_UploadPath}/*
    OS_echo "UPGRADE_SH: Execute the preprocess script execute success and finish." >/dev/null
    return 0

}

function ClearPreprocessPatch()
{
    if [ ! -d $G_UPDATE_BOOT_DIR/update_pkg/preprocess ]; then
        OS_echo "UPGRADE_SH: boot_osp/update_pkg/preprocess/ is not exist." >/dev/null
    else
        rm -rf $G_UPDATE_BOOT_DIR/update_pkg/preprocess/*
    fi
    
    OS_echo "UPGRADE_SH: rm preprocess success." >/dev/null
    return 0
}

function ClearUnusedFileInPkg()
{
    local pkg_dir=$1
    if [ ! -d $pkg_dir/update_pkg/preprocess ]; then
        OS_echo "UPGRADE_SH: /update_pkg/preprocess/ is not exist." >/dev/null
    else
       rm -rf $pkg_dir/update_pkg/preprocess/*
    fi
    
    #清除update_pkg目录下无用的小固件包
    UPD_CLEAR_USELESS_FIRMWARE ${G_PRODUCT_TYPE} ${pkg_dir}
    
    OS_echo "UPGRADE_SH: rm unused file success." >/dev/null
    
    return 0
}

function ClearBakDirWhenUpgSucc()
{
    local success=0; local dir_not_exist=1; local boot_link_error=2;
    
    if [ ! -d $G_BOOT_OSP_BAK_DIR ]; then
        OS_echo "UPGRADE_SH: boot_osp_bak is not exist." >/dev/null
        return $dir_not_exist
    fi

    # 如果链接指向boot_osp_bak 不予删除boot_osp_bak目录
    local l_boot_link=`ls -l $G_DISK_MOUNT_IMAGE | grep -a "boot ->" | awk '{print $11}'`
    if [ "$l_boot_link" == "boot_osp_bak" ] ; then
        OS_echo "UPGRADE_SH: boot is linked to boot_osp_bak, can not delete it." >/dev/null
        return $boot_link_error;
    fi

    # 删除 boot_osp_bak 中除了 versions.conf 的所有内容
    cd $G_BOOT_OSP_BAK_DIR

    OS_SET_DISK_RW
    ls | grep -vw "\." | grep -vw "versions.conf" | xargs rm -rf
    OS_SET_DISK_RO

    if [ ! -f "versions.conf" ]; then
        OS_echo "UPGRADE_SH: boot_osp_bak is empty, versions.conf is not exist." >/dev/null
    fi

    cd - &>/dev/null
    return $success
}

function OS_GET_ASL_VERSION()
{
    local L_Local_ASLVER
    local L_TMPFILE_ASLVER="/tmp/aslver.conf"

    L_Local_ASLVER=`OS_ASL_ENCODE_VERSION  ${G_ASL_CONFIG_FILE_DIR}/${G_ASL_CONFIG_FILE_NAME}`
    if [ 0 != "$?" ]; then
       OS_echo "UPGRADE_SH: get the local asl patch encoded version failed" >/dev/null
       return 1
    fi

    if [ -f "${L_TMPFILE_ASLVER}" ];then
        rm ${L_TMPFILE_ASLVER} >/dev/null
    fi

    echo ${L_Local_ASLVER} >${L_TMPFILE_ASLVER}
    OS_echo "UPGRADE_SH: Get master asl encoded version ${L_Local_ASLVER}, and write to ${L_TMPFILE_ASLVER} success." >/dev/null
    return 0
}

function UPGRADE_SMARTIO_CARD()
{
    local ret
    local sys_version=`cat $G_DISK_MOUNT_IMAGE/boot/versions.conf |grep -m 1 Version |awk -F"=" '{print $2}'`

    OS_echo "UPGRADE_SH: boot version is ${sys_version}."

    /OSM/bin/upgrade_atom -f UPGRADE_INTERFACE_CARD -m SmartIO -t sync -v ${sys_version} -n all;ret=$?

    # 删除由于标准输出/错误输出异常 拉起原子产生的文件
    if [ -f /OSM/log/cur_debug/om_messages_upgrade_atom ]; then
        rm /OSM/log/cur_debug/om_messages_upgrade_atom
    fi

    OS_echo "UPGRADE_SH: upgrade smartio card result is ${ret}."

    return 0
}

function UPGRADE_PCIE_CARD()
{
    local ret
    local sys_version=`cat $G_DISK_MOUNT_IMAGE/boot/versions.conf |grep -m 1 Version |awk -F"=" '{print $2}'`

    OS_echo "UPGRADE_SH: upgrade pcie begin, boot version is ${sys_version}."

    /OSM/bin/upgrade_atom -f UPGRADE_PCIE_UPDATE -t sync -v ${sys_version} -n all;ret=$?

    # 删除由于标准输出/错误输出异常 拉起原子产生的文件
    if [ -f /OSM/log/cur_debug/om_messages_upgrade_atom ]; then
        rm /OSM/log/cur_debug/om_messages_upgrade_atom
    fi

    OS_echo "UPGRADE_SH: upgrade pcie card result is ${ret}."

    return 0
}

function UPGRADE_PCIE_CARD_DMI()
{
    local ret
    local sys_version=`cat $G_DISK_MOUNT_IMAGE/boot/versions.conf |grep -m 1 Version |awk -F"=" '{print $2}'`

    OS_echo "UPGRADE_SH: upgrade pcie begin, boot version is ${sys_version}."

    /OSM/bin/upgrade_atom -f UPGRADE_INTERFACE_CARD_CALL_DMI -m PCIE -t sync -v ${sys_version} -n all;ret=$?

    # 删除由于标准输出/错误输出异常 拉起原子产生的文件
    if [ -f /OSM/log/cur_debug/om_messages_upgrade_atom ]; then
        rm /OSM/log/cur_debug/om_messages_upgrade_atom
    fi

    OS_echo "UPGRADE_SH: upgrade pcie card result is ${ret}."

    return 0
}

function UPGRADE_UpdatePkg()
{
    local l_dstVersion="$1"
    local l_ospVersion=""
    local l_bakVersion=""
    local l_tmpVersion=""

    OS_echo "UPGRADE_SH: OS_UPDATE_PACKAGE Begin" >/dev/null

    # check current system
    L_BOOT_TYPE=`cat /boot/boot_type`
    if [ "$L_BOOT_TYPE" != "os_boot_osp" ] ; then
        OS_echo "UPGRADE_SH: Warning!!!System in $L_BOOT_TYPE type, not os_boot_osp." >/dev/null
        OS_echo "UPGRADE_SH: Warning!!!It is dangerous to update in $L_BOOT_TYPE type." >/dev/null
    fi

    #获取三个目录下的版本
    [ -f $G_UPDATE_BOOT_DIR/$G_PKG_VERSION_FILENAME ] \
            && { l_ospVersion=$(grep -m 1 Version $G_UPDATE_BOOT_DIR/$G_PKG_VERSION_FILENAME | awk -F"=" '{print $2}'); }
    [ -f $G_BOOT_OSP_BAK_DIR/$G_PKG_VERSION_FILENAME ] \
            && { l_bakVersion=$(grep -m 1 Version $G_BOOT_OSP_BAK_DIR/$G_PKG_VERSION_FILENAME | awk -F"=" '{print $2}'); }
    [ -f $G_UPDATE_TMP_DIR/$G_PKG_VERSION_FILENAME ] \
            && { l_tmpVersion=$(grep -m 1 Version $G_UPDATE_TMP_DIR/$G_PKG_VERSION_FILENAME | awk -F"=" '{print $2}'); }

    #检查升级目标版本在哪个目录下
    if [ "$l_ospVersion" == "$l_dstVersion" ]; then
        #如果升级目标版本在boot_osp下，则要和boot_osp_bak交换
        OS_echo "UPGRADE_SH: Upgrade dst version is in boot_osp, exchange it with boot_osp_bak." >/dev/null
        if [ -d  $G_UPDATE_TMP_DIR ]; then
            rm $G_UPDATE_TMP_DIR -rf &>/dev/kmsg
        fi
        mv $G_UPDATE_BOOT_DIR $G_UPDATE_TMP_DIR &>/dev/kmsg
        mv $G_BOOT_OSP_BAK_DIR $G_UPDATE_BOOT_DIR &>/dev/kmsg
        mv $G_UPDATE_TMP_DIR $G_BOOT_OSP_BAK_DIR &>/dev/kmsg
    elif [ "$l_bakVersion" == "$l_dstVersion" ]; then
        #如果升级目标版本已经在boot_osp_bak下，则OK
        OS_echo "UPGRADE_SH: Upgrade dst version is already in boot_osp_bak." >/dev/null
    elif [ "$l_tmpVersion" == "$l_dstVersion" ]; then
        #如果升级目标版本已经在boot_osp_tmp下，则需要将其文件放到boot_osp_bak下
        OS_echo "UPGRADE_SH: Upgrade dst version is already in boot_osp_tmp." >/dev/null
        OS_echo "UPGRADE_SH: cd $G_DISK_MOUNT_IMAGE" >/dev/null

        cd $G_DISK_MOUNT_IMAGE

        OS_echo "UPGRADE_SH: rm -rf boot_osp_bak" >/dev/null
        if [ ! -d $G_BOOT_OSP_BAK_DIR ]; then 
            mkdir $G_BOOT_OSP_BAK_DIR  &>/dev/kmsg
            chmod 775 $G_BOOT_OSP_BAK_DIR
        fi
        rm -rf boot_osp_bak/* &>/dev/kmsg

        OS_echo "UPGRADE_SH: mv -f boot_osp_tmp boot_osp_bak" >/dev/null
        mv boot_osp_tmp/* boot_osp_bak &>/dev/kmsg
        rm -rf boot_osp_tmp &>/dev/kmsg

        OS_echo "UPGRADE_SH: OS_UPDATE_PACKAGE Exist" >/dev/null
    else
        #如果升级目标版本三个目录均没有，则返回失败
        OS_echo "UPGRADE_SH: Upgrade dst version is not in boot_osp, boot_osp_bak and boot_osp_tmp." >/dev/null
        return 1;
    fi
    
    OS_echo "UPGRADE_SH: cd $G_DISK_MOUNT_IMAGE/boot_osp_bak" >/dev/null
    cd $G_DISK_MOUNT_IMAGE/boot_osp_bak &>/dev/kmsg
    if [ ! -h $G_BOOTLOADER ]; then
        OS_echo "UPGRADE_SH: ln -s ../$G_BOOTLOADER $G_BOOTLOADER" >/dev/null
        ln -s ../$G_BOOTLOADER $G_BOOTLOADER &>/dev/kmsg
    fi
    cd - &>/dev/kmsg
    
    #清除nvram
    OS_echo "UPGRADE_SH: OS_ClearResetTimes" >/dev/null
    OS_ClearResetTimes

    sync
    echo 3 >/proc/sys/vm/drop_caches

    FREE_MEM=`free -m|grep ^Mem|awk '{print $4}'`
    if [ "${FREE_MEM}" -lt "${G_MIN_MEM}" ];then
        OS_echo "[OS_CreatePolicy] Force free memory"
        OS_UPGRADE_FORCE_FREEMEM
    fi
    OS_echo "UPGRADE_SH: OS_UPDATE_PACKAGE End" >/dev/null

    Check_Initrd_and_Bzimage $G_BOOT_OSP_BAK_DIR
    if [ "$?" != "0" ] ; then
        OS_echo "UPGRADE_SH: upgrade system check failed">/dev/null
        return 1
    fi
    
    #修改boot链接指向boot_osp_bak
    local l_bootLink=$(ls -l $G_BOOT_LINK | awk '{print $11}')
    if [ "$l_bootLink" == "boot_osp_bak" ]; then
        OS_echo "UPGRADE_SH: boot link(boot->$l_bootLink) is already point to boot_osp_bak."
        return 0
    fi

    OS_echo "UPGRADE_SH: rm boot and relink boot point to boot_osp_bak">/dev/null
    cd $G_DISK_MOUNT_IMAGE
    rm -fr boot &>/dev/kmsg
    if [ "0" != "$?" ] ; then
        OS_SET_DISK_RW
        rm -fr boot &>/dev/kmsg
        if [ "0" != "$?" ] ; then
            OS_echo "UPGRADE_SH: rm boot point failed">/dev/null
            return 1
        fi
    fi
    OS_echo "UPGRADE_SH: rm boot point success">/dev/null

    ln -s boot_osp_bak boot &>/dev/kmsg
    if [ 0 != $? ] ; then
        OS_echo "UPGRADE_SH: relink boot point to boot_osp_bak failed">/dev/null
        return 1
    fi
    OS_echo "UPGRADE_SH: relink boot point to boot_osp_bak success">/dev/null
    
    cd /OSM
    sh /OSM/script/product_gap.sh -u
    if [ "0" != "$?" ] ; then
        OS_echo "UPGRADE_SH: modify gap value failed.">/dev/null
        return 1
    else
        OS_echo "UPGRADE_SH: modify gap value succeed.">/dev/null
    fi
    
    return 0
}
#备份boot_osp和hotpatch目录到/OSM/ccdb/store/soft_backup/
function OS_BACKUP_SOFTWARE()
{     
    if [ ! -d $BACKUP_DIR ] ; then
        OS_echo "UPGRADE_SH: begin to mkdir soft_backup.">/dev/null        
        mkdir $BACKUP_DIR
        if [ 0 != $? ] ; then
            OS_echo "UPGRADE_SH: mkdir soft_backup failed.">/dev/null
            return 1
        fi
        OS_echo "UPGRADE_SH: succeed to mkdir soft_backup.">/dev/null
    fi
    #如果boot_osp备份已经存在，先删除
    if [ -d $BACKUP_BOOT_OSP_DIR ] ; then
        OS_echo "UPGRADE_SH: boot_osp is exist, remove it before backup.">/dev/null
        rm -rf $BACKUP_BOOT_OSP_DIR
        if [ 0 != $? ] ; then
            OS_echo "UPGRADE_SH: remove boot_osp dir failed.">/dev/null
            return 1
        fi
        OS_echo "UPGRADE_SH: succeed to remove boot_osp dir.">/dev/null
    fi    
    cp -rf $G_UPDATE_BOOT_DIR $BACKUP_DIR
    if [ 0 != $? ] ; then
        OS_echo "UPGRADE_SH: copy boot_osp to soft_backup failed, try again.">/dev/null
        #第一次拷贝失败重试一次，重试也失败，返回失败
        cp -rf $G_UPDATE_BOOT_DIR $BACKUP_DIR
        if [ 0 != $? ] ; then
            OS_echo "UPGRADE_SH: copy boot_osp to soft_backup failed again, return error.">/dev/null
            return 1
        fi        
    fi
    #将/OSM/coffer_bin/hotpatch备份到/OSM/ccdb/store/soft_backup/boot_osp/hotpatch
    if [ -d $G_OS_HP_DIR ] && [ "`ls -A $G_OS_HP_DIR`" != "" ] ; then
        mkdir -p $BACKUP_BOOT_OSP_DIR/hotpatch
        cp -rf $G_OS_HP_DIR/* $BACKUP_BOOT_OSP_DIR/hotpatch
        if [ 0 != $? ] ; then
            OS_echo "UPGRADE_SH: copy hotpatch to /OSM/ccdb/store/soft_backup/boot_osp/hotpatch failed, try again.">/dev/null
            #第一次拷贝失败重试一次
            cp -rf $G_OS_HP_DIR/* $BACKUP_BOOT_OSP_DIR/hotpatch
            if [ 0 != $? ] ; then
                OS_echo "UPGRADE_SH: copy hotpatch to /OSM/ccdb/store/soft_backup/boot_osp/hotpatch failed again.">/dev/null
            fi        
        fi
    fi

    #拷贝ISM包到备份目录，需要确保存在/OSM/ccdb/store/soft_backup/ISM/路径
    rm /OSM/ccdb/store/soft_backup/boot_osp/update_pkg/ISM
    mkdir /OSM/ccdb/store/soft_backup/boot_osp/update_pkg/ISM
    cp /OSM/coffer_data/ISM/package/ism_cs_full.tgz /OSM/ccdb/store/soft_backup/boot_osp/update_pkg/ISM/

    OS_echo "UPGRADE_SH: succeed to copy boot_osp to soft_backup.">/dev/null
    return 0
}
#记录升级历史路径
function OS_RECORD_UPGRADE_PATH()
{     
    local BAK_PATH_FILE=/startup_disk/image/boot_osp_bak/versions.conf
    local VERSION_FILE=/startup_disk/image/boot_osp/versions.conf
    local RECORD_TO_FILE=/OSM/ccdb/store/upgrade_path.log
    local FILE_SIZE=1024
    
    if [ ! -f ${BAK_PATH_FILE} ] ; then
        OS_echo "UPGRADE_SH: can't find bak version file.">/dev/null
        return 1
    fi
    if [ ! -f ${VERSION_FILE} ] ; then
        OS_echo "UPGRADE_SH: can't find version file.">/dev/null
        return 1
    fi
    
    #检查记录文件是否存在，不存在，则创建并写一条记录
    if [ ! -f ${RECORD_TO_FILE} ] ; then
        OS_echo "UPGRADE_SH: upgrade_path.log is not exist, create it and add one record.">/dev/null
        #创建upgrade_path.log
        touch ${RECORD_TO_FILE}
        if [ 0 != $? ] ; then
            OS_echo "UPGRADE_SH: touch upgrade_path.log failed.">/dev/null
            return 1
        fi
        #添加一条记录
        echo "["`date "+%Y-%m-%d %H:%M:%S"`"]" "Before Upgrade: GLOBAL" `grep "GLOBAL" -A 1 ${BAK_PATH_FILE} | sed -n 2p` `grep "SPCVER" -A 1 ${BAK_PATH_FILE} | sed -n 2p` "After Upgrade: GLOBAL" `grep "GLOBAL" -A 1 ${VERSION_FILE} | sed -n 2p` `grep "SPCVER" -A 1 ${VERSION_FILE} | sed -n 2p` >> ${RECORD_TO_FILE}
        if [ 0 != $? ] ; then
            OS_echo "UPGRADE_SH: add record to upgrade_path.log failed.">/dev/null
            return 1
        fi
        OS_echo "UPGRADE_SH: succeed to add record to upgrade_path.log.">/dev/null
    else
    #判断upgrade_path.log大小
        local size=`du -b ${RECORD_TO_FILE} | awk '{print $1}'`
        #大于FILE_SIZE，删upgrade_path.log首行记录
        if [ $size -gt ${FILE_SIZE} ] ; then
            sed -i '1 d' ${RECORD_TO_FILE}
            if [ 0 != $? ] ; then
                OS_echo "UPGRADE_SH: del record from upgrade_path.log failed.">/dev/null
                return 1
            fi
        fi
        #添加一条记录
        echo "["`date "+%Y-%m-%d %H:%M:%S"`"]" "Before Upgrade: GLOBAL" `grep "GLOBAL" -A 1 ${BAK_PATH_FILE} | sed -n 2p` `grep "SPCVER" -A 1 ${BAK_PATH_FILE} | sed -n 2p` "After Upgrade: GLOBAL" `grep "GLOBAL" -A 1 ${VERSION_FILE} | sed -n 2p` `grep "SPCVER" -A 1 ${VERSION_FILE} | sed -n 2p` >> ${RECORD_TO_FILE}
        if [ 0 != $? ] ; then
            OS_echo "UPGRADE_SH: add record to upgrade_path.log failed.">/dev/null
            return 1
        fi
        OS_echo "UPGRADE_SH: succeed to add record to upgrade_path.log.">/dev/null
    fi
    return 0
}

#构造兼容不同版本的固件配套表
function OS_REBUILD_VER_CONF_FILE()
{
    local l_dstVersion="$1"
    local l_ospVersion=""
    local l_bakVersion=""
    local l_tmpVersion=""

    #获取三个目录下的版本
    [ -f $G_UPDATE_BOOT_DIR/$G_PKG_VERSION_FILENAME ] \
            && { l_ospVersion=$(grep -m 1 Version $G_UPDATE_BOOT_DIR/$G_PKG_VERSION_FILENAME | awk -F"=" '{print $2}'); }
    [ -f $G_BOOT_OSP_BAK_DIR/$G_PKG_VERSION_FILENAME ] \
            && { l_bakVersion=$(grep -m 1 Version $G_BOOT_OSP_BAK_DIR/$G_PKG_VERSION_FILENAME | awk -F"=" '{print $2}'); }
    [ -f $G_UPDATE_TMP_DIR/$G_PKG_VERSION_FILENAME ] \
            && { l_tmpVersion=$(grep -m 1 Version $G_UPDATE_TMP_DIR/$G_PKG_VERSION_FILENAME | awk -F"=" '{print $2}'); }

    if [ "$l_ospVersion" == "$l_dstVersion" ]; then
        OS_echo "UPGRADE_SH: dst version is in boot_osp." >/dev/null
        local PKG_VERCONF_FILE=/startup_disk/image/boot_osp/versions.conf
    elif [ "$l_bakVersion" == "$l_dstVersion" ]; then
        OS_echo "UPGRADE_SH: dst version is in boot_osp_bak." >/dev/null
        local PKG_VERCONF_FILE=/startup_disk/image/boot_osp_bak/versions.conf
    elif [ "$l_tmpVersion" == "$l_dstVersion" ]; then
        OS_echo "UPGRADE_SH: dst version is in boot_osp_tmp." >/dev/null
        local PKG_VERCONF_FILE=/startup_disk/image/boot_osp_tmp/versions.conf
    else
        OS_echo "UPGRADE_SH: dst version is not in boot_osp, boot_osp_bak and boot_osp_tmp when rebuild versions.conf." >/dev/null
        return 1;
    fi
 
    local ver_num=`cat ${PKG_VERCONF_FILE} | grep "VersionNum=" | awk -F "=" '{print $2}'`
    local ver_num_tmp=`cat ${PKG_VERCONF_FILE} | grep "VersionNum=" | awk -F "=" '{print $2}'`
    local BBU_FLAG="\[BBU\]"
    local IOC_HD_FLAG="\[IOC_HD\]"
    local PCIE_FLAG_8609="\[PCIE8609\]"
    local PCIE_FLAG_8624="\[PCIE8624\]"
    local bbu_ver=`grep $BBU_FLAG -A 1 ${PKG_VERCONF_FILE} | sed -n 2p | awk -F "=" '{print $2}'`
    local ioc_hd_ver_tmp=`grep $IOC_HD_FLAG -A 1 ${PKG_VERCONF_FILE} | sed -n 2p | awk -F "=" '{print $2}'`
    
    #解析得到ioc和8725版本号    
    local ioc_ver=`grep $IOC_HD_FLAG -A 1 ${PKG_VERCONF_FILE} | sed -n 2p | awk -F "=" '{print $2}' | awk -F "_" '{print $1}'`
    local ioc_8725_ver=`grep $IOC_HD_FLAG -A 1 ${PKG_VERCONF_FILE} | sed -n 2p | awk -F "=" '{print $2}' | awk -F "_" '{print $2}'`
    local pcie_8609_ver=`grep $PCIE_FLAG_8609 -A 1 ${PKG_VERCONF_FILE} | sed -n 2p | awk -F "=" '{print $2}'`
    local pcie_8624_ver=`grep $PCIE_FLAG_8624 -A 1 ${PKG_VERCONF_FILE} | sed -n 2p | awk -F "=" '{print $2}'`
    OS_echo "Rebuild versions.conf for downgrade." >/dev/null
    #查找bbu版本号，并写入
    if [ "$bbu_ver" != "" ];then
        echo "Version${ver_num}=bbu.bin,${bbu_ver}">> $PKG_VERCONF_FILE
        ver_num=`expr $ver_num + 1`
    fi
    #查找ioc_hd版本号，并写入    
    if [ "$ioc_hd_ver_tmp" != "" ];then
        echo "Version${ver_num}=ioc_fw.bin,${ioc_ver}">> $PKG_VERCONF_FILE
        ver_num=`expr $ver_num + 1`
        echo "Version${ver_num}=ioc_card_8725.bin,8725 ${ioc_8725_ver}">> $PKG_VERCONF_FILE
        ver_num=`expr $ver_num + 1`
    fi
    #查找pcie版本号，并写入
    if [ "$pcie_8624_ver" != "" ];then
        echo "Version${ver_num}=trans_sw.bin,8624 ${pcie_8624_ver}">> $PKG_VERCONF_FILE 
        ver_num=`expr $ver_num + 1`
    fi
    if [ "$pcie_8609_ver" != "" ];then
        echo "Version${ver_num}=trans_nt.bin,8609 ${pcie_8609_ver}">> $PKG_VERCONF_FILE 
        ver_num=`expr $ver_num + 1`
    fi
    #更新VersionNum
    sed -i -e "s|VersionNum=${ver_num_tmp}|VersionNum=${ver_num}|" $PKG_VERCONF_FILE
    OS_echo "Rebuild versions.conf success." >/dev/null
    
    return 0
}

#R版本降级场景，构造兼容不同版本的固件配套表
function isDowngradeAndRebuildVerconf()
{
    L_PKG_VERSION=$1

    # Dorado不存在R版本降级的场景
    L_PRODUCT_TYPE=`cat "$G_PRODUCT_CFG_FILE" | awk '/ProductName =/ {print $(NF-1)}'`
    if [ "$L_PRODUCT_TYPE" = "Dorado5000" -o "$L_PRODUCT_TYPE" = "Dorado6000" ]; then
        OS_echo "UPGRADE_SH: $L_PRODUCT_TYPE have not R version downgrade."
        return 0;
    fi
    #往830、1230、v3r3c00、v3r3c10回退，需要构造版本配套表
    #涉及ioc、bbu、pcie
    if [ -n "$(echo $L_PKG_VERSION | grep "^31801")" ] \
    || [ -n "$(echo $L_PKG_VERSION | grep "^32001")" ] \
    || [ -n "$(echo $L_PKG_VERSION | grep "^3200310")" ] \
    || [ -n "$(echo $L_PKG_VERSION | grep "^3500310")" ] \
    || [ -n "$(echo $L_PKG_VERSION | grep "^3180310")" ] \
    || [ -n "$(echo $L_PKG_VERSION | grep "^3200320")" ] \
    || [ -n "$(echo $L_PKG_VERSION | grep "^3500320")" ] \
    || [ -n "$(echo $L_PKG_VERSION | grep "^3180320")" ]; then
        OS_echo "UPGRADE_SH: It is downgrade,dst version is $L_PKG_VERSION,need to rebuild versions.conf." >/dev/null
        OS_REBUILD_VER_CONF_FILE $L_PKG_VERSION
        if [ "0" != $? ];then
            OS_echo "UPGRADE_SH: Rebuild versions.conf for downgrade failed!" >/dev/null
        fi
    fi
    return 0
}


function GET_CONFIG_SYS_DISK_NUM()
{
    local L_SYSDISK_CONFIG=`cat $G_PRODUCT_CFG_FILE | grep "UPGSysDiskNum" |awk -F = '{print $2}'`
    local mem1=`echo $L_SYSDISK_CONFIG |awk -F ";" '{print $1}' |awk -F ":" '{print $1}'`
    local mem2=`echo $L_SYSDISK_CONFIG |awk -F ";" '{print $2}' |awk -F ":" '{print $1}'`
    #没有配置项，默认为1块，不做检查
    if [ "$L_SYSDISK_CONFIG" == "" ] ; then
        OS_echo "[UPGRADE_SH] sys disk num config is not exist in product.ini, so skip sys disk num check." >/dev/null
        return 1
    fi
    
    #系统盘配置规格有两种形式：
    #1、系统盘规格和内存规格相关，如2200 V3，格式为：UPGSysDiskNum=8:1;16:2
    #2、系统盘规格和内存规格无关，如5600 V3，格式为：UPGSysDiskNum=2
    
    #如果配置项值的长度为1，则为第二种场景
    if [ 1 == ${#L_SYSDISK_CONFIG} ]; then
        OS_echo "[UPGRADE_SH] Get config sys disk num($L_SYSDISK_CONFIG)." >/dev/null
        return $L_SYSDISK_CONFIG
    fi
    
    #优化内存值换算为GB后不准确的场景，如换算结果为7.9G，取8G
    local L_CTRL_MEM=`cat /proc/osp/bsp | grep "byte memory" | grep -oE "[0-9]+"`
    let L_CTRL_MEM_IN_GB=$L_CTRL_MEM/1024/1024/1024
    let L_CTRL_MEM_IN_GB=$L_CTRL_MEM_IN_GB-$mem1+$L_CTRL_MEM_IN_GB-$mem2
    if [ $L_CTRL_MEM_IN_GB -le 0 ]; then
        OS_echo "[UPGRADE_SH] 2200 controller with 1 sys disk." >/dev/null
        L_CTRL_MEM_IN_GB=$mem1
    else
        OS_echo "[UPGRADE_SH] 2200 controller with 2 sys disk." >/dev/null
        L_CTRL_MEM_IN_GB=$mem2
    fi
    
    local L_CFG_DISK_NUM=`echo $L_SYSDISK_CONFIG |awk -F "$L_CTRL_MEM_IN_GB" '{print $2}' |awk -F ";" '{print $1}' |awk -F ":" '{print $2}'`
    
    OS_echo "[UPGRADE_SH] Get config sys disk num($L_CFG_DISK_NUM)." >/dev/null
    return $L_CFG_DISK_NUM
    
}

# **************************************************************************** #
# Function Name: DESTROY_SYS_DISK_MBR_MAGIC
# Description: 写0指定系统盘的MBR的MAGIC，使系统无法从该盘进行引导
# Parameter: 1、分区名，如: /dev/sda1
# Return: 无
# Attention: MBR结构：|Boot Loader(446B)|硬盘分区表(64B)|MAGIC(2B)(0X55AA)|
# **************************************************************************** #
function DESTROY_SYS_DISK_MBR_MAGIC()
{
    local DiskPart=$1
    #将分区名的最后一个字符去掉，作为硬盘名
    local DiskName=${DiskPart%?}
    local DiskStateFile=/sys/block/${DiskName##*/}/device/state
    
    OS_echo "[UPGRADE_SH] Befor format sys disk(${DiskName}), force set the status to be running." >/dev/null
    echo running > $DiskStateFile
    
    OS_echo "[UPGRADE_SH] Begin to dd flag to shield fault disk($DiskName)." >/dev/null
    dd if=/dev/zero of=${DiskName} bs=1 count=2 seek=510
    if [ "$?" != "0" ]; then
        OS_echo "[UPGRADE_SH] dd if=/dev/zero of=${DiskName} bs=1 count=1 seek=510 failed." >/dev/null
    fi
    return 0
}

# **************************************************************************** #
# Function Name: GET_DISK_RAID_STATUS
# Description: 获取RAID组中盘的状态信息
# Parameter: 1、RAID组名称，如: /dev/md1
#            2、盘符，如: /dev/sda1
# Return: 无
# **************************************************************************** #
function GET_DISK_RAID_STATUS()
{
    local raidName=$1
    local disk=$2
    
    echo `mdadm -D $raidName |grep $disk |awk '{print $5}'`
}

# **************************************************************************** #
# Function Name: CHECK_SYS_IS_REPAIR
# Description: 检查是否正在进行系统盘修复 
# Parameter: 无
#          
# Return: 无
# **************************************************************************** #

function CHECK_SYS_IS_REPAIR()
{
    for((i=0;i<10;i++))
    do
        if [ -e /tmp/sync_repair_flag ]; then
            OS_echo "[UPGRADE_SH] checking sync_repair_flag,  sync_repair_flag exists. "
            sleep 10
        else
            return 0
        fi
    done
    return 1
}
#*********************************************************************#
# Function Name: OS_CHECK_IMAGE_DISK
# Description:检查系统镜像分区是否可以继续升级
# 1、IMAGE RAID分区所有盘故障：升级中止；
# 2、IMAGE RAID分区单盘故障：写坏故障盘引导分区继续升级；
# 3、无故障：继续升级
# Usage: 
# 1、升级系统完成，重启系统前调用
# Parameter:
# Return:0——继续升级；1——升级中止
#*********************************************************************#
function OS_CHECK_IMAGE_DISK()
{
    local L_shieldFlag=$1
    local MDADM_CONF_FILE=/etc/mdadm.conf
	
    CHECK_SYS_IS_REPAIR
    if [ 0 != $? ]; then
        OS_echo "[UPGRADE_SH] The sync_repair_flag file is exist."
        return 1
    fi
    
    #/etc/mdadm.conf文件不存在，直接返回
    if [ ! -e ${MDADM_CONF_FILE} ]; then
        OS_echo "[UPGRADE_SH] There is no $MDADM_CONF_FILE, no need check sys disk."
        return 0
    fi
    
    GET_CONFIG_SYS_DISK_NUM
    local L_CFG_SYS_DISK_NUM=$?
    
    #标配只有一块系统盘，不检查
    if [ "2" != "$L_CFG_SYS_DISK_NUM" ]; then
        OS_echo "[UPGRADE_SH] Config sys disk num is($L_CFG_SYS_DISK_NUM), no need check sys disk." >/dev/null
        return 0
    fi    

    local ImageRaid=/dev/md1
    local RaidInfo=`cat $MDADM_CONF_FILE | grep $ImageRaid | awk '{print $3}'`
    local disk1=`echo $RaidInfo |awk -F= '{print $2}' |awk -F, '{print $1}'`
    local disk2=`echo $RaidInfo |awk -F= '{print $2}' |awk -F, '{print $2}'`
    
    #检查RAID组中盘状态是否正常：
    #1、两块盘均非active，直接失败；
    local disk1RaidStatus=$(GET_DISK_RAID_STATUS $ImageRaid $disk1)
    local disk2RaidStatus=$(GET_DISK_RAID_STATUS $ImageRaid $disk2)
    if [ "active" != "$disk1RaidStatus" -a "active" != "$disk2RaidStatus" ]; then
        OS_echo "[UPGRADE_SH.SH] Both of the sys disk($disk1:$disk1RaidStatus, $disk2:$disk2RaidStatus) of raid($ImageRaid) is not active." >/dev/null
        return 1
    fi
    
    #2块系统盘都active都成功
    if [ "active" == "$disk1RaidStatus" -a "active" = "$disk2RaidStatus" ]; then
        OS_echo "[UPGRADE_SH.SH] Both of the sys disk($disk1:$disk1RaidStatus, $disk2:$disk2RaidStatus) of raid($ImageRaid) is active." >/dev/null
        return 0
    fi    
    
    #两块盘其中有1块是非active的
    #非升级则不对系统盘进行隔离，直接返回失败
    if [ "1" != "$L_shieldFlag" ]; then
        OS_echo "[UPGRADE_SH.SH] one of the sys disk($disk1:$disk1RaidStatus, $disk2:$disk2RaidStatus) of raid($ImageRaid) is not active, can not download package." >/dev/null
        return 1
    fi
	
    #升级时根据CCB需要隔离非active的盘
    if [ "active" != "$disk1RaidStatus" ]; then
        OS_echo "[UPGRADE_SH] The sys disk($disk1) raid status($disk1RaidStatus) is abnormal, try to shield it." >/dev/null
        DESTROY_SYS_DISK_MBR_MAGIC $disk1
    fi
    
    if [ "active" != "$disk2RaidStatus" ]; then
        OS_echo "[UPGRADE_SH] The sys disk($disk2) raid status($disk2RaidStatus) is abnormal, try to shield it." >/dev/null
        DESTROY_SYS_DISK_MBR_MAGIC $disk2
    fi

    return 0
}

#*********************************************************************#
# Function Name: OS_CHECK_SYS_DISK
# Description:检查系统镜像分区是否可以继续升级
# 1、IMAGE RAID分区所有盘故障：升级中止；
# 2、IMAGE RAID分区单盘故障：写坏故障盘引导分区继续升级；
# 3、CONF挂载状态非读写：升级中止；
# 4、无故障：继续升级
# Usage: 
# 1、升级系统完成，重启系统前调用
# Parameter:
# Return:0——继续升级；1——升级中止
#*********************************************************************#
function OS_CHECK_SYS_DISK()
{
    local L_shieldFlag=$1
    #检查系统镜像分区：   
    OS_CHECK_IMAGE_DISK $L_shieldFlag
    local Ret=$?
    if [ "$Ret" != "0" ]; then 
        return $Ret
    fi

    #CONF分区非可读写（未挂载/只读）：升级中止；
    local ConfDiskRW=`mount |grep /startup_disk/conf |grep rw`
    if [ "$ConfDiskRW" == "" ]; then
        OS_echo "[UPGRADE_SH]: /startup_disk/conf is read only, can not upgrade."
        return 1
    fi

    return 0
}

function UPGRADE_IsDorado()
{
    L_PRODUCT_TYPE=`cat "$G_PRODUCT_CFG_FILE" | awk '/ProductName =/ {print $(NF-1)}'`
    if [ "$L_PRODUCT_TYPE" = "Dorado5000" -o "$L_PRODUCT_TYPE" = "Dorado6000" ]; then
        return 0
    fi 
    return 1
}

function ROLLBACK_REBUILD_VERCONF()
{
    local rollbackVer=$1

    isDowngradeAndRebuildVerconf $rollbackVer
    return 0
}

#*********************************************************************#
# Function Name: UPGRADE_GET_VER_DIR
# Description:根据传入的数字版本信息获取对应的字符串版本信息
# Usage: UPGRADE_GET_VER_DIR 系统版本信息
# Parameter:版本信息
# Return:字符串版本信息
#*********************************************************************#
function UPGRADE_GET_SPC_VER()
{
    local version=$1
    
    PKG_DIR_LIST=($G_UPDATE_BOOT_DIR $G_BOOT_OSP_BAK_DIR $G_UPDATE_TMP_DIR)
    
    for pkg_dir in "${PKG_DIR_LIST[@]}"
    do
        pkg_version=`cat $pkg_dir/versions.conf |grep -m 1 Version |awk -F"=" '{print $2}'`
        if [ "${version}" == "${pkg_version}" ]; then
            spc_version=`cat ${pkg_dir}/versions.conf |grep -m 1 SpcVersion |awk -F"=" '{print $2}'`
            echo $spc_version
            return 0
        fi
    done
    
    return 1
}

function GENERATE_UPGRADE_CONFIG_INI()
{
    local config_path=/tmp/upd_config_info.ini
    local upd_state_file=/startup_disk/conf/conf_local/upd_state_flows.lua
    echo '[UPGRADE]' > $config_path
    
    local versions=`awk -F\" '/spc/ {printf("%s=%s\n", $2, $4)}' $upd_state_file`
    if [ "$versions" != "" ]; then
        echo "${versions}" >> $config_path
        return 0
    fi
    
    local pkg_version=$(grep -A20 "ParamList" $upd_state_file | grep -m 1 pkgversion | grep -oP "[0-9]+")
    local roll_version=$(grep -A20 "ParamList" $upd_state_file | grep -m 1 rollversion | grep -oP "[0-9]+")
    
    local pkg_spc_version=$(UPGRADE_GET_SPC_VER $pkg_version)
    local roll_spc_version=$(UPGRADE_GET_SPC_VER $roll_version)
    
    if [ -n "${pkg_spc_version}" -a -n "${roll_spc_version}" ]; then
        echo "pkgspcversion=$(UPGRADE_GET_SPC_VER $pkg_version)" >> $config_path
        echo "rollspcversion=$(UPGRADE_GET_SPC_VER $roll_version)" >> $config_path
        return 0
    fi
    
    UPD_ECHO "Generate upgrade config ini failed(pkgspcverion: ${pkg_spc_version}, rollspcverion: ${roll_spc_version})."
    return 1
}
#*********************************************************************#
# Function Name: UPGRADE_CheckMemory
# Description:检查内存或者coffer_data/update盘空间是否足够
# Parameter:
# Return:
#*********************************************************************#
function UPGRADE_CheckMemory()
{
    local L_NEED_MEM=$1
    
    OS_CHECK_FREE_MEM_ENOUGH $L_NEED_MEM
    if [ "0" != "$?" ] ; then
        L_TIME=`ps -aux 2>/dev/null |grep "/bin/bash /OSM/script/os_system_update.sh -m $G_MIN_MEM" |wc -l`
        OS_echo "[UPGRADE_FREE_MEM]: [free thread num: $L_TIME].">/dev/null
        if [ "$L_TIME" -ge "4" ];then
            OS_echo "[UPGRADE_FREE_MEM]: has already release mem, [free thread num: $L_TIME] and put the package in ${G_SYS_PKG_DIR_IN_COFFER_DATA}.">/dev/null
            LinkToCofferData
            #upgrade_startwork_fail.sh远程调用该脚本通过以下打印获取执行结果
            echo "Upgrade success"
            return 0
        fi
        OS_FREE_MEM_FUC &
        OS_CHECK_FREE_MEM_ENOUGH $L_NEED_MEM
        if [ "0" != "$?" ] ; then
            OS_echo "[UPGRADE_FREE_MEM]: The memory is not enough, and put the package in ${G_SYS_PKG_DIR_IN_COFFER_DATA}.">/dev/null
            LinkToCofferData
            echo "Upgrade success"
            return 0
        else
            ChangeLinkToDIR $G_UPDATE_DIR
            echo "Upgrade success"
            return 0
        fi
    else
        ChangeLinkToDIR $G_UPDATE_DIR
        echo "Upgrade success"
        return 0
    fi
    
    return 0
}

# --------------------------  main  ------------------------------------------ #

OS_GetDriverID

L_INPUT_PARA_NUM=$#

if [ $L_INPUT_PARA_NUM -lt 1 ] ; then
    OS_echo "UPGRADE_SH: [os_system_update.sh]wrong input num: $#." >/dev/null
    OS_UpdateHelp
else
    ## 新增命令不能使用-E -e -n作为输入参数   
        L_TMP=`echo $1 | grep '\-[a-zA-Z0-9]'`
    if [ -z "$L_TMP" ] ; then
        OS_echo "UPGRADE_SH: [os_system_update.sh]wrong input para $1." >/dev/null
        OS_UpdateHelp
    fi
fi

while getopts u:iogyza:b:sqm:wrdv:t:cfplk:h:j:xq:ABRC:DF:G:H:I:J:KLMNOQP:SY:T:UVW:XZ: options 2>/dev/null
do
    case $options in
        S)  OS_echo "UPGRADE_SH [-S]: Create Upgrade Config File."
            GENERATE_UPGRADE_CONFIG_INI
            exit 0
            ;;
        m)  OS_echo "UPGRADE_SH [-m]: Check Memory" >/dev/null
            L_NEED_MEM=$OPTARG
            G_MEM_NEEDED_WHEN_CP_PKG=$L_NEED_MEM
            UPGRADE_CheckMemory $L_NEED_MEM
            exit $?
            ;;
        b)  OS_echo "UPGRADE_SH [-b]: Hotpatch Check Memory" >/dev/null
            L_NEED_MEM=$OPTARG
            G_MEM_NEEDED_WHEN_CP_PKG=$L_NEED_MEM
            UPGRADE_CheckMemory $L_NEED_MEM
            if [ "$?" != "0" ];then
                exit 1
            fi
            #热补丁安装前先释放coffer_bin不用的空间再检查空间是否足够
            /OSM/script/os_upgrade_hotpatch.sh -e $L_NEED_MEM
            exit $?
           ;;
        A)  OS_echo "UPGRADE_SH [-A]: Record upgrade path to /OSM/ccdb/store/upgrade_path.log" >/dev/null
            OS_SET_DISK_RW
            OS_RECORD_UPGRADE_PATH
            exit $?
            ;;
        B)  #备份boot_osp和hotpatch目录到/OSM/ccdb/store/soft_backup
            OS_echo "UPGRADE_SH [-B]: Backup boot_osp and hotpatch to /OSM/ccdb/store/soft_backup" >/dev/null
            OS_echo "UPGRADE_SH $OPTARG"
            OS_SET_DISK_RW
            OS_BACKUP_SOFTWARE
            exit $?
            ;;
        R)  #备份boot_osp和hotpatch目录到/OSM/ccdb/store/soft_backup
            OS_echo "UPGRADE_SH [-R]: Backup boot_osp and hotpatch to /OSM/ccdb/store/soft_backup" >/dev/null
            if [ ! -d $BACKUP_BOOT_OSP_DIR ] ; then
                OS_echo "UPGRADE_SH $BACKUP_BOOT_OSP_DIR is not exist, need to backup."
                OS_SET_DISK_RW
                OS_BACKUP_SOFTWARE
            else
                OS_echo "UPGRADE_SH $BACKUP_BOOT_OSP_DIR is exist, no need to backup."
            fi
            exit $?
            ;;  
            
        C)  #解压异构包到指定目录下
            OS_echo "UPGRADE_SH [-C]: tar asl package" >/dev/null
            OS_echo "UPGRADE_SH $OPTARG"
            OS_SET_DISK_RW
            OS_TAR_ASL_UPDATE_PACKAGE $OPTARG
            exit $?
            ;;
        D)  OS_echo "UPGRADE_SH [-D]: check the asl package content" >/dev/null
            OS_SET_DISK_RW
            OS_CHECK_ASL_PACKAGE
            if [ 0 != $? ] ; then
                OS_FREE_MEM_FUC
                OS_echo "UPGRADE_SH: [os_system_update.sh -D]Check the update packaget error." >/dev/null
                exit $G_ERROR_PKG_INVALIDE
            fi
            OS_CHECK_ASL_REINSTALL
            exit $?
            ;;
        F)  OS_echo "UPGRADE_SH [-F]: AslVersionCompatibleCheck[0:not need sync asl;1:need sync asl;2:exception error]" >/dev/null
            OS_CHECK_ASL_VERSION  $OPTARG
            exit $?
            ;;
        G)  OS_echo "UPGRADE_SH [-G]: asl patch sync" >/dev/null
            CopyAnythingWithRetry $OPTARG "ASL_SYNC"
            exit $?
            ;;
        O)  OS_echo "UPGRADE_SH [-O]: check the device is Dorado or not." >/dev/null
            UPGRADE_IsDorado
            exit $?
            ;;
        f)  OS_echo "UPGRADE_SH [-f]: -no need prompt" >/dev/null
            G_PROMPT=true
            ;;
        k)  OS_echo "UPGRADE_SH [-k]: delete the all files in update dir" >/dev/null
            OS_DEL_FILES_IN_UPDATE_DIR
            OS_SET_DISK_RW
            UPGRADE_RESTART_OMM_UPD_SERVER_AND_AGENT &
            OS_DEL_ALL_FILES_IN_UPDATE $OPTARG
            exit $?
            ;;
        w)  OS_echo "UPGRADE_SH [-w]: Change disk to write." >/dev/null
            OS_SET_DISK_RW
            exit $?
            ;;
        r)  OS_echo "UPGRADE_SH [-r]: Change disk to read only" >/dev/null
            OS_SET_DISK_RO
            if [ 0 != $? ] ; then
                OS_echo "UPGRADE_SH: [os_system_update.sh -r] Change disk to read only error." >/dev/null
                exit 1
            fi
            ;;
        c)  OS_echo "UPGRADE_SH [-c]: check the update package content" >/dev/null
            OS_SET_DISK_RW
            OS_CHECK_PACKAGE
            if [ 0 != $? ] ; then
                OS_FREE_MEM_FUC
                OS_echo "UPGRADE_SH: [os_system_update.sh -c]Check the update packaget error." >/dev/null
                exit $G_ERROR_PKG_INVALIDE
            else
                OS_FREE_MEM_FUC
                exit 0
            fi
            ;;
        p)  OS_echo "UPGRADE_SH [-p]: -update package" >/dev/null
            OS_SET_DISK_RW
            OS_Confirm
            OS_UPDATE_PACKAGE
            exit $?
            ;;
        l)  OS_echo "UPGRADE_SH [-l]: link boot to boot_osp_bak " >/dev/null
            OS_SET_DISK_RW
            OS_MODIFY_LINK_TO_BAK
            #must call the function
            OS_SET_DISK_RO
            exit 0
            ;;
        z)  OS_echo "UPGRADE_SH [-z]: Rollback change link " > /dev/null
            OS_SET_DISK_RW
            OS_ROLLBACK_CHANGE_LINK
            OS_SET_DISK_RO
            exit 0
            ;;
        d)  OS_echo "UPGRADE_SH [-d]: make dir" >/dev/null
            if [ ! -d $G_DISK_MOUNT_IMAGE/ISM ] ; then
                OS_SET_DISK_RW
                OS_echo "UPGRADE_SH: create image/ISM dir" >/dev/null
                mkdir -p $G_DISK_MOUNT_IMAGE/ISM
            fi
            if [ ! -d $G_UPDATE_DIR ] ; then
                OS_SET_DISK_RW
                OS_echo "UPGRADE_SH: create image/update dir" >/dev/null
                mkdir -p $G_UPDATE_DIR
            fi
            ;;
        t)  OS_echo "UPGRADE_SH [-t]: tar update package" >/dev/null
            OS_SET_DISK_RW
            OS_TAR_UPDATE_PACKAGE $OPTARG
            OS_EXEC_UNZIP_PKG_NEXT_PRETREATMENT
            HandleDIRAfterTarSYSPkg
            ;;
        v)  OS_echo "UPGRADE_SH [-v]: tar update package for version" >/dev/null
            OS_SET_DISK_RW
            OS_GET_UPDATE_PACKAGE_VERSION $OPTARG
            exit $?
            ;;
        s) OS_echo "UPGRADE_SH [-s]: Check Start_up is Boot Form USB" >/dev/null
           OS_CHECK_IS_BOOT_FROM_USB
           ;;
        g) OS_echo "UPGRADE_SH [-g]: Check Is Need Fire Disk For Update" >/dev/null
           OS_SET_DISK_RW
           OS_CHECK_IS_NEED_FIRE_DISK
           exit $?
           ;;
        y) OS_echo "UPGRADE_SH [-y]: update patch or BIOS in system starting" >/dev/null           
           OS_UPDATE_BIOS
           if [ "0" != "$?" ] ; then
                OS_echo "UPGRADE_SH: update bios failed." >/dev/null
                exit 1
           fi

           OS_REBOOT_SYSTEM
           exit 0
           ;;
        Y) OS_echo "UPGRADE_SH [-Y]: update BIOS in system runing" >/dev/null   
           OS_echo "UPGRADE_SH: BIOS $OPTARG." >/dev/null
           OS_UPDATE_BIOS_BEFORE_REBOOT $OPTARG
           exit $?
           ;;
        o) OS_echo "UPGRADE_SH [-o]: select version in updating" >/dev/null
           #os os_load_select_ver.sh中调用
           OM_VER_SELECT
           exit $?
           ;;
        i) OS_echo "UPGRADE_SH [-i]: isochronous" >/dev/null
           OS_SET_DISK_RW
           SYNC_SYSTEM
           if [ 0 != $? ] ; then
                OS_echo "UPGRADE_SH: [os_system_update.sh -i]isochronous version error." >/dev/null
                OS_SET_DISK_RO
                exit 1
            else
                OS_SET_DISK_RO
                exit 0
            fi
           ;;

        u) OS_echo "UPGRADE_SH [-u]: execute upgrade process script" >/dev/null
           G_PARA="$OPTARG"
           OS_EXECUTE_UPGRADE_SCRIPT "$G_PARA"
           exit $?
           ;;
        h) OS_echo "UPGRADE_SH [-h]: tar upgrade output file" >/dev/null
           OS_TAR_UPGRADE_OUTPUT_FILE $OPTARG
           exit $?
           ;;
        j) OS_echo "UPGRADE_SH [-j]: copy software from other nid " >/dev/null
           CopySoftwareWithRetry $OPTARG
           exit $?
           ;;
        x) #判断热补丁是否需要回退
           OS_echo "UPGRADE_SH [-x]: Check Hotpatch Need Rollback function." >/dev/null
           OS_UPG_HP_IS_NEED_ROLLBACK
           L_TMP_RTN=$?
           if [ "$L_TMP_RTN" != 0 ] ;then
                OS_echo "Hotpatch need rollback."
                exit $L_TMP_RTN
           fi
           OS_echo "Hotpatch need not rollback."
           exit $L_TMP_RTN
           ;;
        H) OS_echo "UPGRADE_SH [-H]: analyse atom state file." >/dev/null
           AnalyseAtomStateFile $OPTARG
           exit $?
           ;;
        I) OS_echo "UPGRADE_SH [-I]: copy atom state file." >/dev/null
           CopyAtomStateFile $OPTARG
           exit $?
           ;;
        J) OS_echo "UPGRADE_SH [-J]: Check hotpatch.tgz is preprocess pkg." >/dev/null
           CheckIsPrePkg $OPTARG
           exit $?
           ;;
        K) OS_echo "UPGRADE_SH [-K]: Execute preprocess script." >/dev/null
           ExecutePreScript
           exit $?
           ;;
        L) OS_echo "UPGRADE_SH [-L]: Clear boot_osp_bak when upg success." >/dev/null
           #大系统升级成功清空补丁目录
           /OSM/script/os_upgrade_hotpatch.sh -k
           ClearBakDirWhenUpgSucc
           exit $?
           ;;
        M) OS_echo "UPGRADE_SH [-M]: Get Asl Encode Version Info." >/dev/null
           OS_GET_ASL_VERSION
           exit $?
           ;;
        N) OS_echo "UPGRADE_SH [-N]: upgrade SmartIO card and PCIE2.0." >/dev/null
           #在心跳同步版本中等待2分钟让版本拷贝完成
           if [ -f /tmp/sync_upgrading ];then
                OS_echo "UPGRADE_SH: it is syncing,sleep 120s." >/dev/null
        sleep 120
           fi
           UPGRADE_SMARTIO_CARD
           UPGRADE_PCIE_CARD
           exit $?
           ;;
        Q) OS_echo "UPGRADE_SH [-Q]: upgrade SmartIO card and PCIE." >/dev/null
           #在心跳同步版本中等待2分钟让版本拷贝完成
           if [ -f /tmp/sync_upgrading ];then
                OS_echo "UPGRADE_SH: it is syncing,sleep 120s." >/dev/null
        sleep 120
           fi
           UPGRADE_SMARTIO_CARD
           UPGRADE_PCIE_CARD_DMI
           exit $?
           ;;
        P) OS_echo "UPGRADE_SH [-P]: upgrade sys package, dstVer=$OPTARG." >/dev/null
           OS_SET_DISK_RW
           OS_CHECK_SYS_DISK 1
           if [ "0" != "$?" ] ; then
               OS_SET_DISK_RO
               exit 1
           fi
           UPGRADE_UpdatePkg $OPTARG
           ret=$?
           OS_echo "UPGRADE_SH [-P]: check value return $ret." >/dev/null
           OS_SET_DISK_RO
           exit $ret
           ;;
        a) OS_echo "UPGRADE_SH [-a]: Judging R Version rollback and rebuild versions.conf, rollbackVer=$OPTARG." >/dev/null
           OS_SET_DISK_RW
           ROLLBACK_REBUILD_VERCONF $OPTARG
           OS_SET_DISK_RO
           exit $?
           ;;
        ##在导包之前进行系统盘修复
        q) OS_echo "UPGRADE_SH [-n]: Check sys disk." >/dev/null
           OS_CHECK_SYS_DISK 0
           if [ "0" != "$?" ] ; then
               exit 1
           fi
           ;;
        T) OS_echo "UPGRADE_SH [-T]: tar disk package" >/dev/null
            OS_echo "del history package before tar disk package" >/dev/null
            UPGRADE_DEL_DISK_PACKAGE
            OS_SET_DISK_RW
            UPGRADE_TAR_UPDATE_DISK_PACKAGE $OPTARG
            ret=$?
            if [ "0" != "$ret" ] ; then
               OS_SET_DISK_RO
               exit $ret
            fi
            HandleDIRAfterTarSYSPkg
            exit 0
            ;;
        U) OS_echo "UPGRADE_SH [-U]: check disk package" >/dev/null
            UPGRADE_CHECK_DISK_PACKAGE
            ret=$?
            if [ "0" != "$ret" ] ; then
               OS_SET_DISK_RO
               exit $ret
            fi
            exit 0
            ;;
        V) OS_echo "UPGRADE_SH [-V]: del disk package" >/dev/null
            UPGRADE_DEL_DISK_PACKAGE
            ret=$?
            if [ "0" != "$ret" ] ; then
               exit $ret
            fi
            exit 0
            ;;  
        W) OS_echo "UPGRADE_SH [-W]: sync disk fw from master" >/dev/null
            OS_SET_DISK_RW
            UPGRADE_SYNC_DISK_PACKAGE $OPTARG
            ret=$?
            if [ "0" != "$ret" ] ; then
               exit $ret
            fi
            exit 0
            ;;
        X) OS_echo "UPGRADE_SH [-X]: sync disk fw from master" >/dev/null
            UPGRADE_BACKUP_DISK_FILE_TO_CCDB
            ret=$?
            if [ "0" != "$ret" ] ; then
               exit $ret
            fi
            exit 0
            ;;
        Z) OS_echo "UPGRADE_SH [-Z]: produce checksum for dir" >/dev/null 
           checkdir=$OPTARG 
           PRODUCE_CHECKSUM_FOR_DIR $checkdir 
           Del_DM_in_Checksum $checkdir 
           ret=$? 
           if [ "0" != "$ret" ] ; then 
               exit $ret 
           fi 
           exit 0 
           ;;
        *) OS_UpdateHelp
           ;;
    esac
done

exit 0
