#!/bin/bash
[ -z "$1" ] && exit 1
[ "$2" = "/dev/md8" -o "$2" = "/dev/md9" ] && exit 1
. /etc/profile >/dev/null
. /etc/tos/scripts/scripts

buzzerpid=/var/run/warnning.pid
buzzerexe=/etc/tos/scripts/warnning
buzzer_config=/etc/buzzer/buzzer_config.info
MNTOPTS=$MNTOPT_EXT4

# optimization sync speed limit
sysctl -w dev.raid.speed_limit_max=200000
sysctl -w dev.raid.speed_limit_min=100000

mkparted() {
    local blk=$1
    local offset=0
    local offend=0
    # parted -s $blk mktable gpt
    [ $? -ne 0 ] && return 1
    let offend=$offset+$TOS_BOOT_SIZE
    if [ ! -b ${blk}1 ];then
        parted -s $blk mkpart primary ext2 0% $offend
    fi
    let offset=$offend
    let offend=$offset+$TOS_CORE_SIZE
    if [ ! -b ${blk}2 ];then
        parted -s $blk mkpart primary ext2 $offset $offend
    fi
    let offset=$offend
    let offend=$offset+$TOS_SWAP_SIZE
    if [ ! -b ${blk}3 ];then
        parted -s $blk mkpart primary ext2 $offset $offend
    fi
    partprobe "${blk}"
    udevadm settle --timeout=10
    if [ ! -b ${blk}1 ] || [ ! -b ${blk}2 ] || [ ! -b ${blk}3 ];then
        sleep 2
        if [ ! -b ${blk}1 ] || [ ! -b ${blk}2 ] || [ ! -b ${blk}3 ];then
            logger -t "MDADM-MONITOR" "[hotspare]: mkparted [$blk] Error, can't get valid part(1-3)"
            return 1
        fi
    fi
    let offset=$offend
    parted -s $blk mkpart primary ext2 $offset 100%
    if [ $? -ne 0 ];then
        logger -t "MDADM-MONITOR" "[hotspare]: mkparted [$blk] Error, can't parted user partition"
        return 1
    fi
    partprobe "${blk}"
    udevadm settle --timeout=10
    sleep 1
    mdadm --zero-superblock "${blk}4"
    # init partition 1 ...
    # /etc/tos/scripts/initboot "$blk"
    return 0
}

hotspare() {
    local raid=$1
    local name=$(basename $raid)
    local wait=5
    while [ $wait -gt 0 ]; do
        local status=$(cat /sys/block/${name}/md/sync_action)
        logger -t "MDADM-MONITOR" "[hotspare]: raid ${name} status [$status]"
        if [ "$status" = "idle" ]; then
            break
        fi
        let wait=wait-1
        [ $wait -eq 0 ] && exit 1
        sleep 1
    done
    local avadisk=$(ter_hotspare -r ${raid})
    avadisk=$(echo "$avadisk" | grep -o -E '\bsd[a-z]+\b')
    logger -t "MDADM-MONITOR" "[hotspare]: raid ${name} avadisk [$avadisk]"
    #fix Traid in ter_hotspare
    if [ "$avadisk" = "traid" ]; then
        return
    fi

    [ -z "$avadisk" ] && exit 1
    local blk="/dev/$avadisk"
    [ ! -b "$blk" ] && exit 1
    mkparted "$blk"
    [ $? -ne 0 ] && exit 1
    logger -t "MDADM-MONITOR" "[hotspare]: raid ${name} parted [$blk]"
    if [ -b "${blk}2" -a -b "${blk}3" -a -b "${blk}4" ]; then
        local diskname=$blk
        local tmpfile="/tmp/hotspare_${avadisk}"
        if [ -f $tmpfile ]; then
            diskname=$(cat $tmpfile)
            rm -f $tmpfile
        fi
        # mdadm -a /dev/md9 ${blk}2
        # mdadm -a /dev/md8 ${blk}3
        mdadm -a $raid ${blk}4
        #hotspare send mail
        local diskInfo=$(ter_disk_tool -blockdev $blk)
        local diskName=$(echo $diskInfo | jq -r .name)
        ter_msg_add -c storage -l info -s notification -k notice_hotspare_enable -o $diskName
        # stop the warnning
        close_buzzer
    fi
}

sync_finish() {
    local raid=$1
    local raidname=$(basename "$raid")
    local status=$(cat /sys/block/$raidname/md/degraded)
    local sort=${raidname:2}
    local fs=$(blkid -o export $raid | awk -F= '/TYPE/ {print $2}')
    if [ $status -eq 0 ]; then
        ter_curl --unix-socket /var/api/TerVgMonitor.sock "http://TerVgMonitor.sock/VgMonitor?raid=${raid}&event=finish"
        #    ter_msg_add -c storage -l info -s notification -k raid_sync_complete -o ${raidname:2}
        logger -t "MDADM-MONITOR" "[RebuildFinished]: raid ${raid} device rebuild finish"
        close_buzzer
    fi
    mdadm --grow $raid --size=max >/dev/null 2>&1
    if [ "$fs" = "LVM2_member" ]; then
        pvresize -y $raid
        mdadm -Ds >/etc/mdadm.conf
    elif [ "$fs" = "btrfs" ]; then
        local MNTPATH=/mnt/md${sort}
        df-json | grep "$MNTPATH$" >/dev/null
        if [ $? -eq 0 ]; then
            btrfs filesystem resize max $MNTPATH >/dev/null 2>&1
        fi
    elif [ "$fs" = "ext4" ]; then
        resize2fs -f $raid >/dev/null 2>&1
    fi
}

buzzer_raid() {
    local raid=$1
    local raidname=$(basename $raid)
    touch /etc/base/.buzzer_$raidname
    if [ -e $buzzer_config ]; then
        status=$(awk -F '=' '/''/{a=1}a==1&&$1~/'raid_drive_miss'/{print $2;exit}' $buzzer_config)
        if [ "$status" != '' ] && [ "$status" -eq '1' ]; then
            [ ! -f $buzzerpid ] && ($buzzerexe >/dev/null &)
        fi
    else
        [ ! -f $buzzerpid ] && ($buzzerexe >/dev/null &)
    fi

  #    ter_msg_add -c storage -l warning -s notification -k raid_risk_warning -o ${raidname:2}

  ter_raid_warning $raid
}

close_buzzer_raid() {
    local raid=$1
    local raidname=$(basename $raid)
    local buzzerfile=/etc/base/.buzzer_$raidname
    if [ -e $buzzerfile ]; then
        close_buzzer
        rm -f $buzzerfile
    fi
}

close_buzzer() {
    if [ -f $buzzerpid ]; then
        local pid=$(cat $buzzerpid)
        [ ! -z "$pid" ] && kill $pid
        rm -f $buzzerpid
    fi
}

case $1 in
DeviceDisappeared)
    logger -t "MDADM-MONITOR" "[$1]: raid $2 device is disappear"
    ;;
RebuildStarted)
    logger -t "MDADM-MONITOR" "[$1]: raid $2 device is rebuild"
    # start to sync
    close_buzzer_raid $2
    raid=$2
    ter_curl --unix-socket /var/api/TerVgMonitor.sock http://TerVgMonitor.sock/VgMonitor?raid=${raid}\&event=start

    #  raidname=$(basename $2)
    #  raidinfo=$(ter_mdadm_tool -name $raidname)
    #  finish_time=$(echo $raidinfo | jq -r .finish_time)
    #  ter_msg_add -c storage -l info -s notification -k raid_sync_start -o ${raidname:2} -o $finish_time
    ;;
Rebuild??)
    logger -t "MDADM-MONITOR" "[$1]: raid $2 device is $1"
    ;;
RebuildFinished)
    # sync finish
    logger -t "MDADM-MONITOR" "[$1]: raid $2 device is $1"
    raid=$2
    sync_finish $raid
    ;;
Fail | FailSpare)
    logger -t "MDADM-MONITOR" "[$1]: raid $2 device spare failed"
    if [ -b "$2" ]; then
        sign=$(mdadm -D ${raid} | grep ${TOS_USER_SIGN})
        if [ -z "$sign" ]; then
            return 0
        fi
        buzzer_raid $2
        hotspare $2
    fi
    ;;
SpareActive)
    # active a disk
    close_buzzer_raid $2
    logger -t "MDADM-MONITOR" "[$1]: raid $2 device spare active"
    ;;
NewArray)
    # create a new raid
    logger -t "MDADM-MONITOR" "[$1]: raid $2 device create new array"
    ;;
DegradedArray)
    raid=$2
    raidname=$(basename $raid)
    RDN=$(ls -l /sys/block/$raidname/slaves/sd[a-z]4 2>/dev/null | wc -l)
    TDN=$(cat /sys/block/$raidname/md/raid_disks)
    if [ $RDN -ne $TDN ]; then
        logger -t "MDADM-MONITOR" "[$1]: raid $raid device degraded"
        buzzer_raid $raid
        hotspare $raid
    fi
    ;;
MoveSpare)
    logger -t "MDADM-MONITOR" "[$1]: raid $2 device move spare"
    ;;
SparesMissing)
    logger -t "MDADM-MONITOR" "[$1]: raid $2 device spare missing"
    hotspare $2
    ;;
TestMessage) ;;

esac
