#!/bin/bash
set +x
G_MML_FILE_PATH="/opt/huawei/snas/script/inspect_mml"
[ -f $G_MML_FILE_PATH/CheckItems ] && source $G_MML_FILE_PATH/CheckItems
[ -f /opt/node_type_recognize.sh ] && source /opt/node_type_recognize.sh
[ -f /opt/node_devicename.sh ] && source /opt/node_devicename.sh
curInspectNum="133"
curInspectFun="$(GetInspectType $curInspectNum)"
isPass=0
resultFile="/tmp/tmpResult${curInspectFun}"

function LOG
{
    local LOG_FILE="/var/log/inspect.log"
    echo [$(date)][$$]$@ >> $LOG_FILE
}

function IsSMRDisk()
{
    local type=0
    local tmp=""
    local snas_ini="/opt/huawei/snas/etc/snas.ini"

    if [ -f ${sans_ini} ]; then
        tmp=$(sed -n '/DiskNodeType/p' ${snas_ini})
    else
        tmp=""
    fi

    if [ -z "$tmp" ]; then
        smr_cnt=$(lsscsi -g | awk '{if ($2=="(0x14)") print $NF}'| wc -l)
        if [ ${smr_cnt} -gt 0 ]; then
            type=1
        fi
    else
        type=$(grep -w DiskNodeType ${snas_ini} | awk -F '=' '{print $2}')
    fi

    return $type
}

function GetStdTotalMemSize()
{
    local nodeType=$1
    local isARM=$2
    local NVMEFlag=""
    local SMRFlag=""
    local SurveillanceFlag=""
    local index=0
    local StdMemSizeX86=0
    local StdMemSizeARM=0
    local memSize=0
    local stdMemSize=0
    local ProductType=""

    ProductType=$(cat "/opt/huawei/snas/etc/snas.ini" | grep -Po '(?<=^productType=)[0-9]+')
    if [ $ProductType -eq 80 ];then
        declare -a memArr=(["0"]=49152  ["1"]=49152  ["2"]=32768  ["3"]=32768  ["4"]=32768 ["5"]=49152 ["6"]=49152 ["7"]=32768
               ["8"]=32768 ["12"]=32768 ["13"]=49152 ["14"]=81920 ["15"]=32768)
        memSize=${memArr[$nodeType]}
        LOG "[$FUNCNAME][${curInspectFun}] nodeType($nodeType) tStdTotalMemSize(${memSize}), ARM(${isARM})"
        echo ${memSize}
        return
    fi

    IsSMRDisk
    if [ $? -eq 1 ]; then
        SMRFlag=1    #SMR disk on node
    else
        SMRFlag=0
    fi

    lspci | grep -w Non > /dev/null 2>&1
    if [ $? -eq 0 ];then
        NVMEFlag=1
    else
        NVMEFlag=0
    fi

    local tmpServiceType=$(grep -w serviceType /opt/huawei/snas/etc/snas.ini |awk -F "=" '{print $2}')
    if [[ "${tmpServiceType}" == "surveillance" ]];then
        SurveillanceFlag=1
    else
        SurveillanceFlag=0
    fi

    if [ "${SMRFlag}" = "1" ];then
        ##处理9000 RH服务器含有SMR盘
        declare -a memArr=(["0"]=49152   ["1"]=49152   ["2"]=32768   ["3"]=32768   ["4"]=32768   ["5"]=49152   ["6"]=49152   ["7"]=32768   ["8"]=32768
            ["12"]=32768   ["13"]=49152  ["14"]=49152  ["15"]=32768  ["16"]=49152  ["17"]=49152  ["21"]=32768  ["22"]=98304  ["23"]=81920  ["24"]=98304
            ["25"]=81920   ["26"]=81920  ["27"]=65536  ["28"]=98304  ["29"]=81920  ["31"]=114688 ["32"]=49152  ["33"]=114688 ["34"]=98304  ["35"]=98304
            ["36"]=81920   ["37"]=114688 ["38"]=98304  ["39"]=147456 ["40"]=65536  ["41"]=131072 ["42"]=131072 ["43"]=131072 ["44"]=131072 ["46"]=81920
            ["47"]=81920   ["48"]=81920)
    elif [ "${SMRFlag}" = "0" ];then
        ##处理9000 RH服务器没有SMR盘
        declare -a memArr=(["0"]=49152   ["1"]=49152   ["2"]=32768   ["3"]=32768   ["4"]=32768   ["5"]=49152   ["6"]=49152   ["7"]=32768   ["8"]=32768
            ["12"]=32768   ["13"]=49152  ["14"]=49152  ["15"]=32768  ["16"]=49152  ["17"]=49152  ["21"]=32768  ["22"]=98304  ["23"]=49152  ["24"]=49152
            ["25"]=32768   ["26"]=32768  ["27"]=65536  ["28"]=98304  ["29"]=81920  ["31"]=114688 ["32"]=49152  ["33"]=114688 ["34"]=65536  ["35"]=49152
            ["36"]=81920   ["37"]=114688 ["38"]=98304  ["39"]=147456 ["40"]=65536  ["41"]=131072 ["42"]=131072 ["43"]=131072 ["44"]=98304  ["46"]=49152
            ["47"]=32768   ["48"]=32768)
    fi

    memSize=${memArr[$nodeType]}
    if [ "${memSize}" == "" ];then
        echo ""
        LOG "[$FUNCNAME][${curInspectFun}] nodeType($nodeType) not in memArr!"
        return
    fi

    # T系列以不涉及下场景
    if [ $nodeType -lt 12 ];then
        echo $memSize
        LOG "[$FUNCNAME][${curInspectFun}] nodeType($nodeType) tStdTotalMemSize(${memSize}), ARM(${isARM})"
        return
    fi

    if [ "${NVMEFlag}${SMRFlag}${SurveillanceFlag}" == "111" ] ;then
        #X86 大于80G ；ARM 大于96G
        StdMemSizeX86=81920
        StdMemSizeARM=98304
    elif [ "${NVMEFlag}${SMRFlag}${SurveillanceFlag}" == "110" ] ;then
        #X86 大于64G ；ARM 大于80G
        StdMemSizeX86=65536
        StdMemSizeARM=81920
    elif [ "${NVMEFlag}${SMRFlag}${SurveillanceFlag}" == "101" ] ;then
        #X86 大于48G ；ARM 大于64G
        StdMemSizeX86=49152
        StdMemSizeARM=65536
    elif [ "${NVMEFlag}${SMRFlag}${SurveillanceFlag}" == "100" ] ;then
        #X86 大于48G ；ARM 大于64G
        StdMemSizeX86=49152
        StdMemSizeARM=65536
    elif [ "${NVMEFlag}${SMRFlag}${SurveillanceFlag}" == "011" ] ;then
        #X86 大于80G ；ARM 大于96G
        StdMemSizeX86=81920
        StdMemSizeARM=98304
    elif [ "${NVMEFlag}${SMRFlag}${SurveillanceFlag}" == "010" ] ;then
        #X86 大于48G ；ARM 大于64G
        StdMemSizeX86=49152
        StdMemSizeARM=65536
    elif [ "${NVMEFlag}${SMRFlag}${SurveillanceFlag}" == "001" ] ;then
        #按现在规格
        StdMemSizeX86=0
        StdMemSizeARM=0
    elif [ "${NVMEFlag}${SMRFlag}${SurveillanceFlag}" == "000" ] ;then
        #按现在规格
        StdMemSizeX86=0
        StdMemSizeARM=0
    fi

    if [ $isARM -eq 0 ];then
        stdMemSize=$StdMemSizeARM
    else
        stdMemSize=$StdMemSizeX86
    fi

    if [ $stdMemSize -gt $memSize ];then
        echo $stdMemSize
    else
        echo $memSize
    fi
    LOG "[$FUNCNAME][${curInspectFun}] nodeType($nodeType), NVME(${NVMEFlag}), SMR(${SMRFlag}), Surveillance(${SurveillanceFlag}), ARM(${isARM})"

}

function checkPyhMem()
{
    local Result=""
    local stdSpeed=0
    local stdNvSize=0
    local totalMemSize=0
    local firstMemSize=0
    local nvSize=0
    local isMemSizeDiff=0
    local lessSpeedList=""
    local memresultFile="/tmp/tmpfilecheckPhyMemory"
    local ddr3list="0 1 3 5 6 7 8" #P(0) C(1) M(3) P25(5) P36(6) C36(7) P12(8)  1333(MHZ)DDR3

    > $memresultFile
    > ${resultFile}

    IsStandardNode
    if [ $? -eq 0 ];then
        echo  "Locator:Does not involve.||size:--||Speed:--"  >> ${resultFile}  2>&1
        echo "${curInspectFun}_Pass $isPass" >>${resultFile} 2>&1
        return
    fi

    nodepool=$(cat /opt/huawei/snas/etc/snas.ini | grep ^nodepool | awk -F'=' '{print $2}' | awk '{print $1}')
    nodetype=$(cat /opt/huawei/deploy/etc/deploy.ini | grep -Po '(?<=^devicetype=)[0-9]+')
    if [ "${nodetype}" == "" ];then
        isPass=1
        echo "[ERR]INFO:nodetype is empty!" >> ${resultFile}  2>&1
        echo "${curInspectFun}_Pass $isPass" >>${resultFile} 2>&1
        return
    fi

    #ARM服务器中不存在NVdimm内存
    IsTSNode
    isARM=$?

    IsRHNode
    if [ $? -eq 0 ]; then
        IsRHV5Node
        if [ $? -eq 0 ];then
            isRH="V5RH"
            stdSpeed=2400
            stdNvSize=16384
        else
            isRH="V3RH"
            stdNvSize=8192
            stdSpeed=2133
        fi
    else
        isRH=0
        stdNvSize=2048
        stdSpeed=1600
        echo "${ddr3list}" | grep -w "${nodetype}" >/dev/null
        if [ $? -eq 0 ];then
            stdSpeed=1333
        elif [ ${isARM} -eq 0 ] ;then
            stdSpeed=2933
        fi
    fi

    dmidecode -t memory | grep -P "^\s+(Locator:|Size:|Speed:)" >> $memresultFile  2>&1
    while read line; do
        local tmpSize=$(echo $line |grep "Size:" |awk '{print $2}')
        local tmpUnit=$(echo $line |grep "Size:" |awk '{print $3}')
        local tmpSlot=$(echo $line |grep "Locator:" | awk -F":" '{print $2}' | sed 's/Slot//g' | awk '{print $1}')
        local tmpSpeed=$(echo $line |grep "Speed:" |awk '{print $2}')
        #统一单位为MB
        if [ "${tmpUnit}X" = "GBX" ];then
            tmpSize=$(($tmpSize*1024))
        elif [ "${tmpUnit}X" = "KBX" ];then
            tmpSize=$(($tmpSize/1024))
        fi
        Result="${Result} ${tmpSize} ${tmpSlot}"
        if [ "${tmpSpeed}X" != "X" ]; then
            tmpSize=$(echo $Result |awk '{print $1}')
            tmpSlot=$(echo $Result |awk '{print $2}')
            if [ "${tmpSize}" == "No" -o "${tmpSlot}" == "" ];then
                Result=""
                continue
            fi
            if [ "$tmpSlot" = "F0" ] || [ "$tmpSlot" = "DIMM000" -a $isARM != 0 ]; then
                nvSize=$tmpSize
            else
                if [  ${tmpSpeed} -lt ${stdSpeed}  ]; then
                    lessSpeedList="$lessSpeedList $tmpSlot"
                fi
                if [ $firstMemSize -eq 0 ];then
                    firstMemSize=$tmpSize
                else
                    if [ $firstMemSize -ne $tmpSize ];then
                        isMemSizeDiff=1
                    fi
                fi
                totalMemSize=$(expr $tmpSize + $totalMemSize)
            fi
            echo  "Locator:$tmpSlot||size:$tmpSize(MB)||Speed:$tmpSpeed(MHZ)"  >> ${resultFile}  2>&1
            Result=""
        fi
    done < $memresultFile
    #restore_ifs
    if [ "${lessSpeedList}" != "" ];then
        echo  "[ERR]INFO:The physical memory frequency of slots(${lessSpeedList}) is lower than ${stdSpeed}(MHZ)."  >>${resultFile} 2>&1
        isPass=1
    fi

    if [ "$isMemSizeDiff" -ne 0 ] ; then        #不通过
        echo  "[ERR]INFO:Node physical memory sizes are different."  >> ${resultFile} 2>&1
        isPass=1
    fi

    if [ $isARM != 0 -a ${nvSize} -lt ${stdNvSize} ]; then
        echo  "[ERR]INFO: nvdimm ${nvSize}(MB) less than ${stdNvSize}(MB)" >> ${resultFile} 2>&1
        isPass=1
    fi

    local stdTotalMemSize=0
    stdTotalMemSize=$(GetStdTotalMemSize $nodetype $isARM)


    if [ "${stdTotalMemSize}" != "" ];then
        if [ "$totalMemSize" -lt "${stdTotalMemSize}" ]; then
            NodeType=$(MapNodeType "$nodetype")
            echo "[ERR]INFO:${NodeType} total capacity of physical memory ${totalMemSize}(MB) is less than ${stdTotalMemSize}(MB)." >> ${resultFile} 2>&1
            isPass=1
        fi
    fi
    [ -f ${memresultFile} ] && rm -f ${memresultFile}

    #节点cat /proc/snas_mem/phymem 取内存会去掉x86的nvdimm， ARM的BBU
    local totalMemSize1=$(cat /proc/snas_mem/phymem | grep -Po '^[0-9]+$')
    if [ "${totalMemSize1}" == "" ];then
        isPass=1
        echo "[ERR]INFO:Failed to execute command(cat /proc/snas_mem/phymem)." >> ${resultFile} 2>&1
    else
        totalMemSize=$(expr $totalMemSize1 \* 1024)
    fi

    echo "nodepool=${nodepool}" >> ${resultFile} 2>&1
    echo "totalmemsize=${totalMemSize}" >> ${resultFile} 2>&1
}

function checkX86LargeMemoryRestartRisk()
{
    local total_phy_kibs=0
    local total_phy_gb=0
    local serviceType=""
    local isSmrNode="false"
    local static_mem_config_file=""
    local memSize=0

    # 1.0 大内存arm节点重启不存在因为mds内存初始化耗时过长被狗咬死的问题
    arch | grep x86 >/dev/null 2>&1
    if [ $? -ne 0 ]; then
        LOG "[$FUNCNAME][${curInspectFun}] restart large-memory ARM nodes do not have crash risks."
        return
    fi
    # 2.0 获取节点物理内存， 取内存会去掉x86的nvdimm， ARM的BBU
    total_phy_kibs=$( grep total_phy /opt/huawei/snas/etc/snas.ini | awk -F '=' '{print $2}' | sed "s/ *//g" )
    total_phy_gb=$((total_phy_kibs/1024/1024))
    if [ ${total_phy_gb} -le 0 ]; then
        #节点cat /proc/snas_mem/phymem 取内存会去掉x86的nvdimm， ARM的BBU
        total_phy_gb=$( cat /proc/snas_mem/phymem | sed 's/ *//g' )
    fi

    if [ ${total_phy_gb} -le 0 ]; then
        LOG "[$FUNCNAME][${curInspectFun}] Failed to get node total physical memory size."
        return
    fi

    # 3.0 获取节点业务类型
    serviceType=$( grep serviceType /opt/huawei/snas/etc/snas.ini | awk -F '=' '{print $2}' | sed 's/ *//g' )

    # 4.0 获取是否smr节点
    /opt/huawei/snas/sbin/nofs-snas dumpzoneleft |grep -v "NAME" |grep -w "^P.*" >/dev/null 2>&1
    if [ $? -eq 0 ]; then
        isSmrNode="true"
    fi

    # 5.0 获取mds模块内存大小
    if [ "X${serviceType}" != "X" -a "X${serviceType}" == "Xsurveillance" ]; then
        # 视频监控场景，内存规格满足以下条件重启可能会出现crash：smr盘>=240G，非smr盘>=208G
        if [ "X${isSmrNode}" == "Xtrue" -a ${total_phy_gb} -ge 240 ]; then
            static_mem_config_file="/opt/huawei/snas/static/snas_node_c1_dram_${total_phy_gb}g_${serviceType}smr.ini"
        fi

        if [ "X${isSmrNode}" == "Xfalse" -a ${total_phy_gb} -ge 208 ]; then
            static_mem_config_file="/opt/huawei/snas/static/snas_node_c1_dram_${total_phy_gb}g_${serviceType}mix.ini"
        fi

    elif [ "X${serviceType}" != "X" -a "X${serviceType}" == "Xother" ]; then
        # 默认场景，内存规格满足以下条件重启可能会出现crash：smr盘>=352G，非smr盘>=336G
        if [ "X${isSmrNode}" == "Xtrue" -a ${total_phy_gb} -ge 352 ]; then
            static_mem_config_file="/opt/huawei/snas/static/snas_node_c1_dram_${total_phy_gb}g_${serviceType}smr.ini"
        fi

        if [ "X${isSmrNode}" == "Xfalse" -a ${total_phy_gb} -ge 336 ]; then
            static_mem_config_file="/opt/huawei/snas/static/snas_node_c1_dram_${total_phy_gb}g_${serviceType}.ini"
        fi

    elif [ "X${serviceType}" != "X" -a "X${serviceType}" == "Xarchive" ]; then
        # 海量小文件场景，针对内存：smr盘>=192G，非smr盘>=176G
        if [ "X${isSmrNode}" == "Xtrue" -a ${total_phy_gb} -ge 192 ]; then
            static_mem_config_file="/opt/huawei/snas/static/snas_node_c1_dram_${total_phy_gb}g_${serviceType}smr.ini"
        fi

        if [ "X${isSmrNode}" == "Xfalse" -a ${total_phy_gb} -ge 176 ]; then
            static_mem_config_file="/opt/huawei/snas/static/snas_node_c1_dram_${total_phy_gb}g_${serviceType}.ini"
        fi

    else
        LOG "[$FUNCNAME][${curInspectFun}] serviceType:${serviceType} is not in [surveillance other archive],have no large-memory restart mds mem init crash risk."
        return
    fi

    if [ -f "${static_mem_config_file}" -a -s "${static_mem_config_file}" ]; then
        memSize=$( sed -n '9p' ${static_mem_config_file} | awk -F '=' '{print $2}' | sed "s/ *//g" )
    else
        LOG "[$FUNCNAME][${curInspectFun}] ${static_mem_config_file} is not a file or nonexist."
        return
    fi

    # 判定mds模块内存大小是否超过56892，如果超过，重启就可能因为mds内存初始化耗时过长被狗咬死
    if [ ${memSize} -gt 56892 ]; then
        echo "[ERR]INFO:serviceType(${serviceType}),isSmrNode(${isSmrNode}),mds mem_size(${memSize}) in ${static_mem_config_file} is greater than 56892,crash may occur during node restart." >> ${resultFile} 2>&1
        LOG "[$FUNCNAME][${curInspectFun}] node serviceType(${serviceType}),isSmrNode(${isSmrNode}),mds mem_size(${memSize}) in ${static_mem_config_file} is greater than 56892,crash may occur during node restart."
        isPass=1
    else
        LOG "[$FUNCNAME][${curInspectFun}] node serviceType(${serviceType}),isSmrNode(${isSmrNode}),mds mem_size(${memSize}) in ${static_mem_config_file},have no restart crash risk."
    fi

    return
}

checkPyhMem

# x86大内存标准如下：视频监控场景，smr盘>=240G，非smr盘>=208；默认场景，smr盘>=352G，非smr盘>=336G；海量小文件场景，smr盘>=192G，非smr盘>=176G
# x86节点大内存环境重启可能会出现狗咬死，没有规避需要提示
checkX86LargeMemoryRestartRisk

echo "${curInspectFun}_Pass $isPass" >>${resultFile} 2>&1
LOG "[$FUNCNAME]${curInspectFun}_Pass ${isPass}"
