#!/bin/bash
#Copyright (c) Huawei Technologies Co.,All rights reserved.

#tools version and release date is used to identify tool

#script direction
FILEDIRECTORY=$(dirname "$0")
cd "${FILEDIRECTORY}"
find ./ -type f | grep -Ev ".cfg|.ini|.doc|.chm" | xargs chmod u+x >/dev/null 2>&1
. modules/lib/log.sh

DOUBLE_QUOTE='"'
#get version
TOOL_VERSION=$(cat version.ini | awk 'NR==1')
TOOL_VERSION=${TOOL_VERSION#*${DOUBLE_QUOTE}}
TOOL_VERSION=${TOOL_VERSION%${DOUBLE_QUOTE}*}

#get release date
TOOL_RELEASE_DATE=$(cat version.ini | awk 'NR==2')
TOOL_RELEASE_DATE=${TOOL_RELEASE_DATE#*${DOUBLE_QUOTE}}
TOOL_RELEASE_DATE=${TOOL_RELEASE_DATE%${DOUBLE_QUOTE}*}

#get supported os list
REDHAT=`cat config.ini |grep "Redhat Support Version"|awk -F: '{print $2}'`
SLES=`cat config.ini |grep "SLES Support Version"|awk -F: '{print $2}'`
UBUNTU=`cat config.ini |grep "Ubuntu Support Version"|awk -F: '{print $2}'`

#collected log is saved to the direction
OUTPUTLOG="$(hostname)_$(date +%Y%m%d_%H%M%S)"

#get system type
SYS_TYPE=`uname -i`
#check is oem
OEM_TYPE=""
if [ -f "oem.ini" ];then
    OEM_TYPE="oem"
fi

#init subprocess directory
SUB_PROCESS_DIR="subprocess"
if [ -d ${SUB_PROCESS_DIR} ];then
  rm -rf ${SUB_PROCESS_DIR}
fi
mkdir ${SUB_PROCESS_DIR}

#log collection security mode
SECURITY_MODE="true"


################################################################
#Function:		<get_DA_lspci_info>
#Description:	get DA200 pci information 
#Parameter:	NA
#Return:	DA200 logs
#Since:		bigdata\logCollect.cfg
#Other:		N/a				
###################################################################
function get_DA_lspci_info()
{
    local log_dir="${OUTPUTLOG}/bigdata"
    local ret=0
    # Get fireware lspci info
    run_cmd "lspci | grep d501" "${log_dir}/lspci_log.txt"
    if [ 0 -ne $? ]
    then
        LOG_ERROR "Get DA200 pci info failed."
        ret=1
    else
        LOG_INFO "Get DA200 pci info succeed."
    fi    
    return $ret
}

################################################################
#Function:		<get_DA_selfdiag_info>
#Description:	get DA200 self diag information 
#Parameter:	NA
#Return:	DA200 logs
#Since:		bigdata\logCollect.cfg
#Other:		N/a				
###################################################################
function get_DA_selfdiag_info()
{
    local log_dir="${OUTPUTLOG}/bigdata"
    local ret=0
    pwd=`pwd`
    final="$pwd/$log_dir"
    # Get fireware lspci info
    if [ -d /opt/DA200/compress_tools/tools ]; then
        cd /opt/DA200/compress_tools/tools
        run_cmd "./dcadm selfdiag" "${final}/selfdiag_log.txt"
        if [ 0 -ne $? ]
        then
            LOG_ERROR "Get DA200 self diag info failed."
            ret=1
        else
            LOG_INFO "Get DA200 self diag info succeed."
        fi
        cd - 1>/dev/null
    fi
    return $ret
}

################################################################
#Function:		<get_logic_disk_map>
#Description:	get the disk map between logic and physical log file 
#Parameter:	NA
#Return:	logs
#Since:		logCollect.cfg
#Other:		N/a				
###################################################################
 function get_logic_disk_map()
{
 	local log_dir="${OUTPUTLOG}/raid/diskmap.txt"

    run_cmd "lsscsi" "${log_dir}"
    echo "get_logic_disk_map:The current server adopts the ${SYS_TYPE} architecture." >> ${log_dir}

 	if [ "${SYS_TYPE}" == "aarch64" ]; then
 	    TOOLS="opt/MegaRAID/storcli/storcli64_arm"
 	    echo "get_logic_disk_map:The current server adopts the ARM architecture." >> ${log_dir}
 	elif [ "${SYS_TYPE}" == "x86_64" ]; then
 		TOOLS="opt/MegaRAID/storcli/storcli64"
 	elif [ "${SYS_TYPE}" == "i386" ]; then
 		TOOLS="opt/MegaRAID/storcli/storcli"
 	else
 	    echo "get_logic_disk_map:The current server adopts the unknown architecture which does not support log collection." >> $log_dir
 	    return
 	fi
	num=`"${TOOLS}" show ctrlcount | grep "Controller Count"| awk -F "=" '{print $2}'| tr -d '\r\n'`
 	for((i=0;i<$num;i++))
 	do
 		run_cmd "${TOOLS} /c$i show" "${log_dir}"
	done
	return 0
}
################################################################
#Function:		<get_sas_raid_log>
#Description:	get lsi3108/2208 log file 
#Parameter:	NA
#Return:	logs
#Since:		logCollect.cfg
#Other:		N/a				
###################################################################
function get_sas_raid_log()
{
    local log_dir="${OUTPUTLOG}/raid/mega"
    run_cmd "mkdir -p ${log_dir}"
    local TOOLS=""
    local adpCnt=0
    local log_file="${log_dir}/sasraidlog.txt"

    echo "get_sas_raid_log:The current server adopts the ${SYS_TYPE} architecture." >> ${log_file}

    if [ "${SYS_TYPE}" == "aarch64" ]; then
        TOOLS="opt/MegaRAID/storcli/storcli64_arm"
        echo "get_sas_raid_log:use storcli64_arm to support log collection." >> ${log_file}
    elif [ "${SYS_TYPE}" == "x86_64" ]; then
        TOOLS="opt/MegaRAID/storcli/storcli64"
    elif [ "${SYS_TYPE}" == "i386" ]; then
        TOOLS="opt/MegaRAID/storcli/storcli"
    else
        echo "get_sas_raid_log:The current server adopts the unknown architecture which does not support log collection." >> ${log_file}
        return
    fi

    if [ "${SECURITY_MODE}" == "true" ]; then
        local raid_type=`lspci -D | grep LSI`
        if ( echo ${raid_type} |grep -q '3008' ); then
            echo "get_sas_raid_log:Currently, the security mode is used. By default, the storcli64 tool does not collect
            logs of the 3008 RAID controller card. If you need to use the storcli64 tool to collect logs of the
            3008 RAID controller card, Change the value of SECURITY_MODE in the infoCollect.sh file to false.">> ${log_file};
            return
        fi
    fi
     
    adpCnt=`$TOOLS /call show all| grep -i "device id" | wc -l`

    run_cmd "$TOOLS /call/vall show all" "${log_file}"

    run_cmd "$TOOLS /call show all" "${log_file}"

    run_cmd "$TOOLS /call/eall show all" "${log_file}"

    run_cmd "$TOOLS /call/eall/sall show all" "${log_file}"

    run_cmd "$TOOLS /call show alilog" "${log_file}"

    run_cmd "$TOOLS /call get snapdump ID=all" "${log_file}"

    run_cmd "$TOOLS /call/cv show all" "${log_file}"

    run_cmd "$TOOLS /call/pall show all" "${log_file}"

    # collect link errorcode log
    run_cmd "$TOOLS /call/eall show phyerrorcounters" "${log_file}"
    run_cmd "$TOOLS /call/eall/sall show phyerrorcounters" "${log_file}"

    for((adpNum=0;adpNum<adpCnt;adpNum++))
    do
       local logAdapterFile="${OUTPUTLOG}/raid/mega/sasraidlog_Adapter${adpNum}.txt"

       run_cmd "$TOOLS /c${adpNum}/vall show all" "${logAdapterFile}"

       run_cmd "$TOOLS /c${adpNum} show all" "${logAdapterFile}"

       run_cmd "$TOOLS /c${adpNum}/eall show all" "${logAdapterFile}"

       run_cmd "$TOOLS /c${adpNum}/eall/sall show all" "${logAdapterFile}"

       run_cmd "$TOOLS /c${adpNum} show alilog" "${logAdapterFile}"

       run_cmd "$TOOLS /c${adpNum}/bbu show" "${logAdapterFile}"

       run_cmd "$TOOLS /c${adpNum}/cv show all" "${logAdapterFile}"

       run_cmd "$TOOLS /c${adpNum}/pall show all" "${logAdapterFile}"

       run_cmd "$TOOLS /c${adpNum}/eall show phyerrorcounters" "${logAdapterFile}"

       run_cmd "$TOOLS /c${adpNum}/eall/sall show phyerrorcounters" "${logAdapterFile}"
    done
    return 0
}

################################################################
#Function:		<get_raid_snap_dump_log>
#Description:	get raid card snmp dump log info
#Parameter:	NA
#Return:	raid snmp dump log info
#Since:		raid/logCollect.cfg
#Other:		N/a
###################################################################
function get_raid_snap_dump_log()
{
    LOG_INFO "start to get raid snap dump log."
    local log_dir="${OUTPUTLOG}/raid/"
    local snmp_dump_result_file="${log_dir}snap_dump_result.txt"

    if [ "${SYS_TYPE}" == "aarch64" ]
    then
        TOOLS="opt/MegaRAID/storcli/storcli64_arm"
        LOG_INFO "get_raid_snap_dump_log:use storcli64_arm to support log collection."
    elif [ "${SYS_TYPE}" == "x86_64" ]
    then
        TOOLS="opt/MegaRAID/storcli/storcli64"
    elif [ "${SYS_TYPE}" == "i386" ]
    then
        TOOLS="opt/MegaRAID/storcli/storcli"
    else
        LOG_INFO "get_raid_snap_dump_log:The current server adopts the unknown architecture which does not support log collection."
        return 0
    fi

    # raid卡固件版本较高(raid fw版本>=5.09)才支持snapdump；OS侧驱动不兼容时也无法获取到snapdump
    # 查询snapdump信息
    run_cmd "${TOOLS} /call show snapdump" "${snmp_dump_result_file}"
    # 生成snapdump信息到当前目录
    run_cmd "${TOOLS} /call get snapdump ID=all" "${snmp_dump_result_file}"
    local snmp_dump_log_tmp_file=$(ls | grep -E "snapdump.*zip")

    if [ -z "${snmp_dump_log_tmp_file}" ]
    then
        LOG_INFO "get_raid_snap_dump_log: raid snmp dump log file is not exist."
        return 0
    fi

    # 拷贝匹配的全部文件
    for item in ${snmp_dump_log_tmp_file}
    do
        LOG_INFO "There is exist raid snmp dump log file, file name: ${item}."
        cp "${item}" "${log_dir}"
    done
    return 0
}

################################################################
#Function:		<get_lsi3008_log>
#Description:	get lsi3008 log file 
#Parameter:	NA
#Return:	3008 logs
#Since:		logCollect.cfg
#Other:		N/a				
###################################################################
function get_lsi3008_log()
{
    local mkdirlog_dir="${OUTPUTLOG}/raid/hba"
    run_cmd "mkdir -p ${mkdirlog_dir}"
    local sas3ircu="modules/raid/RAIDtool/3008/sas3ircu"
    local sas3flash="modules/raid/RAIDtool/3008/sas3flash"
    local log_file="${OUTPUTLOG}/raid/hba/sashbalog.txt"

    echo "get_lsi3008_log:The current server adopts the ${SYS_TYPE} architecture." >> ${log_file}

    if [ "${SYS_TYPE}" == "aarch64" ]; then
        echo "get_lsi3008_log:The current server adopts the ARM architecture." >> ${log_file}
        sas3ircu="modules/raid/RAIDtool_ARM/3008/sas3ircu"
    elif [ "${SYS_TYPE}" != "x86_64" ] && [ "${SYS_TYPE}" != "i386" ]; then
        echo "get_lsi3008_log:The current server adopts the unknown architecture which does not support log collection." >> ${log_file}
        return
    fi

    local adpCnt=`$sas3ircu LIST | grep "SAS3*" | grep -v "Adapter" | grep -v "Avago" | wc -l`

    run_cmd "${sas3ircu} LIST" "$log_file"
    for((adpNum=0;adpNum<adpCnt;adpNum++))
    do
        
        run_cmd "${sas3ircu} $adpNum display" "$log_file"

        if [ "${SYS_TYPE}" != "aarch64" ]; then
          run_cmd "${sas3flash} -c $adpNum -list" "$log_file"
        fi
        run_cmd "${sas3ircu}  $adpNum status" "$log_file"

        run_cmd "${sas3ircu}  $adpNum logir upload" "$log_file"
    done
    if [ -f "logir.log" ]
    then
        run_cmd "rm -rf logir.log"
    fi

    for((adpNum=0;adpNum<adpCnt;adpNum++))
    do

        local logAdapterFile="${OUTPUTLOG}/raid/hba/sashbalog_Adapter${adpNum}.txt"

        run_cmd "${sas3ircu} LIST" "$logAdapterFile"

        run_cmd "${sas3ircu} $adpNum display" "$logAdapterFile"
        if [ "${SYS_TYPE}" != "aarch64" ]; then
            run_cmd "${sas3flash} -c $adpNum -list" "$logAdapterFile"
        fi
        run_cmd "${sas3ircu}  $adpNum status" "$logAdapterFile"

        run_cmd "${sas3ircu}  $adpNum logir upload" "$logAdapterFile"
    done

    if [ -f "logir.log" ]
    then
        run_cmd "rm -rf logir.log"
    fi
    return 0

}

################################################################
#Function:		<get_PMC_log>
#Description:	get PMC RAID log file
#Parameter:	NA
#Return:	PMC RAID logs
#Since:		logCollect.cfg
#Other:		N/a
###################################################################
function get_PMC_log()
{
    local log_dir="${OUTPUTLOG}/raid/pmc"
    run_cmd "mkdir -p ${log_dir}"
    local arcconf="modules/raid/RAIDtool/PMC/arcconf"
    local arcconf_arm="modules/raid/RAIDtool/PMC/arcconf_arm"
    local log_file="${log_dir}/Support"

    LOG_INFO "get_PMC_log:The current server adopts the ${SYS_TYPE} architecture."

    if [ "${SYS_TYPE}" == "aarch64" ]; then
        run_cmd "${arcconf_arm} savesupportarchive"
    elif [ "${SYS_TYPE}" == "x86_64" ] ; then
        run_cmd "${arcconf} savesupportarchive"
    fi

    local file=`ls /var/log/Support/ | wc -l`
    if [ "$file" -gt "0" ]; then
        run_cmd "cp -r /var/log/Support $log_file"
        run_cmd "rm /var/log/Support"
    fi
    LOG_INFO "get_PMC_log success"
    return 0

}


################################################################
#Function:		<get_HI1880_RAID_log>
#Description:	get HUAWEI HI1880 RAID log file
#Parameter:	NA
#Return:	HUAWEI HI1880 RAID logs
#Since:		logCollect.cfg
#Other:		N/a
###################################################################
function get_HI1880_RAID_log()
{
    local log_dir="${OUTPUTLOG}/raid/huawei"
    run_cmd "mkdir -p ${log_dir}"
    local hiraidadm_log_collect_tool="modules/raid/hiraid_get_log.sh"
    local path=$("pwd")
    local log_path="${path//"//"//}/${log_dir}/"

    LOG_INFO "get_HI1880_RAID_log:The current server adopts the ${SYS_TYPE} architecture."

    run_cmd "./${hiraidadm_log_collect_tool} -f all -p ${log_path}"
    if [  0 -ne $? ]; then
        LOG_INFO "get_HI1880_RAID_log failed!"
        return 1
    fi

    LOG_INFO "get_HI1880_RAID_log success"
    return 0
}


################################################################
#Function:		<get_module_info>
#Description:	get modue info log 
#Parameter:	NA
#Return:	3008 logs
#Since:		driver\logCollect.cfg
#Other:		N/a				
###################################################################
function get_module_info()
{
    local log_dir="${OUTPUTLOG}/driver/modinfo.txt"
    local ret=0
    local cmd
    modinfo nvme >/dev/null 2>&1
    if [ 0 -eq $? ]
    then
        lsmod | awk '{
                    if(NR!=1)
                    {
                        print "modinfo " $1; 
                        print "{";
                        cmd = sprintf("modinfo %s",$1);
                        system(cmd);
                        print "}";
                    }
                }' >> "$log_dir"
                ret=$?
    else
        lsmod | grep -v "nvme" | awk '{
                    if(NR!=1)
                    {
                        print "modinfo " $1; 
                        print "{";
                        cmd = sprintf("modinfo %s",$1);
                        system(cmd);
                        print "}";
                    }
                }' >> "$log_dir"
                ret=$?
    fi
    
    if [ "${ret}" -eq 0 ]; then
        LOG_INFO "Get modinfo success"
    else
        LOG_ERROR "Get modinfo fail and exitCode is ${ret}"
    fi

    return "$ret"
}

################################################################
#Function:		<get_fc_port_state_info>
#Description:	get fc card port_state_info information 
#Parameter:	NA
#Return:	hba logs
#Since:		driver\logCollect.cfg
#Other:		N/a				
###################################################################
function get_fc_port_state_info()
{
    local log_dir="${OUTPUTLOG}/hba/"
    local ret=0

	cmd="ls /sys/class/fc_host/"
	result=$(eval "${cmd}" 2>&1)
	retCode=$? 	
	
	if [ 0 -ne ${retCode} ]
	then
	   ret=$retCode
	   LOG_ERROR "[$cmd] failed.Ret:$retCode. Desc:$result"
	   LOG_ERROR "Get fc error_frames info failed."
	else	
		for host in ${result}
		do
			if [ -f "/sys/class/fc_host/${host}/port_state" ]
			then
				run_cmd "cat /sys/class/fc_host/${host}/port_state" "${log_dir}/port_state.txt"
			fi
			if [ 0 -ne $? ]
			then
				ret=1
				LOG_ERROR "get fc port_state info failed"
			fi
		done
	fi
    return "$ret"
}

################################################################
#Function:		<get_fc_error_frame_crc_info>
#Description:	get fc card error_frames and  invalid_crc_count information 
#Parameter:	NA
#Return:	hba logs
#Since:		driver\logCollect.cfg
#Other:		N/a				
###################################################################
function get_fc_error_frame_crc_info()
{
    local log_dir="${OUTPUTLOG}/hba/"
    local ret=0

	cmd="ls /sys/class/fc_host/"
	result=$(eval "${cmd}" 2>&1)
	retCode=$? 	
	
	if [ 0 -ne ${retCode} ]
	then
	   ret=$retCode
	   LOG_ERROR "[$cmd] failed.Ret:$retCode. Desc:$result"
	   LOG_ERROR "Get fc error_frames info failed."
	else	
		for host in ${result}
		do
			if [ -f "/sys/class/fc_host/${host}/statistics/error_frames" ]
			then
				run_cmd "cat /sys/class/fc_host/${host}/statistics/error_frames" "${log_dir}/error_frame_crc.txt"
			fi
			if [ 0 -ne $? ]
			then
				ret=1
				LOG_ERROR "no fc port found or get error_frame info failed"
			fi

			if [ -f "/sys/class/fc_host/${host}/statistics/invalid_crc_count" ]
			then
				run_cmd "cat /sys/class/fc_host/${host}/statistics/invalid_crc_count" "${log_dir}/error_frame_crc.txt"
			fi
			if [ 0 -ne $? ]
			then
				ret=1
				LOG_ERROR "no fc port found or get invalid_crc_cout info failed"
			fi
		done
	fi
	return "$ret"
				
}

################################################################
#Function:		<get_fc_wwpn_info>
#Description:	get fc card wwpn information 
#Parameter:	NA
#Return:	hba logs
#Since:		driver\logCollect.cfg
#Other:		N/a				
###################################################################
function get_fc_wwpn_info()
{
    local log_dir="${OUTPUTLOG}/hba/"
    local ret=0

	cmd="ls /sys/class/fc_host/"
	result=$(eval "${cmd}" 2>&1)
	retCode=$? 	
	
	if [ 0 -ne ${retCode}  ]
	then
	   ret=$retCode
	   LOG_ERROR "[$cmd] failed.Ret:$retCode. Desc:$result"
	   LOG_ERROR "Get fc wwpn info failed."
	else	
		for host in ${result}
		do
			run_cmd "cat /sys/class/fc_host/${host}/port_name" "${log_dir}/wwpn.txt"
			if [ 0 -ne $? ]
			then
				ret=1
				LOG_ERROR "No fc port found or get wwpn info failed."
			fi
			run_cmd "cat /sys/class/fc_host/${host}/node_name" "${log_dir}/wwpn.txt"
			if [ 0 -ne $? ]
			then
				ret=1
				LOG_ERROR "No fc port found or get wwn info failed."
			fi
		done	
	fi

    return "$ret"
}

################################################################
#Function:		<get_fc_fw_info>
#Description:	get fc card firmware information 
#Parameter:	NA
#Return:	hba logs
#Since:		driver\logCollect.cfg
#Other:		N/a				
###################################################################
function get_fc_fw_info()
{
    local log_dir="${OUTPUTLOG}/hba/"
    local ret=0
	
	cmd="ls /sys/class/scsi_host/"
	result=$(eval "${cmd}" 2>&1)
	retCode=$? 	
	
	if [ 0 -ne "${retCode}"  ]
	then
	   ret=$retCode
	   LOG_ERROR "[$cmd] failed.Ret:$retCode. Desc:$result"
	   LOG_ERROR "Get fc fw info failed."
	else	
		for host in ${result}
		do
			if [ -f "/sys/class/scsi_host/${host}/fwrev" ]; then
           			run_cmd "cat /sys/class/scsi_host/${host}/fwrev" "${log_dir}/firmware_fc.txt"
			elif [ -f "/sys/class/scsi_host/${host}/fw_version" ]; then
				run_cmd "cat /sys/class/scsi_host/${host}/fw_version" "${log_dir}/firmware_fc.txt"
			fi	
			if [ 0 -ne $? ]
			then
				ret=1
				LOG_ERROR "No fc port found or get fw info failed."
			fi
		done	
	fi

    return "$ret"
}
################################################################
#Function:		<get_fc_driver_info>
#Description:	get fc card driver information 
#Parameter:	NA
#Return:	hba logs
#Since:		driver\logCollect.cfg
#Other:		N/a				
###################################################################
function get_fc_driver_info()
{
    local log_dir="${OUTPUTLOG}/hba/"
    local ret=0
	
	cmd="ls /sys/class/scsi_host/"
	result=$(eval "${cmd}" 2>&1)
	retCode=$? 	
	
	if [ 0 -ne "${retCode}"  ]
	then
	   ret=$retCode
	   LOG_ERROR "[$cmd] failed.Ret:$retCode. Desc:$result"
	   LOG_ERROR "Get fc driver info failed."
	else
		for host in ${result}
		do
			if [ -f "/sys/class/scsi_host/${host}/lpfc_drvr_version" ]; then
				run_cmd "cat /sys/class/scsi_host/${host}/lpfc_drvr_version" "${log_dir}/driver_fc.txt"
			elif [ -f "/sys/class/scsi_host/${host}/driver_version" ]; then
				run_cmd "cat /sys/class/scsi_host/${host}/driver_version" "${log_dir}/driver_fc.txt"
			fi
			if [ 0 -ne $? ]
			then
				ret=1
				LOG_ERROR "No fc port found or get fc driver info failed."
			fi
		done	
	fi

    return "$ret"
}

################################################################
#Function:      <get_reboot_info>
#Description:   get reboot information
#Parameter:     NA
#Return:        reboot info from last logs
#Since:         system\logCollect.cfg
#Other:         N/a
###################################################################
function get_reboot_info()
{
    local log_dir="${OUTPUTLOG}/system/"
    local ret=0
    run_cmd "/usr/bin/last -xF | grep 'reboot\|shutdown\|runlevel\|system'" "${log_dir}/command_log.txt"
    if [ 0 -ne $? ]
    then
        ret=1
        LOG_ERROR "Get reboot info from last failed."
    fi

    return "$ret"
}

###############################################################
#Function:      <get_filesystem_config_info>
#Description:   get filesystem config information
#Parameter: NA
#Return:    FileSystem config logs
#Since:     system\logCollect.cfg
#Other:     N/a
###################################################################
function get_filesystem_config_info()
{
    local log_dir="${OUTPUTLOG}/system"
    local ret=0
    # Get filesystem config
    configs=(
        "/proc/sys/vm/dirty_ratio"
        "/proc/sys/vm/dirty_background_ratio"
        "/proc/sys/vm/dirty_writeback_centisecs"
        "/proc/sys/vm/dirty_expire_centisecs"
        "/proc/sys/vm/vfs_cache_pressure"
        "/proc/sys/vm/swappiness"
    )
    for item in "${configs[@]}"
    do
        run_cmd "echo $item=`cat $item`" "${log_dir}/filesystem_config_log.txt"
        if [ 0 -ne $? ]
        then
            LOG_ERROR "Get filesystem config $item info failed."
            ret=1
        else
            LOG_INFO "Get filesystem config $item info succeed."
        fi
    done

    disks=$(fdisk -l | grep -E "Disk /dev/[sv]d" | awk -F '[ :]' '{print $2}' | awk -F '/dev/' '{print $2}')
    for disk in $disks
    do
        run_cmd "echo blockdev --getra /dev/${disk}=`blockdev --getra /dev/${disk}`" "${log_dir}/filesystem_config_log.txt"
        if [ 0 -ne $? ]
        then
            LOG_ERROR "Get filesystem config blockdev --getra /dev/${disk} failed."
            ret=1
        else
            LOG_INFO "Get filesystem config blockdev --getra /dev/${disk} succeed."
        fi
    done

    dev_configs=(
        "/sys/block/sdx/queue/scheduler"
        "/sys/class/block/sdx/device/block/sdx/queue/nr_requests"
        "/sys/class/block/sdx/device/block/sdx/queue/max_segments"
        "/sys/class/block/sdx/device/block/sdx/queue/max_sectors_kb"
        "/sys/class/block/sdx/device/block/sdx/queue/max_hw_sectors_kb"
        "/sys/class/block/sdx/device/block/sdx/queue/hw_sector_size"
        "/sys/class/block/sdx/device/queue_depth"
    )
    for item in "${dev_configs[@]}"
    do
        for disk in $disks
        do
            param=${item//sdx/${disk}}
            run_cmd "echo $param=`cat $param`" "${log_dir}/filesystem_config_log.txt"
            if [ 0 -ne $? ]
            then
                LOG_ERROR "Get filesystem config $param info failed."
                ret=1
            else
                LOG_INFO "Get filesystem config $param info succeed."
            fi
        done
    done

    return $ret
}

################################################################
#Function:		<get_aep_memory_info>
#Description:	get aep memory information
#Parameter:	NA
#Return:	aep memory logs
#Since:		memory\logCollect.cfg
#Other:		N/a
###################################################################
function get_aep_memory_info()
{
    local log_dir="${OUTPUTLOG}/memory/aep_memory_info.txt"
    local ret=0

    # Check whether the command is available
    ipmctl
    if [ 0 -ne $? ]
    then
        echo "Command ipmctl is not exist!" >> ${log_dir}
        return $ret
    fi

    ############# AEP内存信息收集 - 基本信息查看############
    # 显示已安装内存的拓扑
    run_cmd "ipmctl show -a -topology" "${log_dir}"
    # 显示所以DPCMM内存资源
    run_cmd "ipmctl show -memoryresources" "${log_dir}"
    # 显示DCPMM信息
    run_cmd "ipmctl show -dimm" "${log_dir}"
    # 显示平台配置数据
    run_cmd "ipmctl show -dimm -pcd" "${log_dir}"
    # 显示DCPMM的运行状况统计信息
    run_cmd "ipmctl show -sensor" "${log_dir}"
    # 显示DCPMM FW
    run_cmd "ipmctl show -dimm -firmware" "${log_dir}"

    ############ AEP内存信息收集 - 故障信息查看及收集############
    # 验证DCPMM主机邮箱是否可访问，是否可以读取基本运行状况指示器
    run_cmd "ipmctl start -diagnostic Quick -dimm" "${log_dir}"
    # 验证BIOS平台配置是否与安装的硬件匹配
    run_cmd "ipmctl start -diagnostic Config -dimm" "${log_dir}"
    # 验证所有DCPMM是否具有一致的安全状态
    run_cmd "ipmctl start -diagnostic Security -dimm" "${log_dir}"
    # 验证所有DCPMM FW是否一致
    run_cmd "ipmctl start -diagnostic FW -dimm" "${log_dir}"
    # 显示DCPMM上的热量或介质错误
    run_cmd "ipmctl show -error Thermal -dimm" "${log_dir}"
    run_cmd "ipmctl show -error media -dimm" "${log_dir}"

    return $ret
}

################################################################
#Function:		<get_eth_pci_info>
#Description:	get nic pci information 
#Parameter:	NA
#Return:	hba logs
#Since:		driver\logCollect.cfg
#Other:		N/a				
###################################################################
function get_eth_pci_info()
{
    local log_dir="${OUTPUTLOG}/nic"
    local ret=0
    # Get nic lspci info
    run_cmd "lspci | grep Ethernet" "${log_dir}/lspci_eth.txt"
    if [ 0 -ne $? ]
    then
        LOG_ERROR "Get ethernet pci info failed."
        ret=1
    else
        LOG_INFO "Get ethernet pci info succeed."
    fi
    return $ret
}

################################################################
#Function:		<get_fc_pci_info>
#Description:	get fc pci information 
#Parameter:	NA
#Return:	hba logs
#Since:		driver\logCollect.cfg
#Other:		N/a				
###################################################################
function get_fc_pci_info()
{
    local log_dir="${OUTPUTLOG}/hba"
    local ret=0
    # Get fireware lspci info
    run_cmd "lspci | grep Fibre" "${log_dir}/lspci_fc.txt"
    if [ 0 -ne $? ]
    then
        LOG_ERROR "Get fibre pci info failed."
        ret=1
    else
        LOG_INFO "Get fibre pci info succeed."
    fi    
    return $ret
}


################################################################
#Function:		<get_nic_error_frame_crc_info>
#Description:	get nic card error_frames and  invalid_crc_count information 
#Parameter:	NA
#Return:	nic logs
#Since:		nic\logCollect.cfg
#Other:		N/a				
###################################################################
function get_nic_error_frame_crc_info()
{
    local log_dir="${OUTPUTLOG}/nic/"
    local ret=0

	cmd="ls /sys/class/net/"
	result=$(eval "${cmd}" 2>&1)
	retCode=$? 	
	
	if [ 0 -ne ${retCode} ]
	then
	   ret=$retCode
	   LOG_ERROR "[$cmd] failed.Ret:$retCode. Desc:$result"
	   LOG_ERROR "Get nic error_frames info failed."
	else	
		for netname in ${result}
		do
			if [ -f "/sys/class/net/${netname}/statistics/rx_crc_errors" ]
			then
			    run_cmd "cat /sys/class/net/${netname}/statistics/rx_crc_errors" "${log_dir}/error_frame_crc.txt"
			fi
			if [ 0 -ne $? ]
			then
			    ret=1
			    LOG_ERROR "Get nic crc info failed."
			fi
			if [ -f "/sys/class/net/${netname}/statistics/rx_frame_errors" ]
			then
			    run_cmd "cat /sys/class/net/${netname}/statistics/rx_frame_errors" "${log_dir}/error_frame_crc.txt"
			fi
			if [ 0 -ne $? ]
			then
			    ret=1
			    LOG_ERROR "Get nic error_frame info failed."
			fi
		done
	fi
	return ${ret}
}

################################################################
#Function:		<get_nic_pci_info>
#Description:	get nic card pci information
#Parameter:	NA
#Return:	nic pci logs
#Since:		nic\logCollect.cfg
#Other:		N/a
##################################################################
function get_nic_pci_info()
{
    local log_dir="${OUTPUTLOG}/nic/"
    local ret=0

    cmd="ls /sys/class/net/"
	result=$(eval "${cmd}" 2>&1)
	retCode=$?

    if [ 0 -ne ${retCode} ]
	then
	    ret=$retCode
	    LOG_ERROR "[$cmd] failed.Ret:$retCode. Desc:$result"
	    LOG_ERROR "Get nic card pci_interface info failed."
	else
        for pci_dir in ${result}
        do
            pci=${pci_dir#*/}
            run_cmd "cat /sys/class/net/${pci}/device/vendor" "${log_dir}/nic_pci_info.txt"
            run_cmd "cat /sys/class/net/${pci}/device/device" "${log_dir}/nic_pci_info.txt"
            run_cmd "cat /sys/class/net/${pci}/device/subsystem_vendor" "${log_dir}/nic_pci_info.txt"
            run_cmd "cat /sys/class/net/${pci}/device/subsystem_device" "${log_dir}/nic_pci_info.txt"
        done
    fi
	return ${ret}
}

################################################################
#Function:		<get_network_adapter_numa_node_info>
#Description:	get network_adapter_numa_node
#Parameter:	NA
#Return:	nic logs
#Since:		nic\logCollect.cfg
#Other:		N/a
###################################################################
function get_network_adapter_numa_node_info()
{
    local log_dir="${OUTPUTLOG}/cyclicCollection"
    local ret=0

	cmd="ls /sys/class/net/"
	result=$(eval "${cmd}" 2>&1)
	retCode=$?

	if [ 0 -ne ${retCode} ]
	then
	   ret=$retCode
	   LOG_ERROR "[$cmd] failed.Ret:$retCode. Desc:$result"
	   LOG_ERROR "Get Network adapter name info failed."
	else
		for netname in ${result}
		do
			if [ -f "/sys/class/net/${netname}/device/numa_node" ]
			then
			    run_cmd "cat /sys/class/net/${netname}/device/numa_node" "${log_dir}/network_adapter_numa_node.txt"
			fi
			if [ 0 -ne $? ]
			then
			    ret=1
			    LOG_ERROR "Get Network adapter name info failed."
			fi
		done
	fi
	return ${ret}
}
################################################################
#Function:		<get_cna_pci_port_info>
#Description:	get cna card pci port info and print file
#Parameter:	0£ºok  1: error
#Return:	errocode  0:ok
#Since:		cna\logCollect.cfg
#Other:		N/a
###################################################################
function get_cna_pci_port_info()
{
    local path=$1
    local log_dir=$2
    local port_next_cmd=""
    local port_next_result=""
    local last_cmd=""
    local last_result=""
    #取得port下的文件夹，形式为0000:00:00
    port_next_cmd="ls ${path}"
    port_next_result=$(eval "${port_next_cmd}" 2>&1)

    if [ ! -d "$log_dir" ]
    then
        mkdir -p $log_dir
    fi

    for port_next in ${port_next_result}
    do
        if [ ${port_next:0:4} == "0000" ]
        then
            run_cmd "cat ${path}/${port_next}/vendor" "${log_dir}/cna_pci_info.txt"
            run_cmd "cat ${path}/${port_next}/device" "${log_dir}/cna_pci_info.txt"
            run_cmd "cat ${path}/${port_next}/subsystem_vendor" "${log_dir}/cna_pci_info.txt"
            run_cmd "cat ${path}/${port_next}/subsystem_device" "${log_dir}/cna_pci_info.txt"
        fi
    done
}
################################################################
#Function:		<get_cna_pci_info>
#Description:	CNA card pci info
#Parameter:	NA
#Return:	CNA pci logs
#Since:		cna\logCollect.cfg
#Other:		N/a
###################################################################
function get_cna_pci_info()
{
    local log_dir="${OUTPUTLOG}/cna"
    local ret=0
    local pci_cmd=""
    local pci_result=""
    local pci_retCode=0
    local pci_ch=""
    local port_cmd=""
    local port_result=""
    local port_retCode=0
    local port_ch=""
    local port_ch1=""

    #从/sys/devices/中获取pci0000:xx文件夹
    pci_cmd="ls /sys/devices/"
	pci_result=$(eval "${pci_cmd}" 2>&1)
	pci_retCode=$?

    if [ 0 -ne ${pci_retCode} ]
	then
	    ret=${pci_retCode}
	    LOG_ERROR "[$pci_cmd] failed.Ret:$pci_result. Desc:$pci_retCode"
	    LOG_ERROR "Get cna card pci info failed."
	else
	    for pci in ${pci_result}
	    do
	        if [ ${pci:0:3} == "pci" ]
	        then
                #从pci0000:xx取到xx，用来和root_port对比
                pci_ch=${pci#*:}

                #从/sys/devices/pci0000:xx获取0000:xx:yy.z文件夹
                port_cmd="ls /sys/devices/${pci}/"
                port_result=$(eval "${port_cmd}" 2>&1)
                port_retCode=$?

                if [ 0 -ne ${port_retCode} ]
                then
                    ret=$port_retCode
                    LOG_ERROR "[$port_cmd] failed.Ret:$port_retCode. Desc:$port_result"
                    LOG_ERROR "Get cna card pci info failed."
                else
                    for root_port in ${port_result}
                    do
                        if [ ${root_port:0:4} == "0000" ]
                            then
                            #删除第一个：左边的全部字符
                            port_ch=${root_port#*:}
                            #删除右边第一个：右边的所有字符
                            port_ch1=${port_ch%:*}
                            #判断pci与port文件夹的xx是否相同
                            if [ ${port_ch1} == ${pci_ch} ]
                            then
                                #调用get_cna_pci_port_info获取port下的文件夹并且打印文件夹里对应文件
                                get_cna_pci_port_info "/sys/devices/${pci}/${root_port}" "${log_dir}"
                            fi
                        fi
                    done
                fi
	        fi
	    done
    fi
    return ${ret}
}
################################################################
#Function:		<get_cna_fcoe_firmware_info>
#Description:	get cna fcoe card firmware info
#Parameter:	0£ºok  1: error
#Return:	errocode  0:ok
#Since:		cna\logCollect.cfg
#Other:		N/a
###################################################################
function get_cna_fcoe_firmware_info()
{
    local log_dir="${OUTPUTLOG}/cna"
    local ret=0

    #获取网口名--enp4s0f*
    network_cmd="ip ad|awk '/state UP/ {print $2}'"
	network_result=$(eval "${network_cmd}" 2>&1)
	network_retCode=$?

    if [ 0 -ne ${network_retCode} ]
	then
	    ret=${pci_retCode}
	    LOG_ERROR "[$network_cmd] failed.Ret:$network_result. Desc:$network_retCode"
	    LOG_ERROR "Get cna fcoe card firmware info failed."
	else
	    for network in ${network_result}
	    do
	        if [ ${network:0:1} == 'e' ]
            then
	            run_cmd "ethtool -i ${network}" "${log_dir}/cna_fcoe_info.txt"
	        fi
	    done
	fi
	return ${ret}
}
################################################################
#Function:		<get_cna_fcoe_port_info>
#Description:	get cna fcoe card port info
#Parameter:	0£ºok  1: error
#Return:	errocode  0:ok
#Since:		cna\logCollect.cfg
#Other:		N/a
###################################################################
function get_cna_fcoe_port_info()
{
    local log_dir="${OUTPUTLOG}/cna"
    local ret=0

    #获取/sys/class/fc_host/文件夹下的hoxtX
    get_host_cmd="ls /sys/class/fc_host/"
	get_host_result=$(eval "${get_host_cmd}" 2>&1)
	get_host_retCode=$?

    if [ 0 -ne ${get_host_retCode} ]
	then
	    ret=${get_host_retCode}
	    LOG_ERROR "[$get_host_cmd] failed.Ret:$get_host_result. Desc:$get_host_retCode"
	    LOG_ERROR "Get cna card firmware info failed."
	else
	    for host in ${get_host_result}
	    do
	        run_cmd "cat /sys/class/fc_host/${host}/symbolic_name" "${log_dir}/cna_fcoe_info.txt"
	        run_cmd "cat /sys/class/fc_host/${host}/port_id" "${log_dir}/cna_fcoe_info.txt"
	        run_cmd "cat /sys/class/fc_host/${host}/port_type" "${log_dir}/cna_fcoe_info.txt"
	        run_cmd "cat /sys/class/fc_host/${host}/speed" "${log_dir}/cna_fcoe_info.txt"
	        run_cmd "cat /sys/class/fc_host/${host}/fabric_name" "${log_dir}/cna_fcoe_info.txt"
	    done
	fi
	return ${ret}
}

################################################################
#Function:		<get_network_adapter_numa_node_info>
#Description:	get network_adapter_numa_node
#Parameter:	NA
#Return:	nic logs
#Since:		nic\logCollect.cfg
#Other:		N/a
###################################################################
function get_network_scripts_info()
{
    local log_dir="${OUTPUTLOG}/cyclicCollection"
    local ret=0

	cmd="ls /etc/sysconfig/network-scripts/"
	result=$(eval "${cmd}" 2>&1)
	retCode=$?

	if [ 0 -ne ${retCode} ]
	then
	   ret=$retCode
	   LOG_ERROR "[$cmd] failed.Ret:$retCode. Desc:$result"
	   LOG_ERROR "Get Network scripts info failed."
	else
		for netname in ${result}
		do
			if [ -f "/etc/sysconfig/network-scripts/${netname}" ]
			then
			  network_name="ifcfg"
			  if [[ ${netname} =~ ${network_name} ]]
			  then
			      run_cmd "cat /etc/sysconfig/network-scripts/${netname}" "${log_dir}/network_scripts.txt"
			  fi
			fi
			if [ 0 -ne $? ]
			then
			    ret=1
			    LOG_ERROR "Get Network scripts info failed."
			fi
		done
	fi
	return ${ret}
}

################################################################
#Function:		<get_ethtool_info>
#Description:	get nic info by ethtool 
#Parameter:	NA
#Return:	3008 logs
#Since:		nic\logCollect.cfg 
#Other:		N/a				
###################################################################
function get_ethtool_info()
{
    #Nic config info
    local log_dir="${OUTPUTLOG}/cyclicCollection/ethtool.txt"
    local nic_devices=""
    local device=""

    nic_devices=$(ls /sys/class/net/  2>&1)
    for device in ${nic_devices}
    do
        if [ "${device}" != 'lo' ]
        then             
            run_cmd  "ethtool -i ${device}" "${log_dir}"     
            run_cmd  "ethtool ${device}" "${log_dir}"
            run_cmd  "ethtool -S ${device}" "${log_dir}"
            run_cmd  "ethtool -g ${device}" "${log_dir}"
            run_cmd  "ethtool -k ${device}" "${log_dir}"
            run_cmd  "ethtool -m ${device}" "${log_dir}"
        fi
    done
}
################################################################
#Function:		<queryOsInfo>
#Description:	query os info
#Parameter:	NA
#Return:	os info
#Since:		system\logCollect.cfg 
#Other:		N/a				
###################################################################
function queryOsInfo()
{
    sysVersion=`cat /etc/system-release`
    echo "$sysVersion"
}
################################################################
#Function:		<isPartedBugInvoved>
#Description:	query os info
#Parameter:	NA
#Return:	isRelate bug
#Since:		system\logCollect.cfg 
#Other:		N/a				
###################################################################
function isPartedBugInvoved()
{
    osInfo=`queryOsInfo`
    # centos bug id:12725 (CentOS amd Red Hat 7.3\7.4 invoved)
    isNotCollect=`echo "$osInfo"|grep -E "Red Hat|CentOS"|grep -E "7.3|7.4"`
    LOG_INFO "isNotCollect:${isNotCollect}"
    echo "$isNotCollect"
}

function check_path() {
    local path=$1
    local regex='[<>:"$\|?*]'
    if [[ $path =~ $regex ]]; then
        echo "Error: Path contains special characters"
        return 1
    else
        echo "Path is valid"
        return 0
    fi
}

function check_group() {
    # 获取文件所属组
    file_group=$(stat -c '%G' $1)
    # 判断文件所属组是否为root属组
    if [ "$file_group" == "root" ]; then
        return 0
    else
        return 1
    fi
}

################################################################
#Function:		<get_sosreport_log>
#Description:	get sosreport log by sosreport command
#Parameter:	NA
#Return:	system logs
#Since:		system\logCollect.cfg 
#Other:		N/a				
###################################################################
function get_sosreport_log()
{
    local nvme_version=`cat /sys/module/nvme/version`
    if [ "$nvme_version" = "6.0.0.2" ] || [ "$nvme_version" = "6.0.0.1" ]
    then
      LOG_INFO "NVMe version: $nvme_version,The NVMe version is incorrect and sosreport logs cannot be collected."
      return
    fi
    local ret=0 
    local log_dir="${OUTPUTLOG}/system"
    if [ -d "/etc/redhat-release" ]; then
    cmdversion="cat /etc/redhat-release"
    cmdsosversion=`sosreport -l | grep -i -E "sosreport.*version"`
    v="Red"
    bs=$($cmdversion | head -n1)
    rs=${bs:0:3}
    sosreport_tmp_path = "/tmp/sosreport_tmp_path"
	if [ $rs == $v ]
	then
	    flag="true"
	else
	    flag="false"
	fi

    rhversion=$(echo ${bs}| awk 'BEGIN{FS="release"}{print $2}'| awk 'BEGIN{FS="("}{print $1}')
    red_version=$(echo ${rhversion}| awk 'BEGIN{FS="."}{print $1}')

    b=$(echo $cmdsosversion| head -n1)
    find_sos=$(echo ${b}| awk 'BEGIN{FS=" "}{print $3}'| awk 'BEGIN{FS=")"}{print $1}')
	
	if [ $red_version -eq 7 ] && [ "$flag" == "true" ]
	then
	  versionsos="3.5-6"
          new_versos=$(echo ${versionsos}| awk 'BEGIN{FS="."}{print $1}')
          new_verfindsos=$(echo ${find_sos}| awk 'BEGIN{FS="."}{print $1}')
          if [ $new_verfindsos -gt $new_versos ]
          then
               compare_version_flag="gt"
          elif [ $new_verfindsos -lt $new_versos ]
          then
               compare_version_flag="lt"
          else
               new_versionsos=$(echo ${versionsos}| awk 'BEGIN{FS="."}{print $2}')
               new_versionfindsos=$(echo ${find_sos}| awk 'BEGIN{FS="."}{print $2}')
	           new_sos=$(echo ${new_versionsos} | sed 's/-//g')
	           new_find_sos=$(echo ${new_versionfindsos} | sed 's/-//g')

	           new_sos_len=$(echo ${new_sos} |awk '{print length($0)}')
	           new_findsos_len=$(echo ${new_find_sos} |awk '{print length($0)}')
	           if [ $new_findsos_len -lt $new_sos_len ]
	           then
	            l=`expr $new_sos_len - $new_findsos_len`
	            for((i=0;i<${l};i++))
	            do
	                var="0"
		            new_find_sos=${new_find_sos}${var}
			    
	             done
                  elif [ $new_findsos_len -gt $new_sos_len ]
                  then
	            l=`expr $new_findsos_len - $new_sos_len`
	            for((i=0;i<${l};i++))
	            do
	                var="0"
		            new_sos=${new_sos}${var}
	                done
	           else
	             new_sos_len=new_findsos_len
                 fi
	                if [ $new_find_sos -lt $new_sos ]
                    then
                      compare_version_flag="lt"
                     else
                       compare_version_flag="gt"
                      fi
           fi
	elif [ $red_version -eq 6 ] && [ "$flag" == "true" ]
	then
            versionsos="3.2-63"
            new_versos=$(echo ${versionsos}| awk 'BEGIN{FS="."}{print $1}')
            new_verfindsos=$(echo ${find_sos}| awk 'BEGIN{FS="."}{print $1}')
          if [ $new_verfindsos -gt $new_versos ]
          then
               compare_version_flag="gt"
          elif [ $new_verfindsos -lt $new_versos ]
          then
               compare_version_flag="lt"
          else
               new_versionsos=$(echo ${versionsos}| awk 'BEGIN{FS="."}{print $2}')
               new_versionfindsos=$(echo ${find_sos}| awk 'BEGIN{FS="."}{print $2}')
	           new_sos=$(echo ${new_versionsos} | sed 's/-//g')
	           new_find_sos=$(echo ${new_versionfindsos} | sed 's/-//g')

	           new_sos_len=$(echo ${new_sos} |awk '{print length($0)}')
	           new_findsos_len=$(echo ${new_find_sos} |awk '{print length($0)}')
	           if [ $new_findsos_len -lt $new_sos_len ]
	           then
	            l=`expr $new_sos_len - $new_findsos_len`
	            for((i=0;i<${l};i++))
	            do
	                var="0"
		            new_find_sos=${new_find_sos}${var}
	             done
                elif [ $new_findsos_len -gt $new_sos_len ]
                then
	            l=`expr $new_findsos_len - $new_sos_len`
	            for((i=0;i<${l};i++))
	            do
	                var="0"
		            new_sos=${new_sos}${var}
	                done
	             else
	             new_sos_len=new_findsos_len
                 fi
	                if [ $new_find_sos -lt $new_sos ]
                    then
                      compare_version_flag="lt"
                     else
                       compare_version_flag="gt"
                      fi
           fi
    else
       compare_version_flag="gt"
	fi
	fi
	isPartedRel=`isPartedBugInvoved`
    if [ "$compare_version_flag" == "lt" ]
    then
        if [ "$isPartedRel" == "" ]; then
            cmd="sosreport -n networking --batch --tmp-dir=${sosreport_tmp_path}"
        else
            cmd="sosreport -n networking,block --batch --tmp-dir=${sosreport_tmp_path}"
        fi
    else
        if [ "$isPartedRel" == "" ]; then
            cmd="sosreport --batch --tmp-dir=${sosreport_tmp_path}"
        else
            cmd="sosreport -n block --batch --tmp-dir=${sosreport_tmp_path}"
        fi
    fi
    LOG_INFO "sosreport cmd:$cmd"
    run_cmd "$cmd"
    if [ "$?" -eq 0 ]
    then
        run_cmd "mkdir -p  $log_dir/sosreport "
        if [ 0 -eq $? ]
        then
            sosreportDir="$log_dir/sosreport"
        else
            sosreportDir="${log_dir}"
        fi

        sosreport_log_tbz=$(find ${sosreport_tmp_path} -name "sosreport-*.tar.xz" | sort -r | head -1)
        sosreport_log_tbz_md5=$(find ${sosreport_tmp_path} -name "sosreport-*.tar.xz.md5" | sort -r | head -1)
        sosreport7_log_tbz=$(find /var/tmp/ -name "sosreport-*.tar.xz" | sort -r | head -1)
        sosreport7_log_tbz_md5=$(find /var/tmp/ -name "sosreport-*.tar.xz.md5" | sort -r | head -1)

        check_group "${sosreport_log_tbz}"
        if [ $? -eq 1 ]; then
            LOG_INFO "${sosreport_log_tbz} Permission error. Copying is prohibited."
            return 1
        fi

        if check_path "${sosreport_log_tbz}"; then
            LOG_INFO "${sosreport_log_tbz} Path is valid"
        else
            LOG_INFO "Error: ${sosreport_log_tbz}  Path contains special characters"
            return 1
        fi

        run_cmd "mv ${sosreport_log_tbz} ${sosreportDir}"

        check_group "${sosreport_log_tbz_md5}"
        if [ $? -eq 1 ]; then
            LOG_INFO "${sosreport_log_tbz_md5} Permission error. Copying is prohibited."
            return 1
        fi

        if check_path "${sosreport_log_tbz_md5}"; then
            LOG_INFO "${sosreport_log_tbz_md5} Path is valid"
        else
            LOG_INFO "Error: ${sosreport_log_tbz_md5}  Path contains special characters"
            return 1
        fi

        run_cmd "mv ${sosreport_log_tbz_md5} ${sosreportDir}"

        check_group "${sosreport7_log_tbz}"
        if [ $? -eq 1 ]; then
            LOG_INFO "${sosreport7_log_tbz} Permission error. Copying is prohibited."
            return 1
        fi
        if check_path "${sosreport7_log_tbz}"; then
            LOG_INFO "${sosreport7_log_tbz} Path is valid"
        else
            LOG_INFO "Error: ${sosreport7_log_tbz}  Path contains special characters"
            return 1
        fi

        run_cmd "mv ${sosreport7_log_tbz} ${sosreportDir}"

        check_group "${sosreport7_log_tbz_md5}"
        if [ $? -eq 1 ]; then
            LOG_INFO "${sosreport7_log_tbz_md5} Permission error. Copying is prohibited."
            return 1
        fi
        if check_path "${sosreport7_log_tbz_md5}"; then
            LOG_INFO "${sosreport7_log_tbz_md5} Path is valid"
        else
            LOG_INFO "Error: ${sosreport7_log_tbz_md5}  Path contains special characters"
            return 1
        fi

        run_cmd "mv ${sosreport7_log_tbz_md5} ${sosreportDir}"

        run_cmd "mv dmraid.ddf1 ${sosreportDir}" 
        ret=0
        return ${ret}
    else
        ret=1
        LOG_INFO "sosreport not support or sosreport cmd failed."
    fi

    return ${ret}

}

################################################################
#Function:		<get_suse_log>
#Description:	get suse log by supportconfig command
#Parameter:	NA
#Return:	system logs
#Since:		system\logCollect.cfg 
#Other:		N/a				
###################################################################
function get_suse_log()
{
    local ret=0 
    local log_dir="${OUTPUTLOG}/system"
    local cmd="supportconfig -Q -x PROC"
    result=$(eval "supportconfig -F" 2>&1)
    retCode=$?
    if [ 0 -ne "$retCode" ]
    then
        LOG_ERROR "[$cmd] failed.Ret:$retCode. Desc:$result"
    else
        for i in $(echo $result)
        do
            if [[ "$i" =~ ^a.* ]]
            then
                cmd="${cmd},$i"
            fi
        done
    fi
    LOG_INFO "collect command: ${cmd}"
    run_cmd "${cmd}"
    if [ "$?" -eq 0 ]
    then
        run_cmd "mkdir -p  $log_dir/suse"
        if [ 0 -eq $? ]
        then
            suseDir="$log_dir/suse"
        else
            suseDir="${log_dir}"
        fi

        suse_tbz=$(find /var/log/ -name "nts_$(hostname)*.t*z" | sort -r | head -1)
        suse_tbz_md5=$(find /var/log/ -name "nts_$(hostname)*.t*z.md5" | sort -r | head -1)

        check_group "${suse_tbz}"
        if [ $? -eq 1 ]; then
            LOG_INFO "${suse_tbz} Permission error. Copying is prohibited."
            return 1
        fi
        if check_path "${suse_tbz}"; then
            LOG_INFO "${suse_tbz} Path is valid"
        else
            LOG_INFO "Error: ${suse_tbz}  Path contains special characters"
        fi

        check_group "${suse_tbz_md5}"
        if [ $? -eq 1 ]; then
            LOG_INFO "${suse_tbz_md5} Permission error. Copying is prohibited."
            return 1
        fi
        if check_path "${suse_tbz_md5}"; then
            LOG_INFO "${suse_tbz_md5} Path is valid"
        else
            LOG_INFO "Error: ${suse_tbz_md5}  Path contains special characters"
        fi
        run_cmd "mv ${suse_tbz} ${suseDir}"     
        run_cmd "mv ${suse_tbz_md5} ${suseDir}"  
        ret=0
        return ${ret}
    else
        ret=1
        LOG_INFO "supportconfig not support or supportconfig failed."
    fi 

    return ${ret}
   

}

################################################################
#Function:		<get_vmcore_dmesg>
#Description:	get vmcore dmesg
#Parameter:	NA
#Return:	vmcore_dmesg.txt
#Since:
#Other:		NA
###################################################################
function get_vmcore_dmesg() {
    local ret=0
    local log_dir="${OUTPUTLOG}/system"
    local file_name="vmcore-dmesg.txt"
    result=$(eval "du -ah /var/crash/ | grep ${file_name}" 2>&1)
    if [ "$?" -eq 0 ]
    then
      for i in $(echo $result)
        do
          if [[ ${i} == *vmcore-dmesg.txt ]]
          then
            file_path="${log_dir}/${i%/*}"
            run_cmd "mkdir -p ${file_path}"
            run_cmd "cp ${i} ${file_path}"
          fi 
        done
    else
      LOG_ERROR "[$cmd] failed.Ret:$retCode. Desc:$result"
    fi
}

################################################################
#Function:		<get_system_message>
#Description:	get system message
#Parameter:	NA
#Return:	messages*.txt
#Since:
#Other:		NA
###################################################################
function get_system_message() {
    local ret=0
    local log_dir="${OUTPUTLOG}/system/var/log"
    result=$(eval "ls -t /var/log/messages* | head -n 7" 2>&1)
    if [ "$?" -eq 0 ]
    then
      for file in $(echo $result)
        do
          cp "$file" "$log_dir"
        done
    else
      LOG_ERROR "[$cmd] failed.Ret:$retCode. Desc:$result"
    fi
}

################################################################
#Function:		<get_raid_md_info>
#Description:	get raid md info
#Parameter:	NA
#Return:	mdinfo.txt
#Since:
#Other:		NA
###################################################################
function get_raid_md_info() {
    local ret=0
    local log_dir="${OUTPUTLOG}/raid/md"
    run_cmd "mkdir -p ${log_dir}"
    run_cmd "cat /proc/mdstat" "$log_dir/mdinfo.txt"
    result=$(eval "cat /proc/mdstat | grep md.*:.*" 2>&1)
    if [ "$?" -eq 0 ]
    then
      if [ "" == "$result" ]
        then
          LOG_INFO "The device is not support to create software raid."
          return
        fi
      for i in $(echo $result)
        do
          if [[ $i =~ ^md ]]
            then
            run_cmd "mdadm -D /dev/$i" "$log_dir/mdinfo.txt"
          fi
        done
    else
      LOG_ERROR "Check software raid md info failed, Desc:$result"
    fi
}

################################################################
#Function:		<get_filelist>
#Description:	get collected log file 
#Parameter:	NA 
#Return:	filelist.txt
#Since:		
#Other:		NA				
###################################################################
function get_filelist()
{
 
    run_cmd "cp runlog ${OUTPUTLOG}/system/" 
    
    cd ${OUTPUTLOG}
    local logDir=$(ls)

    #get all collect log info to filelist.txt
    for log in ${logDir}
    do
        if [ -d "${log}" ]; then            
            find ${log} ! -type d  | awk -v modu="${log}" 'BEGIN{print "\n" modu " Dir file list:";
                                                         i = 0;}
                                                        {
                                                        printf "  %-5s %s\n",i+1,$0
                                                        i = i+1               
							}' >> filelist.txt
        else
            files[${i}]="${log}"
            i=$((i+1))
        fi
    done
    
    #write file to the end of the filelist
    for((i=0;i<${#files[@]};i++))
    do
        if [ "" != "${files[${i}]}" ] && [ "version.txt" != "${files[${i}]}" ]
        then 
             run_cmd "ls ${files[${i}]}" "filelist.txt"
        fi
    done
    
	
	echo "version.txt" >>filelist.txt
    echo "filelist.txt" >>filelist.txt
	
    
    cd ../
	
}

function module_log_collect()
{ 
    local file=""
    local cmd=""
    local cmdType=""
    local lineNum=""
    local result="SUCCEED"
    local taskInfo=""
	local line=""

    moduleName="$1"
	
	LOG_INFO "${moduleName} collect start." 

	printf " Collect %.60s" "[${moduleName}] information..." 

	lineNum=`cat modules/$moduleName/logCollect.cfg 2>/dev/null | grep -v "#" | grep "|" | wc -l`

	if [ "" == "$lineNum" ] || [ "0" == "$lineNum" ]
	then
		LOG_INFO "$moduleName logCollect.cfg not found:$lineNum" 
		return
	fi


	for((line=1;line<=lineNum;line++))
	do

		lineContext=`cat modules/$moduleName/logCollect.cfg | grep -v "#" |grep "|" |  awk '(NR=='$line')'`
		file=`echo "$lineContext" | awk -F"|" '{print $3}' |  sed 's/ //g' | sed 's/[ \t]*$//g' `
		cmd=`echo "$lineContext" | awk -F"|" '{print $2}' | sed 's/^\s*\|\s*$//g'`
		cmdType=`echo "$lineContext" | awk -F"|" '{print $1}' |  sed 's/ //g' | sed 's/[ \t]*$//g'`

		cnt=`cat config.ini | grep "$file" | grep -i "yes" | grep "$moduleName" | wc -l`
		if [ "0" == $cnt ] || [ "" == "$cnt" ]
		then
			LOG_INFO "[$file] [$moduleName] not match with the config.Ret:$cnt"  
			LOG_INFO "[$file] collect SKIPPED."  
			continue
		fi

		##start collect
		LOG_INFO  "[${file}] collect start." 
		printf "\r%.75s" "                                                   "
		printf "\r Collect %.75s" "[${file}] ...... please wait"

		#make log dir
		local logDir="${OUTPUTLOG}/$moduleName"
		if [ ! -d "${OUTPUTLOG}/$moduleName" ]
		then
			run_cmd "mkdir -m a=r ${OUTPUTLOG}/$moduleName"
			LOG_INFO "Create ${OUTPUTLOG}/$moduleName ok." 
		fi

		LOG_INFO "[$file] cmd type is $cmdType." 
		
		if [ "cmd" == "$cmdType" ] || [ "CMD" == "$cmdType" ] || [ "COMMAND" == "$cmdType" ]
		then
			run_cmd "$cmd" "$logDir/$file"
			if [ "0" == "$?" ] 
			then
				LOG_INFO "$file collect ok."
				result="SUCCEED"
			else 
				LOG_INFO "$file collect cmd failed."
				result="FAILED"
			fi

		elif [ "background_cmd" == "$cmdType" ] || [ "BACKGROUND_CMD" == "$cmdType" ]
		then
		  eval "$cmd >> $logDir/$file&" 2>&1
			if [ "0" == "$?" ]
			then
			  LOG_INFO "[$cmd], process pid: $!"
			  echo "$logDir/$file" > ${SUB_PROCESS_DIR}/$!
				LOG_INFO "$file collect ok."
				result="SUCCEED"
			else 
				LOG_INFO "$file collect cmd failed."
				result="FAILED"
			fi

		elif [ "file" == "$cmdType" ] || [ "FILE" == "$cmdType" ]
		then

			fileFullDir="$cmd"
			#file is exist
			infilepath=`dirname "${fileFullDir}"`
			subDir=${logDir}${infilepath}

			run_cmd "mkdir -p $subDir"
			if [ 0 -eq $? ]
			then
				logDir="$subDir"
			else 
				LOG_ERROR "mkdir -p $subDir failed." 
			fi

			run_cmd "cp -rf -L $cmd $logDir/"
			if [ "0" == "$?" ] 
			then
				LOG_INFO "$file collect ok."
				result="SUCCEED"
			else 
				LOG_INFO "$file collect cmd failed."
				result="FAILED"
			fi

		elif [ "FUNC" == "$cmdType" ] || [ "func" == "$cmdType" ] 
		then 
			$cmd
			if [ "0" == "$?" ] 
			then
				LOG_INFO "$file collect ok."
				result="SUCCEED"
			else 
				LOG_INFO "$file collect cmd failed."
				fi			
		else
			 LOG_ERROR "$moduleName $file cmd type [$cmdType] is invalid." 
			 result="FAILED"
		fi
		printf "\r Collect %.60s" "[${file}] ...... Done        "

	done
	printf "\r %.60s" "[${moduleName}]...                                                                            "
	printf "%s\n" "Done"

	LOG_INFO "${moduleName} collect finished." 

}

################################################################
#Function:		<main_collect_log>
#Description:	collect log according to config.ini and logCollect.cfg
#Parameter:	N/a	
#Return:	N/a
#Since:		
#Other:		N/a				
###################################################################
function main_collect_log()
{
    local module=$(ls modules 2>&1)
    local result="SUCCEED"
    local timeout=""
    local pid=""

    if [ -f "modules/lib/timeout.ini" ] 
    then
        timeout=`cat modules/lib/timeout.ini`
        if [[ "${timeout}" == *[!0-9]* ]] 
        then
            LOG_ERROR "Invalid timeout set value:${timeout}.User default."
            timeout=1200
        fi

        LOG_INFO "Module collect timeout value is:$timeout."

    else 
        timeout=1200
        LOG_INFO "No timeout.ini found.Module collect timeout value is default:$timeout."
    fi
    
    #install tools
    run_cmd "rm -rf opt"
    run_cmd "mkdir opt"
    run_cmd "mkdir opt/MegaRAID"
    run_cmd "mkdir opt/MegaRAID/storcli"
    if [ "${SYS_TYPE}" == "aarch64" ]; then
        run_cmd "cp modules/raid/RAIDtool_ARM/3408/* ./opt/MegaRAID/storcli/"
    else
        run_cmd "cp modules/raid/RAIDtool/3108/* ./opt/MegaRAID/storcli/"
    fi

    showTitle

    for moduleName in ${module}
    do
        pid=""
        cnt=0
        cyclicModuleName="cyclicCollection"
        if [[ ${moduleName} == ${cyclicModuleName} ]]
        then
          for (( i = 0; i < 12; i++ ))
          do
            module_log_collect "${moduleName}" &
            sleep 5
          done
        fi
        module_log_collect "${moduleName}" &
        pid=$!
        LOG_INFO "Module ${moduleName} collect pid is:$pid"
        sleep 1
        for((i=0;i<timeout;i++))
        do
            ((cnt=cnt+1))
            sleep 1
            ps $pid >/dev/null
            #process finished
            if [ 0 -ne "$?" ]
            then
                LOG_INFO "Module ${moduleName} log collect process is finished in time."
                cnt=0
                break
            fi

        done 
		 
		if [ $timeout -eq $cnt ]
		then

			LOG_ERROR "Module ${moduleName} log collect process is timeout."
            LOG_INFO "kill ${moduleName} log collect process:$pid start."

            run_cmd "which pstree xargs"
            if [ 0 -eq $? ]
            then
			    #pstree $pid -p | awk -F"[()]" '{for(j=0;j<=NF;j++)if($j~/[0-9]+/)print $j}' | xargs kill -9 
                process_list=$(pstree $pid -p | awk -F'[()]' '{for(j=0;j<=NF;j++)if($j~/[0-9]+/)print $j}' | xargs)
               
                LOG_INFO "Process to kill is :$process_list"
               
                for element in $process_list
                do
                    if [[ $element == *[!0-9]* ]]
                    then   
                         LOG_INFO "Process info:$element skipped." 
                         continue
                    fi  
                    LOG_INFO "kill ${moduleName} log collect process:$element start."
                    run_cmd "kill -9 $element" 
                    LOG_INFO "kill ${moduleName} log collect process:$element end."
                done 

            else
                LOG_INFO "kill ${moduleName} log collect process:$pid start."
                run_cmd "kill -9 $pid"                
                LOG_INFO "kill ${moduleName} log collect process:$pid end."
            fi

			LOG_INFO "kill ${moduleName} log collect sub process done."
			LOG_INFO "${moduleName} log collect exsit."
            
            printf "\r %.60s" "[${moduleName}]...                                                                            "
            printf "%s\n" "Done"   
			continue
		fi		 

    done

    pwd=`pwd`
    run_cmd "chmod 640 -R $pwd"
    run_cmd "rm -rf CmdTool.log"
    run_cmd "rm -rf MegaSAS.log"
    run_cmd "rm -rf opt"
	
	
}

function showTitle()
{

printf "%-65.65s\n" "==============================================================================="
if [ "$OEM_TYPE" = "oem" ];then
    printf "%-65.65s\n" "        InfoCollect ${TOOL_VERSION}                                        "
else
  printf "%-65.65s\n" "        SmartKit Computing -- InfoCollect ${TOOL_VERSION}                      "
fi
printf "%-65.65s\n" "             Release Date:${TOOL_RELEASE_DATE}                                 "
printf "%-65.65s\n" "                                                                               "
ret=`cat /proc/cmdline |grep -E "autoDiag|ftk" |wc -l`
if [ $ret -eq "0" ]
	then
	if [ ! -d "/home/Project/FTK" ];then
		printf "%-65.65s\n" " -Supported mainstream Linux 64-bit operating systems (OSs):   "
		printf "%-65.65s\n" "  ${REDHAT}                                                    "
		printf "%-65.65s\n" "  ${SLES}                                                      "
		printf "%-65.65s\n" "  ${UBUNTU}                                                    "
	fi
fi
printf "%-65.65s\n" " -Only professionals are qualified to use this tool.                           "
printf "%-65.65s\n" " -Before performing any maintenance operations by using this                   "
printf "%-65.65s\n" "  tool,obtain authorization from the customer.                                 "
printf "%-65.65s\n" " -Before transmitting fault locating data out of the customer's                "
printf "%-65.65s\n" "  network,obtain written authorized from the customer.                         "
if [ "$OEM_TYPE" != "oem" ];then
    printf "%-65.65s\n" " -Use the latest version:                                                      "
    printf "%-65.65s\n" "  visit the Huawei Enterprise Support website and choose Support>                   "
    printf "%-65.65s\n" "  Server-Intelligent Computing>Management Software>                            "
    printf "%-65.65s\n" "  Server Management Software>SmartKit Computing.                               "
fi
printf "%-65.65s\n" "==============================================================================="

}

################################################################
#Function:		<Compression_log>
#Description:	Compression log directory
#Parameter:	N/a	
#Return:	N/a
#Since:		
#Other:		N/a				
###################################################################
function compression_log() {
  local file_num=""
	local compress_file="${OUTPUTLOG}.tar.gz"
	local Log_size=""
	printf "\r%-65.65s\n" "==[ DONE ]============================================================================================="

	run_cmd "chmod 400 -R ${OUTPUTLOG}"
	run_cmd "tar -czf ${compress_file} ${OUTPUTLOG} --format=gnu"
	if [ 0 -eq $? ]
	then
	  run_cmd "rm -rf ${OUTPUTLOG}"
	  run_cmd "chmod 400 ${compress_file}"
	  Log_size=$(du -sh "${compress_file}"  | awk '{print $1}')
	  echo -e "\033[32mLog file Dir: $(pwd)/${compress_file} \033[0m"
	  echo -e "\033[32mLog file size: ${Log_size} \033[0m"
		
		file_num=$(du -a /var/crash/ 2>>/dev/null | awk 'END{ print NR}')
		if [ "${file_num}" -gt 1 ]; then
			echo -e "\033[31mPlease collect crash files[/var/crash] manually.\033[0m"
		fi
  else
    echo -e "\033[31mCompress $OUTPUTLOG failed. Please compress manually.\033[0m"
    LOG_ERROR "Compress $OUTPUTLOG failed. Please compress manually."
	fi
	
  printf "%-65.65s\n" "================================================================================================="
}

################################################################
#Function:		<check_auth>
#Description:	check auth id is 0
#Parameter:	N/a	
#Return:	exit 1 if not  id0 user
#Since:		
#Other:		N/a				
###################################################################
function check_auth()
{
    local login_id=$(id -u $(whoami))
    if [ "${login_id}" -ne 0 ]; then
        echo  "Current user id is ${login_id}.Recommendation to use ID:0 user to collect logs."
        LOG_ERROR "Current user id is ${login_id}.Recommendation to use ID:0 user to collect logs."
    else 
        LOG_INFO "User ID is:$(id $(whoami))"
    fi 
}

################################################################
#Function:		<run_cmd>
#Description:	exec cmd 
#Parameter:	$1£ºcmd to be run  $2: Variable parameter£ºout put the result to file£¬
#Return:	errocode  0:ok
#Since:		
#Other:		N/a				
###################################################################
function run_cmd()
{
   local ret=1
   local cmd="$1"
   local output="$2"
   local result=""
   local retCode=""

    if [ "" == "$cmd" ] || [ 2 -lt $# ] 
    then
        LOG_ERROR "Invalid parameters."
        ret=1
        return $ret 
    fi
    
    LOG_INFO "[$cmd] is called."
    result=$(eval "${cmd}" 2>&1)
    retCode=$?
    if [ 0 -ne $retCode  ]
    then
       ret=$retCode
       LOG_ERROR "[$cmd] failed.Ret:$retCode. Desc:$result"
    else 
       ret=0
       LOG_INFO "[$cmd] successfull."
    fi 

    if [ "" != "$output" ]      
    then
       echo "${cmd}" >> "$output"  
       echo "{" >> "$output"            
       echo "$result" >> "$output"
       echo "}" >> "$output"
    fi

    return $ret

}

################################################################
#Function:		<get_disk_partition_info>
#Description:	get disk partition info
#Parameter:	0£ºok  1: error
#Return:	errocode  0:ok
#Since:		disk\logCollect.cfg 
#Other:		N/a				
###################################################################
function get_disk_partition_info()
{
    local log_dir="${OUTPUTLOG}/disk/parted_disk.txt"
    local ret=0
    isPartedRel=`isPartedBugInvoved`
    if [[ "$isPartedRel" != "" ]]; then
        LOG_INFO "because of centos bug id:12725 parted don't collect."
        return 0
    fi
    LOG_INFO "isPartedRel:${isPartedRel},collect_parted_info."
    ls /dev/sd* > /dev/null 2>&1
    if [ 0 -eq $? ]
    then
       sd_list=($(ls /dev/sd* | grep -v [1-9]))
    else
       LOG_ERROR "No logical disk found."
       return 
    fi

    local thread=5
    local sd_timeout=300
    local sd_num=${#sd_list[@]}

    for((i=0;i<$sd_num;i+=$thread))
    do
        local concur_thread_num=$thread
        thread_num=$(expr $i + $thread)
        if [ $thread_num -gt $sd_num ]
        then
            thread_num=$(expr $sd_num - $i)
            concur_thread_num=$thread_num
        fi

        start_sd_id=$i
        end_sd_id=$(expr $i + $concur_thread_num)
        
        for((j=$start_sd_id;j<$end_sd_id;++j))
        do
        {
            current_cmd=${sd_list[$j]}
            log_file_id="${OUTPUTLOG}/disk/parted_${j}.txt"
            run_cmd "parted ${current_cmd} print" "$log_file_id" &
            pid=$!
            local cnt=0
            sleep 1
            for((k=0;k<$sd_timeout;k++))
            do
                ((cnt=cnt+1))
                sleep 1
                ps $pid >/dev/null
                #process finished
                if [ 0 -ne $? ]
                then
                    LOG_INFO "Parted ${current_cmd} log collect process is finished in time."
                    break
                fi
            done
 
            if [ $sd_timeout -eq $cnt ]
            then
                ret=1
                LOG_ERROR "Parted ${current_cmd} log collect process is timeout."
                LOG_INFO "kill parted ${current_cmd} log collect process:$pid start."

                run_cmd "which pstree xargs"
                if [ 0 -eq $? ]
                then
                    process_list=$(pstree $pid -p | awk -F'[()]' '{for(m=0;m<=NF;++m)if($m~/[0-9]+/)print $m}' | xargs)

                    LOG_INFO "Process to kill is :$process_list"

                    for element in process_list
                    do
                        if [[ $element == *[!0-9]* ]]
                        then
                            LOG_INFO "Process info: $element skipped."
                            continue
                        fi
                        LOG_INFO "kill parted ${current_cmd} log collect process: $element start."
                        run_cmd "kill -9 $element"
                        LOG_INFO "kill parted ${current_cmd} log collect process: $element end."
                    done
                else
                    LOG_INFO "kill parted ${current_cmd} log collect process: $pid start."
                    run_cmd "kill -9 $pid"
                    LOG_INFO "kill parted ${current_cmd} log collect process: $pid end."
                fi
                LOG_INFO "kill parted ${current_cmd} log collect sub process done."
                LOG_INFO "parted ${current_cmd} log collect information exist."
            fi
        }&
        done
        wait
    done

    for((i=0;i<$sd_num;i++))
    do
        local log_file_id="${OUTPUTLOG}/disk/parted_${i}.txt"
        if [ -f ${log_file_id} ]
        then
            cat $log_file_id >> $log_dir
            rm -f $log_file_id
        fi
    done
    
    return $ret
}

################################################################
#Function:		<get_disk_smart_info>
#Description:	get disk smart info
#Parameter:	0£ºok  1: error
#Return:	errocode  0:ok
#Since:		disk\logCollect.cfg 
#Other:		N/a				
###################################################################
function get_disk_smart_info()
{
    local log_dir="${OUTPUTLOG}/disk/disk_smart.txt"
    local bma_tool="/opt/huawei/bma/bin/hwdiag"
    local ret=0
    local did=""
    local inf=""
    local dnum=0

    echo "get_disk_smart_info:The current server adopts the ${SYS_TYPE} architecture." >> ${log_dir}

    if [ "${SYS_TYPE}" == "aarch64" ]; then
        echo "get_disk_smart_info:use storcli64_arm to support log collection." >> ${log_dir}
        TOOLS="opt/MegaRAID/storcli/storcli64_arm"
    elif [ "${SYS_TYPE}" == "x86_64" ]; then
        TOOLS="opt/MegaRAID/storcli/storcli64"
    elif [ "${SYS_TYPE}" == "i386" ]; then
        TOOLS="opt/MegaRAID/storcli/storcli"
    else
        echo "get_disk_smart_info:The current server adopts the unknown architecture which does not support log collection." >> ${log_dir}
        return
    fi
    
    #get bma disk list
    if [ "$OEM_TYPE" != "oem" ];then
        run_cmd "${bma_tool} -t disk -s" "$log_dir"
    fi

    local is_smartctl_exist="true"
    #judge if smartctl is in OS.If not, put information to log ${log_dir}.
    which smartctl > /dev/null 2>&1
    if [ 0 -ne $? ]
    then
        echo "Command smartctl does not exist!" >> "${log_dir}"
        is_smartctl_exist="false"
    fi
   
    local disk_cmd="${OUTPUTLOG}/disk/disk_cmd.txt"

    # 先获取完整的硬盘smart基础日志，避免硬盘异常时收集smart megaraid日志超时导致smart基础日志收集失败
    get_disk_smart_base_log "$log_dir" "$disk_cmd" "${is_smartctl_exist}"
    ret=$?

    #get system LD info
    ls /dev/sd* > /dev/null 2>&1
    if [ 0 -eq $? ] && [ "${is_smartctl_exist}" == "true" ];
    then
        result=`ls /dev/sd* | grep -v [1-9]`
        for sd in ${result}
        do
            #disk num
            dnum=`"${TOOLS}" /c0/eall/sall show | grep -E '\d*:\d*' | wc -l`
            for((i=3;i<=$dnum;i++))
            do
                #get did
                did=`"${TOOLS}" /c0/eall/sall show | grep -E '\d*:\d*' | awk '(NR=='$i')' | awk -F" " '{print $2}'| tr -d '\r\n'`
                #get interface:sas,sata
                inf=`"${TOOLS}" /c0/eall/sall show | grep -E '\d*:\d*' | awk '(NR=='$i')' | awk -F" " '{print $7}'| tr -d '\r\n'`
                #put log collect cmd to file $disk_cmd
                if [ "SAS" == "$inf" ]
                then
                    local sas_cmd="smartctl -a --device=megaraid,$did ${sd}"
                    local sas_ret=$(${sas_cmd})
                    if [ 2 -ne "$?" ]
                    then
                        add_cmd_and_ret "${sas_cmd}" "${sas_ret}" "${log_dir}"
                    fi
                else
                    local no_sas_cmd="smartctl -a --device=sat+megaraid,$did ${sd}"
                    local no_sas_ret=$(${no_sas_cmd})
                    if [ 2 -ne "$?" ]
                    then
                        add_cmd_and_ret "${no_sas_cmd}" "${no_sas_ret}" "${log_dir}"
                    fi
                fi  
           done
        done
    fi
    return $ret
}


################################################################
#Function:		<add_cmd_and_ret>
#Description:	添加cmd和执行结果到日志
#Parameter:  $1:cmd, $2:cmd ret, $3:log file path
#Return:	N/a
################################################################
function add_cmd_and_ret()
{
    local cmd="$1"
    local cmd_ret="$2"
    local log_file="$3"
    {
        echo "${cmd}"
        echo "{"
        echo "${cmd_ret}"
        echo "}"
    } >> "${log_file}"
}


function build_commmon_disk_smart_cmd() {
    local drive_letter_ret="$1"
    local cmd_file="$2"
    for drive_letter in ${drive_letter_ret}
    do
        echo "smartctl -a ${drive_letter}" >> "${cmd_file}"
    done
}


################################################################
#Function:		<get_disk_smart_base_log>
#Description:	获取硬盘smart基础日志
#Parameter:  $1:log file path, $2:cmd file path
#Return:	N/a
################################################################
function get_disk_smart_base_log()
{
    local log_file="$1"
    local cmd_file="$2"
    local is_smartctl_exist="$3"
    local ret=0
    LOG_INFO "start get disk base smart log"

    # 写入smartctl -a /dev/sd*命令
    local drive_letter_ret=$(ls /dev/sd* | grep -v [1-9])
    if [ 0 -eq $? ] && [ "${is_smartctl_exist}" == "true" ]; then
        build_commmon_disk_smart_cmd "${drive_letter_ret}" "${cmd_file}"
    else
        echo "Command ls /dev/sd* executed failed or smartctl command not exist." >> "${log_file}"
    fi

    # 写入smartctl -a /dev/sg*命令
    drive_letter_ret=$(ls /dev/sg*)
    if [ 0 -eq $? ] && [ "${is_smartctl_exist}" == "true" ]; then
        build_commmon_disk_smart_cmd "${drive_letter_ret}" "${cmd_file}"
    else
        echo "Command ls /dev/sg* executed failed or smartctl command not exist." >> "${log_file}"
    fi

    # 写入nvme盘smart日志收集指令
    get_nvme_disk_smart_info "${cmd_file}" "${log_file}"

    # 异步执行指令收集日志
    if [ -f "${cmd_file}" ]
    then
        get_smart_info_concurrency "${log_file}" "${cmd_file}"
        ret=$?
        rm "$cmd_file"
    fi

    if [ 0 -eq ${ret} ]; then
        LOG_INFO "Get disk smart base log information succeed."
    else
        LOG_ERROR "Get smart base log information failed."
    fi
    return ${ret}
}


################################################################
#Function:		<get_raid_group_drive_letter>
#Description:	获取raid组下的盘符
#Parameter:	查询raid组下disk指令的执行结果
###################################################################
function get_raid_group_drive_letter()
{
    local lsscsi_result="$1"
    local IFS=$'\n'
    for current_line in ${lsscsi_result}
    do
        local dev=`echo "${current_line}" | awk -F " " '{print $NF}'`
        if [ "${dev}" != "" ]; then
            echo ${dev}
        fi
    done
}


################################################################
#Function:		<get_raid3152_smart_info>
#Description:	get raid 3152 disk smart info
#Parameter:	0£ºok  1: error
#Return:	errocode  0:ok
#Since:		disk\logCollect.cfg
#Other:		N/a
###################################################################
function get_raid3152_smart_info()
{
    local log_dir="${OUTPUTLOG}/disk/disk_smart.txt"
    local ret=0

    echo "get_raid3152_smart_info:The current server adopts the ${SYS_TYPE} architecture." >> ${log_dir}

    # check raid card type
    local raid_type_3152=`lsscsi | grep 3152`
    local raid_type_2100=`lsscsi | grep 2100`
    if [ -z "${raid_type_3152}" ] && [ -z "${raid_type_2100}" ];
    then
        echo "get_raid3152_smart_info:raid card type is not 3152 or 2100!" >> ${log_dir}
        return $ret
    fi
    # check whether command exist, if not exist, add log and exit.
    local raid_group_disk=`lsscsi | grep "LOGICAL VOLUME"`
    if [ 0 -ne $? ];
    then
        echo "get_raid3152_smart_info: Command lsscsi does not exist!" >> ${log_dir}
        return $ret
    fi
    which smartctl > /dev/null 2>&1
    if [ 0 -ne $? ];
    then
        echo "get_raid3152_smart_info: Command smartctl does not exist!" >> ${log_dir}
        return $ret
    fi

    # 获取组raid下的盘符
    local drive_letter_list=`get_raid_group_drive_letter "${raid_group_disk}"`
    if [ -z "${drive_letter_list}" ];then
        echo "3152 raid group disk drive letter is empty." >> ${log_dir}
        return $ret
    fi
    # 当前方案为获取组raid下的盘符,再遍历可能存在的所有槽位,下发指令
    for drive_letter in ${drive_letter_list}
    do
      for ((i=0;i<=39;i++))
      do
          run_cmd "smartctl -a --device=cciss,${i} ${drive_letter}" "${log_dir}"
      done
    done
    return $ret
}

################################################################
#Function:		<get_nvme_disk_smart_info>
#Description:	get nvme disk smart info
#Parameter:	disk_smart.txt file directory
#Return:	errocode  0:ok
#Since:		disk\logCollect.cfg
#Other:		N/a
###################################################################
function get_nvme_disk_smart_info()
{
    local disk_cmd=$1
    local log_file=$2
    local nvme_number=`nvme -list | grep '/dev' | wc -l`
    local ret=`nvme -list`
    if [ 0 == $? ] && [ $nvme_number -gt 0 ]; then
        for((i=1; i<=$nvme_number; i++))
        do
            local driver_letter=`nvme -list | grep '/dev' | awk '(NR=='$i')' | awk -F ' ' '{print $1}'`
            echo "nvme -smart-log $driver_letter" >> $disk_cmd
            echo "nvme intel smart-log-add ${driver_letter}" >> ${disk_cmd}
        done
    else
        LOG_ERROR "nvme command not exist or NVMe disk not exist."
        echo "nvme command not exist or NVMe disk not exist." >> "${log_file}"
    fi

    local nvme_number=`nvmecli -list | grep '/dev' | wc -l`
    local ret_nvmecli=`nvmecli -list`
    if [ 0 == $? ] && [ $nvme_number -gt 0 ]; then
        for((i=1; i<=${nvme_number}; i++))
        do
            local driver_letter=`nvmecli -list | grep '/dev' | awk '(NR=='$i')' | awk -F ' ' '{print $1}'`
            echo "nvmecli -smart-log $driver_letter" >> $disk_cmd
        done
    else
        LOG_ERROR "nvme-cli command not exist or NVMe disk not exist."
        echo "nvme-cli command not exist or NVMe disk not exist." >> "${log_file}"
    fi
    return
}

################################################################
#Function:		<get_smart_info_concurrency>
#Description:	get disk smart info
#Parameter:	0£ºok  1: error
#Return:	errocode  0:ok
#Since:		disk\logCollect.cfg 
#Other:		N/a				
###################################################################
function get_smart_info_concurrency()
{
    local log_dir=$1
    local disk_cmd=$2
    local ret=0
    
	if [ "" == "$log_dir" ] || [ "" == "$disk_cmd" ] || [ 2 -lt $# ] 
    then
        LOG_ERROR "Invalid parameters when use smartctl to collect disk information concurrency."
        ret=1
        return $ret
    fi
    
    #collect disk log information concurrency
    local disk_num=`cat ${disk_cmd} | wc -l`
	if [ 0 -eq $? ]
	then
	    local thread=5
		local disk_timeout=300
	    local run_disk_num=0
		
	    for ((i=0;i<$disk_num;i+=$thread))
		do
		    local concur_thread_num=$thread
		    thread_num=`expr $i + $thread`
			if [ $thread_num -gt $disk_num ]
			then
			    thread_num=`expr $disk_num - $i`
				concur_thread_num=$thread_num
			fi
			
			start_disk_id=`expr $i + 1`
			end_disk_id=`expr $i + $concur_thread_num`
			
			for((j=$start_disk_id;j<=$end_disk_id;++j))
			do
			{
			    current_cmd=`cat $disk_cmd | awk NR==$j`
				
				log_file_id="${OUTPUTLOG}/disk/disk_${j}.txt"
				
			    run_cmd "$current_cmd" "$log_file_id" &
				pid=$!
				local cnt=0
				sleep 1
				for((k=0;k<$disk_timeout;++k))
				do
				    ((cnt=cnt+1))
					sleep 1
					ps $pid >/dev/null
					#process finished
					if [ 0 -ne $? ]
					then
					    LOG_INFO "Command ${current_cmd} log collect process is finished in time."
						break
					fi
				done
				
				if [ $disk_timeout -eq $cnt ]
				then
				    LOG_ERROR "Command ${current_cmd} log collect process is timeout."
                    LOG_INFO "kill command ${current_cmd} log collect process:$pid start."
					
					run_cmd "which pstree xargs"
					if [ 0 -eq $? ]
					then
					    process_list=$(pstree $pid -p | awk -F'[()]' '{for(m=0;m<=NF;++m)if($m~/[0-9]+/)print $m}' | xargs)
						
						LOG_INFO "Process to kill is :$process_list"
						
						for element in process_list
						do
						    if [[ $element == *[!0-9]* ]]
							then
							    LOG_INFO "Process info: $element skipped."
								continue
							fi
							LOG_INFO "kill command ${current_cmd} log collect process: $element start."
							run_cmd "kill -9 $element"
							LOG_INFO "kill command ${current_cmd} log collect process: $element end."
						done
					else
					    LOG_INFO "kill command ${current_cmd} log collect process: $pid start."
						run_cmd "kill -9 $pid"
						LOG_INFO "kill command ${current_cmd} log collect process: $pid end."
					fi
					
					LOG_INFO "kill command ${current_cmd} log collect sub process done."
					LOG_INFO "Command ${current_cmd} log collect exist."
				fi
			}&
			done
			wait
			
		done
		
		for((i=1;i<=$disk_num;++i))
	    do
	        local log_file_id="${OUTPUTLOG}/disk/disk_${i}.txt"
            if [ -f ${log_file_id} ]
            then
                cat $log_file_id >> $log_dir
                rm -f $log_file_id
            fi
	    done
	fi
	
    return $ret
}


################################################################
#Function:		<hwdiag_disk_diag_info>
#Description:	get disk hw diag info
#Parameter:	0£ºok  1: error
#Return:	errocode  0:ok
#Since:		disk\logCollect.cfg
#Other:		N/a				
###################################################################
function hwdiag_disk_diag_info()
{
   local log_dir="${OUTPUTLOG}/disk/hwdiag_hdd.txt"
   local bma_tool="/opt/huawei/bma/bin/hwdiag"
   local ret=0
   if [ "$OEM_TYPE" != "oem" ];then
       run_cmd "${bma_tool} -t disk -d" "$log_dir"
       if [ 0 -ne $?  ]
       then
           LOG_ERROR "Get disk hwdiag info failed."
           ret=1
       fi
   fi

   return $ret
}


###################################################################
#Function:		<get_es3000_v2_info>
#Description:	get ES3000 V2 PCIe SSD log info
#Parameter:	0£ºok  1: error
#Return:	errocode  0:ok
#Since:		disk\logCollect.cfg
#Other:		N/a
###################################################################
function get_es3000_v2_info()
{
    local log_dir="${OUTPUTLOG}/disk/es3000_v2.txt"
    local cmd_file="modules/disk/cmdlist.ini"
    local ret=0

    which hio_info > /dev/null 2>&1
    if [ 0 -ne $? ]
    then
        echo "SSD not be found or driver unloaded.Process aborted." >> ${log_dir}
        ret=1
        return ${ret}
    fi
   
    ls /dev/hio* > /dev/null 2>&1
    if [ 0 -eq $? ]
    then
        ssd_num=`ls /dev/hio* | grep -v [0-9]`
        cmd_line_num=`cat ${cmd_file} | wc -l`
        for ssd in ${ssd_num}
        do
            for ((i=1;i<=${cmd_line_num};i++))
            do
                cmd=`cat ${cmd_file} | awk NR==$i | grep -E '^hio_'`
                cmd=${cmd/\r\n/}
                if [ 0 -eq $? ]
                then
                    if [ ${cmd} == "hio_log" ]
                    then
                    whole_cmd="${cmd} -d ${ssd} -l 0"
                    else
                    whole_cmd="${cmd} -d ${ssd}"
                    fi
                    run_cmd "$whole_cmd" "${log_dir}"
                fi
            done
        done
    fi
    
    return ${ret}
}


###################################################################
#Function:		<get_es3000_info>
#Description:	get ES3000 V3/V5 NVMe PCIe SSD log info
#Parameter:	0£ºok  1: error
#Return:	errocode  0:ok
#Since:		disk\logCollect.cfg
#Other:     N/a	
###################################################################
function get_es3000_info()
{
    local log_dir="${OUTPUTLOG}/disk/es3000"
    local log_file="${OUTPUTLOG}/disk/es3000/es3000.txt"
    local ret=0

    LOG_INFO "get_es3000_info:The current server adopts the ${SYS_TYPE} architecture."
    if [ "${SYS_TYPE}" == "aarch64" ]; then
        local hioadm_path="modules/disk/ES3000/hioadm_aarch64"
        LOG_INFO "The current server adopts the ARM architecture. use hioadm_aarch64."
    elif [ "${SYS_TYPE}" == "x86_64" ] || [ "${SYS_TYPE}" == "i386" ]; then
        local hioadm_path="modules/disk/ES3000/hioadm"
        LOG_INFO "The current server adopts the x86 architecture. use hioadm."
    else
        echo "get_es3000_info:The current server adopts the unknown architecture which does not support log collection." >> ${log_file}
        return
    fi

    run_cmd "mkdir -p ${log_dir}"

    run_cmd "modinfo nvme" "${log_file}"
    if [ $? -eq 0 ]
    then
        echo "current system has one ES3000 V3/V5/V6 driver." >> ${log_file}
        LOG_INFO "current system has one ES3000 V3/V5/V6 driver."
    else
        echo "current system has no ES3000 V3/V5/V6 driver." >> ${log_file}
        LOG_ERROR "current system has no ES3000 V3/V5/V6 driver."
    fi

    ${hioadm_path} info > /dev/null 2>&1
    if [ $? -ne 0 ]
    then
        echo "Scan NVMe SSD devices failed. Process aborted." >> ${log_file}
        ret=1
        return ${ret}
    fi

    hioadm_info=($(${hioadm_path} info | grep -E "^\|---- sd|^\|---- nvme|^\|---- pd"))

    nvme_num=$(expr ${#hioadm_info[*]} / 3)
    for ((i=0;i<${nvme_num};i++))
    do 
        nvme_index=$(expr ${i} \* 3 + 1)
        nvme=${hioadm_info[${nvme_index}]}
        # collect SMART information of the specified device
        run_cmd "${hioadm_path} info -d ${nvme} -s" "${log_file}"
        # collect advanced SMART information of the specified device
        run_cmd "${hioadm_path} info -d ${nvme} -a" "${log_file}"
        # collect controller information of the specified device
        run_cmd "${hioadm_path} info -d ${nvme}" "${log_file}"
        # collect log of the specified device
        get_es3000_v3_log "${log_dir}" "${nvme}"
    done

 
    return ${ret}
}


###################################################################
#Function:		<get_es3000_v3_log>
#Description:	get ES3000 V3 NVMe PCIe SSD log
#Parameter:	0£ºok  1: error
#Return:	errocode  0:ok
#Since:		disk\logCollect.cfg
#Other:     N/a	
###################################################################
function get_es3000_v3_log()
{
    local log_dir=$1
    local nvme=$2
    local ret=0

    LOG_INFO "get_es3000_log:The current server adopts the ${SYS_TYPE} architecture."
    if [ "${SYS_TYPE}" == "aarch64" ]; then
        local hioadm_path="modules/disk/ES3000/hioadm_aarch64"
        LOG_INFO "The current server adopts the ARM architecture. use hioadm_aarch64."
    elif [ "${SYS_TYPE}" == "x86_64" ] || [ "${SYS_TYPE}" == "i386" ]; then
        local hioadm_path="modules/disk/ES3000/hioadm"
        LOG_INFO "The current server adopts the x86 architecture. use hioadm."
    else
        LOG_INFO "get_es3000_log:The current server adopts the unknown architecture which does not support log collection."
        return
    fi

    if [ ! -d "/opt/hio" ]
    then
    	run_cmd "mkdir -p /opt/hio"
    fi
    result=$(${hioadm_path} log -d ${nvme} -a)
    if [ $? -ne 0 ]
    then
        LOG_ERROR "Get ES3000 V3 ${nvme} log failed. Reason: ${result}"
        return 1
    fi
 
    local log_file=($(ls /opt/hio | grep -E ".log$|.txt$"))
    file_num=${#log_file[*]}
    for ((j=0;j<${file_num};j++))
    do
        run_cmd "cp /opt/hio/${log_file[$j]} ${log_dir}"
    done
    LOG_INFO "Get ES3000 V3 ${nvme} log successfully."
}


################################################################
#Function:		<get_scheduler_info>
#Description:   get disk scheduler info
#Parameter:     0??ok  1: error
#Return:        errocode  0:ok
#Since:         disk\logCollect.cfg
#Other:         N/a
###################################################################
function get_scheduler_info()
{
 local log_dir="${OUTPUTLOG}/disk/scheduler.txt"
 local bma_tool="/sys/block/*/queue/scheduler"
 local ret=0

  run_cmd "cat ${bma_tool}" ${log_dir}
   if [ 0 -ne $?  ]
   then
       LOG_ERROR "Get disk scheduler info failed."
       ret=1
   fi

   return $ret
}


################################################################
#Function:		<get_1822_nic_info>
#Description:	get 1822 nic card log info
#Parameter:	0£ºok  1: error
#Return:	errocode  0:ok
#Since:		nic\logCollect.cfg
#Other:		N/a
###################################################################
function get_1822_nic_info()
{
   local log_dir="${OUTPUTLOG}/nic"
   local log_file="${OUTPUTLOG}/nic/log_nic.txt"
   local osca_tool="modules/nic/1822_nic_collect.sh"
   local ret=0

   LOG_INFO "get_1822_nic_info:The current server adopts the ${SYS_TYPE} architecture."

   if [ "${SYS_TYPE}" == "aarch64" ]; then
       LOG_INFO "get_1822_nic_info:The current server adopts the ARM architecture which supports log collection."
   elif [ "${SYS_TYPE}" != "x86_64" ] && [ "${SYS_TYPE}" != "i386" ]; then
       LOG_INFO "get_1822_nic_info:The current server adopts the unknown architecture which does not support log collection."
       return
   fi

    if [ ! -d "${log_dir}" ]
    then
        run_cmd "mkdir -m a=r ${log_dir}"
        LOG_INFO "Create ${log_dir} ok."
    fi

   run_cmd "./${osca_tool}" ${log_file}
   if [ 0 -eq $? ]
   then
       cp modules/nic/1822_nic_info.tar.gz $log_dir
   else
       LOG_ERROR "Get 1822_nic log info failed."
       ret=1
   fi

   return $ret
}


################################################################
#Function:		<get_Mellanox_nic_info>
#Description:	Mellanox nic info
#Parameter:	NA
#Return:	errocode  0:ok
#Since:		nic\logCollect.cfg
#Other:		N/a
###################################################################
function get_Mellanox_nic_info()
{
   local log_dir="${OUTPUTLOG}/nic"
   local result_file="${OUTPUTLOG}/nic/Mellanox_fsdump_info.txt"
   local py_file="/usr/sbin/sysinfo-snapshot.py"
   local py_log_file="${OUTPUTLOG}/nic/sysinfo-snapshot_run_log.log"
   local ret=0

   LOG_INFO "get_Mellanox_nic_info:The current server adopts the ${SYS_TYPE} architecture."

    local mell_nic_num=`lspci |grep -i "mellanox" |wc -l`
    if [ 0 -eq $mell_nic_num ]
    then
	    LOG_INFO "no Mellanox nic."
        return $ret
    fi

    if [ ! -d "${log_dir}" ]
    then
        run_cmd "mkdir -m a=r ${log_dir}"
        LOG_INFO "Create ${log_dir} ok."
    fi

    local run_time=1
    for((;run_time<=$mell_nic_num;run_time++))
	do
	    local bdf_id=`lspci |grep -i "mellanox" | awk '(NR=='${run_time}')'| awk -F " " '{print$1}'`
		run_cmd "mlxdump -d ${bdf_id} fsdump --type FT --no_zero" "${result_file}"
		if [ 0 -ne $? ]
		then
		   LOG_ERROR "Get Mellanox nic ${bdf_id} fsdump info failed."
		   ret=1
		fi
    done
	
	if [ ! -f "${py_file}" ]
    then
	   LOG_INFO "${py_file} not exist."
	   return $ret
	fi
	
	run_cmd "python ${py_file}" "${py_log_file}"
	if [ 0 -ne $? ]
	then
	    LOG_ERROR "Get Mellanox sysinfo info failed."
	    ret=1
    fi
	
	if [ -f "${py_log_file}" ]
	then
		local ret_file_num=`cat ${py_log_file} |grep -iE "out file name is \S+" |wc -l`
		if [ 0 -ne $ret_file_num ]
		then
			 result_file=`cat ${py_log_file} |grep -iE "out file name is \S+" | awk '(NR=='1')'| awk -F "name is " '{print$2}'`
			run_cmd "cp ${result_file} ${log_dir}"
	    else
		    LOG_ERROR "Get Mellanox sysinfo, can not get out file."
			ret=1
		fi
	fi
    return $ret
}


################################################################
#Function:		<get_Intel_nic_info>
#Description:	Intel nic info
#Parameter:	NA
#Return:	errocode  0:ok
#Since:		nic\logCollect.cfg
#Other:		N/a
###################################################################
function get_Intel_nic_info()
{
   local log_dir="${OUTPUTLOG}/nic"
   local i40e_dir="/sys/kernel/debug/i40e"
   local ret=0

   LOG_INFO "get_Intel_nic_info:The current server adopts the ${SYS_TYPE} architecture."

    if [ ! -d "${i40e_dir}" ]
    then
	    LOG_INFO "${i40e_dir} not exist."
        return $ret
    fi
	
	i40e_device=`ls ${i40e_dir}`
    if [ -z "${i40e_device}" ]
    then
	    LOG_INFO "${i40e_dir} no devices."
        return $ret
    fi
	
    if [ ! -d "${log_dir}" ]
    then
        run_cmd "mkdir -m a=r ${log_dir}"
        LOG_INFO "Create ${log_dir} ok."
    fi
    
	intel_nic_num=`ls -l ${i40e_dir} | grep -iv "total" | wc -l`
    local run_time=1
    for((;run_time<=$intel_nic_num;run_time++))
	do
        local tmp_bdf=`ls -l ${i40e_dir} | grep -iv "total" |awk '(NR=='${run_time}')' |awk -F' ' '{print $NF}'`
		local bdf_id=`echo "${tmp_bdf}" | sed 's/:/\\\\:/g'`
		local command_file="${i40e_dir}/${bdf_id}/command"
		LOG_INFO "Begin to echo dump command to ${command_file}."
		run_cmd "echo 'dump switch' > ${command_file}"
		sleep 1s
		run_cmd "echo 'dump resources' > ${command_file}"
		sleep 1s
		run_cmd "echo 'dump capabilities' > ${command_file}"
		sleep 1s
		run_cmd "echo 'dump vsi' > ${command_file}"
		sleep 3s
		dmesg | grep -i "${tmp_bdf}: dump vsi\[" > ${log_dir}/intel_tmp.txt
		vsi_num=`cat ${log_dir}/intel_tmp.txt | wc -l`
		if [ 0 -ne $vsi_num ]
		then
		    local vsi_num_str=""
			local i=1
			for((;i<=$vsi_num;i++))
			do
			    local tmp_id=`cat ${log_dir}/intel_tmp.txt | awk '(NR=='${i}')'| awk -F "dump vsi" '{print$2}' | awk -F ": " '{print$2}'`
				if [[ ${vsi_num_str} =~ "[${tmp_id}]" ]]
				then
				    continue
				fi
				vsi_num_str="${vsi_num_str}[${tmp_id}]"
				run_cmd "echo 'dump vsi ${tmp_id}' > ${command_file}"
				sleep 1s
			done
		fi
		rm -rf ${log_dir}/intel_tmp.txt
		run_cmd "echo 'dump veb' > ${command_file}"
		sleep 1s
		run_cmd "echo 'dump vf' > ${command_file}"
		sleep 1s
		run_cmd "echo 'dump reset stats' > ${command_file}"
		sleep 1s
		run_cmd "echo 'dump port' > ${command_file}"
		sleep 1s
		run_cmd "echo 'dump filters' > ${command_file}"
		sleep 1s
    done
	LOG_INFO "Intel info is in dmesg."
	
    return $ret
}

################################################################
#Function:		<get_1822_fc_info>
#Description:	get 1822 fc card log info
#Parameter:	0£ºok  1: error
#Return:	errocode  0:ok
#Since:		hba\logCollect.cfg
#Other:		N/a
###################################################################
function get_1822_fc_info()
{
   local log_dir="${OUTPUTLOG}/hba"
   local log_file="${OUTPUTLOG}/hba/log_hba.txt"
   local osca_tool="modules/hba/1822_fc_collect.sh"
   local ret=0

   LOG_INFO "get_1822_fc_info:The current server adopts the ${SYS_TYPE} architecture."

   if [ "${SYS_TYPE}" == "aarch64" ]; then
       LOG_INFO "get_1822_fc_info:The current server adopts the ARM architecture which supports log collection."
   elif [ "${SYS_TYPE}" != "x86_64" ] && [ "${SYS_TYPE}" != "i386" ]; then
       LOG_INFO "get_1822_fc_info:The current server adopts the unknown architecture which does not support log collection."
       return
   fi

    if [ ! -d "${log_dir}" ]
    then
        run_cmd "mkdir -m a=r ${log_dir}"
        LOG_INFO "Create ${log_dir} ok."
    fi

   run_cmd "./${osca_tool}" ${log_file}
   if [ 0 -eq $? ]
   then
       cp modules/hba/1822_fc_info.tar.gz $log_dir
   else
       LOG_ERROR "Get 1822_fc log info failed."
       ret=1
   fi

   return $ret
}

################################################################
#Function:		<get_hba_pci_port_info>
#Description:	get hba card pic port info and print file
#Parameter:	0£ºok  1: error
#Return:	errocode  0:ok
#Since:		hba\logCollect.cfg
#Other:		N/a
###################################################################
function get_hba_pci_port_info()
{
    local path=$1
    local log_dir=$2
    local port_next_cmd=""
    local port_next_result=""
    local last_cmd=""
    local last_result=""
    #取得port下的文件夹，形式为0000:00:00
    port_next_cmd="ls ${path}"
    port_next_result=$(eval "${port_next_cmd}" 2>&1)

    if [ ! -d "$log_dir" ]; then
        mkdir -p $build_dir
    fi

    for port_next in ${port_next_result}
    do
        if [ ${port_next:0:4} == "0000" ]
        then
            run_cmd "cat ${path}/${port_next}/vendor" "${log_dir}/hba_pci_info.txt"
            run_cmd "cat ${path}/${port_next}/device" "${log_dir}/hba_pci_info.txt"
            run_cmd "cat ${path}/${port_next}/subsystem_vendor" "${log_dir}/hba_pci_info.txt"
            run_cmd "cat ${path}/${port_next}/subsystem_device" "${log_dir}/hba_pci_info.txt"
        fi
    done
}

################################################################
#Function:		<get_hba_pci_info>
#Description:	get hba card pic info
#Parameter:	0£ºok  1: error
#Return:	errocode  0:ok
#Since:		hba\logCollect.cfg
#Other:		N/a
###################################################################
function get_hba_pci_info()
{
    local log_dir="${OUTPUTLOG}/hba"
    local ret=0
    local pci_cmd=""
    local pci_result=""
    local pci_ret_code=0
    local pci_ch=""
    local port_cmd=""
    local port_result=""
    local port_ret_code=0
    local port_ch=""
    local port_ch1=""

    #从/sys/devices/中获取pci0000:xx文件夹
    pci_cmd="ls /sys/devices/"
	pci_result=$(eval "${pci_cmd}" 2>&1)
	pci_ret_code=$?

    if [ 0 -ne ${pci_ret_code} ]
	then
	    ret=${pci_ret_code}
	    LOG_ERROR "[$pci_cmd] failed.Ret:$pci_result. Desc:$pci_ret_code"
	    LOG_ERROR "Get hba card pic info failed."
	else
	    for pci in ${pci_result}
	    do
	        if [ ${pci:0:3} == "pci" ]
	        then
                #从pci0000:xx取到xx，用来和root_port对比
                pci_ch=${pci#*:}

                #从/sys/devices/pci0000:xx获取0000:xx:yy.z文件夹
                port_cmd="ls /sys/devices/${pci}/"
                port_result=$(eval "${port_cmd}" 2>&1)
                port_ret_code=$?

                if [ 0 -ne ${port_ret_code} ]
                then
                    ret=$port_ret_code
                    LOG_ERROR "[$port_cmd] failed.Ret:$port_ret_code. Desc:$port_result"
                    return
                fi

                for root_port in ${port_result}
                do
                    if [ ${root_port:0:4} == "0000" ]
                        then
                        #删除第一个：左边的全部字符
                        port_ch=${root_port#*:}
                        #删除右边第一个：的所有字符
                        port_ch1=${port_ch%:*}
                        #判断pci与port文件夹的xx是否相同
                        if [ ${port_ch1} == ${pci_ch} ]
                        then
                            #调用get_hba_pci_port_info获取port下的文件夹并且打印文件夹里对应文件
                            get_hba_pci_port_info "/sys/devices/${pci}/${root_port}" "${log_dir}"
                        fi
                    fi
                done
	        fi
	    done
    fi
    return ${ret}
}

################################################################
#Function:		<get_hba_port_info>
#Description:	get hba card port info
#Parameter:	0£ºok  1: error
#Return:	errocode  0:ok
#Since:		hba\logCollect.cfg
#Other:		N/a
###################################################################
function get_hba_port_info()
{
    local log_dir="${OUTPUTLOG}/hba"
    local ret=0
    local port_cmd=""
    local port_result=""
    local port_ret_code=0
    #获取/sys/class/fc_host/的文件夹
    port_cmd="ls /sys/class/fc_host/"
    port_result=$(eval "${port_cmd}" 2>&1)
    port_ret_code=$?

    if [ 0 -ne ${port_ret_code} ]
	then
	    ret=${port_ret_code}
	    LOG_ERROR "[$port_cmd] failed.Ret:$port_ret_code. Desc:$port_result"
	    LOG_ERROR "Get hba card pic info failed."
	else
	    for hostX in ${port_result}
	    do
            run_cmd "cat /sys/class/fc_host/${hostX}/port_id" "${log_dir}/hba_pci_info.txt"
            run_cmd "cat /sys/class/fc_host/${hostX}/port_type" "${log_dir}/hba_pci_info.txt"
            run_cmd "cat /sys/class/fc_host/${hostX}/speed" "${log_dir}/hba_pci_info.txt"
            run_cmd "cat /sys/class/fc_host/${hostX}/fabric_name" "${log_dir}/hba_pci_info.txt"
	    done
	fi
}

################################################################
#Function:		<get_hba_driver_info>
#Description:	get hba card driver info
#Parameter:	0£ºok  1: error
#Return:	errocode  0:ok
#Since:		hba\logCollect.cfg
#Other:		N/a
###################################################################
function get_hba_driver_info()
{
    local log_dir="${OUTPUTLOG}/hba"
    run_cmd "rpm -qa | grep lpfc" "${log_dir}/hba_pci_info.txt"
    run_cmd "modinfo lpfc | grep version" "${log_dir}/hba_pci_info.txt"
    run_cmd "modinfo qla2xxx | grep version" "${log_dir}/hba_pci_info.txt"
}

################################################################
#Function:		<get_mezz_info>
#Description:	get mezz card log info
#Parameter:	0£ºok  1: error
#Return:	errocode  0:ok
#Since:		nic\logCollect.cfg
#Other:		N/a				
###################################################################
function get_mezz_info()
{
   local log_dir="${OUTPUTLOG}/nic"
   local osca_tool="modules/nic/mezz_collect.sh"
   local ret=0

   LOG_INFO "get_mezz_info:The current server adopts the ${SYS_TYPE} architecture."

   if [ "${SYS_TYPE}" == "aarch64" ]; then
       LOG_INFO "get_mezz_info:The current server adopts the ARM architecture which does not support log collection."
       return
   elif [ "${SYS_TYPE}" != "x86_64" ] && [ "${SYS_TYPE}" != "i386" ]; then
       LOG_INFO "get_mezz_info:The current server adopts the unknown architecture which does not support log collection."
       return
   fi

    if [ ! -d "${log_dir}" ]
    then
        run_cmd "mkdir -m a=r ${log_dir}"
        LOG_INFO "Create ${log_dir} ok."
    fi

   run_cmd "./modules/nic/mezz_collect.sh"  "/dev/null"
   if [ 0 -eq $? ]
   then
       cp modules/nic/mezz_info.tar.gz $log_dir
   else
       LOG_ERROR "Get mezz log info failed."
       ret=1
   fi

   return $ret
}

function getJsonValuesByAwk() {
    awk -v json="$1" -v key="$2" -v defaultValue="$3" 'BEGIN{
        foundKeyCount = 0
        while (length(json) > 0) {
            # pos = index(json, "\""key"\""); ## 这行更快一些，但是如果有value是字符串，且刚好与要查找的key相同，会被误认为是key而导致值获取错误
            pos = match(json, "\""key"\"[ \\t]*?:[ \\t]*");
            if (pos == 0) {if (foundKeyCount == 0) {print defaultValue;} exit defaultValue;}

            ++foundKeyCount;
            start = 0; stop = 0; layer = 0;
            for (i = pos + length(key) + 1; i <= length(json); ++i) {
                lastChar = substr(json, i - 1, 1)
                currChar = substr(json, i, 1)

                if (start <= 0) {
                    if (lastChar == ":") {
                        start = currChar == " " ? i + 1: i;
                        if (currChar == "{" || currChar == "[") {
                            layer = 1;
                        }
                    }
                } else {
                    if (currChar == "{" || currChar == "[") {
                        ++layer;
                    }
                    if (currChar == "}" || currChar == "]") {
                        --layer;
                    }
                    if ((currChar == "," || currChar == "}" || currChar == "]") && layer <= 0) {
                        stop = currChar == "," ? i : i + 1 + layer;
                        break;
                    }
                }
            }

            if (start <= 0 || stop <= 0 || start > length(json) || stop > length(json) || start >= stop) {
                if (foundKeyCount == 0) {print defaultValue;} exit 0;
            } else {
                print substr(json, start, stop - start);
            }
            json = substr(json, stop + 1, length(json) - stop)
        }
    }' > ./tmp.txt
}

################################################################
#Function:		<get_smart_info>
#Description:	get disk smart info
#Parameter:	NA
#Return:	errocode  0:ok
#Since:		disk\logCollect.cfg
#Other:		N/a
###################################################################
function get_smart_info()
{
    local log_dir="${OUTPUTLOG}/disk/dfs"
    local dfs_path="modules/disk/dfs"
    local ret=0
    local path=$("pwd")
    local path_disk="${path}/${log_dir}"
    local dfs_smart_log="${path_disk}/dfs_smart.txt"
    local dfs_file="DFS.zip"

    mkdir -p ${log_dir}

    echo "get_smart_info:get_smart_info start!" >> "${dfs_smart_log}"
    cd $dfs_path
    if [ -f ${dfs_file} ]; then
        unzip -o -q ${dfs_file}
        LOG_INFO "unzip dfs_tool/DFS.zip ok."
    else
        LOG_ERROR "dfs_tool/dfs_tool/DFS.zip is not exist"
        ret=1
        return ${ret}
    fi

    if [ -f dfs.py ]; then
        LOG_INFO "dfs_tool is exist"
    else
        LOG_ERROR "dfs_tool is not exist"
        ret=1
        return ${ret}
     fi
    cmd="python dfs.py -o smart"
    result=$(eval "${cmd}")

    getJsonValuesByAwk "$result" "status" "defaultValue"
    for temp_line in $(cat "tmp.txt")
        do
            echo $temp_line >> "${dfs_smart_log}"
            if [ $temp_line != '"success"' ];then
              return 1;
            fi
        done

    getJsonValuesByAwk "$result" "file_path" "defaultValue"
    for temp_line in $(cat "tmp.txt")
        do
            echo $temp_line >> "${dfs_smart_log}"
            if [ -n $temp_line ];then
              cp ${temp_line//\"/} $path/$log_dir
            fi
        done
    cd $path
}

################################################################
#Function:		<get_internal_log>
#Description:	get disk internal log
#Parameter:	NA
#Return:	errocode  0:ok
#Since:		disk\logCollect.cfg
#Other:		N/a
###################################################################
function get_internal_log()
{
    local log_dir="${OUTPUTLOG}/disk/dfs"
    local dfs_path="modules/disk/dfs"
    local ret=0
    local path=$("pwd")
    local path_disk="${path}/${log_dir}"
    local dfs_file="DFS.zip"
    local dfs_internal_log="${path_disk}/dfs_internal_log.txt"
    mkdir -p ${log_dir}

    echo "get_internal_log:get_internal_log start!" >> "${dfs_internal_log}"

    cd $dfs_path

    if [ -f ${dfs_file} ]; then
        unzip -o -q ${dfs_file}
        LOG_INFO "unzip dfs_tool/DFS.zip ok."
    else
        LOG_ERROR "dfs_tool/dfs_tool/DFS.zip is not exist"
        ret=1
        return ${ret}
    fi

    if [ -f dfs.py ]; then
        LOG_INFO "dfs_tool is exist"
    else
        LOG_ERROR "dfs_tool is not exist"
        ret=1
        return ${ret}
    fi

    cmd="python dfs.py -o internalLog"
    resultOfLog=$(eval "${cmd}")

    getJsonValuesByAwk "$resultOfLog" "status" "defaultValue"
    for temp_line in $(cat tmp.txt)
    do
        echo $temp_line >> "${dfs_internal_log}"
        if [ $temp_line != '"success"' ];then
            return 1;
        fi
    done

    cmd="python dfs.py -o internalLogProg"
    resultOfProg=$(eval "${cmd}")
    echo "$resultOfProg" >> "${dfs_internal_log}"

    getJsonValuesByAwk "$resultOfLog" "status" "defaultValue"
    local status=$(cat tmp.txt)
    echo "$status" >> "${dfs_internal_log}"
    while [ $status == '"executing"' ]; do
        resultOfProg=$(eval "${cmd}")
        echo "$resultOfProg" >> "${dfs_internal_log}"
        getJsonValuesByAwk "$resultOfLog" "status" "defaultValue"
        status = $(cat tmp.txt)
    done

    resultOfProg=$(eval "${cmd}")
    echo "$resultOfProg" >> "${dfs_internal_log}"
    getJsonValuesByAwk "$resultOfProg" "file_path" "defaultValue"
    for temp_line in $(cat tmp.txt)
    do
        echo $temp_line >> "${dfs_internal_log}"
        cp ${temp_line//\"/} $path/$log_dir
    done
    cd $path
}

################################################################
#Function:		<get_udisk_info>
#Description:	get get_udisk_info  log info
#Parameter:	0??ok  1: error
#Return:	errocode  0:ok
#Since:		disk\logCollect.cfg
#Other:		N/a
###################################################################
function get_udisk_info()
{

   local log_dir="${OUTPUTLOG}/disk/udisk.txt"
   local osca_tool="modules/disk/udisk_tool"
   local ret=0
   local path=$("pwd")
   local path_disk="${path}/${log_dir}"

   if [ "${SYS_TYPE}" == "aarch64" ]; then
        LOG_INFO "The current server adopts the ARM architecture, use uDisk_aarch64.tar.gz"
        local uDisk_file="uDisk_aarch64.tar.gz"
   elif [ "${SYS_TYPE}" == "x86_64" ] || [ "${SYS_TYPE}" == "i386" ]; then
        LOG_INFO "The current server adopts the x86 architecture, use uDisk.tar.gz"
        local uDisk_file="uDisk.tar.gz"
   else
        LOG_INFO "get_udisk_info:The current server adopts the unknown architecture which does not support log collection."
        return
   fi

    if [ -f ${osca_tool}/${uDisk_file} ]; then
		tar -xzvf $osca_tool/${uDisk_file} -C $osca_tool
		LOG_INFO "tar -xzvf $osca_tool/uDisk.tar.gz ok."
	else
		LOG_ERROR "$osca_tool/uDisk.tar.gz is not exist"
        ret=1
	fi

    cd $osca_tool/uDisk/
	if [ -f udisk ]; then
		chmod 550 udisk
		run_cmd "./udisk -h" "$path_disk"
		LOG_INFO "excute ./udisk -h success"
	fi
	if [ $? == 0 ]
	then
	    run_cmd "./udisk -v" "$path_disk"
	    LOG_INFO "excute ./udisk -v success"
	    run_cmd "./udisk -l all" "$path_disk"
	    LOG_INFO "excute ./udisk -l SN|all success"
	    run_cmd "./udisk -s all" "$path_disk"
	    LOG_INFO "excute ./udisk -s all success"
	    run_cmd "./udisk -m all" "$path_disk"
	    LOG_INFO "excute ./udisk -m SN|all success"
	    run_cmd "./udisk -d all" "$path_disk"
	    LOG_INFO "excute ./udisk -d SN|all success"
        run_cmd "./udisk -p all" "$path_disk"
	    LOG_INFO "excute ./udisk -p SN|all success"
        fi
       cd $path
   return $ret
}

###############################################################
#Function:      <get_blktrace_info>
#Description:   get disk blktrace information
#Parameter: NA
#Return:    Disk blktrace logs
#Since:     disk\logCollect.cfg
#Other:     N/a
###################################################################
function get_blktrace_info()
{
    local log_dir="${OUTPUTLOG}/disk/blktrace"
    local ret=0
    mkdir -p ${log_dir}

    top -b -d 3 > "${log_dir}/top.log" &
    top_pid=$!

    iostat -xct 3 > "${log_dir}/iostat.log" &
    iostat_pid=$!

    date > "${log_dir}/free.log" && free -s 3 >> "${log_dir}/free.log" &
    free_pid=$!

    disks=$(fdisk -l | grep -E "Disk /dev/[hsv]d" | awk -F '[ :]' '{print $2}' | awk -F '/dev/' '{print $2}')
    for disk in $disks
    do
        LOG_INFO "Get /dev/${disk} blktrace"
        mkdir -p ${log_dir}/${disk}
        run_cmd "blktrace -d /dev/${disk} -w 30 -D ${log_dir}/${disk}" "${log_dir}/${disk}/blktrace_log.txt"
        run_cmd "blkparse -i ${disk} -D ${log_dir}/${disk} -d ${log_dir}/${disk}/blktrace.bin" "${log_dir}/${disk}/blktrace_log.txt"
        run_cmd "cd ${log_dir}/${disk} && btt -i blktrace.bin -l d2c_latency -q q2c_latency -B offset > blktrace.txt" "${log_dir}/${disk}/blktrace_log.txt"

        run_cmd "rm -rf ${log_dir}/${disk}/${disk}.blktrace.*" "${log_dir}/${disk}/blktrace_log.txt"
        run_cmd "rm -rf ${log_dir}/${disk}/blktrace.bin" "${log_dir}/${disk}/blktrace_log.txt"
        run_cmd "rm -rf ${log_dir}/${disk}/offset_*_c.dat" "${log_dir}/${disk}/blktrace_log.txt"
    done

    kill $top_pid
    kill $iostat_pid
    kill $free_pid

    return $ret
}

################################################################
#Function:		<get_disk_other_info>
#Description:	get disk other log info
#Parameter:	0??ok  1: error
#Return:	errocode  0:ok
#Since:		disk\logCollect.cfg
#Other:		N/a
###################################################################
function get_disk_other_info()
{
    local log_dir="${OUTPUTLOG}/disk/disk_other_info.txt"
    local ret=0

    #collect sg_logs/sg_modes command log info
    ls /dev/sd* > /dev/null 2>&1
    if [ 0 -ne $? ]
    then
        echo "Failed to run the ls /dev/sd* command." >> $log_dir
    else
        local result=`ls /dev/sd* | grep -v [1-9]`
        for sd in ${result}
        do
            run_cmd "sg_logs -a ${sd}" "$log_dir"
            run_cmd "sg_modes -a -a ${sd}" "$log_dir"
        done
    fi

    #collect lspci command log info
    local lspci_result=`lspci`
    if [ 0 -ne $? ]
    then
        echo "Failed to run the lspci command." >> $log_dir
        return $ret
    fi

    local nvme_disk=""
    # 记录nvme盘BDF参数值
    local nvme_bdf_arr=([0]="")
    # 定义分割符为换行，临时变量，当前函数生效
    local IFS=$'\n'
    for line in `ls -l /sys/class/block/ | grep "nvme"`
    do
        nvme_disk="nvme result is not empty"
        # 获取BDF参数
        local bdf_value=`get_nvme_bdf "$line"`
        if [[ "${nvme_bdf_arr[@]}" =~ "$bdf_value" ]] && [ "$bdf_value" != "" ]
        then
            echo "This nvme bdf value:$bdf_value has handled." >> $log_dir
        else
            run_cmd "lspci -vvvxxx -s $bdf_value" "$log_dir"
            nvme_bdf_arr[${#nvme_bdf_arr[@]}]=$bdf_value
        fi
    done
    if [ "$nvme_disk" == "" ]
    then
        echo "Match nvme disk command result is empty." >> $log_dir
    fi

    return $ret
}


################################################################
#Function:		<get_nvme_bdf>
#Description:	get nvme bdf value,
#Parameter:	command(ls -l /sys/class/block/ | grep "nvme") result line
#Return:	errocode  0:ok 1:error
#Since:		disk\logCollect.cfg
#Other:		N/a
###################################################################
function get_nvme_bdf
{
    local line_str=$1
    if [ -n "$line_str" ] && [[ $line_str =~ "/nvme/" ]]
    then
        # 获取nvme_bdf的值
        echo $line_str | sed "s/.*\(..\:..\..\)\/nvme\/.*/\1/g"
    else
        echo ""
    fi
}

################################################################
#Function:		<get_ifconfig_info>
#Description:	get ifconfig info
#Return:	errocode  0:ok
#Since:		cyclicCollection\logCollect.cfg
#Other:		N/a				
###################################################################
function get_ifconfig_info()
{
   local log_dir="${OUTPUTLOG}/cyclicCollection"
   local ret=0

    ifconfig >/dev/null 2>&1
	if [ $? == 0 ]
    then
		run_cmd "ifconfig -a" "$log_dir/ifconfig.txt"
        LOG_INFO "excute ifconfig -a success"
    else
       run_cmd "ip a" "$log_dir/ifconfig.txt"
	   run_cmd "ip -s link list" "$log_dir/ifconfig.txt"
	   run_cmd "ip route list" "$log_dir/ifconfig.txt"
       LOG_INFO "excute ip a success"
   fi

   return $ret
}


################################################################
#Function:		<get_netstat_info>
#Description:	get netstat info
#Return:	errocode  0:ok
#Since:		nic\logCollect.cfg
#Other:		N/a				
###################################################################
function get_netstat_info()
{
   local log_dir="${OUTPUTLOG}/cyclicCollection"
   local ret=0

    netstat -V>/dev/null 2>&1
	if [ $? == 0 ]
    then
		run_cmd "netstat -i -n" "$log_dir/netstat.txt"
		LOG_INFO "excute netstat -i -n success"
		run_cmd "netstat -avn" "$log_dir/netstat.txt"
		LOG_INFO "excute netstat -avn success"
		run_cmd "netstat -s" "$log_dir/netstat.txt"
		LOG_INFO "excute netstat -s success"
		run_cmd "netstat -rvn" "$log_dir/netstat.txt"
        LOG_INFO "excute netstat -s success"
    else
       run_cmd "ss -ape" "$log_dir/netstat.txt"
	   LOG_INFO "excute ss -ape success"
	   run_cmd "ss -s" "$log_dir/netstat.txt"
	   LOG_INFO "excute ss -s success"
   fi

   return $ret
}
################################################################
#Function:                          <get_ib_info>
#Description:     get infiniband/OPA information
#Parameter:      NA
#Return:              infiniband or OPA logs
#Since:                 hpc\logCollect.cfg
#Other:                                N/a
###################################################################
function get_ib_info()
{
    local log_dir="${OUTPUTLOG}/hpc"
    local ret=0
    # Get ibstat output
    run_cmd "ibstat" "${log_dir}/ibstat_log.txt"
    if [ 0 -ne $? ]
    then
        LOG_ERROR "Get infiniband/OPA info failed."
        ret=1
        return $ret
#   else
#       LOG_INFO "Get infiniband/OPA info succeed."
    fi
    if ibstat | grep -q -P "CA 'hfi\d_\d'";then
       # OPA collect
        run_cmd "mkdir -p ${log_dir}/opa"

                run_cmd "opainfo" "${log_dir}/opa/opainfo_log.txt"
                run_cmd "opareport -v" "${log_dir}/opa/opareport-v_log.txt"
                run_cmd "opareport -o slowlinks" "${log_dir}/opa/opareport-slowlinks_log.txt"
                run_cmd "opareport -o errors" "${log_dir}/opa/opareport-errors_log.txt"
                run_cmd "opareport -o linear" "${log_dir}/opa/opareport-linear_log.txt"
                run_cmd "opasaquery -o swinfo" "${log_dir}/opa/opasaquery-swinfo_log.txt"
                run_cmd "opasaquery -o node" "${log_dir}/opa/opasaquery-nodeinfo_log.txt"
                run_cmd "opahfirev" "${log_dir}/opa/opahfirev_log.txt"

    elif ibstat | grep -q -P "CA 'mlx\d_\d'";then
       # MELLENOX IB collect

        run_cmd "mkdir -p ${log_dir}/infiniband/ibdiagnet"

                run_cmd "iblinkinfo" "${log_dir}/infiniband/iblinkinfo_log.txt"
                run_cmd "ibnetdiscover" "${log_dir}/infiniband/ibnetdiscover_log.txt"
                run_cmd "ibdev2netdev"  "${log_dir}/infiniband/ibdev2netdev_log.txt"
        run_cmd "ibdiagnet -r -P all=1 -o ${log_dir}/infiniband/ibdiagnet" "${log_dir}/infiniband/ibdiagnet_runlog.txt"
    fi

    return $ret

}

################################################################
#Function:        <get_ibma_log>
#Description:     get ibma full log
#Parameter:       NA
#Return:          ibma full logs
#Since:           ibma\logCollect.cfg
#Other:           N/a
###################################################################
function get_ibma_log()
{
    local log_dir="${OUTPUTLOG}/ibma"
    local ret=0
    # Get ibma full log
    run_cmd "mkdir -p ${log_dir}"
    if [ "$OEM_TYPE" == "oem" ];then
        run_cmd "cp -r /opt/ibma/log/* ${log_dir}"
    else
        run_cmd "cp -r /opt/huawei/ibma/log/* ${log_dir}"
    fi
    return $ret
}

################################################################
#Function:        <get_message_copy_info>
#Description:     get message copy info
#Parameter:       NA
#Return:          message copy info
#Since:           system\logCollect.cfg
#Other:           N/a
###################################################################
function get_message_copy_info()
{
    local ret=0

    if [ -d /var/log/logdump ]; then
        #Get FS Openstack HOST OS 6.1 6.3 6.5 message copy info
        local openstack_log_dir="${OUTPUTLOG}/system/var/log"
        run_cmd "mkdir -p $openstack_log_dir"
        run_cmd "cp -r /var/log/logdump $openstack_log_dir"
        ls -l -t /var/log | grep -m3 logdump- |awk '{print $9}' > test_temp   
        for temp_line in $(cat test_temp)
        do 
            LOG_INFO $temp_line
            run_cmd "cp -r /var/log/$temp_line $openstack_log_dir"
        done
        run_cmd "rm -rf test_temp"
    fi
    
    if [ -d /var/log/$(hostname) ]; then
        # Get FS FusionCompute CNA HOST OS 6.1 message copy info
        local cna1_dir="${OUTPUTLOG}/system/var/log/$(hostname)"
        run_cmd "mkdir -p $cna1_dir" 
        ls -l /var/log/$(hostname) | tail -n 3 | awk '{print $9}' >test_temp_1 
        for temp_line_1 in $(cat test_temp_1)
        do 
            LOG_INFO $temp_line_1
            run_cmd "cp -r /var/log/$(hostname)/$temp_line_1 $cna1_dir"
        done
        run_cmd "rm -rf test_temp_1"
    fi
    
    if [ -d /var/backuplog/galaxenginelog ]; then
        # Get FS FusionCompute CNA HOST OS 6.3 6.5 message copy info
        local cna2_dir="${OUTPUTLOG}/system/var/backuplog/galaxenginelog"
        run_cmd "mkdir -p $cna2_dir"
        ls -l /var/backuplog/galaxenginelog | tail -n 3 | awk '{print $9}' >test_temp_2
        
        for temp_line_2 in $(cat test_temp_2)
        do 
            LOG_INFO $temp_line_2
            run_cmd "cp -r /var/backuplog/galaxenginelog/$temp_line_2 $cna2_dir"
        done       
        run_cmd "rm -rf test_temp_2"
    fi
    LOG_INFO $ret
    return $ret
}

################################################################
#Function:        <get_atlas300_log>
#Description:     get atlas300 full log
#Parameter:       NA
#Return:          atlas300 full logs
#Since:           atlas300\logCollect.cfg
#Other:           N/a
###################################################################
function get_atlas300_log()
{
    local log_dir="${OUTPUTLOG}/atlas"
    local ret=0
    # Get atlas300 full log
    run_cmd "mkdir -p ${log_dir}"
    if [ -d "/var/dlog" ]; then
        local dlog_dir="${log_dir}/dlog"
        run_cmd "mkdir -p ${dlog_dir}"
        run_cmd "cp -rf /var/dlog/* ${dlog_dir}"
    else
        echo "/var/dlog is not exist"
    fi

    if [ -f "/tmp/atlas300_smartkit.log" ]; then
        run_cmd "cp -rf /tmp/atlas300_smartkit.log ${log_dir}"
    else
        echo "/tmp/atlas300_smartkit.log is not exist"
    fi

    if [ -f "/tmp/npu-healthcheck.log" ]; then
        run_cmd "cp -rf /tmp/npu-healthcheck.log ${log_dir}"
    else
        echo "/tmp/npu-healthcheck.log is not exist"
    fi
    return $ret
}

################################################################
#Function:        <get_ascend_log>
#Description:     get ascend log
#Parameter:       NA
###################################################################
function get_ascend_log()
{
    LOG_INFO "start get_ascend_log"
    local ret=0
    local log_dir="${OUTPUTLOG}/atlas"
    # ascend-dmi新版本工具有目录权限约束，选择用户主目录作为ascend日志生成临时目录.生成完成后会转移位置
    local tmpdir="${HOME}/ascend-log-collect.tar.gz"
    local atlasdir="modules/atlas/atlas_ascend/AXESMI/script"
    run_cmd "mkdir -p ${log_dir}"
    cd modules/atlas

    if [ "${SYS_TYPE}" == "aarch64" ]; then
        LOG_INFO "The current server adopts the ARM architecture"
        local atlas_file="Ascend-mindx-toolbox_5.0.0_linux-aarch64.run"
   elif [ "${SYS_TYPE}" == "x86_64" ] || [ "${SYS_TYPE}" == "i386" ]; then
        LOG_INFO "The current server adopts the x86 architecture"
        local atlas_file="Ascend-mindx-toolbox_5.0.0_linux-x86_64.run"
    fi
    run_cmd "./${atlas_file} --extract=atlas_ascend --noexec"
    cd ../..
    LOG_INFO "open ascend-dmi tool .run file."
    if [ -f "${atlasdir}/ascend-log-collect.sh" ]; then
       LOG_INFO "execution ascend-log-collect"
       chmod 550 ${atlasdir}/ascend-log-collect.sh
       run_cmd "bash ${atlasdir}/ascend-log-collect.sh --output-file=${tmpdir}"
       run_cmd "cp -rf ${tmpdir} ${log_dir}"
    else
      LOG_INFO "ascend-log-collect.sh is not exist!"

    fi

    if [ -f ${tmpdir} ]; then
      LOG_INFO "delete ascend-log-collect.tar.gz"
      run_cmd "rm -rf ${tmpdir}"
    fi
    return $ret
}

################################################################
#Function:        <get_gpu_info>
#Description:     get cpu infomation
#Parameter:       NA
###################################################################
function get_gpu_info()
{
    local log_dir="${OUTPUTLOG}/gpu"
    local ret=0
    run_cmd "mkdir -p ${log_dir}"
	
	# excute "nvidia-smi -q" , save the result to nvidia-smi.txt
    run_cmd "nvidia-smi -q >> ${log_dir}/nvidia-smi.txt"
	
	# cp nvidia install and uninstall log file
	run_cmd "cp -rf /var/log/nvidia-installer.log ${log_dir}/nvidia-installer.log"
	run_cmd "cp -rf /var/log/nvidia-uninstall.log ${log_dir}/nvidia-uninstall.log"
	
	# cp Xorg.*.log file
	run_cmd "cp -rf /var/log/Xorg.*.log ${log_dir}"
	
	# excute nvidia-bug-report.sh and copy result file.
	run_cmd "nvidia-bug-report.sh"
	run_cmd "cp -rf nvidia-bug-report.log.gz ${log_dir}/nvidia-bug-report.log.gz"
	run_cmd "rm nvidia-bug-report.log.gz"
	
    return $ret
}

################################################################
#Function:        <get_hiarm_log>
#Description:     get arm cpu log
#Parameter:       NA
#Return:          arm cpu log
#Since:           hiarm\logCollect.cfg
#Other:           N/a
###################################################################
function get_hiarm_log()
{
    local log_dir="${OUTPUTLOG}/hiarm"
    local hiarm_tool="modules/hiarm/hiarm_tool"
    local current_dir=`pwd`
    local ret=0

    if [ "${SYS_TYPE}" == "aarch64" ]; then
        LOG_INFO "The current server adopts the ARM architecture, start collect"
        if [ -f "${hiarm_tool}/hiarm_log_collect.sh" ]; then
            if [ -f "${hiarm_tool}/hiarmtool" ]; then
                chmod 550 ${hiarm_tool}/hiarmtool
                export PATH=$PATH:${hiarm_tool}
                LOG_INFO "get_hiarm_log: hiarmtool is ok."
            else
                LOG_ERROR "get_hiarm_log:hiarmtool is not exist."
            fi
            chmod 550 ${hiarm_tool}/hiarm_log_collect.sh
            run_cmd "hiarm_log_collect.sh -a -s -l /tmp -z ${current_dir}/${log_dir}"
            LOG_INFO "get_hiarm_log: execute hiarm_log_collect.sh success."
        else
            LOG_ERROR "get_hiarm_log: hiarm_log_collect.sh is not exist"
        fi
    elif [ "${SYS_TYPE}" == "x86_64" ] || [ "${SYS_TYPE}" == "i386" ]; then
        LOG_INFO "The current server adopts the x86 architecture, not involving"
        return
    else
        LOG_INFO "get_udisk_info:The current server adopts the unknown architecture which does not support log collection."
        return
    fi

    return $ret
}

################################################################
#Function:		<kill_subprocess>
#Description:	kill background process
#Parameter:	N/a
#Return:	N/a
#Since:		N/a
#Other:		N/a
###################################################################
function kill_subprocess(){
  local task_info=""
  for file in ${SUB_PROCESS_DIR}/*
    do
      if [[ ! -s file ]]
      then
        LOG_INFO "subprocess file name: ${file}"
        cat ${file} | while read line
        do
          LOG_INFO "subprocess file content: ${line}"
          task_info=$(eval "fuser -TERM ${line}" 2>&1)
          LOG_INFO "File occupancy infomation: $task_info"
          if [ "0" == "$?" ]
          then
            for i in $(echo $task_info)
            do
              if [[ $i =~ ^[1-9][0-9]+ ]]
               then
                LOG_INFO "subprocess pid: $i"
                run_cmd "kill $i"
                if [ "0" == "$?" ]
                then
                  LOG_INFO "kill subprocess [pid: $i] successfully."
                else
                  LOG_INFO "kill subprocess [pid: $i] failed."
                fi
              fi
            done
          fi
        done
			fi
    done
}

#main 
function start_log_collect()
{
    OUTPUTLOG=`echo "${OUTPUTLOG}" | sed 's/[#$%@&^-]*//g'`
    LOG_INFO "InfoCollect start time is:$(date +%Y%m%d_%H%M%S)..." 

    check_auth
  
    #create log directory
    run_cmd "mkdir -m a=r -p ${OUTPUTLOG}"

    run_cmd "echo Tools version:$TOOL_VERSION >> ${OUTPUTLOG}/version.txt"
    run_cmd "echo Tools Release date:$TOOL_RELEASE_DATE >> ${OUTPUTLOG}/version.txt"
 
    #log collect 
    main_collect_log

    #create filelist
    get_filelist

    #kill subprocess
    kill_subprocess

    #zip log package
    compression_log
}

start_log_collect

