#!/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="${G_TMP_INSPECT_PATH}tmpResult${CurInspectFun}"
LOG_FILE="/var/log/inspect.log"
>${RESULTFILE}
isPass=0

DISKTYPEFILE="${G_TMP_INSPECT_PATH}tmpfile_disk_typefile.tmp"
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}
}

#获取节点场景: 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/"
    is3008SasCard
    if [ $? -eq 0 ]; then
        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
    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)"
        return 1
    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
}

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
    LOG "[$LINENO] Check Disk write cache"
    GetDiskWriteCache &
    disktoolPID=$!
    while [ "X$(pidstat -l -p ${disktoolPID} | grep ${disktoolPID} | awk '{print $4}')" != "X" ];do
        sleep 5
        timeCnt=$((timeCnt+1))
        if [ ${timeCnt} -ge 60 ];then
            isPass=1
            $(kill -1 ${disktoolPID} >/dev/null 2>&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}
            return
        fi
   done
}

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

