#!/bin/bash

# **************************************************************************** #
# File Name: os_hotpatch.sh
# Description:提供热补丁管理功能: 热补丁包加载、激活、删除、恢复生效等功能。
# Author: 
# Created: 2009.11.24
# Function List：
# History
# 1.Date:
#   Author:
#   Modification:
# **************************************************************************** #
source /OSM/script/os_patch_source.sh

#R2 P11G-4082 modified2012/02/05 begin
#根据热补丁新需求重新实现热补丁管理功能

#热补丁目录、配置文件
G_OS_HP_VER_TEMP_CONF="/tmp/hotpatch_version.conf"
G_OS_HP_VER_TEMP_PEER_CONF="/tmp/hotpatch_peer_version.conf"  #用于临时存放热补丁版本信息的文件 
G_OS_HP_RB_FAIL_LIST="/tmp/os_hp_rollback_fail_list"   #用于存放热补丁回滚失败的补丁信息
G_OS_HP_SYS_STATUS="hp_status"                 #热补丁内部状态:normal、abnormal
G_OS_HP_MD5SUM_FILE="patch_sha256sum"
G_HP_DEV_CHR=/dev/os_hotpatch
G_HP_LOAD_EXE=`which livepatch`
G_OS_HP_CONF="patch.conf"
G_OS_HP_DIR="/OSM/coffer_bin/hotpatch"
G_HOT_PATCH_BOOT_DIR="/OSM/coffer_bin"
G_HOT_PATCH_BACKUP_ROOT_DIR="/OSM/coffer_data"
G_HOT_PATCH_BACKUP_VERSION="V300R006C61"
G_HOT_PATCH_BACKUP_DIR="${G_HOT_PATCH_BACKUP_ROOT_DIR}/patch_backup/${G_HOT_PATCH_BACKUP_VERSION}"
G_OS_HP_LINK="patch"
G_OS_HP_CUR="patch_cur"    #当前补丁包名
G_OS_HP_BAK="patch_bak"    #旧补丁包名
G_OS_HP_TEMP="patch_temp"  #新补丁包解压目录名
G_OS_HP_DIR_LINK="$G_OS_HP_DIR/$G_OS_HP_LINK"
G_OS_HP_DIR_CUR="$G_OS_HP_DIR/$G_OS_HP_CUR"
G_OS_HP_DIR_BAK="$G_OS_HP_DIR/$G_OS_HP_BAK"
G_OS_HP_DIR_TEMP="${G_OS_HP_DIR}/${G_OS_HP_TEMP}"
G_OS_HP_DIR_LINK_CONF="${G_OS_HP_DIR_LINK}/${G_OS_HP_CONF}"
G_OS_HP_DIR_TEMP_CONF="${G_OS_HP_DIR_TEMP}/${G_OS_HP_CONF}"

#紧急补丁包名#
G_OS_HP_EMERGENCY="patch_emergency"
G_OS_HP_DIR_EMERGENCY="$G_OS_HP_DIR/$G_OS_HP_EMERGENCY"
##系统中被用户态补丁替换前备份的文件后缀#
G_OS_USR_HP_BAK_FIELD="origin"

G_OS_KER_HP_ACTIVE_FIELD="applied"
G_OS_KER_HP_DEACTIVE_FIELD="deactive"

G_OS_HP_VER="$G_OS_HP_DIR/patch_version"

#内核热补丁模块操作信息
G_OS_HP_OP_SUCC="OS_HP_OP_SUCC"   #操作成功

#热补丁内部返回的错误码
G_OS_HP_RESULT_SUCC=0               #操作成功
G_OS_HP_RESULT_FAIL=1               #操作失败
G_OS_HP_RESULT_MD5_NOT_EXIST=2        #sha256文件不存在
G_OS_HP_RESULT_VERSION_ERR=3        #基础版本不一致
G_OS_HP_RESULT_REINSTALL_ERR=4      #热补丁包重复安装
G_OS_HP_RESULT_NO_HOTPATCH=5        #没有热补丁包
G_OS_HP_RESULT_REROLLBACK_ERR=6     #热补丁包重复回退
G_OS_HP_RESULT_RB_UNCONFIRMED=7     #回退未确认的版本
G_OS_HP_RESULT_RB_UNCONFIRMED_FAIL=10     #回退未确认的版本
G_OS_HP_RESULT_KER_MEM_ERR=8         #内核态热补丁区大小错误#
G_OS_HP_RESULT_CUR_HP_ERROR=9       #当前的热补丁包错误#
G_OS_USR_HP_RESULT_SUCC=0               #操作成功
G_OS_USR_HP_RESULT_BAK_FAIL=1               #备份替换文件时失败
G_OS_USR_HP_RESULT_LOAD_FAIL=2               #替换文件时失败
G_OS_USR_HP_RESULT_SCRIPT_FAIL=3               #scripit执行失败
#R2R5&R5C01 P12I-3843 modified2013/1/11 begin

G_HOTPATCH_STATUS=/tmp/hotpatch_status_tmp

#R2R5&R5C01 P12I-3843 modified2013/1/11 end

# --------------------------  functions  -------------------------------------- #

# **************************************************************************** #
# Function Name: OS_GetHPVer
# Description: 获取版本号
# Parameter: 
# Return: 
# **************************************************************************** #
OS_GetHPVer()
{
    cat $G_OS_HP_VER 2>/dev/kmsg

}
# **************************************************************************** #
# Function Name: OS_SetHPVer
# Description: 设置版本号
# Parameter: 
# Return: 
# **************************************************************************** #
OS_SetHPVer()
{
    echo $1 > $G_OS_HP_VER 

}

# **************************************************************************** #
# Function Name: OS_GetKHPStage
# Description: 获取状态
# Parameter: 
# Return: 
# **************************************************************************** #
OS_GetKHPStage()
{
    local L_KID=$1
    local L_SYS_STAGE=
    local L_STAGE_VALUE=
    
    L_SYS_STAGE="/sys/module/ksplice_${L_KID}/ksplice/stage"
    if [ ! -f "$L_SYS_STAGE" ];then
        OS_echo "sys file stage is not exist, and kernel patch[kid: ${L_KID}] is not load."
        return 1
    fi
    cat $L_SYS_STAGE 2>/dev/kmsg 
    
    return 0
}

# **************************************************************************** #
# Function Name: OS_FilterPatch
# Description: 过滤出需要打补丁的文件
# Parameter: 
# Return: 
# **************************************************************************** #
OS_FilterPatch()
{
    local L_NEW_DIR=$1
    local L_OLD_DIR=$2
    local L_FILTER_CONF=$3
    local L_INSTALL_FLAG=$4
    local L_RET=
    local L_OLD_FILE=/tmp/l_old_file_$$
    local L_NEW_FILE=/tmp/l_new_file_$$
    local L_FILTER_FILE=/tmp/l_filterpatch_file_$$
    if [ -z "${L_NEW_DIR}" ];then
        OS_echo "L_NEW_DIR is null, OS_FilterPatch failed."
        return 1 
    fi
    #过滤出热补丁配置文件中需要打补丁的文件
    if [ "${L_INSTALL_FLAG}" == "upgrade" ];then
        OS_echo "Filter upgrade hotpatch in old patch.conf."
        cat "${L_OLD_DIR}/${G_OS_HP_CONF}" 2>/dev/kmsg |grep "^Item" |sed 's/^Item //g' |grep " upgrade"> ${L_OLD_FILE}
    elif [ "${L_INSTALL_FLAG}" == "upgrade_left" ];then
        OS_echo "Filter no-upgrade hotpatch in old patch.conf."
        cat "${L_OLD_DIR}/${G_OS_HP_CONF}" 2>/dev/kmsg |grep "^Item" |sed 's/^Item //g' |grep -v " upgrade"> ${L_OLD_FILE}
    else
        cat "${L_OLD_DIR}/${G_OS_HP_CONF}" 2>/dev/kmsg |grep "^Item" |sed 's/^Item //g' > ${L_OLD_FILE} 
    fi
    
    if [ -z "${L_OLD_DIR}" ];then
        echo "" > ${L_OLD_FILE} 
    fi
    
    if [ "${L_INSTALL_FLAG}" == "upgrade" ];then    ##生效带upgrade标志的补丁
        OS_echo "Filter upgrade hotpatch in new patch.conf."
        cat "${L_NEW_DIR}/${G_OS_HP_CONF}" 2>/dev/kmsg |grep "^Item" |sed 's/^Item //g' |grep " upgrade" > ${L_NEW_FILE}
    elif [ "${L_INSTALL_FLAG}" == "upgrade_left" ];then  ##生效不带upgrade标志的补丁
        OS_echo "Filter no-upgrade hotpatch in new patch.conf."
        cat "${L_NEW_DIR}/${G_OS_HP_CONF}" 2>/dev/kmsg |grep "^Item" |sed 's/^Item //g' |grep -v " upgrade" > ${L_NEW_FILE}
    else                                    ##生效全量补丁
        OS_echo "Filter all hotpatch in new patch.conf."
        cat "${L_NEW_DIR}/${G_OS_HP_CONF}" 2>/dev/kmsg |grep "^Item" |sed 's/^Item //g'> ${L_NEW_FILE}
    fi    
    
    diff "${L_OLD_FILE}" "${L_NEW_FILE}" |grep ">" | sed 's/^> //g' >${L_FILTER_FILE}
    ##如果当前版本为正常补丁，升级版本为临时补丁，则打所有的补丁，就不需要diff
    OS_CheckEHPFlag "${L_NEW_DIR}/${G_OS_HP_CONF}"
    if [ $? -eq 0 ];then
        cp -af ${L_NEW_FILE} ${L_FILTER_FILE}
        if [ $? -ne 0 ];then
            OS_echo "copy ${L_NEW_FILE} to ${L_FILTER_FILE} failed."
            rm -rf ${L_OLD_FILE} ${L_NEW_FILE} ${L_FILTER_FILE}
            return 1
        fi
    fi
    
    cat ${L_FILTER_FILE} > $L_FILTER_CONF
    if [ $? -ne 0 ];then
        OS_echo "cat ${L_FILTER_FILE} to $L_FILTER_CONF failed."
        rm -rf ${L_OLD_FILE} ${L_NEW_FILE} ${L_FILTER_FILE}
        return 1
    fi    
    rm -rf ${L_OLD_FILE} ${L_NEW_FILE} ${L_FILTER_FILE}
    return 0
}

# **************************************************************************** #
# Function Name: OS_FindPidByName
# Description: 通过进程名找pid
# Parameter: 
# Return: 
# **************************************************************************** #
OS_FindPidByName()
{
    local L_PROCESS_NAME="$1"
    local L_PROCESS_PID=
    local L_PROCESS_PIDS=
    local L_PROCESS_TMPFILE=/tmp/l_process_tmpfile_$$
    local L_PS_LINE=
    local L_PS_LINE_PROCESS=
    local L_PIDOF_FIND_NUM=
    
    if [ -z "$L_PROCESS_NAME" ];then
        return 0
    fi    
    
    L_PROCESS_PIDS="`pidof "$L_PROCESS_NAME"`" 
    ##如果pidof找到的不是单个id，即0或多个，则从ps -ef 全匹配查找

    L_PIDOF_FIND_NUM="`echo "$L_PROCESS_PIDS" | wc -w`"
    if [ "$L_PIDOF_FIND_NUM" != "1" ];then
        L_PROCESS_PIDS=
        ps -efww | grep "$L_PROCESS_NAME"$ > $L_PROCESS_TMPFILE
        while read L_PS_LINE
        do
            ##ps -efww第8列到最后得到的进程跟参数进程名相比，全匹配查找可以支持找出多个进程号

            L_PS_LINE_PROCESS="`echo "$L_PS_LINE" |awk '{for(i=8;i<=NF;i++)printf("%s ",$i)}'`"
            if [ "$L_PROCESS_NAME " = "$L_PS_LINE_PROCESS" ];then
                L_PROCESS_PID="`echo "$L_PS_LINE" |awk '{print $2}'`"
                L_PROCESS_PIDS="$L_PROCESS_PID $L_PROCESS_PIDS"    
            fi
        done < $L_PROCESS_TMPFILE
        rm -rf $L_PROCESS_TMPFILE
        if [ -z "$L_PROCESS_PIDS" ] && [ "$L_PIDOF_FIND_NUM" != "0" ];then    
            ##如果全匹配没找到，pidof找到多个，说明匹配进程名有问题，
            return 1            
        fi        
    
    fi

    echo "$L_PROCESS_PIDS"
    return 0
    
}

# **************************************************************************** #
# Function Name: OS_HP_SCRIPT
# Description: 用户态补丁脚本预处理
# Parameter: 1. 从patch.conf读取的行（不包括Item）
#
# Return: 
# **************************************************************************** #
OS_HP_SCRIPT()
{
    local L_SCRIPT="$1"
    local L_INSTALL_FLAG="$2"
    local L_INSTALL_DIR="$3"
    if [ "${L_SCRIPT}" = "0" -o -z "${L_SCRIPT}" ];then
        return 0
    fi
    OS_echo "begin to run ${L_SCRIPT} ${L_INSTALL_FLAG}"
    "${L_INSTALL_DIR}"/"${L_SCRIPT}" "${L_INSTALL_FLAG}"
    L_RET=$?    
    return $L_RET
}
# **************************************************************************** #
# Function Name: OS_HP_KILL_PREOCESS
# Description: kill进程
# Parameter: 1. 从patch.conf读取的行（不包括Item）
#             2. 是否为安装，如果是安装，kill失败反正出错，如果是回退不出错
# Return: 
# **************************************************************************** #
OS_HP_KILL_PREOCESS()
{
    local L_LINE="$1"
    local L_INSTALL_FLAG="$2"
    local L_FILE=
    local L_RET=
    local L_HP_KILL_PROCESS=
    local L_HP_KILL_PID=
    local L_HP_KILL_PROCESS_LIST=/tmp/L_HP_KILL_PROCESS_LIST_$$

    ##***从第3列到最后都为kill的进程，多个进程的话，同个分号";"分割***#

    L_FILE="`echo "${L_LINE}" |awk '{print $2}'`"
    L_HP_KILL_PROCESS="`echo "${L_LINE}" | awk '{print $3}'`"
    echo "$L_HP_KILL_PROCESS" | awk -F';' '{for(i=1;i<=NF;i++)printf("%s\n",$i)}' > $L_HP_KILL_PROCESS_LIST    
    while read line
    do
        if [ -z "$line" ];then
            continue
        fi
        L_HP_KILL_PID="`OS_FindPidByName "${line}"`"
        L_RET=$?
        if [ $L_RET -ne 0 ];then
        ##如果全匹配没找到，pidof找到多个，说明匹配进程名有问题，
            OS_echo "find process $line[usr hotpatch: $L_FILE] pid failed."
            if [ "$L_INSTALL_FLAG" = "install" ];then
                return $L_RET
            else
                continue
            fi
        fi
        if [ -z "$L_HP_KILL_PID" ];then
            OS_echo "process $line[usr hotpatch: $L_FILE] is not found in system."    
            continue
        fi
        kill -9 ${L_HP_KILL_PID} 2>/dev/kmsg
        L_RET=$?
        if [ $L_RET -ne 0 ];then
            OS_echo "kill process $line[usr hotpatch: $L_FILE, pid: ${L_HP_KILL_PID}] failed, please check it."        
            if [ "$L_INSTALL_FLAG" = "install" ];then
                return $L_RET
            else
                continue
            fi
        fi
        OS_echo "kill process $line[usr hotpatch: $L_FILE, pid: ${L_HP_KILL_PID}] success."        
        
    done < $L_HP_KILL_PROCESS_LIST    

    rm -rf $L_HP_KILL_PROCESS_LIST 
    return 0

}



# **************************************************************************** #
# Function Name: OS_HP_ECHO_STATUS_TO_CONF
# Description: 设置热补丁状态
# Parameter:
#   $1:热补丁包状态(running/active/abnormal)
#   $2:热补丁包的状态文件所在的目录
# Retrun: 
#   0:始终返回成功
# **************************************************************************** #
OS_HP_ECHO_STATUS_TO_CONF()
{
    local L_TYPE=$1
    local L_DIR=$2
    local L_VER=
      
    L_VER=`cat ${L_DIR%/}/${G_OS_HP_CONF} |grep "^Version" |awk '{print $2}'`     
    echo "${L_TYPE}" > "${L_DIR%/}/${L_VER}.status"
 
    OS_echo "set ${L_TYPE} to ${L_DIR}/${L_VER}.status."
    return 0
}

# **************************************************************************** #
# Function Name: 
#   OS_HP_CHECK_STATUS
# Description
#   检查系统热补丁内部状态是否正常:normal、abnormal
#   #导致内部状态不正常的原因有:
#   #1、安装失败，自动回退时发生内部错误；
#   #2、回退失败，发生内部错误；
#   #3、删除失败；
#   #4、系统重启，恢复热补丁失败，自动回退也失败。
#   #内部状态不正常，系统将禁止操作热补丁，系统重启后将自动回到正常状态。
# Parameter:
#   none
# Retrun: 
#   0:系统热补丁状态正常
#   1:系统热补丁状态不正常。 
# **************************************************************************** #
OS_HP_CHECK_STATUS()
{
    local L_DIR=$1
    local L_STATUS_FILE=
    local L_STATUS=
    
    #若没有SPHXXX.status文件，说明系统还未安装过热补丁，所以也认为状态是正常
    L_STATUS_FILE=`ls -l "${L_DIR%/}/"*".status" 2>/dev/kmsg |awk '{print $9}'`
    if [ -n "${L_STATUS_FILE}" ];then
        L_STATUS=`cat ${L_STATUS_FILE} |grep "abnormal"`
        if [ -n "${L_STATUS}" ];then
            OS_echo "system hotpatch status is abnormal."
            return 1
        fi
    fi
    
    OS_echo "check hotpatch status complete."
    return 0
}

# **************************************************************************** #
# Function Name: OS_FREEMEM_TO_SPECIFY_SIZE
# Description: 尝试强制释放内存到指定的内存大小, 注意：这里的1152取得是经验值
# Parameter: 期望的内存大小
# Return: 0表示已经释放到指定内存,1表示释放失败
# **************************************************************************** #
OS_FREEMEM_TO_SPECIFY_SIZE()
{
    local L_SPECIFY_SIZE=$1
    declare -i L_FREE_TIMES
    declare -i L_FREE_MEMORY
    
    echo 3 >/proc/sys/vm/drop_caches
    
    L_FREE_TIMES=0
    L_FREE_MEMORY=0
    while true ;do
        echo "freepages" >/proc/osp/bsp
        let L_FREE_TIMES=${L_FREE_TIMES}+1
        if [ ${L_FREE_TIMES} -gt 3 ];then
            OS_echo "it has test ${L_FREE_TIMES} times when install hotpatch."
            L_FREE_MEMORY=`free -m|grep ^Mem|awk '{print $4}'`
            if [ ${L_FREE_MEMORY} -ge ${L_SPECIFY_SIZE} ];then
                OS_echo "it[${L_FREE_MEMORY}] has reached ${L_SPECIFY_SIZE}M memory when install hotpatch."
                return 0
            else
                OS_echo "it[${L_FREE_MEMORY}] has not reached ${L_SPECIFY_SIZE}M memory when install hotpatch."
                return 1
            fi
        fi 
        
        L_FREE_MEMORY=`free -m|grep ^Mem|awk '{print $4}'`
        if [ ${L_FREE_MEMORY} -ge ${L_SPECIFY_SIZE} ];then
            OS_echo "it[${L_FREE_MEMORY}] has reached ${L_SPECIFY_SIZE}M memory when install hotpatch."
            break
        fi
    done
    
    OS_echo "free memory to ${L_SPECIFY_SIZE}M succeed[cur:${L_FREE_MEMORY}] when install hotpatch."
    return 0
}

# **************************************************************************** #
# Function Name: 
#   OS_HP_CHECK_MD5
# Description
#   检查补丁包MD5检验和是否正确。
# Parameter:
#   $1:补丁包所在目录。
# Retrun: 
#   0:成功
#   1:失败
#   2:sha256校验文件不存在
# **************************************************************************** #
OS_HP_CHECK_MD5()
{
    local L_HP_DIR=$1
    local L_MD5_LINE=
    local L_CHK_RET=
    local L_MD5_OK=
    local L_MD5_RET=/tmp/hp_sha256_$$

    #首次安装热补丁时,回退的目录下没有sha256检验文件
    if [ ! -f "${L_HP_DIR%/}/${G_OS_HP_MD5SUM_FILE}" ];then
        OS_echo "hotpatch sha256file[${L_HP_DIR%/}/${G_OS_HP_MD5SUM_FILE}] is not exist."
        return ${G_OS_HP_RESULT_MD5_NOT_EXIST}
    fi
    
    cd ${L_HP_DIR}
    sha256sum -c "${G_OS_HP_MD5SUM_FILE}" &> ${L_MD5_RET}
    L_CHK_RET=$?
    cd - &>/dev/null
    if [ "$L_CHK_RET" != "0" ]; then
        cat ${L_MD5_RET} >/dev/kmsg
        rm -rf ${L_MD5_RET}
        OS_echo "hotpatch[${L_HP_DIR}] sha256sum check fail."
        return ${G_OS_HP_RESULT_FAIL}
    fi
    
    L_MD5_LINE=`cat "${L_HP_DIR%/}/${G_OS_HP_MD5SUM_FILE}" | wc -l`
    L_MD5_OK=`cat "${L_MD5_RET}" | grep "OK" | wc -l`
    
    rm -rf ${L_MD5_RET}
    
    if [ "${L_MD5_OK}" != "${L_MD5_LINE}" ] ;then
        OS_echo "hotpatch[${L_HP_DIR}] sha256sum fail[sha256sum:${L_MD5_LINE}, ok:${L_MD5_OK}]."
        return ${G_OS_HP_RESULT_FAIL}
    fi
    
    OS_echo "check hotpatch[${L_HP_DIR}] sha256sum complete[sha256sum:${L_MD5_LINE}, ok:${L_MD5_OK}]."
    return 0
}
# **************************************************************************** #
# Function Name: 
#   OS_HP_CHECK_CUR_VER
# Description
#   判断当前补丁的版本是否正常，防止存在未确认的补丁
# Parameter:
#   none
# Retrun: 
# **************************************************************************** #
OS_HP_CHECK_CUR_VER()
{

    local L_CUR_VER=
    local L_LAST_VER=`OS_GetHPVer`

    if [ -f "${G_OS_HP_DIR_LINK_CONF}" ] ;then
        L_CUR_VER=`cat "${G_OS_HP_DIR_LINK_CONF}" | grep ^Version | awk '{print $2}'`
        if [ "${L_CUR_VER}" != "${L_LAST_VER}" ];then
            OS_echo "the current hotpatch[${L_CUR_VER}] is different with last hotpatch version[${L_LAST_VER}]."
            return ${G_OS_HP_RESULT_CUR_HP_ERROR}
        fi
    else
        if [ -n "${L_LAST_VER}" ];then
            OS_echo "the current hotpatch is null, but hotpatch[ver: ${L_LAST_VER}] is not null."
            return ${G_OS_HP_RESULT_CUR_HP_ERROR}
        fi
    fi
    OS_echo "check cur hotpatch version complete."
    return 0
}

# **************************************************************************** #
# Function Name: 
#   OS_HP_CHECK_PKG_VER
# Description
#   热补丁包版本检查:待安装的补丁包不能比已安装的补丁包旧。
# Parameter:
#   none
# Retrun: 
#   0         操作成功
#   1          基础版本不一致
#   2          热补丁包重复安装
# **************************************************************************** #
OS_HP_CHECK_PKG_VER()
{
    local L_UPG_VER=
    local L_SYS_VER=
    local L_CUR_VER=
    local L_CUR_KER_HP_VER=""
    local L_TEMP=
    local L_RET=
    local L_LAST_VER=`OS_GetHPVer`
     
    #当前软件版本是否支持该补丁版本
    L_UPG_VER=`cat "${G_OS_HP_DIR_TEMP_CONF}" 2>/dev/kmsg| grep ^SysVersionSupported |awk '{print $2}'`
    L_SYS_VER=`grep -A 1 "\[SYS\]" /OSM/conf/versions.conf| tail -1| awk -F'=' '{print $2}'`
    if [ "${L_UPG_VER}" != "${L_SYS_VER}" ] ;then
        OS_echo "this hotpatch package[${L_UPG_VER}] can not match with system version[${L_SYS_VER}]."
        return ${G_OS_HP_RESULT_VERSION_ERR}
    fi
    
    #补丁包版本检查:待被安装的补丁包不能比已安装的补丁包旧,即是否是重复安装
    if [ -f "${G_OS_HP_DIR_LINK_CONF}" ] ;then
        L_UPG_VER=`cat "${G_OS_HP_DIR_TEMP_CONF}" | grep ^Version | awk -F"SPH" '{print $2}'`
        L_CUR_VER=`cat "${G_OS_HP_DIR_LINK_CONF}" | grep ^Version | awk -F"SPH" '{print $2}'`
        if [ -z "${L_UPG_VER}" ];then
            OS_echo "the version of hotpatch is null, it is not hotpatch package."
            return ${G_OS_HP_RESULT_NO_HOTPATCH}
        fi

        #如果当前系统没有临时补丁，而升级补丁为临时补丁，则ok,不需要比较版本号
        OS_CheckEHPFlag ${G_OS_HP_DIR_TEMP_CONF}
        if [ $? -eq 0 ];then
            return 0
        fi
        
        if [ "${L_CUR_VER}" \> "${L_UPG_VER}" -o "${L_CUR_VER}" == "${L_UPG_VER}" ] ;then
            OS_echo "this package[${L_UPG_VER}] is older than current hotpatch[${L_CUR_VER}]."
            return ${G_OS_HP_RESULT_REINSTALL_ERR}
        fi

    else
        if [ -n "${L_LAST_VER}" ];then
            OS_echo "${G_OS_HP_DIR_LINK_CONF} is not exist, but hotpatch[${L_LAST_VER}] is not null."
            return ${G_OS_HP_RESULT_CUR_HP_ERROR}
        fi
    fi
    
    OS_echo "check hotpatch version complete."
    return 0
}

# **************************************************************************** #
# Function Name: OS_HP_CHECK_LINK
# Description: 检查链接是否正确。
#                    链接错误定义:链接存在，但链接指向的目录不存在，或者链接不存在，但cur或者bak存在。
# Parameter:
# Retrun: 
#   0:链接正确
#   1:链接错误
#   2:系统没有补丁包
# **************************************************************************** #
OS_HP_CHECK_LINK()
{
    local L_FILE_NUM=
    local L_LINK=
    
    #若存在cur、bak，则必然存在link否则错误
    if [ ! -L "${G_OS_HP_DIR_LINK}" ] ;then
        if [ -d "${G_OS_HP_DIR_CUR}" -o -d "${G_OS_HP_DIR_BAK}" -o -d "${G_OS_HP_DIR_EMERGENCY}" ] ;then
            OS_echo "hotpatch link file isn't exist,but diretory exist."
            return 1
        fi
    else
        if [ ! -d "${G_OS_HP_DIR_LINK}" ] ;then
            L_LINK=`ls -l "${G_OS_HP_DIR_LINK}" | awk '{print $11}'`
            OS_echo "hotpatch ${G_OS_HP_DIR_LINK} -> ${L_LINK}, but ${L_LINK} does not exist."
            return 1
        fi
    fi
    OS_echo "check hotpatch link file complete."
    return 0
}


# **************************************************************************** #
# Function Name: OS_HP_IS_PERMIT_ROLLBACK
# Description: 系统是否运行回退,不支持多次回退。
# Parameter:
# Retrun: 
#   0:允许回退
#   1:不允许回退
# **************************************************************************** #
OS_HP_IS_PERMIT_ROLLBACK()
{
    local L_LINK=
    
    if [ ! -L "${G_OS_HP_DIR_LINK}" ];then
        OS_echo "${G_OS_HP_DIR_LINK} is not exist, do not rollback hotpatch."
        return ${G_OS_HP_RESULT_NO_HOTPATCH}
    fi
    
    L_LINK=`ls -l "${G_OS_HP_DIR_LINK}" | awk '{print $11}'`
    if [ "${L_LINK}" = "${G_OS_HP_BAK}" ];then
        OS_echo "${G_OS_HP_DIR_LINK} has already link to ${G_OS_HP_BAK}, do not rollback hotpatch."
        return ${G_OS_HP_RESULT_REROLLBACK_ERR}
    fi    
    
    OS_echo "system permit to rollback hotpatch."
    return 0
}

# **************************************************************************** #
# Function Name: 
#   OS_HP_ECHO_VER_TO_CONF
# Description
#   把热补丁包版本信息写到版本临时文件中。
#   #版本信息包括:系统软件C版本号+热补丁包版本号、热补丁包创建时间
# Parameter:
#   $1:热补丁包版本类型: [RUNNING]、[ROLLBACK]、[INACTIVE]
#   $2:热补丁包配置文件所目录。
# Retrun: 
#   0:始终返回成功
# **************************************************************************** #
OS_HP_ECHO_VER_TO_CONF()
{
    local L_TYPE=$1
    local L_CONF_DIR=$2
    local L_FILE=$3

    #uniform P11A-7304 modified2012/05/29 begin
    #R1 P11A-7211 modified2012/05/18 begin
    if [ "[INVALID]" == "${L_TYPE}" ];then
        echo "[INACTIVE]" >> "${L_FILE}"
        echo "PVersion=INVALID" >> "${L_FILE}"
        echo "Version=" >> "${L_FILE}"
        echo "CreateTime=" >> "${L_FILE}" 

        OS_echo "it is a invalid hotpatch package"
        return 1
    fi
    #R1 P11A-7211 modified2012/05/18 end
    #uniform P11A-7304 modified2012/05/29 end

    #uniform P11G-4903 modified2012/05/29 begin
    #R1 P11G-4838 modified2012/05/18 begin
    L_PRODUCT_VER=`grep -A 1 "\[SPCVER\]" /OSM/conf/versions.conf| tail -1| awk -F'=' '{print $2}'`
    #R1 P11G-4838 modified2012/05/18 end
    #uniform P11G-4903 modified2012/05/29 end
    
    L_PATCH_VER=`cat "$L_CONF_DIR/$G_OS_HP_CONF" | grep ^Version | awk '{print $2}'`

    L_CREATE_TIME=`cat "$L_CONF_DIR/$G_OS_HP_CONF" | grep ^CreateTime | awk '{print $2}'`

   
    #R2R5 P11A-7735 modified2012/9/24 begin
    if [ -n "$L_PATCH_VER" ] ; then
       L_PRODUCT_VER="${L_PRODUCT_VER%%SPC*}"     
    fi
    #R2R5 P11A-7735 modified2012/9/24 end
 
    echo "$L_TYPE" >> "$L_FILE"
    echo "PVersion=$L_PRODUCT_VER" >> "$L_FILE"
    echo "Version=$L_PATCH_VER" >> "$L_FILE"
    echo "CreateTime=$L_CREATE_TIME" >> "$L_FILE"

    return 0
}

# **************************************************************************** #
# Function Name: OS_HP_CHANGE_UPG_DIR
# Description: 更改目录名(temp=>cur,cur=>bak)，并使patch重新指向cur.
#   1、备份cur:
#      若patch -> cur:
#         cur=>bak; temp=>cur
#      否则:
#         load => cur
#   2、使link重新指向cur
# Parameter:
#   none
# Retrun: 0:始终返回成功。
# **************************************************************************** #
OS_HP_CHANGE_UPG_DIR()
{
    local L_LINK=
    local L_VER=
    local L_CMOS_TIME=
    local L_TIME=
    local L_TEMP_CONF=/tmp/conf_$$

    
    OS_echo "begin to change hotpatch upgrade directory."
    cd "${G_OS_HP_DIR}"
    
    OS_CheckEHPFlag ${G_OS_HP_DIR_TEMP_CONF}
    if [ $? -eq 0 ];then
        #patch -> ${G_OS_HP_EMERGENCY}  
        rm -rf "${G_OS_HP_LINK}" ${G_OS_HP_EMERGENCY} 
        mv -f "${G_OS_HP_TEMP}" "${G_OS_HP_EMERGENCY}"
        OS_echo "mv hotpatch ${G_OS_HP_TEMP} to ${G_OS_HP_EMERGENCY}." 
 
        ln -sf "${G_OS_HP_EMERGENCY}" "${G_OS_HP_LINK}" 
        OS_echo "let hotpatch ${G_OS_HP_LINK} point to ${G_OS_HP_EMERGENCY}."   
        
        cd - &>/dev/null    
        return 0
        
    fi


    #1:若存在cur，则备份cur: cur -> bak
    L_LINK=`ls -l | grep "${G_OS_HP_LINK}"|awk '{print $11}'`
    if [ "${L_LINK}" = "${G_OS_HP_CUR}" ] ;then
        if [ -d "${G_OS_HP_BAK}" ] ;then
            rm -fr "${G_OS_HP_BAK}"
            OS_echo "rm hotpatch directory:${G_OS_HP_BAK}."
        fi
        mv -f "${G_OS_HP_CUR}" "${G_OS_HP_BAK}"
        OS_echo "mv hotpatch ${G_OS_HP_CUR} to ${G_OS_HP_BAK}."
    fi

    #2:temp -> cur
    mv -f "${G_OS_HP_TEMP}" "${G_OS_HP_CUR}"
    OS_echo "mv hotpatch ${G_OS_HP_TEMP} to ${G_OS_HP_CUR}."
    
    #3:使patch重新指向cur
    if [ -L "${G_OS_HP_LINK}" ] ;then
        rm -f "${G_OS_HP_LINK}"
        OS_echo "delete hotpatch link file at first."
    elif [ ! -d "${G_OS_HP_BAK}" ];then
        #第一次安装没有该链接文件,创建空的bak目录只用于第一次安装后的回退,其中只有patch.conf文件,避免导致回退流程复杂
        mkdir -p "${G_OS_HP_BAK}"
        #去掉配置文件中的内核热补丁项,以免上电恢复热补丁时无法比较出差异部分,导致恢复内核热补丁失败
        
        L_VER=`cat ${G_OS_HP_CUR}/${G_OS_HP_CONF} |grep "^Version"`
        L_TIME=`cat ${G_OS_HP_CUR}/${G_OS_HP_CONF} |grep "^CreateTime"`
        L_CMOS_TIME=`cat "/OSM/conf/versions.conf" | grep "CmosTime"| awk -F'=' '{print $2}' 2>/dev/null`
        sed "s/$L_VER/Version/" ${G_OS_HP_CUR}/${G_OS_HP_CONF} |sed "s/${L_TIME}/CreateTime ${L_CMOS_TIME}/" > ${L_TEMP_CONF}
        sed -i 's/Item/#Item/g' ${L_TEMP_CONF}
        mv ${L_TEMP_CONF} ${G_OS_HP_BAK}/${G_OS_HP_CONF}
        
        OS_echo "it is the first time to install hotpatch, so mkdir ${G_OS_HP_BAK}."
    fi
    ln -s "${G_OS_HP_CUR}" "${G_OS_HP_LINK}"
    OS_echo "let hotpatch ${G_OS_HP_LINK} point to ${G_OS_HP_CUR}."   
    

    cd - &>/dev/null
    
    OS_echo "end to change hotpatch upgrade directory."
    return 0    
}

# **************************************************************************** #
# Function Name: OS_HP_CHANGE_ROLLBACK_DIR
# Description: 回退时更改目录名，并重定向patch.
# Parameter: 
# Retrun: 0:始终返回成功。
# **************************************************************************** #
OS_HP_CHANGE_ROLLBACK_DIR()
{
    local L_CUR_VER=
    local L_BAK_VER=
    local L_RET=
    local L_HP_ROLL_DIR=${G_OS_HP_CUR}
    local L_HP_ROLL_TO_DIR=${G_OS_HP_BAK}
    OS_echo "begin to change hotpatch rollback directory."
    
    cd "${G_OS_HP_DIR}"
    OS_CheckEHPFlag ${G_OS_HP_LINK}/${G_OS_HP_CONF}
    if [ $? -eq 0 ];then
        L_HP_ROLL_DIR=${G_OS_HP_DIR_EMERGENCY}
        if [ -d ${G_OS_HP_CUR} ];then
            L_HP_ROLL_TO_DIR=${G_OS_HP_CUR}    
        fi
    fi
    
    L_CUR_VER=`cat ${L_HP_ROLL_DIR}/${G_OS_HP_CONF} 2>/dev/kmsg |grep "^Version" |awk '{print $2}'`
    L_BAK_VER=`cat ${L_HP_ROLL_TO_DIR}/${G_OS_HP_CONF} 2>/dev/kmsg |grep "^Version" |awk '{print $2}'`

    rm -rf ${G_OS_HP_LINK}
    rm -rf ${L_HP_ROLL_DIR}
    
    if [ -z "${L_BAK_VER}" ];then
        #系统首次安装后(即bak目录下的配置文件的Version字段后没有跟版本号)回退时,删除bak目录.
        ##对应第一次就安装临时补丁也为空
        rm -rf ${L_HP_ROLL_TO_DIR} 
        L_RET=0
        OS_echo "it is the first time to install,so delete bak directory when rollback hotpatch."
    elif [ "${L_CUR_VER}" != "${L_BAK_VER}" ];then
        #对于多次安装后的回退,将patch链接文件指向bak
        ln -s ${L_HP_ROLL_TO_DIR} ${G_OS_HP_LINK}
        L_RET=0 
        OS_echo "${G_OS_HP_LINK} point to ${G_OS_HP_BAK} complete when rollback hotpatch."
    else
        L_RET=1
        OS_echo "change diretory failed when rollback hotpatch."        
    fi
    cd - &>/dev/null
    
    OS_echo "end to change hotpatch rollback directory."
    return ${L_RET}
}

# **************************************************************************** #
# Function Name: OS_HP_CHANGE_DIR
# Description: 更改目录名，并重定向patch.
# Parameter: 修改的类型,即安装后修改,回退时修改
# Retrun: 0:始终返回成功。
# **************************************************************************** #
OS_HP_CHANGE_DIR()
{
    local L_TYPE=$1
    local L_RET=
    
    if [ "install" == "${L_TYPE}" ];then
        #安装热补丁后的确认功能需要修改链接文件
        OS_HP_CHANGE_UPG_DIR
        L_RET=$?
    elif [ "rollback" == "${L_TYPE}" ];then
        #回退时候需要修改链接文件
        OS_HP_CHANGE_ROLLBACK_DIR
        L_RET=$?
    else
        #参数错误
        OS_echo "param is error when changing hotpatch link."
        L_RET=1
    fi
    
    OS_echo "change hotpatch link in ${L_TYPE} complete[ret:${L_RET}]."
    return ${L_RET}
}

# **************************************************************************** #
# Function Name: OS_HP_LOAD_KERNEL
# Description: 加载内核态热补丁
# Parameter:  
# Retrun: 0表示加载成功,非0表示加载失败
# **************************************************************************** #
OS_HP_LOAD_KERNEL()
{
    local L_HP_FILE=$1
    local L_KER_HOTPATCH_NAME=
    local L_KID=
    local L_RET=
    local L_ACT_MAXNUM=2
    local L_ACT_NUM=0

    L_KER_HOTPATCH_NAME=${L_HP_FILE##*/}
    L_KID=${L_KER_HOTPATCH_NAME#ksplice-}
    L_KID=${L_KID%.tar.gz}

    OS_echo "begin to load kernel hotpatch[file:${L_KER_HOTPATCH_NAME}]."
    #加载内核态进程
    ${G_HP_LOAD_EXE} "--load" "${L_HP_FILE}" &>/dev/kmsg
    L_RET=$?
    if [ $L_RET -ne 0 ];then
        OS_echo "load kernel hotpatch[file:${L_KER_HOTPATCH_NAME}] failed,ret:${L_RET},load again."
        ${G_HP_LOAD_EXE} "--load" "${L_HP_FILE}" &>/dev/kmsg
        L_RET=$?
        if [ $L_RET -ne 0 ];then
            OS_echo "load kernel hotpatch[file:${L_KER_HOTPATCH_NAME}] failed,ret:${L_RET}."
            return ${L_RET}
        fi
    fi
   
    
    ${G_HP_LOAD_EXE} "--activate" "${L_KID}" &>/dev/kmsg
    L_RET=$?
    if [ $L_RET -ne 0 ];then
        OS_echo "activate kernel hotpatch[file:${L_KER_HOTPATCH_NAME}] failed,ret:${L_RET},try again."
        #if act failed,try three times
        while [ ${L_ACT_MAXNUM} -gt ${L_ACT_NUM} ]
        do
            sleep 0.5
            L_ACT_NUM=$((${L_ACT_NUM} + 1))
            ${G_HP_LOAD_EXE} "--activate" "${L_KID}" &>/dev/kmsg
            L_RET=$?
            if [ $L_RET -ne 0 ]
            then
                OS_echo "activate kernel hotpatch[file:${L_KER_HOTPATCH_NAME}] failed(try:${L_ACT_NUM}),ret:${L_RET}."
                continue
            fi
            break
        done 
    fi
    if  [ $L_RET -ne 0 ];then
        OS_HP_ROLLBACK_KERNEL $L_KER_HOTPATCH_NAME
    fi
    OS_echo "end to load kernel hotpatch[file:${L_KER_HOTPATCH_NAME}]."
    return $L_RET
}



# **************************************************************************** #
# Function Name: OS_HP_LOAD_USR
# Description: 可执行程序的加载
# Parameter: 1 加载的文件，2目标文件 3 需要执行的脚本，4 补丁所在的目录
# Retrun: 0表示加载成功,非0表示加载失败
# **************************************************************************** #
OS_HP_LOAD_USR()
{
    local L_HP_LINE=$1
    local L_HP_LOAD_DIR_USR=$2
    local L_HP_FILE=`echo "${L_HP_LINE}" |awk '{print $1}'`
    local L_HP_LOCATION=`echo "${L_HP_LINE}" |awk '{print $2}'`
    local L_HP_SCRIPT=`echo "${L_HP_LINE}" |awk '{print $3}'`
    local L_HP_NEW_FLAG=`echo "${L_HP_LINE}" |awk '{print $5}'`

    ##如果没有补丁文件，补丁文件补丁不替换文件，只执行脚本。
    if [ "${L_HP_LOCATION}" == "script_only" -a "${L_HP_FILE}" == "script_only" ]; then
        if [ "${L_HP_SCRIPT}" != "0" -a -n "${L_HP_SCRIPT}" ];then
            OS_HP_SCRIPT "${L_HP_SCRIPT}" "start" "${L_UPG_DIR}"
            L_RET=$?
            if [ $L_RET -ne 0 ];then
                OS_echo "run ${L_HP_FILE} script start failed"
                return ${G_OS_USR_HP_RESULT_SCRIPT_FAIL}
            fi
        fi
        return $G_OS_USR_HP_RESULT_SUCC 
    fi
        
    if [ -d "${L_HP_LOCATION}" ];then
        OS_echo "${L_HP_LOCATION} is directory, load $L_HP_FILE failed."
        return 1
    fi

    ##新增文件需要new 标识位
    if [ ! -e "${L_HP_LOCATION}"  -a "$L_HP_NEW_FLAG" != "new" ];then
        OS_echo "${L_HP_LOCATION} is not exist, load $L_HP_FILE failed. please user new flag to add a file"
        return 1
    fi

    if [ "${L_HP_SCRIPT}" != "0" -a -n "${L_HP_SCRIPT}" ];then
        OS_HP_SCRIPT "${L_HP_SCRIPT}" "start" "${L_UPG_DIR}"
        L_RET=$?
        if [ $L_RET -ne 0 ];then
            #由于实际上补丁文件还没有替换，因此补丁流程针对该补丁不做回滚操作，需要由用户在start参数中进行异常处理
            #后面只要start执行成功了，都需要调用回滚脚本
            OS_echo "run ${L_HP_FILE} script start failed"
            return ${G_OS_USR_HP_RESULT_SCRIPT_FAIL}
        fi
    fi
    
    #/OSM/bin的文件备份到系统盘
    local bNeedNewDir=`echo ${L_HP_LOCATION} | grep "/OSM/bin/"`
    if [ -z "$bNeedNewDir" ] || [ ! -d "${G_HOT_PATCH_BACKUP_DIR}" ];then 
        if [ ! -e "${L_HP_LOCATION}_${G_OS_USR_HP_BAK_FIELD}" -a "${L_HP_NEW_FLAG}" != "new" ];then
            #第一次安装,为删除时做准备
            cp -af "${L_HP_LOCATION}" "${L_HP_LOCATION}_${G_OS_USR_HP_BAK_FIELD}"
            L_RET=$?
            if [ ${L_RET} -ne 0 ];then
                OS_echo "back up ${L_HP_LOCATION} to ${L_HP_LOCATION}_${G_OS_USR_HP_BAK_FIELD} failed"
                return ${G_OS_USR_HP_RESULT_BAK_FAIL}
            fi
        fi
    else
        local file_name=${L_HP_LOCATION##*/}
        if [ ! -e "${G_HOT_PATCH_BACKUP_DIR}/${file_name}_${G_OS_USR_HP_BAK_FIELD}" -a "${L_HP_NEW_FLAG}" != "new" ];then
            #拷贝成临时文件再mv，防止拷贝过程中异常复位文件损坏
            rm -f "${G_HOT_PATCH_BACKUP_DIR}/${file_name}_temp"
            cp -af "${L_HP_LOCATION}" "${G_HOT_PATCH_BACKUP_DIR}/${file_name}_temp"
            L_RET=$?
            if [ ${L_RET} -ne 0 ];then
                OS_echo "cp ${L_HP_LOCATION} to ${G_HOT_PATCH_BACKUP_DIR}/${file_name}_temp failed"
                return ${G_OS_USR_HP_RESULT_BAK_FAIL}
            fi
            mv "${G_HOT_PATCH_BACKUP_DIR}/${file_name}_temp" "${G_HOT_PATCH_BACKUP_DIR}/${file_name}_${G_OS_USR_HP_BAK_FIELD}"
            L_RET=$?
            if [ ${L_RET} -ne 0 ];then
                OS_echo "mv ${G_HOT_PATCH_BACKUP_DIR}/${file_name}_temp to ${G_HOT_PATCH_BACKUP_DIR}/${file_name}_${G_OS_USR_HP_BAK_FIELD} failed"
                return ${G_OS_USR_HP_RESULT_BAK_FAIL}
            fi
        fi
    fi
    
    cp -af "${L_HP_LOAD_DIR_USR}/${L_HP_FILE}" "${L_HP_LOCATION}"
    L_RET=$?
    if [ ${L_RET} -ne 0 ];then
        OS_echo "copy ${L_HP_LOAD_DIR_USR}/${L_HP_FILE} to ${L_HP_LOCATION} failed"
        return ${G_OS_USR_HP_RESULT_LOAD_FAIL}
    fi  

    if [ "${L_HP_SCRIPT}" != "0" -a -n "${L_HP_SCRIPT}" ];then
        OS_HP_SCRIPT "${L_HP_SCRIPT}" "end" "${L_UPG_DIR}"
        L_RET=$?
        if [ $L_RET -ne 0 ];then
            OS_echo "run ${L_HP_FILE} script end  failed"
            return ${G_OS_USR_HP_RESULT_SCRIPT_FAIL}
        fi
    fi

    if [ $? -ne 0 ];then
        OS_echo "load usr hotpatch[${L_HP_FILE}] failed." 
        return ${G_OS_USR_HP_RESULT_KILL_FAIL}
    fi
    return $G_OS_USR_HP_RESULT_SUCC
}

# **************************************************************************** #
# Function Name: OS_HP_ROLLBACK_USR
# Description: 回退用户文件热补丁
# Parameter:  
# Retrun: 0表示回退成功,1表示回退失败
# **************************************************************************** #
OS_HP_ROLLBACK_USR()
{ 
    local L_LINE=$1
    local L_HP_RB_DIR=$2
    local L_HP_DEL_DIR=$3
    local L_HP_FILE=
    local L_HP_LOCATION=
    local L_RB_FILE=
    local L_RB_LOCATION=
    local L_RB_LINENUM=
    local L_RET=
    local L_HP_SCRIPT=
    local L_HP_NEW_FLAG=

    if [ -z "${L_LINE}" ];then
        OS_echo "patch item is null, no usr hotpatch to roll."
        return 0
    fi
    L_HP_SCRIPT=`echo "${L_LINE}" |awk '{print $3}'`
    L_HP_LOCATION=`echo "${L_LINE}" |awk '{print $2}'`
    L_HP_FILE=`echo "${L_LINE}" |awk '{print $1}'`
    L_HP_NEW_FLAG=`echo "${L_LINE}" |awk '{print $5}'`

    ##如果没有补丁文件，补丁不回退文件，只执行脚本。
    if [ "${L_HP_LOCATION}" == "script_only" -a "${L_HP_FILE}" == "script_only" ]; then
        if [ "${L_HP_SCRIPT}" != "0" -a -n "${L_HP_SCRIPT}" ];then
            OS_HP_SCRIPT "${L_HP_SCRIPT}" "rollstart" "${L_HP_DEL_DIR}"
            L_RET=$?
            if [ $L_RET -ne 0 ];then
                OS_echo "run ${L_HP_FILE} script start failed"
                return ${G_OS_USR_HP_RESULT_SCRIPT_FAIL}
            fi
        fi
        return 0 
    fi

    if [ "${L_HP_SCRIPT}" != "0" -a -n "${L_HP_SCRIPT}" ];then
        OS_HP_SCRIPT "${L_HP_SCRIPT}" "rollstart" "${L_HP_DEL_DIR}"
        L_RET=$?
        if [ $L_RET -ne 0 ];then
            OS_echo "run ${L_HP_FILE} script rollstart failed"
        fi
    fi

    if [ -n "${L_HP_RB_DIR}" ];then
        L_RB_LINENUM=`cat ${L_HP_RB_DIR}/${G_OS_HP_CONF} 2>/dev/kmsg| wc -l`
        while [ $L_RB_LINENUM -ge 1 ]
        do
            L_RB_LOCATION="`sed -n ${L_RB_LINENUM}p ${L_HP_RB_DIR}/${G_OS_HP_CONF} |awk '{print $3}'`"    
            if [ "$L_RB_LOCATION" = "$L_HP_LOCATION" ];then
                L_RB_FILE="`sed -n ${L_RB_LINENUM}p ${L_HP_RB_DIR}/${G_OS_HP_CONF} |awk '{print $2}'`"
                break
            fi
            L_RB_LINENUM=$((L_RB_LINENUM - 1))            
        done
    fi
    
    local bNeedNewDir=`echo ${L_HP_LOCATION} | grep "/OSM/bin/"`
    local file_name=""
    if [ -n "$bNeedNewDir" ];then
        file_name=${L_HP_LOCATION##*/}
    fi
    if [ -n "$L_RB_FILE" ] && [ -f "${L_HP_RB_DIR}"/"${L_RB_FILE}" ];then
        cp -af "${L_HP_RB_DIR}"/"${L_RB_FILE}" "${L_HP_LOCATION}" 
        if [ $? -ne 0 ];then
            OS_echo "copy ${L_HP_RB_DIR}/${L_RB_FILE} to ${L_HP_LOCATION} faild, roll usr hotpatch(${L_HP_FILE}) failed"
            return 1             
        fi
        
    elif [ -n "$bNeedNewDir" ] && [ -f "${G_HOT_PATCH_BACKUP_DIR}/${file_name}_${G_OS_USR_HP_BAK_FIELD}" ];then
        mv "${G_HOT_PATCH_BACKUP_DIR}/${file_name}_${G_OS_USR_HP_BAK_FIELD}" "${L_HP_LOCATION}" 
        if [ $? -ne 0 ];then
            OS_echo "move ${G_HOT_PATCH_BACKUP_DIR}/${file_name}_${G_OS_USR_HP_BAK_FIELD} to ${L_HP_LOCATION} faild, roll usr hotpatch(${L_HP_FILE}) failed"
            return 1    
        fi
        #删除内存中的备份文件
        rm -f "${L_HP_LOCATION}_${G_OS_USR_HP_BAK_FIELD}"
    elif [ -f "${L_HP_LOCATION}_${G_OS_USR_HP_BAK_FIELD}" ];then
        mv "${L_HP_LOCATION}_${G_OS_USR_HP_BAK_FIELD}" "${L_HP_LOCATION}" 
        if [ $? -ne 0 ];then
            OS_echo "move ${L_HP_LOCATION}_${G_OS_USR_HP_BAK_FIELD} to ${L_HP_LOCATION} faild, roll usr hotpatch(${L_HP_FILE}) failed"
            return 1    
        fi
    else
        #新增文件需要有new标签，所以非new标签的补丁，上述两个文件肯定有一个，如果没有就不正常,或者只回退失败一半的场景，所以只记录
        if [ "${L_HP_NEW_FLAG}" != "new" ]; then
            OS_echo "roll usr hotpatch(${L_HP_FILE}) failed, ${L_HP_LOCATION}_${G_OS_USR_HP_BAK_FIELD} maybe not exist"
        else
            rm "${L_HP_LOCATION}"
        fi
    fi
    
    if [ "${L_HP_SCRIPT}" != "0" -a -n "${L_HP_SCRIPT}" ];then
        OS_HP_SCRIPT "${L_HP_SCRIPT}" "rollend" "${L_HP_DEL_DIR}"
        L_RET=$?
        if [ $L_RET -ne 0 ];then
            OS_echo "run ${L_HP_FILE} script rollend failed"
        fi
    fi

    return 0
}


# **************************************************************************** #
# Function Name: OS_HP_ROLLBACK_KERNEL
# Description: 回退内核态热补丁
# Parameter:  参数1:回退的版本号
# Retrun: 0表示回退成功,1表示回退失败
# **************************************************************************** #
OS_HP_ROLLBACK_KERNEL()
{
    local L_LINE=$1
    local L_KID=
    local L_DEACTIVATE_RET=
    local L_REMOVE_RET=
    local L_RET=
    if [ -z "$L_LINE" ];then
        return 1
    fi
    OS_echo "begin to rollback kernel hotpatch[version:${L_HP_KER_VER}]."
    #内核态热补丁直接回退
        
    L_KID=${L_LINE#ksplice-}
    L_KID=${L_KID%.tar.gz}

    L_RET=`${G_HP_LOAD_EXE} "--query=""${L_KID}"`
    if [ -z "$L_RET" ];then
            OS_echo "kernel hotpatch[kid:${L_KID}] is rollback."
            return 0
    fi
    
    ${G_HP_LOAD_EXE} "--deactivate" "${L_KID}" &>/dev/kmsg
    L_DEACTIVATE_RET=$?
    if [ $L_DEACTIVATE_RET -ne 0 ] ;then
        OS_echo "deactivate kernel hotpatch[kid:${L_KID}] failed,ret:${L_DEACTIVATE_RET},deactivate again."
        sleep 0.5
        ${G_HP_LOAD_EXE} "--deactivate" "${L_KID}" &>/dev/kmsg
        L_DEACTIVATE_RET=$?
        if [ $L_DEACTIVATE_RET -ne 0 ] ;then
            OS_echo "deactivate kernel hotpatch[kid:${L_KID}] failed,ret:${L_DEACTIVATE_RET}."
            OS_echo "deactivate kernel hotpatch[kid:${L_KID}] failed, maybe already de-active, try to remove patch."
        fi
    fi    
    
    
    ${G_HP_LOAD_EXE} "--remove" "${L_KID}" &>/dev/kmsg
    L_REMOVE_RET=$?
    if [ $L_REMOVE_RET -ne 0 ] ;then
        #如果去激活成功，但是卸载失败，肯定是B类补丁（因为A类补丁如果去激活成功，卸载肯定能够成功，这个由livepatch保证），需要记录到$G_OS_HP_RB_FAIL_LIST
        if [ $L_DEACTIVATE_RET -eq 0 ];then
            echo "$L_LINE" >>$G_OS_HP_RB_FAIL_LIST
            OS_echo "remove kernel hotpatch[kid:${L_KID}] failed,ret:${L_REMOVE_RET},i will try again later."
            #先返回成功，稍后在上层再尝试回滚
            return 0
        else
            OS_echo "rollback kernel hotpatch[kid:${L_KID}] failed,ret:${L_REMOVE_RET},rollback again."
            ${G_HP_LOAD_EXE} "--remove" "${L_KID}" &>/dev/kmsg
            L_REMOVE_RET=$?
            if [ $L_REMOVE_RET -ne 0 ] ;then
                OS_echo "rollback kernel hotpatch[kid:${L_KID}] failed,ret:${L_REMOVE_RET}."
                return $L_REMOVE_RET
            fi
        fi
    fi
    OS_echo "rollback kernel hotpatch[kid:${L_KID}] success."
    return 0
}

# **************************************************************************** #
# Function Name: OS_HP_REMOVE_RETRY
# Description: 回退内核态热补丁。
# Parameter:  NA
# Retrun: 0表示清单中的补丁全部回退成功,1表示回退失败，2表示部分回退成功
# **************************************************************************** #
OS_HP_REMOVE_RETRY()
{
    local L_KID=
    local L_RET=
    local L_HP_RB_FAIL_LIST_TMP="/tmp/os_hp_rollback_fail_list_tmp"
    local L_RB_RET=1

    OS_echo "[OS_HP_REMOVE_RETRY]begin to remove kernel hotpatch."
    
    #先删除临时文件
    rm -rf $L_HP_RB_FAIL_LIST_TMP
    
    while read line
    do
        L_KID=${line#ksplice-}
        L_KID=${L_KID%.tar.gz}
        if [ ! -f "/sys/module/ksplice_${L_KID}/ksplice/stage" ];then
            OS_echo "[OS_HP_REMOVE_RETRY]kernel hotpatch[kid:${L_KID}] already removed."
            continue
        fi
        
        ${G_HP_LOAD_EXE} "--remove" "${L_KID}" &>/dev/kmsg
        L_RET=$?
        if [ $L_RET -ne 0 ] ;then
            echo "$line" >>$L_HP_RB_FAIL_LIST_TMP
        else
            OS_echo "[OS_HP_REMOVE_RETRY]remove kernel hotpatch[kid:${L_KID}] success."
            L_RB_RET=0
        fi
    done<$G_OS_HP_RB_FAIL_LIST
    
    #全部回退失败
    if [ $L_RB_RET -eq 1 ];then
        rm -rf $L_HP_RB_FAIL_LIST_TMP
        OS_echo "[OS_HP_REMOVE_RETRY]remove kernel hotpatch failed."
        return 1
    else
        #部分回退成功
        if [ -f $L_HP_RB_FAIL_LIST_TMP ];then
            mv -f $L_HP_RB_FAIL_LIST_TMP $G_OS_HP_RB_FAIL_LIST
            OS_echo "[OS_HP_REMOVE_RETRY]remove kernel hotpatch partially success."
            return 2
        else
            #所有补丁回退成功，删除补丁清单
            rm -rf $G_OS_HP_RB_FAIL_LIST
            OS_echo "[OS_HP_REMOVE_RETRY]remove kernel hotpatch success."
            return 0
        fi
    fi

}

# **************************************************************************** #
# Function Name: OS_HP_REMOVE_RETRY_REPEATEDLY
# Description: 读取回退失败的补丁清单$G_OS_HP_RB_FAIL_LIST，进行回滚重试。
# Parameter:  NA
# Retrun: 0表示补丁全部回退成功,1表示回退失败
# **************************************************************************** #
OS_HP_REMOVE_RETRY_REPEATEDLY()
{
    local L_RET=0
    local L_RETRY_TIMES=3
    
    if [ -f $G_OS_HP_RB_FAIL_LIST ];then
        OS_echo "[OS_HP_REMOVE_RETRY_REPEATEDLY]begin to retry remove hotpatch."
        for((i=1;i<=$L_RETRY_TIMES;i++))
        do
            if [ $i -eq 1 ];then
                OS_echo "[OS_HP_REMOVE_RETRY_REPEATEDLY]sleep 10s before retry."
                sleep 10
            else
                OS_echo "[OS_HP_REMOVE_RETRY_REPEATEDLY]sleep 5s before retry."
                sleep 5
            fi
            OS_echo "[OS_HP_REMOVE_RETRY_REPEATEDLY]begin to retry remove hotpatch, time $i."
            OS_HP_REMOVE_RETRY
            L_RET=$?
            if [ $L_RET -eq 0 ];then
                OS_echo "[OS_HP_REMOVE_RETRY_REPEATEDLY]remove hotpatch success."
                break;
            fi
            OS_echo "[OS_HP_REMOVE_RETRY_REPEATEDLY]remove hotpatch fail($L_RET), time $i."
        done
        rm -rf $G_OS_HP_RB_FAIL_LIST
    fi
    return $L_RET
}

# **************************************************************************** #
# Function Name: OS_HP_DO_ROLLBACK
# Description: 回退热补丁
# Parameter:  参数1:当前使用的热补丁文件配置信息
#                     参数2:需要回退的目录
#                     参数3:当前的补丁目录
# Retrun: 0表示回退成功,1表示回退失败
# **************************************************************************** #
OS_HP_DO_ROLLBACK()
{
    local L_HP_CUR_CONF=$1
    local L_HP_RB_DIR=$2
    local L_HP_CUR_DIR=$3
    local L_HP_LOCATION=
    local L_LINE=
    local L_RET=
    local L_ROLL_RET=0
    local L_HP_LINENUM=

    if [ ! -f ${L_HP_CUR_CONF} ];then
        OS_echo "${L_HP_CUR_CONF} is not exist, roll usr hotpatch failed."
        return 1
    fi
    
    #先删除记录回滚失败补丁的清单文件
    rm -rf $G_OS_HP_RB_FAIL_LIST
    
    #用户态热补丁根据情况加载情况来回退
    L_HP_LINENUM=`cat ${L_HP_CUR_CONF} 2>/dev/kmsg| wc -l`
    while [ $L_HP_LINENUM -ge 1 ]
    do                
        L_LINE="`sed -n ${L_HP_LINENUM}p ${L_HP_CUR_CONF}`"
        L_HP_LINENUM=$((L_HP_LINENUM - 1))

        if [ -z "${L_LINE}" ];then
            continue
        fi
    
        L_HP_LOCATION=`echo "${L_LINE}" |awk '{print $2}'`
        if [ -n "${L_HP_LOCATION}" ] && [ "${L_HP_LOCATION}" != "upgrade" ];then    
            OS_HP_ROLLBACK_USR "${L_LINE}" "${L_HP_RB_DIR}" "${L_HP_CUR_DIR}" &>/dev/kmsg
            L_RET=$?
        else
            OS_HP_ROLLBACK_KERNEL "${L_LINE}" &>/dev/kmsg
            L_RET=$?            
        fi   
        if [ 0 -ne ${L_RET} ];then            
            OS_echo "rollback hotpatch[${L_LINE}] failed"
            L_ROLL_RET=1
        fi
    done

    #用户态补丁和A类补丁（需经过栈检测激活的补丁）都回滚成功时，检查B类补丁（不要栈检测激活的补丁）是否已回滚成功。
    #检查是否存在回滚失败的B类补丁，重试回滚，上层不感知。
    if [ ${L_ROLL_RET} -eq 0 ];then
        OS_HP_REMOVE_RETRY_REPEATEDLY
    fi
    rm -rf $G_OS_HP_RB_FAIL_LIST
    OS_echo "do rollback hotpatch complete[ret:${L_ROLL_RET}]."
    return $L_ROLL_RET 
}


# **************************************************************************** #
# Function Name: OS_HP_ROLLBACK
# Description: 回退热补丁
# Parameter:  L_CUR_DIR=link L_RB_DIR=bak
# Retrun: 0表示回退成功,1表示回退失败
# **************************************************************************** #
OS_HP_ROLLBACK()
{
    local L_CUR_DIR=$1
    local L_RB_DIR=$2
    local L_RET=
    local L_TEMP_VER=
    local L_CUR_VER=
    local L_CUR_LAST_HP_VER=
    local L_UNCONFIRMED_FLAG=0
    local L_HP_CONF=/tmp/l_hp_conf_$$

    #如果是紧急补丁，则回退到cur版本
    OS_CheckEHPFlag ${L_CUR_DIR}/${G_OS_HP_CONF}
    if [ $? -eq 0 ] ;then
        if [ -d ${G_OS_HP_DIR_CUR} ] ;then
            L_RB_DIR=${G_OS_HP_DIR_CUR}
        fi        
    fi    
    
    #系统中已运行的版本，可能为确认的版本号，所有有可能跟L_CUR_VER不一样#
    L_CUR_LAST_HP_VER=`OS_GetHPVer`
    if [ -z "${L_CUR_LAST_HP_VER}" ];then
        OS_echo "get last hotpatch version failed."
        return 1
    fi
    #获取当前已确认当前的版本 
    L_CUR_VER=`cat "${L_CUR_DIR}/${G_OS_HP_CONF}" 2>/dev/kmsg |grep "^Version" |awk '{print $2}'`
    if [ -z "${L_CUR_VER}" ];then
        OS_echo "get current hotpatch version failed, maybe it is the first time to rollback unconfirmed hotpatch."  
        L_UNCONFIRMED_FLAG=$G_OS_HP_RESULT_RB_UNCONFIRMED
    elif [ "${L_CUR_VER}" = "${L_CUR_LAST_HP_VER}" ];then
        OS_echo "rollback the current hotpatch[${L_CUR_VER}]."
    else        
        #只有当系统热补丁安装或激活但还未确认时才会出现以下场景,否则认为回退失败.
        L_TEMP_VER=`cat "${G_OS_HP_DIR_TEMP_CONF}" 2>/dev/kmsg |grep "^Version" |awk '{print $2}'`    
        if [ "${L_TEMP_VER}" = "${L_CUR_LAST_HP_VER}" ];then
            ##最新版本与tmp中一致，属于未确认版本
            L_UNCONFIRMED_FLAG=$G_OS_HP_RESULT_RB_UNCONFIRMED
        else
            #三个版本都不匹配，所以不能回退
            OS_echo "maybe there is error[last:${L_CUR_LAST_HP_VER}, current:${L_CUR_VER}, unconfirmed:${L_TEMP_VER}], do not rollback hotpatch."
            return 1
        fi 
    fi
    ##如果是未确认的补丁，则就回退到link上去
    if [ "$G_OS_HP_RESULT_RB_UNCONFIRMED" = "${L_UNCONFIRMED_FLAG}" ] ;then
        OS_echo "rollback the unconfirmed hotpatch[${L_CUR_LAST_HP_VER}]."
        L_RB_DIR=${L_CUR_DIR}
        L_CUR_DIR=$G_OS_HP_DIR_TEMP
    fi    

    OS_FilterPatch "${L_CUR_DIR}" "${L_RB_DIR}" "${L_HP_CONF}" 

    OS_HP_DO_ROLLBACK "${L_HP_CONF}" "${L_RB_DIR}" "${L_CUR_DIR}"
    L_RET=$?
    if [ 0 -ne $L_RET ];then
        OS_echo "rollback hotpatch failed."
        rm -rf ${L_HP_CONF}
        L_CUR_VER=`cat "${L_RB_DIR}/${G_OS_HP_CONF}" 2>/dev/kmsg |grep "^Version" |awk '{print $2}'`
        OS_SetHPVer  "$L_CUR_VER"
        if [ "$G_OS_HP_RESULT_RB_UNCONFIRMED" = "${L_UNCONFIRMED_FLAG}" ] ;then
        return $G_OS_HP_RESULT_RB_UNCONFIRMED_FAIL
    fi
        return $L_RET
    fi
    rm -rf ${L_HP_CONF}  
    
    L_CUR_VER=`cat "${L_RB_DIR}/${G_OS_HP_CONF}" 2>/dev/kmsg |grep "^Version" |awk '{print $2}'`
    OS_SetHPVer  "$L_CUR_VER"
    
    OS_echo "rollback hotpatch complete."
    return ${L_UNCONFIRMED_FLAG}
}

# **************************************************************************** #
# Function Name: OS_HP_ROLLBACK_NORMAL
# Description: 热补丁包回退
# Parameter:
# Retrun: 0表示成功,1表示失败
# **************************************************************************** #
OS_HP_ROLLBACK_NORMAL()
{
    local L_RET=
    local L_VER=
        
    #回退补丁
    OS_HP_ROLLBACK "${G_OS_HP_DIR_LINK}" "${G_OS_HP_DIR_BAK}"
    L_RET=$? 
    if [ 0 -eq ${L_RET} ];then  
        #正常场景下回滚成功需要修改热补丁文件链接
        OS_HP_CHANGE_DIR "rollback"
        L_RET=$?
        if [ 0 -ne ${L_RET} ];then
            OS_echo "change hotpatch link failed when rollback in normal."
        fi
    elif [ ${G_OS_HP_RESULT_RB_UNCONFIRMED} -eq ${L_RET} ];then
        #回滚未确认的热补丁不需要修改补丁链接文件,只删除temp目录
        L_RET=0
        L_VER=`cat ${G_OS_HP_DIR_TEMP_CONF} 2>/dev/kmsg |grep "^Version"`
        rm -rf ${G_OS_HP_DIR_TEMP}

        OS_echo "delete ${G_OS_HP_DIR_TEMP} when rollback unconfirmed hotpatch[${L_VER}]."
        OS_echo "rollback the unconfirmed hotpatch succeed."
    elif [ ${G_OS_HP_RESULT_RB_UNCONFIRMED_FAIL} -eq ${L_RET} ];then
        L_RET=1
        OS_echo "rollback the unconfirmed hotpatch fail."
    else
        #回滚热补丁失败
        L_RET=1
        OS_HP_CHANGE_DIR "rollback"
        OS_echo "rollback the hotpatch failed."
    fi
    
    OS_echo "rollback hotpatch ret[${L_RET}]."
    return ${L_RET} 
}

# **************************************************************************** #
# Function Name: OS_HP_DO_DEL
# Description: 删除热补丁
# Parameter:  无
# Retrun: 0表示成功,1表示失败
# **************************************************************************** #
OS_HP_DO_DEL()
{
    local L_HP_CUR_CONF=$1
    local L_HP_DEL_DIR=$2
    local L_HP_CONF_TEMP=/tmp/hp_conf_$$
    local L_HP_LOCATION=
    local L_HP_LINENUM=
    local L_LINE=
    local L_RET=0
    
    if [ ! -e "${L_HP_CUR_CONF}" ];then
    ##如果不存在patch.conf，就认为没有通过os_upgrade_hotpatch.sh 的补丁
        OS_echo "${L_HP_CUR_CONF} is not exist, no hotpatch to delete."
        return 0
    fi
    
    #先删除记录回滚失败补丁的清单文件
    rm -rf $G_OS_HP_RB_FAIL_LIST
    
    #获取升级版本的热补丁文件信息
    cat "${L_HP_CUR_CONF}" 2>/dev/kmsg |grep "^Item" |sed 's/^Item //g' > ${L_HP_CONF_TEMP}    

    #用户态热补丁根据情况加载情况来回退
    #while read L_LINE
    L_HP_LINENUM=`cat ${L_HP_CONF_TEMP} 2>/dev/kmsg| wc -l`
    while [ $L_HP_LINENUM -ge 1 ]    
    do
        L_LINE="`sed -n ${L_HP_LINENUM}p ${L_HP_CONF_TEMP}`"
        L_HP_LINENUM=$((L_HP_LINENUM - 1))
        
        L_HP_LOCATION=`echo "${L_LINE}" |awk '{print $2}'`
        if [ -z "${L_HP_LOCATION}" ] || [ "${L_HP_LOCATION}" = "upgrade" ];then
        ##删除，失败了也继续删除下个，这样避免
            OS_HP_ROLLBACK_KERNEL $L_LINE 
            if [ $? -ne 0 ];then
                L_RET=1
            fi
            
        else 
            #回退到空，即删除
            OS_HP_ROLLBACK_USR "$L_LINE" "" "$L_HP_DEL_DIR"
            if [ $? -ne 0 ];then
                L_RET=1
            fi
        fi
       
    done    

    rm -rf $L_HP_CONF_TEMP
     #用户态补丁和A类补丁（需经过栈检测激活的补丁）都回滚成功时，检查B类补丁（不要栈检测激活的补丁）是否已回滚成功。
    #检查是否存在回滚失败的B类补丁，重试回滚，上层不感知。
    if [ ${L_RET} -eq 0 ];then
        OS_HP_REMOVE_RETRY_REPEATEDLY
    fi   
    rm -rf $G_OS_HP_RB_FAIL_LIST
    return $L_RET 
}



# **************************************************************************** #
# Function Name: 
#   OS_HP_DEL_OTHER_KERNEL 不处理
# Description
#   #删除非正常加载的热补丁包，即通过livepatch直接加载。
# Parameter:
#   none 
# Retrun: 
# **************************************************************************** #
OS_HP_DEL_OTHER_KERNEL()
{
    local L_TEMP=
    local L_RET=0
    
    L_TEMP=`ls /sys/module/| grep ^ksplice_ | grep -v "new"$ | grep -v "old"$ 2>/dev/kmsg`
    if [ -n "${L_TEMP}" ];then
        return 0
    fi
    return 0 
}


# **************************************************************************** #
# Function Name: 
#   OS_HP_DEL_HOTPATCH
# Description
#   #删除所有热补丁包，但不删除补丁目录及文件。
# Parameter:
#   none     
# Retrun: 
#   G_OS_HP_RET_SUCC
#   G_OS_HP_RET_FUNC_IN_USE
# **************************************************************************** #
OS_HP_DEL_HOTPATCH()
{
    local L_DEL_DIR=$1
    local L_CUR_CONF=/tmp/cur_conf_$$
    local L_HP_LOCATION=
    local L_HP_FILE=
    local L_RET=
    local L_CUR_VER=
    local L_LAST_VER=`OS_GetHPVer`
    local L_RET1=0
    local L_RET2=0
    
    L_CUR_VER=`cat "${G_OS_HP_DIR_LINK_CONF}" 2>/dev/kmsg | grep ^Version | awk '{print $2}'`
    L_TEMP_VER=`cat "${G_OS_HP_DIR_TEMP_CONF}" 2>/dev/kmsg |grep "^Version" |awk '{print $2}'`
    if [ -n "${L_TEMP_VER}" ] && [ "${L_TEMP_VER}" = "${L_LAST_VER}" ] && [ "${L_LAST_VER}" != "${L_CUR_VER}" ];then
        L_DEL_DIR=${G_OS_HP_DIR_TEMP}
    fi

    OS_CheckEHPFlag ${L_DEL_DIR}/${G_OS_HP_CONF}
    if [ $? -eq 0 ];then
        
        OS_HP_DO_DEL ${L_DEL_DIR}/${G_OS_HP_CONF} ${L_DEL_DIR}
        L_RET1=$?
        if [ 0 -ne ${L_RET1} ];then
            OS_echo "delete hotpatch(${L_DEL_DIR}/${G_OS_HP_CONF}) failed."
        fi
        
        if [ -d $G_OS_HP_DIR_CUR ];then
            L_DEL_DIR=$G_OS_HP_DIR_CUR
        else 
            L_DEL_DIR=$G_OS_HP_DIR_BAK
        fi
    fi
    
    OS_HP_DO_DEL ${L_DEL_DIR}/${G_OS_HP_CONF} ${L_DEL_DIR}
    L_RET2=$?
    if [ 0 -ne ${L_RET2} ];then
        OS_echo "delete hotpatch(${L_DEL_DIR}/${G_OS_HP_CONF}) failed."
    fi

    if [ 0 -ne ${L_RET1} ];then
    return ${L_RET1}
    fi

    if [ 0 -ne ${L_RET2} ];then
    return ${L_RET2}
    fi
    
    #删除非os_upgrade_hotpatch.sh的热补丁，这个需要删除吗？之前是会删除的
    OS_echo "delete all hotpatch complete."     
    return 0
    
    
}

# **************************************************************************** #
# Function Name: 
#   OS_HP_DEL_FILE
# Description
#   删除补丁目录及文件。
# Parameter:
#   none 
# Retrun: 
#   G_OS_HP_RET_SUCC
#   G_OS_HP_RET_FUNC_IN_USE
# **************************************************************************** #
OS_HP_DEL_FILE()
{
    rm -rf ${G_OS_HP_DIR}/*
    OS_echo "delete hotpatch files complete."
    return 0
}
# **************************************************************************** #
# Function Name: OS_REACT_BEF_DEL
# Description: 删除热补丁前恢复重启会生效的补丁操作
# Parameter:  无
# Retrun: 0表示成功,1表示失败
# **************************************************************************** #
OS_REACT_BEF_DEL()
{
    if [ ! -d "$G_HOT_PATCH_BOOT_DIR/react_dir" ] ; then
        OS_echo "no react_dir , no need recover the action before delete temp hotpatch directory."
        return 0
    fi	
    for script in `ls $G_HOT_PATCH_BOOT_DIR/react_dir/React_*.sh`
    do
        ${script}
        L_RET=$?
        if [ "0" != "${L_RET}" ];then
            OS_echo "${script} return ${L_RET}."
            return 1
        fi
    done
    return 0
}

# **************************************************************************** #
# Function Name: OS_HP_DEL_ALL
# Description: 删除热补丁
# Parameter:  无
# Retrun: 0表示成功,1表示失败
# **************************************************************************** #
OS_HP_DEL_ALL()
{
    local L_RET=
    
        
    ##顺序跟OS_HP_DEL_FILE换了下
    #删除所有热补丁
    OS_HP_DEL_HOTPATCH "${G_OS_HP_DIR_LINK}"
    L_RET=$?
     
    #删除链接和目录/OSM/coffer_bin/hotpatch/*

    OS_HP_DEL_FILE 
    return ${L_RET} 
}

# P12I-3095 modified2012-04-23 begin
# **************************************************************************** #
# Function Name: OS_HP_RESUME_CHECK
# Description: 重启后恢复热补丁前的检查
# Parameter:  无
# Retrun: 0表示成功,1表示失败,2表示热补丁安装目录不存在
# **************************************************************************** #
OS_HP_RESUME_CHECK()
{
    local L_RET=
    local L_HP_INSTALL_STAGE=$1
    local L_IS_RESUME_IN_UPGRADING=$2
    #hotpatch目录不存在,不需要恢复
    if [ ! -d "${G_OS_HP_DIR}" ] ;then
        OS_echo "there are no ${G_OS_HP_DIR} exist, do not resume hotpatch."
        #创建目录用于同步时拷贝
        mkdir $G_OS_HP_DIR
        return 2
    fi
    #校验temp目录
    if [ "${L_IS_RESUME_IN_UPGRADING}" == "true" ] && [ -d ${G_OS_HP_DIR_TEMP} ];then
        OS_HP_CHECK_MD5 "${G_OS_HP_DIR_TEMP}"
        L_RET=$?
        if [ ${G_OS_HP_RESULT_FAIL} -eq ${L_RET} ];then
            OS_echo "check hotpatch[${G_OS_HP_DIR_TEMP}] sha256 failed, do not resume hotpatch."
            return 1                
        fi
        OS_echo "check hotpatch[${G_OS_HP_DIR_TEMP}] sha256 complete." 
		return 0
    fi    
    
    #重启后，load将失效，因此删除load
    if [ -d "${G_OS_HP_DIR_TEMP}" ] ;then   
        #备份回退脚本到内存目录	
        mkdir $G_HOT_PATCH_BOOT_DIR/react_dir
        cp ${G_OS_HP_DIR_TEMP}/React_*.sh $G_HOT_PATCH_BOOT_DIR/react_dir
    fi
	
    #回退重启依然生效的操作，如固件补丁
    if [ "$L_HP_INSTALL_STAGE" == "second" ] ;then
        OS_REACT_BEF_DEL
        rm -rf $G_HOT_PATCH_BOOT_DIR/react_dir
    fi
    #重启后，usr_version 删除，根据加载重新生成
    if [ -f "${G_OS_HP_VER}" ] ;then
        rm -fr "$G_OS_HP_VER"
        OS_echo "delete ${G_OS_HP_VER} when resuming hotpatch."
    fi
    #若不存在link，不需要恢复
    if [ ! -L "$G_OS_HP_DIR_LINK" ] ;then
        OS_echo "there is no ${G_OS_HP_DIR_LINK} exist, do not resume hotpatch."
        return 2
    fi
# P12I-3095 modified2012-04-23 end

    #检查链接是否正常
    OS_HP_CHECK_LINK
    L_RET=$?
    if [ 0 -ne ${L_RET} ];then
        OS_echo "check link failed, do not resume hotpatch."
        return 1
    fi
    
    #校验bak目录
    if [ -d ${G_OS_HP_DIR_BAK} ];then
        OS_HP_CHECK_MD5 "${G_OS_HP_DIR_BAK}"
        L_RET=$?
        #首次安装bak目录中没有sha256文件,因此返回G_OS_HP_RESULT_FAIL才表示校验失败
        if [ ${G_OS_HP_RESULT_FAIL} -eq ${L_RET} ];then
            OS_echo "check hotpatch[${G_OS_HP_DIR_BAK}] sha256 failed, do not resume hotpatch."
            return 1
        fi
        OS_echo "check hotpatch[${G_OS_HP_DIR_BAK}] sha256 complete."        
    fi
        
    #校验cur目录
    if [ -d ${G_OS_HP_DIR_CUR} ];then
        OS_HP_CHECK_MD5 "${G_OS_HP_DIR_CUR}"
        L_RET=$?
        #当前的热补丁中肯定要有sha256校验文件,校验失败返回检查失败
        if [ 0 -ne ${L_RET} ];then
            OS_echo "check hotpatch[${G_OS_HP_DIR_CUR}] sha256 failed, do not resume hotpatch."
            return 1
        fi
        OS_echo "check hotpatch[${G_OS_HP_DIR_CUR}] sha256 complete."        
    fi

    #校验EMERGENCY目录
    if [ -d ${G_OS_HP_DIR_EMERGENCY} ];then
        OS_HP_CHECK_MD5 "${G_OS_HP_DIR_EMERGENCY}"
        L_RET=$?
        #当前的热补丁中肯定要有sha256校验文件,校验失败返回检查失败
        if [ 0 -ne ${L_RET} ];then
            OS_echo "check hotpatch[${G_OS_HP_DIR_EMERGENCY}] sha256 failed, do not resume hotpatch."
            return 1
        fi
        OS_echo "check hotpatch[${G_OS_HP_DIR_EMERGENCY}] sha256 complete."        
    fi
    
    #检查patch指向的补丁与当前系统是否匹配，不匹配不恢复，针对有补丁时去烧包或者升级场景
    if [ -f "${G_OS_HP_DIR_LINK_CONF}" ] ;then
        L_CUR_VER=`cat "${G_OS_HP_DIR_LINK_CONF}" | grep ^SysVersionSupported | awk '{print $2}'`
        L_SYS_VER=`grep -A 1 "\[SYS\]" /OSM/conf/versions.conf| tail -1| awk -F'=' '{print $2}'`
        if [ "${L_CUR_VER}" != "${L_SYS_VER}" ] ;then
            OS_echo "Resume hotpatch [${L_CUR_VER}] can not match with system version[${L_SYS_VER}]."
            return 2
        fi
    fi
    
    OS_echo "check hotpatch complete before resuming."
    return 0
}


# **************************************************************************** #
# Function Name: 
#   OS_HP_INSTALL
# Description
#   安装热补丁
# Parameter:待升级的热补丁包名
# Retrun: 0表示成功,1表示失败
# **************************************************************************** #
OS_HP_INSTALL()
{
    local L_UPG_DIR=$1
    local L_CUR_DIR=$2
    local L_HP_INSTALL_STAGE=$3
    local L_INSTALL_FLAG=$4
    local L_PATCH_CONF=$G_OS_HP_CONF
    local L_TEMP_HP_CONF=/tmp/temp_hp_conf_$$
    local L_HP_LOAD_SUCC_CONF=/tmp/temp_load_succ_conf_$$
    local L_HP_LINE=
    local L_HP_FILE_NAME=
    local L_HP_FILE_LOCATION=
    local L_HP_VER=
    local L_RET=1

    #当前系统(L_CUR_DIR)如果为紧急补丁，则报错，不打(这部分-w检查的时候也会检查)#
    if [ -n "${L_CUR_DIR}" ];then
        OS_CheckEHPFlag ${L_CUR_DIR}/${L_PATCH_CONF}
        if [ $? -eq 0 ];then
            OS_echo "the current hotpatch is emergency hotpatch, please rollback to install."
            return 1
        fi
    fi
    #先获取当前安装的版本号是为了安装内核态热补丁
    L_HP_VER=`cat ${L_UPG_DIR}/${L_PATCH_CONF} |grep "^Version" |awk '{print $2}'`
    
    #过滤出需要打patch的补丁，输入到L_TEMP_HP_CONF文件中，并会去掉Item字段#
    OS_FilterPatch "${L_UPG_DIR}" "${L_CUR_DIR}" "${L_TEMP_HP_CONF}" "${L_INSTALL_FLAG}"
    if [ $? -ne 0 ];then
        OS_echo "filter hotpatch failed."
        rm -rf ${L_TEMP_HP_CONF} 
        return 1
    fi    

    #如果生成的比较文件为空,
    if [ ! -s ${L_TEMP_HP_CONF} ];then
        OS_echo "there is no file to install hotpatch[version:${L_HP_VER}]."
        OS_echo "current hotpatch"
        cat ${L_CUR_DIR}/${L_PATCH_CONF} 2>/dev/kmsg |grep "^Version" >/dev/kmsg
        cat ${L_CUR_DIR}/${L_PATCH_CONF} 2>/dev/kmsg |grep "^Item" >/dev/kmsg
        OS_echo "upgrade hotpatch"
        cat ${L_UPG_DIR}/${L_PATCH_CONF} 2>/dev/kmsg |grep "^Version" >/dev/kmsg
        cat ${L_UPG_DIR}/${L_PATCH_CONF} 2>/dev/kmsg |grep "^Item" >/dev/kmsg
        OS_echo "install hotpatch[version:${L_HP_VER}] failed."
        #为空也要删除吧
        rm -rf ${L_TEMP_HP_CONF} 
        if [ "${L_INSTALL_FLAG}" == "upgrade" ] || [ "${L_INSTALL_FLAG}" == "upgrade_left" ];then
            OS_echo "Upgrade hotpatch in upgrading,return success when filter file is null."		
            return 0
        fi	
        OS_echo "Return fail in normal resume when filter file is null."		
        return 1
    fi
    
    rm -rf ${L_HP_LOAD_SUCC_CONF}
    echo "" > ${L_HP_LOAD_SUCC_CONF}
    #热补丁加载. 依次将热补丁配置文件中的所有热补丁文件加载, 加载失败则回退热补丁
    while read L_HP_LINE
    do   
        L_HP_FILE_NAME=`echo "${L_HP_LINE}" |awk '{print $1}'`
        L_HP_FILE_LOCATION=`echo "${L_HP_LINE}" |awk '{print $2}'`
        L_HP_COLD_FLAG=`echo "${L_HP_LINE}" |awk '{print $4}'`
        L_HP_NEW_FLAG=`echo "${L_HP_LINE}" |awk '{print $5}'`
        if [ -n "${L_HP_FILE_LOCATION}" ] && [ "${L_HP_FILE_LOCATION}" != "upgrade" ];then
            #如果是第一加载点恢复，不恢复非coldpatch标签的补丁。
            if [ "$L_HP_INSTALL_STAGE" == "first" -a "$L_HP_COLD_FLAG" != "coldpatch" ];then
                L_RET=0            
                continue
            fi
            #如果是第二加载点恢复，不恢复带coldpatch标签的补丁。
            if [ "$L_HP_INSTALL_STAGE" == "second" -a "$L_HP_COLD_FLAG" == "coldpatch" ];then
                L_RET=0            
                continue
            fi
            #用户态的热补丁在函数OS_UPG_HP_INSTALL_USR()中处理
            #加载并激活用户态热补丁
            OS_echo "Begin to load usr hotpatch : ${L_HP_LINE}" 
            OS_HP_LOAD_USR "${L_HP_LINE}" "${L_UPG_DIR}" &>/dev/kmsg
            L_RET=$?
            OS_echo "End to load usr hotpatch : ${L_HP_LINE}, result is ${L_RET}"
            if [ ${G_OS_USR_HP_RESULT_SUCC} -ne ${L_RET} ] && [ ${G_OS_USR_HP_RESULT_BAK_FAIL} -ne ${L_RET} ];then
                ##如果是在替换时，或者执行脚本时失败，也需要回退
                echo "${L_HP_LINE}" >> ${L_HP_LOAD_SUCC_CONF}
            fi            
        else
            #加载热补丁
            #如果是第一加载点恢复，不恢复内核模块补丁。
            if [ "$L_HP_INSTALL_STAGE" == "first" ];then
                L_RET=0            
                continue
            fi
            OS_echo "Begin to load kernel or module hotpatch : ${L_HP_FILE_NAME}"
            OS_HP_LOAD_KERNEL "${L_UPG_DIR}/${L_HP_FILE_NAME}" &>/dev/kmsg
            L_RET=$? 
            OS_echo "End to load kernel or module hotpatch : ${L_HP_FILE_NAME}, result is ${L_RET}"
        fi
        
        if [ 0 -ne ${L_RET} ];then
            OS_echo "load hotpatch failed[version:${L_HP_VER}, file:${L_HP_FILE_NAME}]."
            break
        else
            echo "${L_HP_LINE}" >> ${L_HP_LOAD_SUCC_CONF}
            OS_echo "load hotpatch succeed[version:${L_HP_VER}, file:${L_HP_FILE_NAME}]."
        fi    

    done < ${L_TEMP_HP_CONF}
    rm -rf ${L_TEMP_HP_CONF} 

    #加载失败则回退之前加载成功的热补丁,这里只回退内核态热补丁
    if [ 0 -ne ${L_RET} ];then
        OS_echo "load hotpatch failed[version:${L_HP_VER}], begin to rollback hotpatch."
        #回退之前加载成功的热补丁
        OS_HP_DO_ROLLBACK "${L_HP_LOAD_SUCC_CONF}" "${L_CUR_DIR}" "${L_UPG_DIR}" &>/dev/kmsg
        L_RET=$?
        rm -rf ${L_HP_LOAD_SUCC_CONF}
        OS_echo "end to rollback hotpatch[version:${L_HP_VER}, ret:${L_RET}] when loading failed."
        return 1
    fi
    OS_SetHPVer "$L_HP_VER"
    rm -rf ${L_HP_LOAD_SUCC_CONF}
    OS_echo "load and active hotpatch[version:${L_HP_VER}] succeed."

    return 0
}



# **************************************************************************** #
# Function Name: OS_HP_RESUME
# Description: 重启后恢复热补丁，链接文件前面做过检查，所以肯定是指向bak cur em之一
# Parameter:  无
# Retrun: 0表示成功,1表示失败
# **************************************************************************** #
OS_HP_RESUME()
{
    local L_LINK=
    local L_RET=
    local L_FILE_NUM=
    local L_HP_INSTALL_STAGE=$1
    local L_IS_RESUME_IN_UPGRADING=$2
    
    if [ "${L_IS_RESUME_IN_UPGRADING}" == "true" ] && [ -d ${G_OS_HP_DIR_TEMP} ];then
        #升级过程中进行补丁恢复
        OS_HP_INSTALL "${G_OS_HP_DIR_TEMP}" "" "${L_HP_INSTALL_STAGE}" "upgrade"
        L_RET=$?
        if [ 0 -ne ${L_RET} ];then
            OS_echo "resume hotpatch[${G_OS_HP_DIR_TEMP}] failed."                      
            return 1
        fi
        return 0
    fi  
    
    #若存在bak，先使bak生效   
    if [ -d "$G_OS_HP_DIR_BAK" ];then
        L_FILE_NUM=`ls ${G_OS_HP_DIR_BAK} |wc -l`
        #系统首次安装热补丁后,bak目录下只有patch.conf文件,该种场景下不用恢复
        if [ -f ${G_OS_HP_DIR_BAK}/${G_OS_HP_CONF} -a "1" = "${L_FILE_NUM}" ];then
            OS_echo "only ${G_OS_HP_CONF} is exist, do not resume hotpatch."
        else          
            OS_HP_INSTALL "${G_OS_HP_DIR_BAK}" "" "${L_HP_INSTALL_STAGE}" 
            L_RET=$?
            if [ 0 -ne ${L_RET} ];then
                OS_echo "resume hotpatch [$G_OS_HP_DIR_BAK] failed."
                return 1
            fi
        fi
        OS_echo "resume hotpatch [$G_OS_HP_DIR_BAK] complete."
    fi

    #若链接指向bak，返回
    cd "${G_OS_HP_DIR}"
    L_LINK=`ls -l | grep "${G_OS_HP_LINK}" | awk '{print $11}'`
    if [ "${L_LINK}" = "${G_OS_HP_BAK}" ];then
        OS_echo "patch link to ${L_LINK}, resume hotpatch complete."
        cd - &>/dev/null    
        return 0
    fi
    cd - &>/dev/null
    
    if [ -d "${G_OS_HP_DIR_CUR}" ];then
        #链接指向cur，使cur生效
        OS_HP_INSTALL "${G_OS_HP_DIR_CUR}" "${G_OS_HP_DIR_BAK}" "${L_HP_INSTALL_STAGE}" 
        L_RET=$?
        if [ 0 -ne ${L_RET} ];then
            OS_echo "resume hotpatch[${G_OS_HP_DIR_CUR}] failed."  
            return 1
        fi
    fi
    if [ "${L_LINK}" = "${G_OS_HP_CUR}" ] ;then
        OS_echo "patch link to ${L_LINK}, resume hotpatch complete."
        return 0
    fi    
    if [ -d "${G_OS_HP_DIR_EMERGENCY}" ];then
        #链接指向emergency，使emergency生效
        OS_HP_INSTALL "${G_OS_HP_DIR_EMERGENCY}" "" "${L_HP_INSTALL_STAGE}"
        L_RET=$?
        if [ 0 -ne ${L_RET} ];then
            OS_echo "resume hotpatch[${G_OS_HP_DIR_EMERGENCY}] failed."  
            return 1
        fi
    fi
    OS_echo "resume hotpatch[$G_OS_HP_DIR_CUR] complete."
    
    return 0
}

# P12I-3095 modified2012-04-23 begin
# **************************************************************************** #
# Function Name: OS_HP_RESUME_RUN
# Description: 启动重启后恢复热补丁
# Parameter:  无
# Retrun: 0表示成功,1表示失败,2表示热补丁安装目录缺失
# **************************************************************************** #
OS_HP_RESUME_RUN()
{
    local L_RET=
    local L_HP_INSTALL_STAGE=$1
    local L_IS_RESUME_IN_UPGRADING=$2  
    #恢复前检查
    OS_HP_RESUME_CHECK "${L_HP_INSTALL_STAGE}" "$L_IS_RESUME_IN_UPGRADING"
    L_RET=$?
    if [ 1 == ${L_RET} ] && [ "true" != "${L_IS_RESUME_IN_UPGRADING}" ];then    
        #恢复前检查失败,删除所有热补丁文件
        OS_HP_DEL_FILE
        L_RET=$?
        OS_echo "check hotpatch failed before resuming, delete hotpatch files[ret:${L_RET}]."
        return 1
    elif [ 2 == ${L_RET} ];then
        # /OSM/coffer_bin/hotpatch 目录不存在或/OSM/coffer_bin/hotpatch/patch
        # 软链接不存在，无法恢复热补丁
        return 2
    fi
# P12I-3095 modified2012-04-23 end   
    
    #恢复热补丁
    OS_HP_RESUME "${L_HP_INSTALL_STAGE}" "${L_IS_RESUME_IN_UPGRADING}"
    L_RET=$?
    if [ 0 -ne ${L_RET} ];then
        if [ "true" != "${L_IS_RESUME_IN_UPGRADING}" ];then    
            #恢复热补丁失败,删除所有热补丁
            OS_HP_DEL_ALL
        else
            #不删除补丁目录，支持升级暂停后重试
            OS_HP_DEL_HOTPATCH "${G_OS_HP_DIR_LINK}"
        fi
        L_RET=$?
        OS_echo "resume hotpatch failed, delete hotpatch[ret:${L_RET}]."
        return 1
    fi  

    OS_echo "resume all of hotpatch complete."
    return 0
}

# **************************************************************************** #
# Function Name: OS_HP_GET_VER_LOCAL
# Description: 获取本端热补丁包配置信息
# Parameter:
# Retrun: 0表示成功,1表示失败
# **************************************************************************** #
OS_HP_GET_VER_LOCAL()
{
    local L_INACTIVE_PKG=$1
    local L_TMP=
    local L_LINK=
    local L_CMOS_TIME=
    local L_VERSION= 
    local L_TEMP_FILE=/tmp/ver_$$
    #R2 P11G-4149 modified2012/02/14 begin
    local L_RET=
    #R2 P11G-4149 modified2012/02/14 begin
    
    if [ -f "$L_TEMP_FILE" ] ;then
        rm -f "$L_TEMP_FILE"
    fi
    L_TMP=`touch "$L_TEMP_FILE" 2>/dev/stdout`
    if [ "$?" != 0 ] ;then
        OS_echo "create hotpatch configure failed."
        return 1
    fi
    
    #没有G_OS_HP_DIR目录时直接获取当前系统版本系统
    if [ "`ls -A ${G_OS_HP_DIR} 2>/dev/null`" = "" -o ! -L ${G_OS_HP_DIR_LINK} ];then
        L_CMOS_TIME=`cat "/OSM/conf/versions.conf" | grep "CmosTime" | awk -F'=' '{print $2}'`
        L_VERSION=`grep -A 1 "\[SPCVER\]" /OSM/conf/versions.conf| tail -1| awk -F'=' '{print $2}'`
        
        #R2R5&R5C01 P12I-3843 modified2013/1/11 begin
        if [ -f "$G_HOTPATCH_STATUS" ] ;then
            L_VERSION="${L_VERSION%%SPC*}"
            rm -rf $G_HOTPATCH_STATUS
        fi
        #R2R5&R5C01 P12I-3843 modified2013/1/11 end
        
        echo "[RUNNING]" >> ${L_TEMP_FILE}
        echo "PVersion=${L_VERSION}" >> ${L_TEMP_FILE}
        echo "Version=" >> ${L_TEMP_FILE}
        echo "CreateTime=${L_CMOS_TIME}" >> ${L_TEMP_FILE}
    fi
    
    if [ -d "$G_OS_HP_DIR" ];then
        cd "$G_OS_HP_DIR"
        if [ -L ${G_OS_HP_LINK} ] ;then           
            #检查patch指向的补丁与当前系统是否匹配，不匹配则不显示版本，针对有补丁时去烧包或者升级场景
            if [ -f "${G_OS_HP_DIR_LINK_CONF}" ] ;then
                L_CUR_VER=`cat "${G_OS_HP_DIR_LINK_CONF}" | grep ^SysVersionSupported | awk '{print $2}'`
                L_SYS_VER=`grep -A 1 "\[SYS\]" /OSM/conf/versions.conf| tail -1| awk -F'=' '{print $2}'`
                if [ "${L_CUR_VER}" != "${L_SYS_VER}" ] ;then
                    OS_echo "Show hotpatch [${L_CUR_VER}] can not match with system version[${L_SYS_VER}]."
                    rm -f $G_OS_HP_VER_TEMP_CONF
                    return 0
                fi
            fi
            L_LINK=`ls -l "$G_OS_HP_LINK" | awk '{print $11}'`
            if [ "${L_LINK}" = "${G_OS_HP_EMERGENCY}" ] ;then
                
                #写[RUNNING]信息
                OS_HP_ECHO_VER_TO_CONF "[RUNNING]" "${G_OS_HP_EMERGENCY}" "${L_TEMP_FILE}"
                
                #写[ROLLBACK]信息
                diff ${G_OS_HP_DIR_CUR}/${G_OS_HP_CONF} ${G_OS_HP_DIR_BAK}/${G_OS_HP_CONF} >/dev/null 2>&1

                if [ -f ${G_OS_HP_DIR_CUR}/${G_OS_HP_CONF} ];then                    
                    OS_HP_ECHO_VER_TO_CONF "[ROLLBACK]" "$G_OS_HP_CUR" "${L_TEMP_FILE}"
                elif [ -f ${G_OS_HP_DIR_BAK}/${G_OS_HP_CONF} ];then
                    OS_HP_ECHO_VER_TO_CONF "[ROLLBACK]" "$G_OS_HP_DIR_BAK" "${L_TEMP_FILE}"
                else
                    #在tmp目录下，利用cur和系统启动时的cmos时间临时构造一个配置文件
                    cd /tmp
                    echo "Version" > "$G_OS_HP_CONF"
                    L_PRODUCT_VER=`cat "$G_OS_HP_DIR_LINK_CONF" | grep ^SysVersionBSupported`
                    echo "$L_PRODUCT_VER" >> "$G_OS_HP_CONF"
                    L_CMOS_TIME=`cat "/OSM/conf/versions.conf" | grep "CmosTime"| awk -F'=' '{print $2}' 2>/dev/null`
                    echo "CreateTime $L_CMOS_TIME" >> "$G_OS_HP_CONF"

                    OS_HP_ECHO_VER_TO_CONF "[ROLLBACK]" "." "${L_TEMP_FILE}"
                    rm -f "$G_OS_HP_CONF"
                    cd - &>/dev/null
                fi               
            elif [ "${L_LINK}" = "${G_OS_HP_CUR}" ] ;then
                
                #写[RUNNING]信息
                OS_HP_ECHO_VER_TO_CONF "[RUNNING]" "${G_OS_HP_CUR}" "${L_TEMP_FILE}"
                
                #写[ROLLBACK]信息
                diff ${G_OS_HP_DIR_CUR}/${G_OS_HP_CONF} ${G_OS_HP_DIR_BAK}/${G_OS_HP_CONF} >/dev/null 2>&1
                L_RET=$?
                if [ 0 -ne ${L_RET} ];then
                    #首次安装热补丁后,仍旧有bak目录,其中patch.conf与cur目录下还是不一致,去掉了后缀pat,所以当不一致时说明为多次安装
                    OS_HP_ECHO_VER_TO_CONF "[ROLLBACK]" "$G_OS_HP_BAK" "${L_TEMP_FILE}"
                else
                    #在tmp目录下，利用cur和系统启动时的cmos时间临时构造一个配置文件
                    cd /tmp
                    echo "Version" > "$G_OS_HP_CONF"
                    L_PRODUCT_VER=`cat "$G_OS_HP_DIR_LINK_CONF" | grep ^SysVersionBSupported`
                    echo "$L_PRODUCT_VER" >> "$G_OS_HP_CONF"
                    L_CMOS_TIME=`cat "/OSM/conf/versions.conf" | grep "CmosTime"| awk -F'=' '{print $2}' 2>/dev/null`
                    echo "CreateTime $L_CMOS_TIME" >> "$G_OS_HP_CONF"

                    OS_HP_ECHO_VER_TO_CONF "[ROLLBACK]" "." "${L_TEMP_FILE}"
                    rm -f "$G_OS_HP_CONF"
                    cd - &>/dev/null
                fi               
            else
                #只写[RUNNING]信息
                OS_HP_ECHO_VER_TO_CONF "[RUNNING]" "$G_OS_HP_BAK" "${L_TEMP_FILE}"
            fi        
        fi
        cd - &>/dev/null
    fi
    
    #写[INACTIVE]信息
    if [ -n "$L_INACTIVE_PKG" -a -f "$L_INACTIVE_PKG" ] ;then
        cd /tmp
        L_TEMP=`tar -xzvf "$L_INACTIVE_PKG" "$G_OS_HP_CONF" 2>/dev/stdout 1>/dev/null`
        #R2 P11G-4149 modified2012/02/14 begin
        L_RET=$?
        if [ 0 -ne ${L_RET} ];then
            OS_echo "tar hotpatch $L_INACTIVE_PKG to /tmp failed[${L_RET}]."
            OS_echo "tar hotpatch failreason: ${L_TEMP}."
        #R2 P11G-4149 modified2012/02/14 end

    #uniform P11A-7304 modified2012/05/29 begin
        #R1 P11A-7211 modified2012/05/18 begin
        OS_HP_ECHO_VER_TO_CONF "[INVALID]" "." "${L_TEMP_FILE}"
        #R1 P11A-7211 modified2012/05/18 end
    #uniform P11A-7304 modified2012/05/29 end
        else
            OS_HP_ECHO_VER_TO_CONF "[INACTIVE]" "." "${L_TEMP_FILE}"
        fi
        rm -rf "$G_OS_HP_CONF" &>/dev/kmsg
        cd - &>/dev/null
    fi
    
    cat ${L_TEMP_FILE} > ${G_OS_HP_VER_TEMP_CONF}
    rm -rf ${L_TEMP_FILE}
    return 0
}

# **************************************************************************** #
# Function Name: OS_HP_GET_VER_PEER_TO_LOCAL
# Description: 从对端获取本端热补丁包配置信息
# Parameter:
# Retrun: 0表示成功,1表示失败
# **************************************************************************** #
OS_HP_GET_VER_PEER_TO_LOCAL()
{
    local L_RET=
    
    OS_HP_GET_VER_LOCAL
    L_RET=$?
    if [ 0 -eq ${L_RET} ];then
        echo "expect_success"
        OS_echo "create local hotpatch conf from peer succeed."
    else
        echo "expect_failed"
        OS_echo "create local hotpatch conf from peer failed."
    fi
    return ${L_RET}
}

OS_HP_GET_SSHD_PORT()
{
L_DEFAULT_PORT=22
L_PORT=""
L_SSH_CFG="/etc/ssh/sshd_config"

L_PORT=`cat $L_SSH_CFG | grep -w "Port" | grep -v "#" |awk '{print $2}'`
if [ -z "$L_PORT" ]; then
        L_PORT=$L_DEFAULT_PORT
fi


echo "$L_PORT"
}

# **************************************************************************** #
# Function Name: OS_HP_GET_VER_ALL
# Description: 获取双端热补丁包配置信息
# Parameter:
# Retrun: 0表示成功,1表示失败
# **************************************************************************** #
OS_HP_GET_VER_ALL()
{
    local L_EXPECT_SCRIPT="/OSM/script/os_hotpatch_peer_exec.sh"
    local L_DEST_IP=
    local L_CMD=
    local L_EXPECT_TIME_OUT=
    local L_TEMP_CONF_NAME=${G_OS_HP_VER_TEMP_CONF##*/}
    local L_TMP_DIR=/tmp/peer_hotpatch_$$
    local L_RET=
    local L_PORT=`OS_HP_GET_SSHD_PORT`
    
    #本端获取
    OS_HP_GET_VER_LOCAL
    L_RET=$?
    if [ 0 -ne ${L_RET} ];then
        OS_echo "get local hotpatch conf file failed."
        return 1
    fi
    OS_echo "get local hotpatch conf file succeed."
    
    #对端获取
    L_DEST_IP=`OS_GetRemoteIBCIP`
    OS_IsLinkOk "${L_DEST_IP}"
    L_RET=$?
    if [ 0 -eq ${L_RET} ];then
        L_CMD="sudo /OSM/script/os_upgrade_hotpatch.sh -v peertolocal"
        L_EXPECT_TIME_OUT=3
        $L_EXPECT_SCRIPT ${L_DEST_IP} "${L_CMD}"  ${L_PORT} ${L_EXPECT_TIME_OUT}
        L_RET=$?
        if [ 0 -ne ${L_RET} ];then
            OS_echo "create peer hotpatch[${L_TEMP_CONF_NAME}] failed."
            return 1
        fi
        mkdir -p ${L_TMP_DIR}
        lftp -c "lftp -u ibc_os_hs, sftp://${L_DEST_IP}:${L_PORT};set net:reconnect-interval-base 3;set net:max-retries 2;set net:timeout 2s;set xfer:clobber on;get ${G_OS_HP_VER_TEMP_CONF} -o ${L_TMP_DIR};bye"
        L_RET=$?
        if [ 0 -ne ${L_RET} ];then
            OS_echo "get peer hotpatch[${L_TEMP_CONF_NAME}] failed."
            rm -rf ${L_TMP_DIR}
            return 1
        fi
        
        mv ${L_TMP_DIR}/${L_TEMP_CONF_NAME} ${G_OS_HP_VER_TEMP_PEER_CONF}
        rm -rf ${L_TMP_DIR}
        OS_echo "get peer hotpatch conf file succeed."
    else
        L_RET=1
        OS_echo "peer is not link, get peer hotpatch conf failed."
    fi
    
    OS_echo "get all of hotpatch conf files succeed."
    return 0
}

# **************************************************************************** #
# Function Name: OS_HP_CHECK_CPU
# Description: 检查当前系统是否繁忙
# Parameter:
# Retrun: 0表示成功,1表示失败
# **************************************************************************** #
OS_HP_CHECK_CPU()
{
    local L_CUR_CPU_USING=
    local L_TEMP=
    local L_RET=

    OS_echo "begin to check the cpu using when upgrading hotpatch."
    #检查2s内的cpu利用率
    L_TEMP=`os_getcpuusage 2000`
    L_RET=$?
    if [ 0 -ne ${L_RET} ];then
        OS_echo "get cpu using failed[${L_TEMP}, ret[${L_RET}]] when upgrading hotpatch."
        return 1
    fi
    
    #取出cpu利用率
    #R2 P11A-6596 modified2012/02/29 begin
    #添加引号防止解析异常
    L_CUR_CPU_USING=`echo "${L_TEMP}" |awk '{print $3}'| sed 's/\[//'|sed 's/]//'`
    #R2 P11A-6596 modified2012/02/29 end
    if [ ${G_MIN_CPU_USING} -lt ${L_CUR_CPU_USING} ];then
        OS_echo "check cpu using failed[cur:${L_CUR_CPU_USING}, limit:${G_MIN_CPU_USING}] when upgrading hotpatch."
        return 1    
    fi

    OS_echo "check cpu using complete[cur:${L_CUR_CPU_USING}, limit:${G_MIN_CPU_USING}] when upgrading hotpatch."
    return 0
}

# **************************************************************************** #
# Function Name: OS_HP_CHECK_PKG_FILE
# Description: 检查升级的热补丁包是否包含当前正在运行的热补丁文件
# Parameter:
# Retrun: 0表示成功,1表示未正确收编,2表示重复安装
# **************************************************************************** #
OS_HP_CHECK_PKG_FILE()
{
    local L_CUR_RUNNING_LINK=${G_OS_HP_DIR_LINK}
    local L_UPG_DIR=${G_OS_HP_DIR_TEMP}
    local L_CUR_FILE=/tmp/cur_file_$$
    local L_UPG_FILE=/tmp/upg_file_$$
    local L_RET1=
    local L_RET2=
    
    #当前没有安装过热补丁,不需要比较,直接返回
    if [ ! -L "${L_CUR_RUNNING_LINK}" ];then
        OS_echo "hotpatch ${L_CUR_RUNNING_LINK} is not exist, check file complete."
        return 0
    fi
    
    #检查需要升级的补丁包是否包含当前运行的补丁文件
    cat ${L_CUR_RUNNING_LINK}/${G_OS_HP_CONF} 2>/dev/kmsg |grep "^Item" > ${L_CUR_FILE}
    cat ${L_UPG_DIR}/${G_OS_HP_CONF} 2>/dev/kmsg |grep "^Item" > ${L_UPG_FILE} 
    #cur has patches upgrade not have
    L_RET1=`diff ${L_CUR_FILE} ${L_UPG_FILE} |grep "<"`
    #upgrade has patches cur not have
    L_RET2=`diff ${L_CUR_FILE} ${L_UPG_FILE} |grep ">"`
    
    rm -rf ${L_CUR_FILE} ${L_UPG_FILE}
    
    if [ -n "${L_RET1}" -a -n "${L_RET2}" ];then
        OS_echo "upgrade hotpatch package do not include the current hotpatch file[cur:${L_RET}]."
        return 1
    elif [ -z "${L_RET2}" ];then
    OS_echo "patches in upgrade hotpatch already installed"
    return 2
    else
    OS_echo "upgrade hotpatch package include the current hotpatch file."
    return 0
    fi
    
    
}


# **************************************************************************** #
# Function Name: OS_HP_CHECK_PKG_FILE
# Description: 检查升级的用户补丁热补丁在运行的系统中是否存在，不支持新增，替换目录
# Parameter:
# Retrun: 0表示成功,1表示失败
# **************************************************************************** #
OS_HP_CHECK_PKG_USR_FILE()
{
    local L_UPG_CONF=$1
    local L_UPG_FILE=/tmp/upg_usrfile_$$
    local L_HP_FILE_LOCATION=
    local L_HP_FILE_NEW_FLAG=

    #当前没有安装过热补丁,不需要比较,直接返回
    if [ ! -f "${L_UPG_CONF}" ];then
        OS_echo "${L_UPG_CONF} is not exist, check usr file failed."
        return 1
    fi
    
    cat ${L_UPG_CONF} 2>/dev/kmsg |grep "^Item" > ${L_UPG_FILE} 
    
    while read L_HP_LINE
    do   
        L_HP_FILE_LOCATION=`echo "${L_HP_LINE}" |awk '{print $3}'`
        L_HP_FILE_NEW_FLAG=`echo "${L_HP_LINE}" |awk '{print $6}'`
        if [ -z "${L_HP_FILE_LOCATION}" ];then
            #用户态的热补丁在函数OS_UPG_HP_INSTALL_USR()中处理
            continue
        fi
        # L_HP_FILE_LOCATION 为"script_only"说明该补丁不替换文件，只执行脚本。
        if [ "${L_HP_FILE_LOCATION}" != "script_only" ]; then
            # L_HP_FILE_NEW_FLAG 为new说明该补丁新增文件。
            if [ "${L_HP_FILE_NEW_FLAG}" != "new" ];then
                if [ ! -e "${L_HP_FILE_LOCATION}" ] || [ -d "${L_HP_FILE_LOCATION}" ];then
                    OS_echo "${L_HP_FILE_LOCATION} is a directory or not exist, check usr file failed."
                    rm -rf ${L_UPG_FILE}
                    return 1
                fi
            fi
        fi
    done < ${L_UPG_FILE}
    rm -rf ${L_UPG_FILE} 
    
    OS_echo "check usr file succeed."
    return 0
    
}
# **************************************************************************** #
# Function Name: OS_CheckOrDelCurHotpatch
# Description: 补丁安装前先删除最老的补丁目录 patch_bak
# Parameter:
# Return:
# **************************************************************************** #
OS_DelCurHotpatch()
{   
    local L_CUR_VER=""
    local L_SYS_VER=""
    
    #若不存在link，删除hotpatch目录下所有的东西
    if [ ! -L "$G_OS_HP_DIR_LINK" ] ;then
        rm -fr $G_OS_HP_DIR/*
        OS_echo "rm hotpatch directory:${G_OS_HP_DIR}."
        return 0
    else
        if [ -f "${G_OS_HP_DIR_LINK_CONF}" ] ;then
            #若补丁目录下的补丁和当前系统不匹配，删除hotpatch目录下所有的东西
            L_CUR_VER=`cat "${G_OS_HP_DIR_LINK_CONF}" | grep ^SysVersionSupported | awk '{print $2}'`
            L_SYS_VER=`grep -A 1 "\[SYS\]" /OSM/conf/versions.conf| tail -1| awk -F'=' '{print $2}'`
            if [ "${L_CUR_VER}" != "${L_SYS_VER}" ] ;then
                OS_echo "Check hotpatch [${L_CUR_VER}] can not match with system version[${L_SYS_VER}]."
                rm -fr $G_OS_HP_DIR/*
                return 0
            fi
        fi
    fi
    
    
    #如果安装前存在临时补丁目录，先删除
    if [ -d "${G_OS_HP_DIR_TEMP}" ] ;then
        rm -fr "$G_OS_HP_DIR_TEMP"
        OS_echo "delete ${G_OS_HP_DIR_TEMP} when check hotpatch."
    fi
    
    #补丁安装前先删除最老的补丁目录 patch_bak，释放空间用于解压新的补丁。
    #执行补丁回滚后只保留了patch_bak（链接也指向这个），此时不能删除
    if [ -d "${G_OS_HP_DIR_BAK}" ];then
        local L_LINK=`ls -l "${G_OS_HP_DIR_LINK}" | awk '{print $11}'`
        if [ "${L_LINK}" == "${G_OS_HP_BAK}" ];then
            OS_echo "${G_OS_HP_DIR_LINK} has already link to ${G_OS_HP_BAK}, do not del."
            return 0
        fi
        rm -fr "${G_OS_HP_DIR_BAK}"
        OS_echo "rm hotpatch directory:${G_OS_HP_DIR_BAK}."
    fi
    
    return 0
}
