스토리지 마이그레이션을 위한 LUN 갯수 체크 스크립트.

기존 VIOLIN 스토리지에서 HITACHI 스토리지로 변경하면서 LUN 갯수는 같지만 패스의 갯수가 달라짐.

많은 서버를 일일히 확인하기 쉽지 않으므로 자동으로 체크해 주는 스크립를 짰다.

vxdisk 라는 베리타스파일시스템 명령어가 있는 환경이어야 동작한다.

 

luncheck.sh

#!/bin/bash
# This script for storage migration. Wirriten by mahyun.kim.

##### User Define Variable Start #####
. ./var_luncheck.conf
######################################

##### Script Code Start #####
# User check and command setting
WHO=$(whoami)

if [ $UID = "0" ] || [ $WHO = $MANAGEMENTUSER ]; then
    if [ $UID != "0" ]; then
        VXCOMMAND1='sudo /sbin/vxdisk'
        VXCOMMAND2='sudo /sbin/vxdmpadm'
    elif [ $UID = "0" ]; then
        VXCOMMAND1='/sbin/vxdisk'
        VXCOMMAND2='/sbin/vxdmpadm'
    fi
elif [ $UID != "0" ] || [ $WHO != $MANAGEMENTUSER ]; then
    echo "It's only able to excute by root or system management user."
    exit 0
fi

# Variable of option
ARGS=1
E_BADARGS=65

# Function of 'How to'
HowTo () {
if [ $# -ne $ARGS ]; then
    echo "How to : ./`basename $0` -option"
    echo ""
    echo "The options are :"
    echo "-q : quiet mode"
    echo "-v : verbose mode"
    echo "-h : help"
    exit $E_BADARGS
fi
}

# Function of Verbose
VerBose () {

BORDER1=$(echo "=================================================")
BORDER2=$(echo "-------------------------------------------------")

ENCLR1PORT=$(echo `$VXCOMMAND2 listctlr all | grep $CONTROLLER1 | awk '{print $1}' | sed 's/c/\[/g'` | awk '{print "\\"$1"|\\"$2""}')
ENCLR2PORT=$(echo `$VXCOMMAND2 listctlr all | grep $CONTROLLER2 | awk '{print $1}' | sed 's/c/\[/g'` | awk '{print "\\"$1"|\\"$2""}')

APATHINFO=$(lsscsi | egrep $ENCLR1PORT | grep -v encl)
TPATHINFO=$(lsscsi | egrep $ENCLR2PORT | grep -v encl)

ASISSTOR=$(echo "$APATHINFO" | head -1 | awk '{print $3}')
TOBESTOR=$(echo "$TPATHINFO" | head -1 | awk '{print $3}')

TIDS=$($VXCOMMAND1 list | awk '{print $1}' | grep $CONTROLLER1 | grep -v DEVICE)
AIDS=$($VXCOMMAND1 list | awk '{print $1}' | grep $CONTROLLER2 | grep -v DEVICE)

echo $BORDER1
echo -e "vxdisk list - $ASISSTOR  :"

for ALIST in $AIDS;
do
    ADEVICES=$($VXCOMMAND1 list $ALIST | tail -n 1 | awk '{print $1}')
    for ABLOCKS in $ADEVICES;
    do
        ARESULT=$(cat /proc/partitions | egrep "\ $ABLOCKS$" | awk -F " " '{print $3 " " $4}' | egrep -v [1-9]$ | awk '{print $1}')
        echo $ARESULT >> ~/lun_check_atemp.txt
        ARR=$(echo $ARESULT)
        for VALUE in "${ARR[@]}"
        do 
            echo "$ALIST  $ADEVICES  $VALUE (`bc <<< "$VALUE/1024/1024"` GB)" >> ~/lun_check_atemp0.txt
        done
    done
done
column -t ~/lun_check_atemp0.txt | sort -n -k 3

ADEVICENUM=$(cat ~/lun_check_atemp0.txt | sort -n -k 3 | wc -l)
echo $BORDER2
echo "$ASISSTOR Number of LUNs : $ADEVICENUM"
echo $BORDER2
rm -f ~/lun_check_atemp0.txt

echo $BORDER2
echo -e "vxdisk list - $TOBESTOR :"

for TLIST in $TIDS;
do
    TDEVICES=$($VXCOMMAND1 list $TLIST | tail -n 1 | awk '{print $1}')
    for TBLOCKS in $TDEVICES;
    do 
        TRESULT=$(cat /proc/partitions | egrep "\ $TBLOCKS$" | awk -F " " '{print $3 " " $4}' | egrep -v [1-9]$ | awk '{print $1}')
	echo $TRESULT >> ~/lun_check_ttemp.txt
        ARR=$(echo $TRESULT)
        for VALUE in "${ARR[@]}"
        do 
            echo "$TLIST  $TDEVICES  $VALUE (`bc <<< "$VALUE/1024/1024"` GB)" >> ~/lun_check_ttemp0.txt
        done
    done
done
column -t ~/lun_check_ttemp0.txt | sort -n -k 3

TDEVICENUM=$(cat ~/lun_check_ttemp0.txt | sort -n -k 3 | wc -l)
echo $BORDER2
echo "$TOBESTOR Number of LUNs : $TDEVICENUM"
echo $BORDER2
rm -f ~/lun_check_ttemp0.txt

cat ~/lun_check_ttemp.txt | sort > ~/lun_check_ttemp_sort.txt
cat ~/lun_check_atemp.txt | sort > ~/lun_check_atemp_sort.txt

diff ~/lun_check_ttemp_sort.txt ~/lun_check_atemp_sort.txt
if [ $? == "0" ]; then
    echo "Number of LUNs is Same."
    echo -e "\033[1;32mResult : OK. \033[0m"
    echo $BORDER1
    flag2=1
else
    echo -e "\033[1;31mResult : Abnormal, Check size(or number) of storage. \033[0m"
    echo $BORDER1
    flag2=0
fi

rm -f ~/lun_check_*.txt

ASISHBA1LUNS=$(echo "$APATHINFO" | awk -F ":" '{print $1}' | grep -F `echo "$APATHINFO" | awk -F ":" '{print $1}' | uniq | sort | head -1` | wc -l)
ASISHBA2LUNS=$(echo "$APATHINFO" | awk -F ":" '{print $1}' | grep -F `echo "$APATHINFO" | awk -F ":" '{print $1}' | uniq | sort | tail -1` | wc -l)
TOBEHBA1LUNS=$(echo "$TPATHINFO" | awk -F ":" '{print $1}' | grep -F `echo "$TPATHINFO" | awk -F ":" '{print $1}' | uniq | sort | head -1` | wc -l)
TOBEHBA2LUNS=$(echo "$TPATHINFO" | awk -F ":" '{print $1}' | grep -F `echo "$TPATHINFO" | awk -F ":" '{print $1}' | uniq | sort | tail -1` | wc -l)

SUB11=$(bc <<< "scale=1;$ASISHBA1LUNS/$ADEVICENUM")
SUB12=$(bc <<< "scale=1;$ASISHBA2LUNS/$ADEVICENUM")
SUB21=$(bc <<< "scale=1;$TOBEHBA1LUNS/$TDEVICENUM")
SUB22=$(bc <<< "scale=1;$TOBEHBA2LUNS/$TDEVICENUM")

ASISHBA1PICNUM=$(echo "$APATHINFO" | awk -F ":" '{print $1}' | uniq | sort | head -1 | sed 's/\[//g')
ASISHBA2PICNUM=$(echo "$APATHINFO" | awk -F ":" '{print $1}' | uniq | sort | tail -1 | sed 's/\[//g')
TOBEHBA1PICNUM=$(echo "$TPATHINFO" | awk -F ":" '{print $1}' | uniq | sort | head -1 | sed 's/\[//g')
TOBEHBA2PICNUM=$(echo "$TPATHINFO" | awk -F ":" '{print $1}' | uniq | sort | tail -1 | sed 's/\[//g')

echo ""
echo $BORDER1

if [ $SUB11 == $ASISPATHNUM ]; then
    echo -e "PCI Slot $ASISHBA1PICNUM - $ASISSTOR's HBA CARD PATH : \033[1;32mOK. \033[0m"
    echo -e "PATH : $SUB11, Total LUNs : $ASISHBA1LUNS"
    echo $BORDER2
    flag11=1
else
    echo -e "\033[1;31mResult : Abnormal, PCI Slot $ASISHBA1PICNUM - Check path of storage. \033[0m"
    echo -e "PATH : $SUB11, Total LUNs : $ASISHBA1LUNS"
    echo $BORDER2
    flag11=0
fi

if [ $SUB12 == $ASISPATHNUM ]; then
    echo -e "PCI Slot $ASISHBA2PICNUM - $ASISSTOR's HBA CARD PATH : \033[1;32mOK. \033[0m"
    echo -e "PATH : $SUB12, Total LUNs : $ASISHBA2LUNS"
    echo $BORDER2
    flag12=1
else
    echo -e "\033[1;31mResult : Abnormal, PCI Slot $ASISHBA2PICNUM - Check path of storage. \033[0m"
    echo -e "PATH : $SUB12, Total LUNs : $ASISHBA2LUNS"
    echo $BORDER2
    flag12=0
fi

if [ $SUB21 == $TOBEPATHNUM ]; then
    echo -e "PCI Slot $TOBEHBA1PICNUM - $TOBESTOR's HBA CARD PATH : \033[1;32mOK. \033[0m"
    echo -e "PATH : $SUB21, Total LUNs : $TOBEHBA1LUNS"
    echo $BORDER2
    flag21=1
else
    echo -e "\033[1;31mResult : Abnormal, PCI Slot $TOBEHBA1PICNUM - Check path of storage. \033[0m"
    echo -e "PATH : $SUB21, Total LUNs : $TOBEHBA1LUNS"
    echo $BORDER2
    flag21=0
fi

if [ $SUB22 == $TOBEPATHNUM ]; then
    echo -e "PCI Slot $TOBEHBA2PICNUM - $TOBESTOR's HBA CARD PATH : \033[1;32mOK. \033[0m"
    echo -e "PATH : $SUB22, Total LUNs : $TOBEHBA2LUNS"
    echo $BORDER2
    flag22=1
else
    echo -e "\033[1;31mResult : Abnormal, PCI Slot $TOBEHBA2PICNUM - Check path of storage. \033[0m"
    echo -e "PATH : $SUB22, Total LUNs : $TOBEHBA2LUNS"
    echo $BORDER2
    flag22=0
fi

APATHNUM=$(echo "$APATHINFO" | wc -l)
TPATHNUM=$(echo "$TPATHINFO" | wc -l)

SUB0=$(bc <<< "scale=1;$APATHNUM/$TPATHNUM")

echo "Total Path Number of $ASISSTOR Storage :" $APATHNUM
echo "Total Path Number of $TOBESTOR Storage :" $TPATHNUM
echo "$ASISSTOR is $SUB0 times larger than $TOBESTOR."
if [ $SUB0 == $DIFFTIMES ]; then
    echo -e "\033[1;32mResult : OK. \033[0m"
    echo $BORDER1
    flag1=1
else
    echo -e "\033[1;31mResult : Abnormal, Check path of storage. \033[0m"
    echo $BORDER1
    flag1=0
fi

}

# Code of excution with option
if [ "$1" == "-v" ]; then
    VerBose ;
elif [ "$1" == "-q" ]; then
    VerBose >& /dev/null ;
    if [ $flag1 == "1" ] && [ $flag2 == "1" ] && [ $flag11 == "1" ] && [ $flag12 == "1" ] && [ $flag21 == "1" ] && [ $flag22 == "1" ]; then
	echo -e "\033[1;32mResult : OK. \033[0m"
    else
        echo -e "\033[1;31mResult : Abnormal, Check the LUN. \033[0m"
        echo -e "Run luncheck.sh in verbose mode."
    fi
else
    HowTo ;
fi

##### Script Code End  #####

 

#IFS=$'\n' ARR=$(echo $TRESULT)

->

ARR=$(echo $TRESULT)

변경한 이유는 root는 괜찮은데 akcmamip 계정으로 돌리면 $VXCOMMAND 변수의 내용에 ' ' 가 붙어서 명령어 실행 시 commnad not found 에러가 발생.

따라서 IFS 부분을 생략한 것 적용.

 

portcheck.sh

#!/bin/bash

# Variable of option
ARGS=1
E_BADARGS=65

# Function of 'How to'
HowTo () {
if [ $# -ne $ARGS ]; then
    echo "How to : ./`basename $0` -option"
    echo ""
    echo "The options are :"
    echo "-c : compare mode(port changed)"
    echo "-v : verbose mode"
    echo "-h : help"
    exit $E_BADARGS
fi
}

VerBose () {
HOSTLIST=$(ls /sys/class/fc_host | sed 's/host//g')
HOSTLISTCOUNT=$(ls /sys/class/fc_host | sed 's/host//g' | wc -l)
echo "-----------------------------------------------------"
echo "- SERVER  HOST  HBA_CARD_PORT      STORAGE_PORT"
echo "-----------------------------------------------------"
COUNTER=0
for i in $HOSTLIST
do
    STORAGELIST=$(cat /sys/class/fc_host/host$i/device/rport-$i*/fc_remote_ports/rport-$i*/port_name | sort)
    HBALIST=$(cat /sys/class/fc_host/host$i/port_name)
    for a in $HBALIST
    do
       for b in $STORAGELIST
       do
           echo $HOSTNAME "host"$i $a" "$b 
           COUNTER=$((COUNTER + 1))
       done
    done
done
echo "-----------------------------------------------------"
echo "- Total of HBA_CARD_PORT : $HOSTLISTCOUNT"
echo "- Total of STORAGE_PORT  : $COUNTER"
echo "-----------------------------------------------------"
}

# Code of excution with option
if [ "$1" == "-v" ]; then
    VerBose ;
elif [ "$1" == "-c" ]; then
    TOBEPORT=$(cat var_portcheck.conf | grep $HOSTNAME | awk '{print $2}' | sort | uniq | tr '\n' '|' | rev | cut -c 2- | rev)
    ASISPORT=$(VerBose | egrep "$TOBEPORT" | sort > var_portcheck_temp2.conf)
    cat var_portcheck.conf | grep $HOSTNAME | sort > var_portcheck_temp1.conf
    diff var_portcheck_temp1.conf var_portcheck_temp2.conf
    if [ $? == "0" ]; then
        echo -e "\033[1;32mResult : OK. \033[0m"
    else
        echo -e "\033[1;31mResult : Abnormal, Check the PORT. \033[0m"
        echo -e "Run portcheck.sh in verbose mode."        
    fi
    rm -f var_portcheck_temp{1,2}.conf
else
    HowTo ;
fi

 

report_info.sh

#!/bin/bash
CurrTime=`date +%Y-%m-%d"_"%T`

echo "========== Host Info ==========" >> ~/report_vol_info_"$HOSTNAME"_$CurrTime.txt
echo "$HOSTNAME" >> ~/report_vol_info_"$HOSTNAME"_$CurrTime.txt
date >> ~/report_vol_info_"$HOSTNAME"_$CurrTime.txt

echo "" >> ~/report_vol_info_"$HOSTNAME"_$CurrTime.txt
echo "========= vmem0 info ==========" >> ~/report_vol_info_"$HOSTNAME"_$CurrTime.txt
sudo /sbin/vxdisk list `sudo /sbin/vxdisk list | grep vmem0_ | head -1 | awk '{print $1}'` | grep -e ^sd -e ^numpaths >> ~/report_vol_info_"$HOSTNAME"_$CurrTime.txt

echo "" >> ~/report_vol_info_"$HOSTNAME"_$CurrTime.txt
echo "========= vmem1 info ==========" >> ~/report_vol_info_"$HOSTNAME"_$CurrTime.txt
sudo /sbin/vxdisk list `sudo /sbin/vxdisk list | grep vmem1_ | head -1 | awk '{print $1}'` | grep -e ^sd -e ^numpaths >> ~/report_vol_info_"$HOSTNAME"_$CurrTime.txt

echo "" >> ~/report_vol_info_"$HOSTNAME"_$CurrTime.txt
echo "======= Partition info ========" >> ~/report_vol_info_"$HOSTNAME"_$CurrTime.txt
cat /proc/partitions >> ~/report_vol_info_"$HOSTNAME"_$CurrTime.txt

echo "" >> ~/report_vol_info_"$HOSTNAME"_$CurrTime.txt
echo "========= lsscsi info =========" >> ~/report_vol_info_"$HOSTNAME"_$CurrTime.txt
lsscsi >> ~/report_vol_info_"$HOSTNAME"_$CurrTime.txt

echo "" >> ~/report_vol_info_"$HOSTNAME"_$CurrTime.txt
echo "=========== df info ===========" >> ~/report_vol_info_"$HOSTNAME"_$CurrTime.txt
df -h >> ~/report_vol_info_"$HOSTNAME"_$CurrTime.txt

echo "" >> ~/report_vol_info_"$HOSTNAME"_$CurrTime.txt
echo "====== LUN_check result =======" >> ~/report_vol_info_"$HOSTNAME"_$CurrTime.txt
/home/akcmamip/luncheck/luncheck.sh -v >> ~/report_vol_info_"$HOSTNAME"_$CurrTime.txt

echo "" >> ~/report_vol_info_"$HOSTNAME"_$CurrTime.txt
echo "======== SAN Port info ========" >> ~/report_vol_info_"$HOSTNAME"_$CurrTime.txt
/home/akcmamip/luncheck/portcheck.sh -v >> ~/report_vol_info_"$HOSTNAME"_$CurrTime.txt

 

var_luncheck.conf

CONTROLLER1=hitachi_vspgx1
CONTROLLER2=hitachi_vspgx0
ASISPATHNUM=1.0
TOBEPATHNUM=1.0
DIFFTIMES=1.0
MANAGEMENTUSER=akcmamip

 

var_portcheck.conf

akgmsapf1 host3 0x5001438024253690 0x50060e801233c000
akgmsapf1 host4 0x5001438024253692 0x50060e8012311804
akgmsapf1 host5 0x500143802425383c 0x50060e801233c010
akgmsapf1 host6 0x500143802425383e 0x50060e8012311814
akgodapf1 host2 0x5001438021e09894 0x50060e801233c021
akgodapf1 host3 0x5001438021e09896 0x50060e8012311865
akgodapf1 host4 0x5001438024253e9c 0x50060e801233c031
akgodapf1 host5 0x5001438024253e9e 0x50060e8012311875
akgchapf1 host3 0x5001438024253708 0x50060e801233c001
akgchapf1 host4 0x500143802425370a 0x50060e8012311805
akgchapf1 host5 0x500143802425370c 0x50060e801233c011
akgchapf1 host6 0x500143802425370e 0x50060e8012311815
akgchapf2 host3 0x500143802425363c 0x50060e801233c000
akgchapf2 host4 0x500143802425363e 0x50060e8012311804
akgchapf2 host5 0x5001438024253fdc 0x50060e801233c010
akgchapf2 host6 0x5001438024253fde 0x50060e8012311814
akgchapf3 host3 0x5001438021e096d0 0x50060e801233c021
akgchapf3 host4 0x5001438021e096d2 0x50060e8012311825
akgchapf3 host5 0x5001438021e09874 0x50060e801233c031
akgchapf3 host6 0x5001438021e09876 0x50060e8012311835
akgtrapf1 host3 0x5001438024253f40 0x50060e801233c020
akgtrapf1 host4 0x5001438024253f42 0x50060e8012311864
akgtrapf1 host5 0x5001438024253ccc 0x50060e801233c030
akgtrapf1 host6 0x5001438024253cce 0x50060e8012311874
akgtrapf2 host3 0x5001438021e099f8 0x50060e801233c021
akgtrapf2 host4 0x5001438021e099fa 0x50060e8012311865
akgtrapf2 host5 0x5001438021e096dc 0x50060e801233c031
akgtrapf2 host6 0x5001438021e096de 0x50060e8012311875
akgtrapf3 host3 0x5001438024253be4 0x50060e801233c001
akgtrapf3 host4 0x5001438024253be6 0x50060e8012311805
akgtrapf3 host5 0x5001438024253638 0x50060e801233c011
akgtrapf3 host6 0x500143802425363a 0x50060e8012311815
akgtrapf4 host3 0x5001438021e09e44 0x50060e801233c000
akgtrapf4 host4 0x5001438021e09e46 0x50060e8012311844
akgtrapf4 host5 0x5001438021e099dc 0x50060e801233c010
akgtrapf4 host6 0x5001438021e099de 0x50060e8012311854
akgtrapf5 host3 0x5001438021e09e40 0x50060e801233c001
akgtrapf5 host4 0x5001438021e09e42 0x50060e8012311845
akgtrapf5 host5 0x5001438021e099b4 0x50060e801233c011
akgtrapf5 host6 0x5001438021e099b6 0x50060e8012311855
akgtrapf6 host3 0x5001438021e09e8c 0x50060e801233c020
akgtrapf6 host4 0x5001438021e09e8e 0x50060e8012311864
akgtrapf6 host5 0x5001438021e09d7c 0x50060e801233c030
akgtrapf6 host6 0x5001438021e09d7e 0x50060e8012311874
akgtsapf1 host1 0x5001438024253a98 0x50060e801233c020
akgtsapf1 host2 0x5001438024253a9a 0x50060e8012311824
akgtsapf1 host3 0x5001438024253808 0x50060e801233c030
akgtsapf1 host4 0x500143802425380a 0x50060e8012311834
akgtsapf2 host1 0x5001438024253a34 0x50060e801233c021
akgtsapf2 host2 0x5001438024253a36 0x50060e8012311835
akgtsapf2 host3 0x5001438024253ee8 0x50060e801233c031
akgtsapf2 host4 0x5001438024253eea 0x50060e8012311825
akgtsapf3 host1 0x5001438024253838 0x50060e801233c000
akgtsapf3 host2 0x500143802425383a 0x50060e8012311844
akgtsapf3 host3 0x5001438024253f24 0x50060e801233c010
akgtsapf3 host4 0x5001438024253f26 0x50060e8012311854
akgtsdbf1 host2 0x5001438024253c74 0x50060e801233c020
akgtsdbf1 host3 0x5001438024253c76 0x50060e8012311824
akgtsdbf1 host4 0x50014380242539e4 0x50060e801233c030
akgtsdbf1 host5 0x50014380242539e6 0x50060e8012311834
akgtsdbf2 host2 0x5001438024253904 0x50060e801233c001
akgtsdbf2 host3 0x5001438024253906 0x50060e8012311845
akgtsdbf2 host4 0x5001438024253a0c 0x50060e801233c011
akgtsdbf2 host5 0x5001438024253a0e 0x50060e8012311855
akgmsdbf1 host2 0x5001438024253c98 0x50060e801233c000
akgmsdbf1 host3 0x5001438024253c9a 0x50060e8012311804
akgmsdbf1 host4 0x5001438024253958 0x50060e801233c010
akgmsdbf1 host5 0x500143802425395a 0x50060e8012311814

 

아래는 스크립트 파일임.

201708281327_luncheck

luncheck 스크립트.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다