스토리지 마이그레이션을 위한 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
아래는 스크립트 파일임.
luncheck 스크립트.