系统硬盘盘符和实际槽位对应关系脚本开发需求

之前有个客户需要我们提供一个可以在系统下展示硬盘盘符对应实际服务器上物理槽位的脚本,一开始没有什么思路,后面摸索了下对于板载直连的服务器,pci下设备是固定的,那么机器正常启动过程中,对应的槽位和盘符也是固定的,不过这类需求只能适用于硬盘板载直连的机器了,如果是在raid卡下的硬盘,这个规律可能就不统一了。所以根据这个规律实现了脚本,一开始是想着槽位图上哪个位置有盘就显示出来,没有就显示X,实现效果如下图。后面客户表示不需要这样对应,只要能打印出来盘符和槽位的对应关系,槽位图显示完整的0-11就行,就重新改简单了


截图.PNG

实现代码如下,实现了amd和intel机型的12LFF机器直通硬盘的槽位显示

#!/bin/bash
function CheckPlatform(){
    if [[ `dmidecode | grep -i AMD` != "" ]];then
    echo -e "This is an AMD server\n"
    Platform="AMD"
    elif [[ `dmidecode | grep -i intel` != "" ]];then
    echo -e "This is an Intel server\n"
    Platform="INTEL"
    else
    echo "This is not an AMD nor an Intel server\n"
    fi
}

function CheckPresence()
{
if [[ `cat AHCIDisklist.log |awk '{print $2}'|grep ^$1$` != "" ]];then
    if [ $1 == 9 ]; then
            echo -e "$1  |"
    elif [ $1 == 10 ] || [ $1 == 11 ];then
            echo -e "$1 |"
    elif [ $1 == 1 ] || [ $1 == 2 ];then
            echo -e "|  $1  \c"
    else
            echo -e "$1  \c"
    fi
else
    if [ $1 == 9 ] || [ $1 == 10 ] || [ $1 == 11 ];then
            echo -e "X  |"
    elif [ $1 == 1 ] || [ $1 == 2 ];then
            echo -e "|  X  \c"
    else
            echo -e "X  \c"
    fi
fi

}

function GetINTELSlot() {
    for i in `grep -l Gbps /sys/class/ata_link/*/sata_spd`; do   #循环,打印当前所有盘的link信息,该信息与slot位置有关  
        #截取link信息中盘的link num,当前intel平台是3-14(12个SATA盘),每个位置对应固定的link num;
        linkLine=`basename ${i%/*} | sed 's/^....//' $1 `  
        #每个盘的host num是在link num数字上减一,即intel平台的host num是2-13;        
        hostNum=$[$linkLine-1]  
            if [ $hostNum -lt 6 ];then  #如果host num小于6,是sSATA控制器(因为配置是4个sSATA+8个SATA盘,且顺序是从sSATA开始排序,因此sSATA的host num是2、3、4、5;SATA的是6-13)
                slotNum=$[$linkLine -3]  #slot号是从0开始排序的,所以0-3是sSATA,根据link num算就是3-6,因此需要减3
                sdx=`ls -l /sys/class/block | grep -i host$hostNum/ |awk -F '/' '{print $NF}'|grep -Eo 'sd[a-z]'|uniq`  #抓取该host num对应的盘符
                model=`smartctl -i /dev/$sdx|grep "Device Model:"|awk -F: '{print $2}'|sed 's/ //g'`
                # cat "${i%/*}"/device/dev*/ata_device/dev*/id | perl -nE 's/([0-9a-f]{2})/print chr hex $1/gie' | echo `strings` | awk '{print $1}' | xargs printf "%-5s | %-4s%-2s | %-11s:%-3s | %-14s:%-20s\n" sSATA slot "$slotNum" Disk_Volume "$sdx" Disk_SerialNum `strings`  >> tmp_log.tmp 2>&1
                SN=$(cat "${i%/*}"/device/dev*/ata_device/dev*/id | perl -nE 's/([0-9a-f]{2})/print chr hex $1/gie' | echo `strings` | awk '{print $1}')
#               printf "%-15s %-10s %-10s %-s\n" sSATA $slotNum $sdx $SN  >> tmp_log.tmp 2>&1
                printf "%-15s %-10s %-10s %-20s %-s\n" sSATA $slotNum $sdx $SN $model >> tmp_log.tmp 2>&1
                #抓取该link num对应的盘序列号,并依次打印控制器类型、slot号、盘序列号和盘符
            elif [ $hostNum -ge 6 ];then  #host num大于等于6的是SATA控制器
                slotNum=$[$linkLine -3] #slot号是从4开始排序的,所以4-11是SATA,根据link num算就是7-14,因此也需要减3
                sdx=`ls -l /sys/class/block | grep -i host$hostNum/ |awk -F '/' '{print $NF}'|grep -Eo 'sd[a-z]'|uniq` #抓取该host num对应的盘符
                model=`smartctl -i /dev/$sdx|grep "Device Model:"|awk -F: '{print $2}'|sed 's/ //g'`
                SN=$(cat "${i%/*}"/device/dev*/ata_device/dev*/id | perl -nE 's/([0-9a-f]{2})/print chr hex $1/gie' | echo `strings` | awk '{print $1}')
                printf "%-15s %-10s %-10s %-20s %-s\n" SATA $slotNum $sdx $SN $model>> tmp_log.tmp 2>&1
                #抓取该link num对应的盘序列号,并依次打印控制器类型、slot号、盘序列号和盘符
            else
                echo "No AHCI device"
            fi
    done


# Sort the disk according to the block device name

printf "%-15s %-10s %-10s %-20s %-s\n" Controller Slot Volume  SerialNum Model
#判断是否存在AHCI device
if [ `cat tmp_log.tmp | wc -l` -eq 0 ]; then
 echo "No AHCI devices in the system"
 exit
fi
printf "%-15s %-10s %-10s %-20s %-s\n" Controller Slot Volume SerialNum Model> AHCIDisklist.log
cat tmp_log.tmp | sort -k 3 | tee -a AHCIDisklist.log
rm -rf tmp_log.tmp

echo -e "slot topo:\n"
echo " ------------- "
echo -e "|  \c"
for i in 0 3 6 9 1 4 7 10 2 5 8 11
do
    if [ $i == 1 ] || [ $i == 2 ];then
        echo " ------------- "
    fi
    CheckPresence $i
done
echo " ------------- "

}

function GetAMDSlot(){
#print hdd info
    for i in `grep -l Gbps /sys/class/ata_link/*/sata_spd`;do
        H=`basename ${i%/*} | sed 's/^....//'`  
        m=$[$H-1]
        echo $m >> num_temp.txt
    done

    for m in `sort -n num_temp.txt`;do
        if [[ $m == 0 ]];then
            sdx=`ls -l /sys/class/block/ | grep host0 | awk '{print $9}' | grep -Eo 'sd[a-z]'|uniq`
            Sn=`smartctl /dev/$sdx -a | grep -i Serial | awk '{print $3}'`
            mo=`smartctl -a /dev/$sdx | grep -i model | awk '{print $3,$4}'`
            echo "Slot:M.2 DiskSerialNumber:$Sn Volume:$sdx Model:$mo" | tee -a AHCIDisklist.log
        else    
            sdx=`ls -l /sys/class/block/ | grep host$m | awk '{print $9}' | grep -Eo 'sd[a-z]'|uniq`
            Sn=`smartctl /dev/$sdx -a | grep -i Serial | awk '{print $3}'`
            mo=`smartctl -a /dev/$sdx | grep -i model | awk '{print $3,$4}'`
            echo "Slot:$(($m-4)) DiskSerialNumber:$Sn Volume:$sdx Model:$mo" | tee -a AHCIDisklist.log
        fi
        
    done
#print nvme info
        E=`lsblk | grep -i nvme`
        if [[ $E != "" ]];then
                for i in `ls /sys/class/nvme`;do
                        Sn=`smartctl /dev/$i -a | grep -i Serial | awk '{print $3}'`
                        m=`ls -l /sys/class/nvme/ | grep -i $i | awk '{print $11}' | cut -c 44-45`
                        echo "Slot:Rear $(($(($(($m-1))/2))-13)) DiskSerialNumber:$Sn Volume:$i" | tee -a AHCIDisklist.log
                done
        else
                :
        fi
echo -e "\n"
echo -e "slot topo:\n"
echo " ------------- "
echo -e "|  \c"
echo -e "0  \c"
echo -e "3  \c"
echo -e "6  \c"
echo -e "9  |"
echo " ------------- "
echo -e "|  \c"
echo -e "1  \c"
echo -e "4  \c"
echo -e "7  \c"
echo -e "10 |"
echo " ------------- "
echo -e "|  \c"
echo -e "2  \c"
echo -e "5  \c"
echo -e "8  \c"
echo -e "11 |"
echo " ------------- "
rm -rf num_temp.txt

}

echo -e "[The script is to check the AHCI disks in the Meituan Mercury System]"
echo -e "[List the AHCI device:(The log is in the "AHCIDisklist.log")]"
[ -f AHCIDisklist.log ] && rm -rf AHCIDisklist.log

Platform="UNKNOW"

CheckPlatform

if [[ $Platform == "AMD" ]];then
    GetAMDSlot
elif [[ $Platform == "INTEL" ]];then
    GetINTELSlot
else
    :
fi

你可能感兴趣的:(系统硬盘盘符和实际槽位对应关系脚本开发需求)