# 日志收集脚本由1880Raid提供
#!/bin/sh
DIR=$(cd `dirname $0`; pwd)
SYS_TYPE=`uname -i`
if [ "${SYS_TYPE}" == "aarch64" ]; then
    TOOLNAME="$DIR/RAIDtool_ARM/huawei/hiraidadm"
else
    TOOLNAME="$DIR/RAIDtool/huawei/hiraidadm"
fi

PREFIX="raid"
TIME=$(date "+%Y%m%d%H%M%S")
GET_DIR="$DIR/log_temp_$TIME"
GET_DIR_HOST="$GET_DIR/host"
GET_DIR_FW="$GET_DIR/fw"
GET_DIR_OTHER="$GET_DIR_HOST/other"
GET_DIR_FW_OTHER="$GET_DIR_FW/other"
GET_TEP_DIR="$GET_DIR/temp"
card_index="all"
get_type="fw"
card_type="unknow"

mvfile(){
    for file in `ls *$1`
    do
        if [ -f $file ]; then
            mv $file ${file%$1}$2
        fi
    done
}

#打包获取的日志文件
pkgfile(){
    cd "$1"
    mvfile "log-ram.txt" ${PREFIX}_log_ram.txt
    mvfile "log-flash.txt" ${PREFIX}_log_flash.txt
    mvfile "log-lastword.txt" ${PREFIX}_log_lastword.txt
    mvfile "log-nand.txt" ${PREFIX}_log_nand.txt
    mvfile "regfile-datadump.txt" ${PREFIX}_dump_data.txt
    mvfile "regfile-sdsdump.txt" ${PREFIX}_dump_sds.txt
    mvfile "regfile-regdump.txt" ${PREFIX}_dump_reg.txt
    mvfile "rasfile-datadump.txt" ${PREFIX}_dump_ras_data.txt
    mvfile "rasfile-sdsdump.txt" ${PREFIX}_dump_ras_sds.txt
    mvfile "rasfile-regdump.txt" ${PREFIX}_dump_ras_reg.txt
    mvfile "reglog-datadump.txt" ${PREFIX}_dump_data.txt
    mvfile "reglog-sdsdump.txt" ${PREFIX}_dump_sds.txt
    mvfile "reglog-regdump.txt" ${PREFIX}_dump_reg.txt
    mvfile "raslog-datadump.txt" ${PREFIX}_dump_ras_data.txt
    mvfile "raslog-sdsdump.txt" ${PREFIX}_dump_ras_sds.txt
    mvfile "raslog-regdump.txt" ${PREFIX}_dump_ras_reg.txt
    if [[ -n $(ls | grep txt) ]];then
        tar -zcvf "$2/${PREFIX}_$3_$TIME.tar.gz" *.txt >/dev/null 2>&1
    fi
    rm "$1"/*
}

pkgallfile(){
    cd "$1"
    tar -zcvf "$2/${PREFIX}_$3_$TIME.tar.gz" * >/dev/null 2>&1
    echo "out file:$2/${PREFIX}_$3_$TIME.tar.gz"
}

excute_cmd_to_file(){
    echo "$1" >> "$2"
    $1 >> "$2"
    echo -e "\n" >> "$2"
}

getalldiskinfo(){
    while read line
    do
        #对每一行字符串的操作
        ARR=(${line// / })  
        if [[ "${ARR[0]}" =~ ^[0-9]+$ ]];then
            local PD_INFO="$GET_DIR_DISK_INFO/enc${ARR[1]}_slot${ARR[2]}.txt"
            excute_cmd_to_file "$TOOLNAME c$1:e${ARR[1]}:s${ARR[2]} show" "$PD_INFO"
            excute_cmd_to_file "$TOOLNAME c$1:e${ARR[1]}:s${ARR[2]} show smart" "$PD_INFO"
            excute_cmd_to_file "$TOOLNAME c$1:e${ARR[1]}:s${ARR[2]} show pdcache" "$PD_INFO"
            excute_cmd_to_file "$TOOLNAME c$1:e${ARR[1]}:s${ARR[2]} show phyerror" "$PD_INFO"
            excute_cmd_to_file "$TOOLNAME c$1:e${ARR[1]}:s${ARR[2]} show driveerror" "$PD_INFO"
            excute_cmd_to_file "$TOOLNAME c$1:e${ARR[1]}:s${ARR[2]} show iocnt" "$PD_INFO"
        fi
    done < "$2"
}

getallvdinfo(){
    while read line
    do
        ARR=(${line// / })  
        if [[ "${ARR[0]}" =~ ^[0-9]+$ ]];then
            $TOOLNAME c$1:vd${ARR[0]} show >"$GET_DIR_VD_INFO/vd${ARR[0]}.txt"
        fi
    done < "$2"
}

getallrginfo(){
    while read line
    do
        ARR=(${line// / })  
        if [[ "${ARR[0]}" =~ ^[0-9]+$ ]];then
            local RG_INFO="$GET_DIR_RG_INFO/rg${ARR[0]}.txt"
            excute_cmd_to_file "$TOOLNAME c$1:rg${ARR[0]} show" "$RG_INFO"
            excute_cmd_to_file "$TOOLNAME c$1:rg${ARR[0]} show pdarray" "$RG_INFO"
        fi
    done < "$2"
}

getfwlog(){
    
    mkdir -p "$GET_DIR_FW"
    mkdir -p "$GET_TEP_DIR"
    mkdir -p "$GET_DIR_FW_OTHER"
    operation_log="$GET_DIR_FW_OTHER/operation_log.txt"
    echo "$TOOLNAME c$1 get log path="$GET_TEP_DIR"" >>$operation_log
    $TOOLNAME c$1 get log path="$GET_TEP_DIR" >>$operation_log
    pkgfile "$GET_TEP_DIR" "$GET_DIR_FW" card$1_log
    echo "$TOOLNAME c$1 get dump path="$GET_TEP_DIR" type=flash" >>$operation_log
    $TOOLNAME c$1 get dump path="$GET_TEP_DIR" type=flash >>$operation_log
    pkgfile "$GET_TEP_DIR" "$GET_DIR_FW" card$1_dump_flash
    echo "$TOOLNAME c$1 set dump" >>$operation_log
    $TOOLNAME c$1 set dump >>$operation_log
    echo "$TOOLNAME c$1 get dump path="$GET_TEP_DIR" type=ram" >>$operation_log
    $TOOLNAME c$1 get dump path="$GET_TEP_DIR" type=ram >>$operation_log
    pkgfile "$GET_TEP_DIR" "$GET_DIR_FW" card$1_dump
    echo "$TOOLNAME c$1 get nandlog path="$GET_TEP_DIR"" >>$operation_log
    $TOOLNAME c$1 get nandlog path="$GET_TEP_DIR" >>$operation_log
    pkgfile "$GET_TEP_DIR" "$GET_DIR_FW" card$1_nandlog
    rm -rf "$GET_TEP_DIR"
    chmod 600 $operation_log
    
    #获取raid卡健康状态
    $TOOLNAME c$1 show error >"$GET_DIR_FW_OTHER/health_info.txt"
    #获取raid卡版本信息
    $TOOLNAME c$1 show fw_version >"$GET_DIR_FW_OTHER/version_info.txt"
    #获取电子标签信息
    $TOOLNAME c$1 show elabel >"$GET_DIR_FW_OTHER/elabe_info.txt"
    #获取磁盘信息
    GET_DIR_DISK_INFO="$GET_DIR_FW_OTHER/card_pdinfo"
    mkdir -p "$GET_DIR_DISK_INFO"
    $TOOLNAME c$1 show pdlist >"$GET_DIR_DISK_INFO/pdlist.txt"
    getalldiskinfo $1 "$GET_DIR_DISK_INFO/pdlist.txt"
    #获取vd信息
    GET_DIR_VD_INFO="$GET_DIR_FW_OTHER/card_vdinfo"
    mkdir -p "$GET_DIR_VD_INFO"
    $TOOLNAME c$1 show vdlist >"$GET_DIR_VD_INFO/vdlist.txt"
    getallvdinfo $1 "$GET_DIR_VD_INFO/vdlist.txt"
    #获取raid组信息
    GET_DIR_RG_INFO="$GET_DIR_FW_OTHER/card_rginfo"
    mkdir -p "$GET_DIR_RG_INFO"
    $TOOLNAME c$1 show rglist >"$GET_DIR_RG_INFO/rglist.txt"
    getallrginfo $1 "$GET_DIR_RG_INFO/rglist.txt"
    #获取全局配置信息
    $TOOLNAME c$1 show config >"$GET_DIR_FW_OTHER/config_info.txt"
    #获取状态信息
    $TOOLNAME c$1 show status >"$GET_DIR_FW_OTHER/status_info.txt"
    #获取adc信息
    $TOOLNAME c$1 show adc >"$GET_DIR_FW_OTHER/adc_info.txt"
    #获取超级电容容值
    if [[ $card_type = "RAID" ]]; then
        $TOOLNAME c$1 show scaplearn >"$GET_DIR_FW_OTHER/scap_info.txt"
    fi
    #获取备电电容容值
    $TOOLNAME c$1 show backupcap >"$GET_DIR_FW_OTHER/backupcap_info.txt"
    #获取所有卡信息
    excute_cmd_to_file "$TOOLNAME show allctrl" "$GET_DIR_FW_OTHER/allctrl_info.txt"
    #新增获取其他信息
    local OTHER_INFO="$GET_DIR_FW_OTHER/other_info.txt"
    excute_cmd_to_file "$TOOLNAME c$1 show bgtask" "$OTHER_INFO"
    excute_cmd_to_file "$TOOLNAME c$1 show hspslot" "$OTHER_INFO"
    excute_cmd_to_file "$TOOLNAME c$1 show fncfg" "$OTHER_INFO"
    excute_cmd_to_file "$TOOLNAME c$1 show bst" "$OTHER_INFO"
    if [[ $card_type = "RAID" ]]; then
        excute_cmd_to_file "$TOOLNAME c$1 show bootwithpinnedcache" "$OTHER_INFO"
        excute_cmd_to_file "$TOOLNAME c$1 show pinnedcache" "$OTHER_INFO"
        excute_cmd_to_file "$TOOLNAME c$1 show vdmerge" "$OTHER_INFO"
        excute_cmd_to_file "$TOOLNAME c$1 show merge" "$OTHER_INFO"
        excute_cmd_to_file "$TOOLNAME c$1:sc show supercap" "$OTHER_INFO"
        excute_cmd_to_file "$TOOLNAME c$1:sc show selflearn" "$OTHER_INFO"
    fi
    excute_cmd_to_file "$TOOLNAME c$1 show smart_polling" "$OTHER_INFO"
    excute_cmd_to_file "$TOOLNAME c$1 show phy_cfg" "$OTHER_INFO"
    excute_cmd_to_file "$TOOLNAME c$1 show info" "$OTHER_INFO"
    excute_cmd_to_file "$TOOLNAME c$1 show queue" "$OTHER_INFO"
    excute_cmd_to_file "$TOOLNAME c$1 show repair_policy" "$OTHER_INFO"
    excute_cmd_to_file "$TOOLNAME c$1 show drivefc" "$OTHER_INFO"
    excute_cmd_to_file "$TOOLNAME c$1 show slowdrive" "$OTHER_INFO"
    excute_cmd_to_file "$TOOLNAME c$1 show dphstartmod" "$OTHER_INFO"
    excute_cmd_to_file "$TOOLNAME c$1 show kickdrive" "$OTHER_INFO"
    excute_cmd_to_file "$TOOLNAME c$1 show vdfc" "$OTHER_INFO"
    excute_cmd_to_file "$TOOLNAME c$1 show quedepth" "$OTHER_INFO"
    excute_cmd_to_file "$TOOLNAME c$1:e0 show phy" "$OTHER_INFO"
}

getotherlog(){
    mkdir -p "$GET_DIR_OTHER"
   
    #获取配套系统信息
    rpm -qi kmod-$PREFIX >"$GET_DIR_OTHER/driver_info.txt"
    #获取磁盘信息和盘符信息
    lsscsi >"$GET_DIR_OTHER/os_disk_list_info.txt"
    fdisk -l >"$GET_DIR_OTHER/os_disk_info.txt"

    ps euf >> "$GET_DIR_OTHER/ps.txt"
    ps aux >> "$GET_DIR_OTHER/ps.txt"
    cat /proc/cpuinfo >> "$GET_DIR_OTHER/cpuinfo.txt"
    cat /proc/meminfo >> "$GET_DIR_OTHER/meminfo.txt"
    lspci -vvv >> "$GET_DIR_OTHER/lspci_vvv.txt"
    lspci -xxx >> "$GET_DIR_OTHER/lspci_xxx.txt"
    top -bn 1 >> "$GET_DIR_OTHER/top.txt"
    free -m >> "$GET_DIR_OTHER/free.txt"

    cat /proc/interrupts >> "$GET_DIR_OTHER/interrupts.txt"
    service irqbalance status >> "$GET_DIR_OTHER/irqbalance_status.txt"
    cat /etc/*-release >> "$GET_DIR_OTHER/lsb_release.txt"
    lscpu >> "$GET_DIR_OTHER/lscpu.txt"
    cat /proc/stat >> "$GET_DIR_OTHER/stat.txt"
    getconf PAGESIZE >> "$GET_DIR_OTHER/pagesize.txt"

    irq_num=(`cat /proc/interrupts | grep raid | awk -F "":"" '{print $1}'`)
    for irq in ${irq_num[*]}
    do
        echo "irq $irq:" >> "$GET_DIR_OTHER/smp_affinity.log"
        cat /proc/irq/${irq}/smp_affinity >> "$GET_DIR_OTHER/smp_affinity.log"
    done

    dev_list=(`lsscsi | awk '{print $6}' | awk -F "/" '{print $3}'`)
    for dev in ${dev_list[*]}
    do
        dev_queue="$GET_DIR_OTHER/${dev}_queue.txt"
        info=`cat /sys/block/${dev}/queue/add_random`
        echo "add_random:$info" >> ${dev_queue}
        info=`cat /sys/block/${dev}/queue/max_sectors_kb`
        echo "max_sectors_kb:$info" >> ${dev_queue}
        info=`cat /sys/block/${dev}/queue/nomerges`
        echo "nomerges:$info" >> ${dev_queue}
        info=`cat /sys/block/${dev}/queue/read_ahead_kb`
        echo "read_ahead_kb:$info" >> ${dev_queue}
        info=`cat /sys/block/${dev}/queue/scheduler`
        echo "scheduler:$info" >> ${dev_queue}
    done
}

#获取主机日志
gethostlog(){
    mkdir -p "$GET_DIR_HOST"
    mkdir -p "$GET_DIR_HOST/log"
    mkdir -p "$GET_DIR_HOST/crash"
    for dir in /var/crash/*
    do
        if [ -d $dir ];then
            mkdir -p "$GET_DIR_HOST/crash/$dir"
            if [ -f $dir/vmcore-dmesg.txt ];then
                cp -p $dir/vmcore-dmesg.txt "$GET_DIR_HOST/crash/$dir"
            fi
        fi
    done

    getotherlog
}

#获取卡日志并打包
getcardlog(){
    card_type=`$TOOLNAME c$1 show info | grep "Ctrl Mod" | awk -F "|" '{print $2}' | sed 's/[[:space:]]//g'`
    mkdir -p "$GET_DIR"
    if [[ "$get_type" == "all" || "$get_type" == "fw" ]];then
        #获取固件日志
        getfwlog $1 >/dev/null 2>&1
    fi
    if [[ "$get_type" == "all" || "$get_type" == "host" ]];then
        #获取主机日志
        gethostlog >/dev/null 2>&1
    fi
    #打包所有日志
    pkgallfile "$GET_DIR" "$DIR" card$1_log
    #删除临时目录
    rm -rf "$GET_DIR"
}


#获取所有卡日志
getallcardlog(){
    #遍历获取卡日志
    i=0
    while((i<$CNT))
    do
        echo "collect card$i log ..."
        getcardlog $i
        ((i++))
    done
}

command -v $TOOLNAME >/dev/null 2>&1 || { echo >&2 "$TOOLNAME is not installed. Please install."; exit 1; }
command -v tar >/dev/null 2>&1 || { echo >&2 "tar is not installed. Please install."; exit 1; }

#获取卡数量
CNT=`$TOOLNAME show ctrlcount | grep ctrlcount | awk -F: '{print $2}'`
#系统中没有卡，直接退出
if [ "$CNT" = "0" ];then
    echo "system has no card"
    exit 0
fi


help_info="
  Usage: raid_get_log.sh [option]
    -h, --help      show help information

    (option) The following options are optional:
    -i, --index     collect specific a card, such as 0, 1,...
    -f, --feature   collect specific feature logs, such as fw or host or all
    -p, --path      collect file save path
"

input=$*
para1=${input//--help/-h}
para2=${para1//--index/-i}
para3=${para2//--feature/-f}
para4=${para3//--path/-p}
arr_input=($para4)

for (( i = 0; i < ${#arr_input[@]}; i++ )); do
    case ${arr_input[i]} in
        '-h' )
            echo "$help_info"
            exit 1
            ;;
        '-i' )
            #输入参数为数字
            input_num=${arr_input[i+1]}
            if [[ "$input_num" =~ ^[0-9]+$ ]];then
                NUM=$(expr "$input_num" + 1)
                #输入参数超过最大卡数量
                if [ $NUM -gt $CNT ];then
                    echo "card$input_num not exist"
                    exit 1
                fi
                #获取单张卡日志
                card_index=$input_num
            else
                printf "\n  [ERROR]You can only input num param\n"
                echo "$help_info"
                exit 1
            fi
            ;;
        '-f' )
            case ${arr_input[i+1]} in
            'host' )
                get_type="host"
                ;;
            'fw' )
                get_type="fw"
                ;;
            'all' )
                get_type="all"
                ;;
            * )
                printf "\n  [ERROR]please enter the correct parameters host or fw\n"
                echo "$help_info"
                exit 1
            esac
            ;;
        '-p' )
            case ${arr_input[i+1]} in
                '/'[[:alnum:]]* )
                    DIR=${arr_input[i+1]}
                    final=`echo ${DIR: -1}`
                    if [ $final == '/' ]
                    then
                        DIR=`echo ${DIR%/*}`
                    fi
                    if [ ! -d $DIR ]
                    then
                        printf "\n  [ERROR]please enter the correct path!!\n"
                        echo "$help_info"
                        exit 1
                    fi
                ;;
                * )
                    printf "\n  [ERROR]please enter the correct parameters!!\n"
                    echo "$help_info"
                    exit 1
            esac
            ;;
        [0-9] )
            if [ ${arr_input[i-1]} != '-i' ]
                then
                printf "\n  [ERROR]please enter the correct parameters\n"
                echo "$help_info"
                exit 1
            fi
            ;;
        "host" )
            if [ ${arr_input[i-1]} != '-f' ]
                then
                printf "\n  [ERROR]please enter the correct parameters\n"
                echo "$help_info"
                exit 1
            fi
            ;;
        "fw" )
            if [ ${arr_input[i-1]} != '-f' ]
                then
                printf "\n  [ERROR]please enter the correct parameters\n"
                echo "$help_info"
                exit 1
            fi
            ;;
        "all" )
            if [ ${arr_input[i-1]} != '-f' ]
                then
                printf "\n  [ERROR]please enter the correct parameters\n"
                echo "$help_info"
                exit 1
            fi
            ;;
        '/'[[:alnum:]]* )
            if [ ${arr_input[i-1]} != '-p' ]
            then
                printf "\n  [ERROR]please enter the correct parameters!!\n"
                echo "$help_info"
                exit 1
            fi
            ;;
        * )
            printf "\n  [ERROR]please enter the correct parameters\n"
            echo "$help_info"
            exit 1
    esac
done

#判断系统存储空间是否足够，预留1000M(1024000KB)，不足时删除以往日志
disk_size=`df "$DIR" | grep / | awk '{print $4}'`
while [ $disk_size -lt 1024000 ]
do
    history_file=`ls -rt | grep ${PREFIX}_card | head -n 1`
    if [ -z "$history_file" ];then
        echo "system has no space"
        exit 0
    fi
    echo "remove histroy $history_file"
    rm $history_file
    disk_size=`df "$DIR" | grep / | awk '{print $4}'`
done

if [ "$card_index" == "all" ];then
    #获取所有卡日志
    getallcardlog 
else
    #获取单张卡日志
    getcardlog $card_index
fi