#!/bin/bash
set +x
G_MML_FILE_PATH="/opt/huawei/snas/script/inspect_mml"
source $G_MML_FILE_PATH/CheckItems
CurInspectNum="146"
CurInspectFun="$(GetInspectType $CurInspectNum)"
RESULTFILE="/tmp/tmpResult${CurInspectFun}"
LOG_FILE="/var/log/inspect.log"
>${RESULTFILE}
isPass=0

DISKTYPEFILE="/tmp/tmpfile_disk_typefile.tmp"
BakEndTaskRunOver="/tmp/tmpResultBakEndTaskRunOver${CurInspectFun}"
INVAILDNUMBER=4294967295
DISK_TYPE_SAS=1
DISK_TYPE_SATA=2
DISK_TYPE_SSD=3
DISK_TYPE_SMR_SATA=15
DISK_TYPE_SATA_SSD=17
. /opt/node_type_recognize.sh
. /opt/install_os_common_func.sh

function LOG
{
   time=$(date)
   echo [${time}][$$][${CurInspectFun}]$@ >> ${LOG_FILE}
}

function GetDiskNameList()
{
    local tmpinfo=''
    local diskNum=`/usr/local/bin/disktool -s |grep sd- |wc -l`
    if [ $diskNum == 0 ]; then
        tmpinfo=`/usr/local/bin/disktool -f A |grep "System Device" | awk '{print $3}'`
    else
        tmpinfo=`/usr/local/bin/disktool -s | awk 'BEGIN{i=0}
        {
            if($1~/^\/dev\/sd-[0-9]+a$/)
            {
                #diskname: "/dev/sd-64a",get name of number "64"
                nameLen=length($1)
                sdLen=length("/dev/sd-")
                tmpname=substr($1,sdLen+1,nameLen-sdLen-1)
                if(tmpname >= 64)
                {
                    namelist[i]=$1
                    i++
                }
            }
        }
        END{
            namelistlen=length(namelist)
            for(i=0;i<namelistlen;i++){print namelist[i];}
        }'`
    fi
    echo ${tmpinfo}
}

function GetT3000SASCardWriteCache()
{
    local LSIUTIL_EXE="/opt/driver/lsisas-driver/lsiutil"
    local tmpfilename="/tmp/tmpqueryT3000SAScache"
    local tmpinfo=''
    chmod +x $LSIUTIL_EXE
    echo "1" > $tmpfilename
    echo "68" >> $tmpfilename
    echo "0" >> $tmpfilename
    echo "0" >> $tmpfilename
    ret=`$LSIUTIL_EXE<$tmpfilename | grep Caching | awk '{print $4}'`
    tmpinfo="ioc write cache is $ret."
    LOG "[$LINENO] T3000 SAS info =($tmpinfo)"

    if [ -f $tmpfilename ];then
        rm $tmpfilename
        LOG "[$LINENO] rm $tmpfilename"
    fi

    echo "$tmpinfo" | grep "write cache" | grep -i Disabled > /dev/null
    if [ $? -eq 0 ];then
        LOG "[$LINENO] SAS status =(Disabled)"
        echo "Device:SAS card||Write Cache Status:Disabled"     >>${RESULTFILE}
    else
        echo "$tmpinfo" | grep "write cache" | grep -i Enabled > /dev/null
        if [ $? -eq 0 ];then
            isPass=1
            echo "[ERR]INFO: Device(SAS card),Write Cache Status(Enabled)."    >>${RESULTFILE}
        else
            isPass=1
            echo "[ERR]INFO: Get SAS card write cache failed from command ($LSIUTIL_EXE)."     >>${RESULTFILE}
            LOG "[$LINENO] Get SAS card write cache failed"
        fi
    fi
}

#获取节点场景: 1 - 节点上有SMR磁盘, 需要开启SAS写缓存; 0 - 节点上没有SMR磁盘, 需要关闭SAS写缓存
#(1)先从snas.ini中查看是否有SMR的标记字段DiskNodeType, 以这个字段为主;
#(2)如果查不到DiskNodeType, 那么利用lsscsi工具查看, 获取磁盘类型, 如果有SMR磁盘, 返回1
function GetDiskNodeType()
{
    snas_ini="/opt/huawei/snas/etc/snas.ini"
    if [ -f $sans_ini ]; then
        tmp=`sed -n '/DiskNodeType/p' $snas_ini`
    else
        tmp=""
    fi

    type=0
    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 GetRHSASCardWriteCache()
{
    local tmpinfo=''
    local lsiutil_path="/opt/driver/lsisas-mpt3sas-driver/"

    cd $lsiutil_path
    if [ $? -ne 0 ]; then
        isPass=1
        LOG "[$LINENO] Fail to go to lsiutil directory"
        echo "[ERR]INFO: Failed to go to lsiutil directory." >>${RESULTFILE}
        return
    fi

    tmpinfo=`sh /opt/driver/lsisas-mpt3sas-driver/lsiutil_operateioc_writecache.sh query`
    cd - > /dev/null
    LOG "[$LINENO] RH SAS info =($tmpinfo)"

    GetDiskNodeType
    diskNodeType=$?
    LOG "[$LINENO] node disk type =($diskNodeType)"

    echo "$tmpinfo" | grep "write cache" | grep -i "Disabled" > /dev/null
    if [ $? -eq 0 ];then
        LOG "[$LINENO] SAS status =(Disabled)"
        echo "Device:SAS card||Write Cache Status:Disabled"     >>${RESULTFILE}

        if [ $diskNodeType -eq 1 ]; then
            isPass=1
            echo "[ERR]INFO: Node is SMR Scene or node has SRM disk, need to enable SAS Write Cache."     >>${RESULTFILE}
        fi
    else
        echo "$tmpinfo" | grep "write cache" | grep -i "Enabled" > /dev/null
        if [ $? -eq 0 ];then
            echo "Device:SAS card||Write Cache Status:Enabled"      >>${RESULTFILE}
            if [ $diskNodeType -ne 1 ]; then
                isPass=1
                echo "[ERR]INFO: Node is not SMR scene or node does not have SMR Disk, need to disable SAS Write Cache."      >>${RESULTFILE}
            fi
        else
            isPass=1
            echo "[ERR]INFO: Get SAS card write cache failed"     >>${RESULTFILE}
            LOG "[$LINENO] Get SAS card write cache failed"
        fi
    fi
}

function GetDiskWriteCache()
{
    local StatusInfo=''
    local isNodePass=0
    NameList=()
    NameList=`GetDiskNameList`
    LOG "[$FUNCNAME][$LINENO] NameList =($NameList)"
    /usr/local/bin/MmlBatch 4016 "cm showdiskname" | grep "Disk_Type" |grep -v $INVAILDNUMBER | sed 's/.*\(Disk_Type:.*\)/\1/' > $DISKTYPEFILE
    dos2unix $DISKTYPEFILE > /dev/null 2>&1
    sed -i -e 's/\x1B\[0;[3-4][0-9]m//g' -e 's/\x0D//g' -e 's/\x00//g' $DISKTYPEFILE >/dev/null 2>&1
    LOG "[$LINENO] result=(`cat $DISKTYPEFILE`)"
    if [ ! -s $DISKTYPEFILE ];then
        isPass=1
        echo "[ERR]INFO:Failed to execute command(MmlBatch 4016 'cm showdiskname')."    >>${RESULTFILE}
        LOG "[$LINENO] exec command failed(/usr/local/bin/MmlBatch 4016 cm showdiskname)"
        # 创建后台任务运行完的标志
        touch "${BakEndTaskRunOver}"
        return
    fi
    for item in ${NameList[*]};do
        grep "${item}" $DISKTYPEFILE > /dev/null 2>&1
        if [ $? -ne 0 ];then
            LOG "[$FUNCNAME][$LINENO] skip kicked or fault disk($item)"
            continue
        fi
        disktype=$(cat $DISKTYPEFILE | grep "$item" | awk -F '\\|\\|' '{print $1}' | tail -1 | awk -F':' '{print $2}')
        if [ "${disktype}" == "${DISK_TYPE_SSD}" -o "${disktype}" == "${DISK_TYPE_SATA_SSD}" ];then
            LOG "[$LINENO] skip SSD disk($item),disktype=$disktype"
            continue
        fi
        StatusInfo=`/usr/local/bin/disktool -f o ${item}`
        if [ "${disktype}" == "${DISK_TYPE_SMR_SATA}" ];then
            #SMR盘的写缓存开关预期结果为开启
            echo ${StatusInfo} | grep -i "enable" > /dev/null
            if [ $? -eq 0 ];then
                LOG "[$FUNCNAME][$LINENO] disk($item) status =(Enabled)"
            else
                echo ${StatusInfo} | grep -i "disable" > /dev/null
                if [ $? -eq 0 ];then
                    isPass=1
                    echo "[ERR]INFO: Device(${item}) is SRM disk, Write Cache Status(Disabled)" >>${RESULTFILE}
                    LOG "[$LINENO] Get disk($item) Write Cache Status(Disabled)"
                else
                    isPass=1
                    echo "[ERR]INFO: Get disk($item) write cache failed " >>${RESULTFILE}
                    LOG "[$LINENO] Get disk($item) write cache failed"
                fi
                isNodePass=1
            fi
        else
            echo ${StatusInfo} | grep -i "disable" > /dev/null
            if [ $? -eq 0 ];then
                LOG "[$FUNCNAME][$LINENO] disk($item) status =(Disabled)"
            else
                echo ${StatusInfo} | grep -i "enable" > /dev/null
                if [ $? -eq 0 ];then
                    isPass=1
                    echo "[ERR]INFO: Device(${item}),Write Cache Status(Enabled)"   >>${RESULTFILE}
                    LOG "[$LINENO] Get disk($item) Write Cache Status(Enabled)"
                else
                    isPass=1
                    echo "[ERR]INFO: Get disk($item) write cache failed "   >>${RESULTFILE}
                    LOG "[$LINENO] Get disk($item) write cache failed"
                fi
                isNodePass=1
            fi
        fi
    done

    if [ $isNodePass -eq 0 ];then
        if [ "${disktype}" == "${DISK_TYPE_SMR_SATA}" ];then
            echo "Device:disk||Write Cache Status:Enabled"  >>${RESULTFILE}
        else
            echo "Device:disk||Write Cache Status:Disabled" >>${RESULTFILE}
        fi
    fi

    # 创建后台任务运行完的标志
    touch "${BakEndTaskRunOver}"
    
    return
}

function WaitTaskOrKillAllTasks()
{
    local bakUpTaskPid=${1}
    local timeInterVal=${2}
    local retryCnt=${3}
    local num=1
    
    while [ ${num} -le ${retryCnt} ]
    do
        if [ -f "${BakEndTaskRunOver}" ]; then
            return 0
        else
            sleep ${timeInterVal}
            num=$( expr $num + 1 )
        fi
    done
    
    # 进程1不能干掉
    if [ ${bakUpTaskPid} -eq 1 ]; then
        LOG "[$FUNCNAME][$LINENO]The input background process cannot be killed because it is 1!"
        return 1
    fi
    
    # BakEndTaskRunOver没生成，说明后台任务挂死，干掉后台进程以及拉起的所有子进程
    pstree -p ${bakUpTaskPid} 2>/dev/null | awk -F "[()]" '
    {
        for (i=2;i<=NF;i++)
        {
            if (i%2==0)
            {
                print $i
            }
        }
    }' | xargs kill -9
    
    return 1
}

function GetAllWriteCache()
{
    local is3008SasFlag=0
    local disktoolPID=""
    local timeCnt=0
    is3008SasCard
    is3008SasFlag=$?
    #RH服务器只有SAS3008SAS卡，ARM服务器没有SAS卡，不检查SAS卡写缓存状态
    IsRHNode
    if [ $? -eq 0 -a ${is3008SasFlag} -eq 0 ]; then
        LOG "[$LINENO] Check RH SAS card write cache"
        GetRHSASCardWriteCache
    fi
    IsT3000Node
    if [ $? -eq 0 ];then
        LOG "[$LINENO] Check T3000 SAS card write cache"
        GetT3000SASCardWriteCache
    fi
    LOG "[$LINENO] Check Disk write cache"
    rm -f "${BakEndTaskRunOver}"
    GetDiskWriteCache &
    disktoolPID=$!
    
    # disktool可能导致巡检项挂死，设置超时等待，如果超时，将后台进程及其拉起的子进程全部干掉
    WaitTaskOrKillAllTasks ${disktoolPID} 5 60
    if [ $? -eq 1 ]; then
        isPass=1
        LOG "[$FUNCNAME][$LINENO]disktool:exec cmd 'disktool' timeout(${timeCnt}*5 s).The service may be busy, please Try again later!"
        echo "[ERR]INFO:exec cmd 'disktool' timeout(${timeCnt}*5 s).(${disktoolPID})The service may be busy, please try again later!"  >>${RESULTFILE}
    fi

    rm -f "${BakEndTaskRunOver}"
    
    return
}

GetAllWriteCache
if [ -f $DISKTYPEFILE ];then
    rm -f $DISKTYPEFILE
    LOG "[$LINENO] delete tmp file"
fi
echo "${CurInspectFun}_Pass $isPass" >>${RESULTFILE}
exit 0

