#!/bin/bash

#Check if hifcadm is installed
hifcadm_path_list=`which hifcadm`
if [ -z $hifcadm_path_list ];then
	echo "ERROR: The hifcadm tool can not be used"
	exit 1
fi

DATE_STR="$(date +%Y%m%d%H%M)_log"

#get_os_info
KERNEL_TYPE="$(uname -s)"
messagesnum=3

#Check OS type
if [[ $KERNEL_TYPE = "Linux" ]]
then
	if [[ "" != $1 ]];then
		DATE_STR=$1	
	fi
	DATE_STR_PATTERN='^[0-9]{12}_log$'
	if [[ $DATE_STR =~ $DATE_STR_PATTERN ]];then
		echo -e "File name is OK"
	else
		echo -e "Error:File name is Invalid"
		exit 1
	fi
	LOG_PATH=/opt/hifc
	if [ ! -e $LOG_PATH ]; then
		mkdir $LOG_PATH
		if [[ 0 -ne $? ]];then
			exit 1
		fi
	fi
	mkdir $LOG_PATH/${DATE_STR}
	if [[ 0 -ne $? ]];then
		exit 1
	fi
	mkdir $LOG_PATH/${DATE_STR}/message
	if [[ 0 -ne $? ]];then
		rm $LOG_PATH/${DATE_STR}
		exit 1
	fi
elif [[ $KERNEL_TYPE = "VMkernel" ]]
then
	LOG_PATH=/scratch/hifc
	if [ ! -e $LOG_PATH ]; then
		mkdir $LOG_PATH
		if [[ 0 -ne $? ]];then
		        exit 1
	        fi
	fi
	mkdir $LOG_PATH/${DATE_STR}
	if [[ 0 -ne $? ]];then
		exit 1
	fi
	mkdir $LOG_PATH/${DATE_STR}/syslog
	if [[ 0 -ne $? ]];then
		exit 1
	fi
	mkdir $LOG_PATH/${DATE_STR}/vmkernel
	if [[ 0 -ne $? ]];then
		exit 1
	fi
	mkdir $LOG_PATH/${DATE_STR}/vmkwarning
	if [[ 0 -ne $? ]];then
		exit 1
	fi

fi


checkenvironment()
{
	#check os supported lspci or not
	if [[ ! -n "which lspci" ]];then
	
		echo "WARNING: this OS not supported lscpi command"
		return 1

	fi
	
	if [ $KERNEL_TYPE = "Linux" ];then
	
		#check lspci info
		if [[ -z "lspci -d 19e5:0202" && -z "lspci -d 19e5:0203" && -z "lspci -d 19e5:0212" ]];then

			echo "Info: There is no HW device." |tee -a $LOG_PATH/${DATE_STR}/collect_log.txt
			return 1
		fi
		#check driver info
		lsmod | grep hifc >/dev/null
		
	elif [ $KERNEL_TYPE = "VMkernel" ];then
	
		#check lspci info
		if [[ -z "lspci |grep SP52" && -z "lspci |grep IN300" ]];then

			echo "Info: There is no HW device." |tee -a $LOG_PATH/${DATE_STR}/collect_log.txt
			return 1
		fi
		#check driver info
		esxcli software vib list|grep hifc > /dev/null
		
	fi
	
	if [[ $? -ne 0 ]];then
		echo "ERROR: NO hifc driver." |tee -a $LOG_PATH/${DATE_STR}/collect_log.txt
		return 1
	fi
	

	NAME_OF_CARD=`hifcadm info |grep "(FC_" |grep -o hifc.`
	if [ -z "$NAME_OF_CARD" ];then

		echo "ERROR:NO HW Card " |tee -a $LOG_PATH/${DATE_STR}/collect_log.txt
		return 1
	fi

	NAME_OF_PORT=`hifcadm info |grep "FC:" |grep -o hifc[0-9][0-9][0-9][0-9]`
	if [ -z "$NAME_OF_PORT" ];then
	
		echo "ERROR:NO FC Port " |tee -a $LOG_PATH/${DATE_STR}/collect_log.txt
		return 1
	fi
	return 0
}

packmessage()
{
	cd $LOG_PATH
	chmod 400 ./${DATE_STR}/*
	tar zcvf ${DATE_STR}.tar.gz ${DATE_STR}/ |tee -a $LOG_PATH/${DATE_STR}/collect_log.txt
	chmod 400 ${DATE_STR}.tar.gz
	rm -rf ${DATE_STR}/ 
	cd -
}

collect_fmlog()
{
	hifcadm log -i $1 -a |tee -a $LOG_PATH/${DATE_STR}/collect_log.txt
	cp $LOG_PATH/fwlog/* $LOG_PATH/${DATE_STR}/
	rm -f $LOG_PATH/fwlog/*
}

collect_scsi_counter()
{
	session_num=0
	wait_str="Collecting session logs,please wait"
	index_str="."
	hifcadm fc_dfx -i $1 -m 4 >>$LOG_PATH/${DATE_STR}/scsi_counter.txt
	
	active_session_list=`hifcadm fc_dfx -i $1 -m 4|grep -B 100 "total active session"|grep -A 70 "active session scsi_id list"|grep ^[0-9]`	
	if [ -z "$active_session_list" ];then
		echo "WARNING: $1 NO Port Session " |tee -a $LOG_PATH/${DATE_STR}/collect_log.txt
		return 1
	fi

	for active_session in $active_session_list
	do
                let flag=session_num%20
		index=0
		if [[ 0 == $flag ]];then
			
			printf "%s\r" "$wait_str"
			wait_str=$wait_str$index_str
			let index++
			
		fi

		hifcadm fc_dfx -i $1 -m 5 -s $active_session >> $LOG_PATH/${DATE_STR}/scsi_counter.txt
		let session_num++

	done 
	if [[ index > 0 ]];then
		printf "\n"
	fi
}

main()
{
		#This script only support tow OS,such as linux and vmware
		if [[ $KERNEL_TYPE != "Linux" && $KERNEL_TYPE != "VMkernel" ]];then
			echo "KERNEL_TYPE=$KERNEL_TYPE"
			echo "Unknown kernel type. Collect log failed."
			exit 1
		fi
		
		echo "Check device information..." |tee -a $LOG_PATH/${DATE_STR}/collect_log.txt
		checkenvironment
		if [[ 0 != $? ]];then
			packmessage
			exit 1
		fi
		echo "Device information is OK" |tee -a $LOG_PATH/${DATE_STR}/collect_log.txt

		echo "Collecting OS infomation...." |tee -a $LOG_PATH/${DATE_STR}/collect_log.txt
		uname -a >> $LOG_PATH/${DATE_STR}/OS_info.log 
		
		if [ $KERNEL_TYPE = "Linux" ];then
			sys_log=messages
			if [ ! -e /var/log/messages ] && [ -e /var/log/syslog ]; then
			sys_log=syslog
			fi
			
			ps euf >> $LOG_PATH/${DATE_STR}/ps.log
			ps aux >> $LOG_PATH/${DATE_STR}/ps.log
			cat /proc/cpuinfo >> $LOG_PATH/${DATE_STR}/cpuinfo.log
			top -n 1 >> $LOG_PATH/${DATE_STR}/top.log 
			cat /proc/meminfo >> $LOG_PATH/${DATE_STR}/meminfo.log
			lsscsi >> $LOG_PATH/${DATE_STR}/lsscsi.txt
			ls -t /var/log/$sys_log* | head -$messagesnum |xargs -i -n1 cp {} $LOG_PATH/${DATE_STR}/message/ 
			
		elif [ $KERNEL_TYPE = "VMkernel" ];then
		
			cp_syslog=`ls -t /scratch/log/syslog* | head -$messagesnum`
			cp_vmkernel=`ls -t /scratch/log/vmkernel* | head -$messagesnum`
			cp_vmkwarning=`ls -t /scratch/log/vmkwarning* | head -$messagesnum`
			cp $cp_syslog $LOG_PATH/${DATE_STR}/syslog/ 
			cp $cp_vmkernel $LOG_PATH/${DATE_STR}/vmkernel/ 
			cp $cp_vmkwarning $LOG_PATH/${DATE_STR}/vmkwarning/
			
			cp /scratch/log/shell.log $LOG_PATH/${DATE_STR}/
			cp /scratch/log/vmksummary.log $LOG_PATH/${DATE_STR}/
			cp /scratch/log/hostd.log $LOG_PATH/${DATE_STR}/
			cp /scratch/log/vobd.log $LOG_PATH/${DATE_STR}/
			cp /scratch/log/vpxa.log $LOG_PATH/${DATE_STR}/
			
			vm_name_list=`ls -lt /vmfs/volumes/datastore*/|grep -n ^d|awk '{print $9}'`
			mkdir $LOG_PATH/${DATE_STR}/vmware_log/
			for vm_name in $vm_name_list
			do
				cp_vmwarelog=`ls -t /vmfs/volumes/datastore*/$vm_name/vmware*.log | head -$messagesnum` 2> /dev/null
				if [[ "$cp_vmwarelog" == "" ]];then
				
					echo "The $vm_name Virtual Machine has no vmware.log"
					
				else
				
						mkdir $LOG_PATH/${DATE_STR}/vmware_log/${vm_name}_log
						cp $cp_vmwarelog $LOG_PATH/${DATE_STR}/vmware_log/${vm_name}_log 
						
				fi			
			done
		fi
		
		lspci >> $LOG_PATH/${DATE_STR}/lspci.log 
		dmesg >> $LOG_PATH/${DATE_STR}/dmesg.log
		echo "OS infomation collect succeed" |tee -a $LOG_PATH/${DATE_STR}/collect_log.txt
		

		hifcadm fc_allinfo >> $LOG_PATH/${DATE_STR}/driver_info.txt
		hifcadm info >> $LOG_PATH/${DATE_STR}/driver_info.txt
		for p in $NAME_OF_PORT
		do 
			echo "Collecting port $p log...." |tee -a $LOG_PATH/${DATE_STR}/collect_log.txt
			
			
			echo -e "\n sfp info $p">>$LOG_PATH/${DATE_STR}/${p}_driver_info.txt
			hifcadm fc_sfpinfo -i $p >> $LOG_PATH/${DATE_STR}/${p}_driver_info.txt
			
			echo -e "\n TX&RX state counter $p">>$LOG_PATH/${DATE_STR}/${p}_driver_info.txt
			hifcadm fc_dfx -i $p -m 0 >> $LOG_PATH/${DATE_STR}/${p}_driver_info.txt
			
			echo -e "\n TX&RX error state counter $p">>$LOG_PATH/${DATE_STR}/${p}_driver_info.txt
			hifcadm fc_dfx -i $p -m 1 >> $LOG_PATH/${DATE_STR}/${p}_driver_info.txt
			
			echo -e "\n error state counter $p">>$LOG_PATH/${DATE_STR}/${p}_driver_info.txt
			hifcadm fc_dfx -i $p -m 2 >> $LOG_PATH/${DATE_STR}/${p}_driver_info.txt
			
			echo -e "\n link state counter $p">>$LOG_PATH/${DATE_STR}/${p}_driver_info.txt
			hifcadm fc_dfx -i $p -m 3 >> $LOG_PATH/${DATE_STR}/${p}_driver_info.txt
			
			echo -e "\n dif info $p">>$LOG_PATH/${DATE_STR}/${p}_driver_info.txt
			hifcadm fc_dfx -i $p -m 6 >> $LOG_PATH/${DATE_STR}/${p}_driver_info.txt
			
			echo -e "\n port xchg info $p">>$LOG_PATH/${DATE_STR}/${p}_driver_info.txt
			hifcadm fc_portxchg -i $p >> $LOG_PATH/${DATE_STR}/${p}_driver_info.txt
			
			echo -e "\n ohter info $p">>$LOG_PATH/${DATE_STR}/${p}_other_info.txt
			
			if [ $KERNEL_TYPE = "Linux" ];then
				hifcadm fc_qos -i $p -m 1 >> $LOG_PATH/${DATE_STR}/${p}_other_info.txt
				hifcadm fc_qos -i $p -m 3 >> $LOG_PATH/${DATE_STR}/${p}_other_info.txt
			fi
			hifcadm fc_bbscn -i $p -m 1 >> $LOG_PATH/${DATE_STR}/${p}_other_info.txt
			hifcadm fc_fec -i $p -m 2 >> $LOG_PATH/${DATE_STR}/${p}_other_info.txt
		
			echo -e "\n scsi counger $p">>$LOG_PATH/${DATE_STR}/scsi_counter.txt
			
			collect_scsi_counter $p

		done

		echo "Driver log collect succeed" |tee -a $LOG_PATH/${DATE_STR}/collect_log.txt
		
		for n in $NAME_OF_CARD
		do
			echo "Collecting $n firmware log...." |tee -a $LOG_PATH/${DATE_STR}/collect_log.txt
			
			echo -e "\n card $n version" >> $LOG_PATH/${DATE_STR}/${n}_card_info.txt
			hifcadm version -i $n >> $LOG_PATH/${DATE_STR}/${n}_card_info.txt
			echo -e "\n card $n temperature" >> $LOG_PATH/${DATE_STR}/${n}_card_info.txt
			hifcadm temperature -i $n >> $LOG_PATH/${DATE_STR}/${n}_card_info.txt
			
			echo -e "\n card $n Global Counter" >> $LOG_PATH/${DATE_STR}/${n}_ucode_counter.txt
			hifcadm counter -i $n -t 1 -x 22 >> $LOG_PATH/${DATE_STR}/${n}_ucode_counter.txt
			echo -e "\n card $n Functional Counter" >> $LOG_PATH/${DATE_STR}/${n}_ucode_counter.txt
			hifcadm counter -i $n -t 1 -x 23 >> $LOG_PATH/${DATE_STR}/${n}_ucode_counter.txt
			
			echo -e "\n card $n Common Counter" >> $LOG_PATH/${DATE_STR}/${n}_up_counter.txt
			hifcadm counter -i $n -t 0 -x 0 >> $LOG_PATH/${DATE_STR}/${n}_up_counter.txt
			hifcadm counter -i $n -t 0 -x 2 >> $LOG_PATH/${DATE_STR}/${n}_up_counter.txt	
			hifcadm counter -i $n -t 0 -x 3 >> $LOG_PATH/${DATE_STR}/${n}_up_counter.txt				
			echo -e "\n card $n FC Counter"  >> $LOG_PATH/${DATE_STR}/${n}_up_counter.txt
			hifcadm counter -i $n -t 0 -x 1 >> $LOG_PATH/${DATE_STR}/${n}_up_counter.txt
			
			echo -e "\n card $n mips_epc"  >> $LOG_PATH/${DATE_STR}/${n}_ucode_epc.txt
			hifcadm mips_epc show -i $n -b >>  $LOG_PATH/${DATE_STR}/${n}_mips_epc.txt
			hifcadm mips_epc -i $n -a >> $LOG_PATH/${DATE_STR}/${n}_mips_epc.txt
					
			echo -e "\n card $n hilink_param"  >> $LOG_PATH/${DATE_STR}/${n}_hilink_param.txt
			hifcadm hilink_param -i $n -t 0 >> $LOG_PATH/${DATE_STR}/${n}_hilink_param.txt
			hifcadm hilink_param -i $n -t 1 >> $LOG_PATH/${DATE_STR}/${n}_hilink_param.txt
			
			collect_fmlog $n

		done

		echo "Firmware log collect succeed" |tee -a $LOG_PATH/${DATE_STR}/collect_log.txt

	packmessage
	echo "Collect log success!"
	echo "The log dir: ${LOG_PATH}/${DATE_STR}.tar.gz !"
}

main

