#!/bin/bash

. /etc/profile >/dev/null
. /etc/tos/scripts/scripts
action=$1

if [ -z "$action" -o -z "$2" ]; then
    echo "eg: ${0} [insert|remove] [sda1|sdb1|sdc1|...]"
    exit 1
fi
buzzer_config=/etc/buzzer/buzzer_config.info
buzzerexe=/etc/tos/scripts/warnning
#判断是否可以进行下去...
partition=$2
blockname=${partition:0:0-1}
realpath=$(readlink -f /sys/block/$blockname)
echo "$realpath" | grep "usb" >/dev/null
[ $? -eq 0 ] && exit 1

log_path="/tmp/raid_${action}_$2"
echo "operation ${action} $2 by $(whoami) $(pwd)" >${log_path}
# Personalities : [linear] [raid0] [raid1] [raid10] [raid6] [raid5] [raid4]

# This check is invalid because the first partition of the hard drive does not have a partition label ("UTODISK")---"6.0 TOS"
check_is_member() {
    local blkname=$1
    local partnum=$(ls /dev/${blkname}[0-9] | wc -l)
    if [ $partnum -ge 4 ]; then
        [ ! -b /dev/${blkname}1 ] && return 1
        e2label /dev/${blkname}1 | grep $TOS_DISK_SIGN >/dev/null
        return $?
    fi
    return 1
}

remove_from_raid() {
    local raid=$1
    local blk=$2
    echo "remove blockdev:$blk from raid:$raid" >>${log_path}
    if [ -b $raid ]; then
        mdadm -f $raid $blk >>${log_path} 2>&1
        mdadm -r $raid $blk >>${log_path} 2>&1
    fi
}

scsi_disk_insert() {
    #ps -eafwww >> $log_path
    local device_name=$1
    local blkname=${device_name%%[0-9]*}
    local blk=/dev/$device_name
    local number=${device_name##*[a-z]}

    #如果此硬盘是已被系统移除并标记的硬盘，则不启用此硬盘做修复
    local newDevice_name=$(echo ${device_name:0:3})  #if device_name is sdc4 or sdc1...to get sdc
    local newBlk=/dev/$newDevice_name
    local diskUuid=$(fdisk -l ${newBlk} | grep 'Disk identifier:' | awk '/Disk identifier:/{print $3}')
    for deactivated in $(cat /etc/disk_deactivation.conf | awk '/"disk_uuid":/{print $2}' | sed 's/\"//g'); do
      local diskDeactivation=$(echo $deactivated | sed 's/ //g')
      [ "$diskUuid" = "$diskDeactivation" ] && return 1
    done
    
    echo "-b $blk" >>$log_path
    [ ! -b $blk ] && return 1
    check_is_member $blkname >/dev/null
    local is_member=$?
    echo "check_is_member $blk:$is_member,Number:$number" >>$log_path
    [ $is_member -ne 0 ] && return 1

    # if [ $number -eq 2 ]; then
    #     # sd[abcd]2....
    #     if [ -b $TOS_RAID_CORE ]; then
    #         # mdadm --grow $TOS_RAID_CORE --raid-devices=$TOS_SYS_NUMBER --force
    #         # mdadm -a $TOS_RAID_CORE $blk
    #     fi
    # elif [ $number -eq 3 ]; then
    #     # sd[abcd]3....
    #     if [ -b $TOS_RAID_SWAP ]; then
    #         # mdadm --grow $TOS_RAID_SWAP --raid-devices=$TOS_SYS_NUMBER --force
    #         # mdadm -a $TOS_RAID_SWAP $blk
    #     fi
    if [ $number -ge 4 ]; then
        # sd[abcd]4....
        mdadm -E ${blk} | grep ${TOS_USER_SIGN} >/dev/null
        if [ $? -ne 0 ]; then
            return 1
        fi
        local uuid1=$(mdadm -E $blk --export 2>/dev/null | awk -F= '/MD_UUID/ {print $2}')
        local TOS_RAID_USER=""
        local uuid2=""
        for md in $(ls -d /sys/block/md[0-9]*); do
            local raidblk=/dev/$(basename $md)
            [ ! -b $raidblk ] && continue
            uuid2=$(mdadm -D $raidblk --export 2>/dev/null | awk -F= '/MD_UUID/ {print $2}')
            if [ "$uuid1" = "$uuid2" ]; then
                TOS_RAID_USER=$raidblk
                break
            fi
        done
        echo "Find raid ${TOS_RAID_USER}, UUID:$uuid2" >>${log_path}
        [ -z "$TOS_RAID_USER" ] && exit 1
        local ri=$(mdadm -D $TOS_RAID_USER 2>/dev/null)
        local level=$(echo -e "$ri" | awk -F' : ' '/Raid Level/ {print $2}')
        local total=$(echo -e "$ri" | awk -F' : ' '/Raid Devices/ {print $2}')
        local active=$(echo -e "$ri" | awk -F' : ' '/Active Devices/ {print $2}')
        local workDev=$(echo -e "$ri" | awk -F' : ' '/Working Devices/ {print $2}')
        #如果此阵列已经在做修复则不启用自动修复
        let fixDevDiff=total-workDev
        [ $fixDevDiff -eq 0 ] && exit 1

        let diff=total-active
        echo "Find raid ${TOS_RAID_USER}, UUID:$uuid2, Free:$diff" >>${log_path}
        if [ $diff -gt 0 ]; then
            if [ "$level" = "raid1" ]; then
                mdadm -a $TOS_RAID_USER $blk
            elif [ "$level" = "raid5" -a $diff -eq 1 ]; then
                mdadm -a $TOS_RAID_USER $blk
            elif [ "$level" = "raid6" -a $diff -le 2 ]; then
                mdadm -a $TOS_RAID_USER $blk
            elif [ "$level" = "raid10" ]; then
                mdadm -a $TOS_RAID_USER $blk
            fi
        fi
    fi
}

scsi_disk_remove() {
    local device_name=$1
    local number=${device_name##*[a-z]}
    local blkname=${device_name%%[0-9]*}

    local cacheLvmMda=$(awk '/\/dev\/md/ { print $NF }' /etc/lvmcache/cache.conf)
    local mddetail=$(cat /proc/mdstat | grep $device_name | awk '{print $1}')

    if [[ $cacheLvmMda == *$mddetail* ]]; then
       if [ $mddetail ]; then
          echo "ssd cache error"
          status=$(awk -F '=' '/''/{a=1}a==1&&$1~/'ssd_cache_exceptions'/{print $2;exit}' $buzzer_config)
          if [ "$status" != '' ] && [ "$status" -eq '1' ]; then
            systemctl start tnas-warnning.service
          fi
       fi
    else
        echo "The string does not contain 'mddetail'."
    fi
    if [ $number -eq 2 ]; then
        remove_from_raid $TOS_RAID_CORE $device_name
    elif [ $number -eq 3 ]; then
        remove_from_raid $TOS_RAID_SWAP $device_name
    elif [ $number -ge 4 ]; then
        local slavefile=$(ls -d /sys/block/md[0-9]*/slaves/$device_name 2>/dev/null)
        [ -z "$slavefile" ] && return 1
        local raidname=$(echo $slavefile | cut -d/ -f4)
        local TOS_RAID_USER="/dev/$raidname"
        echo "Find raid ${TOS_RAID_USER}" >>${log_path}
        [ ! -b $TOS_RAID_USER ] && return 1
        mkdir "/tmp/$raidname" >>${log_path} 2>&1
        touch "/tmp/$raidname/$blkname" >>${log_path} 2>&1
        local ri=$(mdadm -D $TOS_RAID_USER 2>/dev/null)
        local level=$(echo -e "$ri" | awk -F' : ' '/Raid Level :/ {print $2}')
        local total=$(echo -e "$ri" | awk -F' : ' '/Total Devices/ {print $2}')
        local active=$(echo -e "$ri" | awk -F' : ' '/Active Devices/ {print $2}')
        # local diff=total-active
        # 因为这里的错误语法local导致diff变量一直是字符串total-active,导致raid5及以上都无法调用remove_from_raid函数
        # local diff=$((total-active))   这里两种写法都可以
        let diff=total-active
        echo "Find raid ${TOS_RAID_USER}, Free:$diff" >>${log_path}
        if [ "$level" = "raid1" ]; then
            remove_from_raid $TOS_RAID_USER $device_name
        elif [ "$level" = "raid5" -a $diff -lt 1 ]; then
            remove_from_raid $TOS_RAID_USER $device_name
        elif [ "$level" = "raid6" -a $diff -lt 2 ]; then
            remove_from_raid $TOS_RAID_USER $device_name
        elif [ "$level" = "raid10" ]; then
            let half=total/2
            if [ $diff -lt $half ]; then
                remove_from_raid $TOS_RAID_USER $device_name
            fi
        fi
    fi
    return 0
}

# insert process
case "$action" in
# removed udev auto fix raid rule，retained the script call
insert)
    scsi_disk_insert $2
    ;;
remove)
    scsi_disk_remove $2
    ;;
esac
exit 0
