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

. /opt/node_type_recognize.sh
ofedConfigPath="/opt/driver/ib-driver"
ROCE_LIST=""
IB_LIST=""
OFED_VER=""
get_cluster_lite_deploy
IS_LITE_NODE=$?
BACKEND_PORT=$(get_lite_backup_netport)

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

#获取OFED版本
function GetOFEDVersion()
{
    local ofedVer="NULL"
    local tmpInfo=""
    local iRet=0
    tmpInfo=$(ofed_info -s)
    iRet=$?
    if [ $? -ne 0 ];then
        LOG "[$LINENO]get ofed info fail,iRet=${iRet},tmpInfo=${tmpInfo}"
        echo ${ofedVer}
        return 0
    fi

    if [[ "${tmpInfo}" =~ "MLNX_OFED_LINUX-3.2" ]];then
        ofedVer="3.2"
    elif [[ "${tmpInfo}" =~ "MLNX_OFED_LINUX-4.2" ]];then
        ofedVer="4.2"
    elif [[ "${tmpInfo}" =~ "OFED-internal-4.4" ]];then
        ofedVer="4.4"
    elif [[ "${tmpInfo}" =~ "OFA-LINUX-4.17" ]];then
        ofedVer="4.17"
    else
        ofedVer="NULL"
        LOG "[$LINENO]no match ofed info,tmpInfo=${tmpInfo}"
    fi

    echo ${ofedVer}
    return 0
}

#ARMofed4.17目前不检查Firmware_Version,只检查ofed版本和网卡配套关系(ofed4.17-->Hi1822#driver: hinic)
function Checkofed_417()
{
    local ethName=$(ls /etc/sysconfig/network-scripts/ifcfg-* | grep -wv lo | sed 's/\/etc\/sysconfig\/network-scripts\/ifcfg-//' | grep -v '\.')
    local ethInfo=""
    local curfwVersion=""
    local businfo=""
    local iRet=0
    local errInfo=""
    local driver=""
    local netType=""
    for item in ${ethName};do
        if [[ "${item}" =~ "NIC" ]];then
            LOG "[$LINENO]no check nic,item=${item}"
            continue
        fi

        if [[ "${item}" =~ "bond" ]]; then
            LOG "[$LINENO]no check bond,item=${item}"
            continue
        fi

        #单节点lite不检查后端网卡
        if [ $IS_LITE_NODE -eq 0 ]; then
            if [[ $BACKEND_PORT =~ $item ]]; then
                LOG "[$LINENO]no check lite backend port,item=${item}"
                continue
            fi
        fi

        netName="${item}"
        ethInfo=$(ethtool -i ${item} 2>&1)
        iRet=$?
        if [ ${iRet} -ne 0 ];then
            ErrInfoCommon "INFO:NetName (${netName}). get network adapter info failed." "${RESULTFILE}"
            LOG "[${LINENO}]INFO:NetName (${netName}). get network adapter info failed.iRet=${iRet}"
            break
        fi


        businfo=$(echo "${ethInfo}" | grep -w "bus-info" | awk -F':' '{print $3 ":" $4}')
        curfwVersion=$(echo "${ethInfo}" | grep -w "firmware-version" | awk -F':' '{sub("^[ \t]*","",$2);print $2}')
        driver=$(echo "${ethInfo}" | grep -w "driver" | awk -F':' '{sub("^[ \t]*","",$2);print $2}')

        if [ "${driver}X" = "hinicX" ];then
            ethInfo=$(ethtool "${netName}" 2>&1)
            iRet=$?
            tmpCardtype=$(echo "${ethInfo}" | grep "Speed:" | awk '{gsub("Mb/s","",$2);printf "%d",$2/1000}')
            if [ ${iRet} -eq 0 ] && [ "${tmpCardtype}" == "10" -o "${tmpCardtype}" == "25" -o "${tmpCardtype}" == "40" -o "${tmpCardtype}" == "100" ];then
                netType="${tmpCardtype}g RoCE(1822)"
            else
                errInfo="INFO:BDF (${businfo}) NetName (${netName}). get network adapter type failed."
                isPass=1
                LOG "[${LINENO}]INFO:BDF (${businfo}) NetName (${netName}). get network adapter type failed. iRet=$iRet"
                break
            fi
            echo "Type:${netType}||BDF:${businfo}||NetName:${netName}||OFED_Version:${OFED_VER}||Firmware_Version:${curfwVersion}" >>${RESULTFILE}
        else
            errInfo="INFO:BDF (${businfo}) NetName(${netName}),The OFED (${OFED_VER}) version does not match the network adapter."
            LOG "[${LINENO}]INFO:NetName (${netName}). driver=${driver},businfo=${businfo}"
            break
        fi
    done

    if [ "${errInfo}X" != "X" ];then
        isPass=1
        ErrInfoCommon "${errInfo}" "${RESULTFILE}"
    fi
}

#检查RoCE卡匹配关系
function CheckRoceorIBFirmware()
{
    local mstInfo="$1"
    local idx=""
    local netType=""
    local netName=""
    local curfwVersion=""
    local tmpCardtype=""
    local flintInfo=""
    local businfo=""
    local tmpPSID=""
    local tmpinfo=""
    local linkinfo=""
    local iret=0
    local baseGUID=""
    local isRHV5=0

    IsRHV5Node
    if [ $? -eq 0 ]; then
        isRHV5=1
    fi

    for idx in ${ROCE_IB_LIST[@]}; do
        #获取网口名字，businfo
        tmpinfo=$(echo "${mstInfo}" | grep -A1 "${idx}" | grep "bus:dev.fn" | awk '{print $1}' | awk -F'=' '{print $2}')
        businfo=$(echo "${tmpinfo}" | awk -F':' '{print $2 ":" $3}')
        linkinfo=$(find /sys/class/net -maxdepth 1 -type l -exec readlink -e {} \; | grep "${tmpinfo}" | head -1)
        netName=$(basename ${linkinfo})

        #单节点lite不检查后端网卡
        if [ $IS_LITE_NODE -eq 0 ]; then
            if [[ $netName =~ $BACKEND_PORT ]]; then
                LOG "[$LINENO]no check lite backend port,item=${netName}"
                continue
            fi
        fi
        # 由于现网flint生产发布有问题，所以换ethtool来获取网卡的固件版本，PSID，baseGUID
        curfwVersion=$( ethtool -i $netName | grep "firmware-version" | awk '{print $2}' )
        tmpPSID=$( ethtool -i $netName | grep "firmware-version" | awk '{print $3}' | awk -F "[()]" '{print $2}' )

        #获取网卡类型，PSID为HUA0010110034的网卡做特殊处理，看实际工作是在10g,还是25g，其他类型的依据配置文件获取
        if [ "${tmpPSID}" == "HUA0010110034" ];then
            tmpinfo=$(ethtool "${netName}" 2>&1)
            iret=$?
            tmpCardtype=$(echo "${tmpinfo}" | grep "Speed:" | awk '{gsub("Mb/s","",$2);printf "%d",$2/1000}')
            if [ $? -eq 0 ] && [ "${tmpCardtype}" == "10" -o "${tmpCardtype}" == "25" ];then
                netType="${tmpCardtype}g RoCE(V3)"
            else
                netType="10g RoCE(V3)"
                LOG "[${LINENO}] actual speed ${tmpCardtype}, ethtool ${netName} return ${iret}"
            fi
        elif [ "${tmpPSID}" == "HUA0000000001" ];then
            #此卡为外购卡没有配套关系，不需要检查
            echo "Type:(${tmpPSID})No need to check.||BDF:--||NetName:--||OFED_Version:--||Firmware_Version:--" >>${RESULTFILE}
            LOG "[${LINENO}] skip it,idx=[${idx}],PSID:${tmpPSID}"
            continue
        elif [ "${tmpPSID}" == "HUA0000000023" ];then
            # mlx的RoCE卡-25g RoCE(V5)，已投到4.4使用，配置文件未更新，巡检规避
            netType=$(cat ${ofedConfigPath}/ofed*.conf|grep ";${tmpPSID};"| grep -v '^#' | head -1 |awk -F';' '{print $1}')
            echo "Type:${netType}||BDF:${businfo}||NetName:${netName}||OFED_Version:${OFED_VER}||Firmware_Version:${curfwVersion}" >>${RESULTFILE}
            continue
        else
            netType=$(grep ";${tmpPSID};" "${ofedConfigPath}/ofed${OFED_VER}.conf" 2>&1 | grep -v '^#' | head -1 |awk -F';' '{print $1}')
            if [ "${netType}X" == "X" ];then
                netType="null"
                echo "Type:${netType}||BDF:${businfo}||NetName:${netName}||OFED_Version:${OFED_VER}||Firmware_Version:${curfwVersion}" >>${RESULTFILE}
                LOG "[${LINENO}]tmpPSID:${tmpPSID}(Failed to obtain the PSID),Type:${netType},BDF:${businfo},NetName:${netName},OFED_Version:${OFED_VER},Firmware_Version:${curfwVersion},iret=[${iret}]."
                continue
            fi
        fi

        #拼接字符串(网卡类型;网卡PSID;网卡固件版本;OFED版本)
        tmpinfo="${netType};${tmpPSID};${curfwVersion};${OFED_VER}"
        #在配套表格中查询
        cat "${ofedConfigPath}/ofed${OFED_VER}.conf" | grep -v "^#" | grep "${tmpinfo}" >/dev/null
        iret=$?
        #判断是否与配置文件中固件配套关系匹配
        if [ ${iret} -ne 0 ];then
            isPass=1
            ErrInfoCommon "INFO:Type (${netType}) BDF (${businfo}) NetName (${netName}). The OFED (${OFED_VER}) version does not match the network adapter firmware version (${curfwVersion})." "${RESULTFILE}"
        fi
        
        echo "Type:${netType}||BDF:${businfo}||NetName:${netName}||OFED_Version:${OFED_VER}||Firmware_Version:${curfwVersion}" >>${RESULTFILE}
        LOG "[${LINENO}]tmpPSID:${tmpPSID},Type:${netType},BDF:${businfo},NetName:${netName},OFED_Version:${OFED_VER},Firmware_Version:${curfwVersion},iret=[${iret}]."
    done

    echo "${ROCE_IB_LIST[@]}" | grep -q "mt4117_pciconf"
    if [ $? -eq 0 -a ${isRHV5} -eq 1 ]; then
        cat /sys/class/infiniband/mlx5_*/node_guid | egrep -q "(0000:0000:0000:0000|0000:0000:0000:0001)"
        if [ $? -eq 0 ]; then
            isPass=1
            ErrInfoCommon "INFO:The Base GUID of some network adapter is N/A. The GUID needs to be restored." "${RESULTFILE}"
        fi
    fi

    return 0
}

function CheckVersion()
{
    local ofedVersion=""
    local mstinfo=""
    local iret=0
    local IsRoceFlag=0
    local IsIBFlag=0

    #获取OFED版本号
    OFED_VER="$(GetOFEDVersion)"
    ofedVersion="${OFED_VER}"
    if [ "${ofedVersion}" = "NULL" ];then
        ErrInfoCommon "INFO:Get ofed version failed." "${RESULTFILE}"
        isPass=1
        LOG "[$LINENO]get ofed version error"
        return 1
    fi

    #arm里面ofed4.4按照V5逻辑从配置文件ofed4.4.conf中获取信息; ofed4.17做特殊处理
    if [ "${OFED_VER}" = "4.17" ];then
        Checkofed_417
        return 0
    fi
    mst start >/dev/null
    iret=$?
    if [ ${iret} -ne 0 ]; then
        ErrInfoCommon "INFO:Execute command (mst start) failed!" "${RESULTFILE}"
        isPass=1
        LOG "[${LINENO}]mst start exec failed,iret=$iret."
        return 1
    fi

    #列出当前系统设备上的ROCE与IB卡对应的MST设备
    mstinfo=$(mst status)
    iret=$?
    if [ ${iret} -ne 0 ]; then
        ErrInfoCommon "INFO:Execute command (mst status) failed!" "${RESULTFILE}"
        isPass=1
        LOG "[${LINENO}]mst status exec failed,iret=$iret."
        return 1
    fi

    ROCE_IB_LIST=$(echo "${mstinfo}" | grep -E "mt4117_pciconf|mt4099_pci_|mt4115_pciconf|mt4119_pciconf" | awk '{print $1}')
    if [ -z "${ROCE_IB_LIST}" ] ; then
        echo "Type: No IB/RoCE network adapter exists||BDF:--||NetName:--||OFED_Version:--||Firmware_Version:--" >>${RESULTFILE}
        LOG "[${LINENO}]No check is required because no IB/RoCE network adapter exists."
        return 0
    fi

    #检查配置文件是否存在
    if [ ! -f "${ofedConfigPath}/ofed${OFED_VER}.conf" ];then
        ErrInfoCommon "INFO:Get network adapter information failed." "${RESULTFILE}"
        isPass=1
        LOG "[${LINENO}]Get Congfig file(${ofedConfigPath}/ofed${OFED_VER}.conf) failed"
        return 1
    fi

    CheckRoceorIBFirmware "${mstinfo}"
    return 0
}

#入口函数
LOG "[$LINENO]start check network adapter."
CheckVersion

echo "${CurInspectFun}_Pass $isPass" >>${RESULTFILE}
LOG "[$LINENO]End check network adapter."
exit 0
