#!/bin/bash

# ********************************************** ***************************** #
# File Name: os_load_select_ver.sh
# Description: slecet the os version beyond loading
# Input:
# Output:0:正常退出1:出错退出2:不需要版本回退
# Author:
# Created: 2009-02-12
# Function List：
# History
# 1.Date:
#   Author:
#   Modification:
# **************************************************************************** #

# Trap signals during script excute.
if [ -f /OSM/script/os_trap_action.sh ];then
    source /OSM/script/os_trap_action.sh
fi
#包含头脚本
source /OSM/conf/initrd.conf
source /OSM/script/os_load_base.sh
# --------------------------  variables  ------------------------------------- #
#变量定义
G_SERIOU_RESET=0
RESET_INFO_DB_NAME="/startup_disk/conf/conf_local/reset_record.db"
RESET_INFO_TABLE_NAME="rbtbl"
SERIOUS_RESET_TYPE=("watchDog_reset" \
"oops_reset" \
"unknown_reset" \
"software_unknown_reset" \
"oom_reset" \
"panic_reset" \
"kernel_reset" \
"mce_reset" \
"bspwatchdog_reset" \
"ecc_reset" \
"power_lost_reset" \
"clock_fail_reset" \
"s3soft_reset" \
"s3wdg_reset" \
"failure_recovery_reset")
# --------------------------  functions  ----------------------- ------------- #

# **************************************************************************** #
# Function Name: OS_SERIOUS_RESET_TIMES
# Description: 获取严重复位的次数，只以当前时间为基准，如果用户修改了硬件时间
#              也已当前时间为基准
# Parameter: none
# Return: 0-succ 1-fail
# **************************************************************************** #
function OS_SERIOUS_RESET_TIMES()
{
    local max_reset_sec=$G_MAX_SYS_RESET_TIME
    local cur_time=`date "+%Y-%m-%d %H:%M:%S"`
    local timeBefore=`date "+%Y-%m-%d %H:%M:%S" -d "-${max_reset_sec}min"`
    # 需要判断记录复位的时间小于当前时间，可能存在修改系统时间的场景
    G_SERIOU_RESET=`sqlite3 $RESET_INFO_DB_NAME "select count(*) from $RESET_INFO_TABLE_NAME where datetime(resetTime)>datetime('$timeBefore') and datetime(resetTime)<datetime('$cur_time')"` 
    if [ $? != 0 ];then
        OS_echo "[os_load_select_ver.sh] query data in db failed ($G_SERIOU_RESET)."
        return 1
    fi
    OS_echo "G_SERIOU_RESET=$G_SERIOU_RESET"
    return 0
}

# **************************************************************************** #
# Function Name: OS_RelinkBoot
# Description: relink the boot link
# Parameter: 1-link to dir
# Return:
# **************************************************************************** #
function OS_RelinkBoot()
{
    #从L_BOOT_LOCAL 启动
    L_BOOT_LOCAL=$1
    mount -o remount,rw,async $G_DISK_MOUNT_IMAGE
    cd $G_DISK_MOUNT_IMAGE

    rm -rf boot
    ln -s $L_BOOT_LOCAL boot
    cd /
    mount -o remount,ro,sync $G_DISK_MOUNT_IMAGE
    sync
    return 0
}
# **************************************************************************** #
# Function Name: OS_RollBack
# Description: rollback the link
# Parameter: 1-link to dir
# Return:
# **************************************************************************** #
function OS_RollBack()
{
    rm -rf /startup_disk/conf/conf_local/reset_record.db  &>/dev/null
                
    local cur_ver=`cat /OSM/conf/versions.conf | grep -m 1 Version | awk -F"=" '{print $2}'`
    local bak_ver=`cat /startup_disk/image/boot_osp_bak/versions.conf | grep -m 1 Version | awk -F"=" '{print $2}'`
    
    if [ "$cur_ver" == "$bak_ver" ];then
        OS_RelinkBoot boot_osp_bak
    else
        OS_RelinkBoot boot_osp
    fi    
    
    reboot -f
}
function check_is_right_rescue()
{
    #获取30分钟内严重复位次数
    G_MAX_RESET_TIMES_30=3
    G_MAX_SYS_RESET_TIME=30 #minitus
    OS_SERIOUS_RESET_TIMES    
    if [ $? -eq 1 ] ; then
        OS_echo "[os_load_select_ver.sh] cant not get OS_SERIOUS_RESET_TIMES."
        return 1
    fi
    #记录30分钟内复位次数
    reset_30=$G_SERIOU_RESET
    
    ##获取10小时的严重复位次数
    G_MAX_RESET_TIMES_600=10
    G_MAX_SYS_RESET_TIME=600  #minitus
    OS_SERIOUS_RESET_TIMES
    if [ $? -eq 1 ] ; then
        OS_echo "[os_load_select_ver.sh] cant not get OS_SERIOUS_RESET_TIMES."
        return 1
    fi
    #记录10小时内复位次数
    reset_600=$G_SERIOU_RESET
    

    #半小时内小于3次且10小时内10次，则为误判
    if [ "$reset_30" -lt "$G_MAX_RESET_TIMES_30" ] && [ "$reset_600" -lt "$G_MAX_RESET_TIMES_600" ]; then
        OS_echo "[os_load_select_ver.sh] it is wrong enter resuce."
        #回退到normal，并重启
        OS_RollBack
        return 0
    fi
    
    return 1
}
# **************************************************************************** #
# Function Name: whether_need_check
# Description: 是否需要做检查
# Parameter: 
# Return:
# **************************************************************************** #
function whether_need_check()
{
    if [ ! -f "$RESET_INFO_DB_NAME" ]; then
        OS_echo "[os_load_select_ver.sh]db file not exists, no need check"
        return 1 
    fi
    
    #os_load_select_ver.sh和补丁恢复是并发的，当前日志看到这个小补丁调用和os_load_select_ver.sh相隔5S左右
    #如果为boot_rescue，则需要判断是否是误判导致进入的小系统
    L_TMP=`ls -l $G_DISK_MOUNT_IMAGE | grep -a "boot ->" |awk '{print $11}'`
    if [ "$L_TMP" == "boot_rescue" ] ; then
        OS_echo "[os_load_select_ver.sh]link is boot_rescue, need check"
        return 0
    fi
    
    return 1    
}
# --------------------------  main  ------------------------------------------ #
OS_echo ">>>>>>>>>> hotpatch select version begin >>>>>>>>>>"

function PATCH_START()
{
    #上电恢复补丁时才生效
    local pid_server=$(ps -ww -eo pid,cmd | grep "/OSM/bin/omm_upd_server.bin" | grep -v grep | awk '{print $1}')
    local pid_agent=$(ps -ww -eo pid,cmd | grep "/OSM/bin/omm_upd_agent.bin" | grep -v grep | awk '{print $1}')
    if [ "$pid_server" = "" ] && [ "$pid_agent" = "" ]; then
        OS_echo "[os_load_select_ver.sh] It is poweron resume."
        whether_need_check
        if [ $? != 0 ]; then
            return
        fi

        check_is_right_rescue
        if [ $? != 0 ]; then
            return
        fi
        return
    fi
    
    OS_echo "[os_load_select_ver.sh] It is installing, do nothing."
    return
}
function PATCH_ROLLSTART()
{
    return
}

#start：打补丁前需要执行的操作，脚本的执行时间点在替换文件前
#rollstart：回滚补丁时需要执行的操作，脚本的执行时间点在文件被恢复之前。
L_CMD=$1
case $L_CMD in
        "start") 
                PATCH_START
                ;;
        "rollstart") 
                PATCH_ROLLSTART
                ;;
        *)
               #log "unsupported option."
esac

exit 0
