#!/usr/bin/bash

TOS_SCRIPTS_PATH=/etc/tos/scripts
TOS_SCRIPTS_LOCK_PATH=/tmp/scripts_run
TOS_SETUP_URL=http://www.terra-master.com/tos/x86_64/setup.tar.gz

TOS_RAID_CORE=/dev/md9 # base system
TOS_RAID_SWAP=/dev/md8 # swap area
TOS_SYS_NUMBER=72
TOS_DEFAULT_CONFIG=/etc/tos/conf/tos.ini

TOS_CORE_SIGN=UTOSCORE-X86-S64
TOS_SWAP_SIGN=UTOSSWAP-X86-S64
TOS_USER_SIGN=UTOSUSER-X86-S64
TOS_BOOT_SIGN=UTOSBOOT
TOS_DISK_SIGN=UTOSDISK
TOS_FC_SIGN=UTOSFC-X86-S64
TOS_TRIP_SIZE=$(iniparse -c -f $TOS_DEFAULT_CONFIG -s raid -k trip_size)

# parameters check unit：mb
TOS_CORE_SIZE=$(iniparse -c -f $TOS_DEFAULT_CONFIG -s tos -k core_size)
TOS_SWAP_SIZE=$(iniparse -c -f $TOS_DEFAULT_CONFIG -s tos -k swap_size)
TOS_BOOT_SIZE=$(iniparse -c -f $TOS_DEFAULT_CONFIG -s tos -k boot_size)


TOS_LVM_OPTS="--noheadings --readonly --nolocking"
TOS_VOLUE_CONFIG=/etc/volume/volume.conf
TOS_STORAGE_CONFIG=/etc/volume/storage.conf
TOS_RAID_CONF=/etc/tos.conf
TOS_RAID_CORE_PATH=/mnt/core
TOS_FLASHCACHE=/etc/flashcache
TOS_USBSORT=/tmp/usbsort
MUSTAPP="
iscsid
iSCSIManager
"

TOS_KERNEL=$(uname -r)
[ ! -d /etc/flashcache ] && mkdir /etc/flashcache
[ ! -e $TOS_USBSORT ] && mkdir -m 777 $TOS_USBSORT

trim_name() {
    local script_name=$1
    if [ "${script_name:0:1}" = "." ]; then
        script_name=${script_name%.*}
        script_name=${script_name:1}
    fi
    echo "$script_name"
}

get_default_addr() {
    echo $(ter_defaultmac)
}

get_root_username() {
    id 0 | grep root >/dev/null 2>&1
    if [ $? -eq 0 ]; then
        echo "root"
    else
        . /etc/profile
        echo $admin
    fi
    return 0
}

usb_init_position() {
    local device_name=$1
    local blk=/dev/${device_name}
    for i in $(ls $TOS_USBSORT); do
        local tmpdev=$TOS_USBSORT/$i
        local dev=$(readlink $tmpdev)
        [ "$dev" = "$blk" ] && return 0
    done
    for k in $(seq 1 10); do
        local tmpdev=$TOS_USBSORT/$k
        if [ -e $tmpdev ]; then
            local dev=$(readlink $tmpdev)
            [ ! -b $dev ] && rm -f $tmpdev
        fi

        if [ ! -L $tmpdev ]; then
            ln -fsn $blk $tmpdev
            return 0
        fi
    done
}

usb_remove_position() {
    local device_name=$1
    local blk=/dev/${device_name}
    for i in $(ls $TOS_USBSORT); do
        local tmpdev=$TOS_USBSORT/$i
        local dev=$(readlink $tmpdev)
        [ "$dev" = "$blk" -o ! -b $dev ] && rm -f $tmpdev
    done
}

GetMntPoint() {
    local uuid="$1"
    iniparse -a -f $TOS_VOLUE_CONFIG -s "$uuid" -system >/dev/null 2>&1
    local sort=$(iniparse -c -f $TOS_VOLUE_CONFIG -s "$uuid" -k sort)
    [ -z "$sort" ] && return 1
    echo "/Volume${sort}"
    return 0
}

script_get_lock() {
    local script_name=$1
    if [ -z "$script_name" ]; then
        script_name=$(trim_name "$(basename $0)")
    fi
    local script_lock=$TOS_SCRIPTS_LOCK_PATH/$script_name

    [ ! -d $TOS_SCRIPTS_LOCK_PATH ] && mkdir -p $TOS_SCRIPTS_LOCK_PATH

    echo script "$script_name" get lock
    if [ -f "$script_lock" ]; then
        echo script "$script_name" get lock failed.
        return 1
    fi
    touch "$script_lock"
    return 0
}

script_put_lock() {
    local script_name=$1
    if [ -z "$script_name" ]; then
        script_name=$(trim_name "$(basename $0)")
    fi
    local script_lock=$TOS_SCRIPTS_LOCK_PATH/$script_name
    echo script "$script_name" put lock
    [ -f "$script_lock" ] && rm "$script_lock"
    return 0
}

script_get_board() {
    local script_bin="/sbin/dmidecode"
    $script_bin | grep "JHS830" >/dev/null
    [ $? -eq 0 ] && {
        echo 2538
        return 0
    }
    $script_bin | grep "retsamarret" >/dev/null
    [ $? -eq 0 ] && {
        echo 1900
        return 0
    }
    echo 1
    return 1
}

get_vg_name() {
    local path=$1
    echo $path | grep "-" >/dev/null
    if [ $? -eq 0 ]; then
        local name=$(basename $path)
        name=${name%%-*}
    else
        local name=$(basename $(dirname $path))
    fi
    echo "$name"
}

get_lvm_name() {
    local path=$1
    echo "$path" | grep "-" >/dev/null
    if [ $? -eq 0 ]; then
        local name=$(basename "$path")
        name=${name##*-}
    else
        local name=$(basename "$path")
    fi
    echo "$name"
}

DestroyCache() {
    local CACHENAME=$1
    # get ssd device
    local CACHE_DEV=$(ter_flashcache -blk $CACHENAME -opt cache_dev -fast)
    if [ $? -eq 0 ]; then
        $DMSETUP remove $CACHENAME >/dev/null 2>&1
        [ -b "$CACHE_DEV" ] && flashcache_destroy -f $CACHE_DEV
        return 0
    fi
    return 1
}

get_device_name() {
    local PTUUID=$1
    for item in $(ls -1d /sys/block/sd*); do
        local blkname=$(basename $item)
        local blk=/dev/$blkname
        if [ -b $blk ]; then
            local uuid=$(blkid -o value -s PTUUID $blk)
            if [ "$uuid" = "$PTUUID" ]; then
                echo "$blk"
                break
            fi
        fi
    done
    return 0
}

dev_sortbyname() {
    local name=$1
    echo $name | grep "-" >/dev/null
    if [ $? -eq 0 ]; then
        echo ${name##*-lv}
    else
        echo ${name:2}
    fi
}

GetDeviceUUID() {
    local blk=$1
    local uuid=""
    echo "$blk" | egrep -q -E "^/dev/md[0-9]+" >/dev/null
    if [ $? -eq 0 ]; then
        uuid=$(mdadm -D $blk --export 2>/dev/null | awk -F= '/MD_UUID/ {print $2}')
    else
        uuid=$(lvs -o lv_tags $blk | grep "000" | sed s/[[:space:]]//g)
    fi
    echo $uuid
}

GetVolumeSort() {
    local blk=$1
    local uuid=$(GetDeviceUUID $blk)
    local sort=$(iniparse -c -f $TOS_VOLUE_CONFIG -s $uuid -k sort 2>/dev/null)
    echo $sort
}

# get mount options from blk
GetMountOpts() {
    local blk=$1
    local blkName=$(basename $blk)
    local uuid=$2
    local fs=$(blkid -o value -s TYPE $blk)
    if [ "$fs" = "btrfs" ]; then
        local MNTOPT=$(iniparse -c -f $TOS_DEFAULT_CONFIG -s filesystem -k btrfs)
        [ -z "$uuid" ] && uuid=$(GetDeviceUUID $blk)
        local level=$(iniparse -c -f "${TOS_VOLUE_CONFIG}" -s "${uuid}" -k compression 2>/dev/null)
        if [ ! -z "$level" -a "$level" != "0" ]; then
            MNTOPT="$MNTOPT,compress=zlib:${level}"
        fi
        # if btrfs root subvolume flag exist; add mount parameter:"subvol=@"
        local btrfsSubvolName=$(iniparse -c -f $TOS_DEFAULT_CONFIG -s filesystem -k btrfs_subvolName)
        if [ -a "/tmp/${blkName}_${btrfsSubvolName}" ]; then
            MNTOPT="subvol=${btrfsSubvolName},$MNTOPT"
        fi
    elif [ "$fs" = "xfs" ]; then
        local MNTOPT=$(iniparse -c -f $TOS_DEFAULT_CONFIG -s filesystem -k xfs)
    else
        local MNTOPT=$(iniparse -c -f $TOS_DEFAULT_CONFIG -s filesystem -k ext4)
    fi
    echo $MNTOPT
}

AutoMountDevice() {
    local blk=$1
    [ ! -b "$blk" ] && exit 1
    local fs=$(blkid -o value -s TYPE $blk)
    [ -z "$fs" ] && exit 1
    local MNTYPE="-t $fs"
    local target=$(ter_flashcache -blk $blk -opt cache_target)
    if [ ! -z "$target" ]; then
        local UUID=$(GetDeviceUUID $target)
    else
        local UUID=$(GetDeviceUUID $blk)
    fi
    local MNTPATH=$(GetMntPoint "$UUID")
    if [ -z "$MNTPATH" ]; then
        echo "Can't mntpath from $UUID" >&2
        return 1
    fi
    [ ! -d "$MNTPATH" ] && mkdir $MNTPATH
    local OPTS=$(GetMountOpts "$blk" "$UUID")
    mount $MNTYPE -o $OPTS $blk $MNTPATH
#    btrfs qgroup disable $MNTPATH >/dev/null 2>&1 &
#    btrfs quota disable $MNTPATH >/dev/null 2>&1 &
    RETVAL=$?
    if [ "$fs" = "btrfs" ]; then
        df-json | grep "${MNTPATH}$" >/dev/null
        [ $? -eq 0 ] && btrfs filesystem resize max $MNTPATH >/dev/null 2>&1
    fi
    if [ $RETVAL -ne 0 ]; then
        echo "Mount Failed: $blk to $MNTPATH" >&2
        return $RETVAL
    fi
    #mount home
    df-json | grep /home >/dev/null
    [ $? -ne 0 ] && /etc/init.d/nas/mkbase >/dev/null 2>&1
    return 0
}


AutoMountDeviceTwo() {
    local blk=$1
    [ ! -b "$blk" ] && exit 1
    local fs=$(blkid -o value -s TYPE $blk)
    [ -z "$fs" ] && exit 1
    local MNTYPE="-t $fs"
    local target=$(ter_flashcache -blk $blk -opt cache_target)
    if [ ! -z "$target" ]; then
        local UUID=$(GetDeviceUUID $target)
    else
        local UUID=$(GetDeviceUUID $blk)
    fi
    local MNTPATH=$(GetMntPoint "$UUID")
    if [ -z "$MNTPATH" ]; then
        echo "Can't mntpath from $UUID" >&2
        return 1
    fi
    [ ! -d "$MNTPATH" ] && mkdir $MNTPATH
    local OPTS=$(GetMountOpts "$blk" "$UUID")
    mount $MNTYPE -o $OPTS $blk $MNTPATH
#    btrfs qgroup disable $MNTPATH >/dev/null 2>&1 &
#    btrfs quota disable $MNTPATH >/dev/null 2>&1 &
    RETVAL=$?
    if [ "$fs" = "btrfs" ]; then
        df-json | grep "${MNTPATH}$" >/dev/null
        [ $? -eq 0 ] && btrfs filesystem resize max $MNTPATH >/dev/null 2>&1
    fi
    if [ $RETVAL -ne 0 ]; then
        echo "Mount Failed: $blk to $MNTPATH" >&2
        return $RETVAL
    fi
    #mount home
    df-json | grep /home >/dev/null
    return 0
}

# check raid0.default_layout
check_raid0_default_layout() {
    defaultlayout=/sys/module/raid0/parameters/default_layout
    if [ -f $defaultlayout ]; then
        layout=$(cat $defaultlayout)
        if [ "$layout" = "0" ]; then
            echo 2 >$defaultlayout
        fi
    fi
}

# check isn't exists..
check_name_exists() {
    local toskey=$1
    local raid=/dev/md${toskey}
    if [ -b $raid ]; then
        local ret=$(timeout 5 blkid -s TYPE -o value $raid)
        [ "$ret" = "ext4" -o "$ret" = "btrfs" -o "$ret" = "swap" ] && return 1
    fi
    local lvname=lv${toskey}
    local lv_names=$(timeout 5 lvs -o lv_name $TOS_LVM_OPTS 2>/dev/null)
    [ -z "$lv_names" ] && return 0
    local HAS=0
    for lv_name in $lv_names; do
        if [ "$lv_name" = "$lvname" ]; then
            HAS=1
            break
        fi
    done
    return $HAS
}

get_main_volume() {
    local result=""
    for item in $(df-json | egrep "/Volume[0-9]+$" | awk '{print $8}'); do
        check_main_raid $item
        [ $? -ne 0 ] && continue
        result=$item
        break
    done
    echo $result
}

check_main_raid() {
    local mntpoint=$1
    local addr=$(cat $mntpoint/.main.inc 2>/dev/null)
    if [ "$addr" = $(get_default_addr) ]; then
        return 0
    fi
    return 1
}

getmntpoint() {
    local blk=$1
    local flag=""
    for line in $(df-json | grep "${blk}" | awk '{print $8}'); do
        [ -z "$flag" ] && flag=$line
        echo $line | egrep "/Volume[0-9]+$" >/dev/null 2>&1
        if [ $? -eq 0 ]; then
            flag=$line
            break
        fi
    done
    echo $flag
}

umountAll() {
    cd /
    local mntpath=$1
    # iso, ecryptfs, ...
    for line in $(df-json | grep ${mntpath}/. | awk '{print $8}'); do
        [ -z "$line" ] && continue
        umount "$line" >/dev/null 2>&1
    done
    # umount usb
    for item in $(df-json | grep ${mntpath}/@usb/* | awk '{print $8}'); do
        [ -z "$item" ] && continue
        umount "$item" >/dev/null 2>&1
    done
    # iso umount
    for item in $(df-json | grep ${mntpath}/@iso/* | awk '{print $8}'); do
        [ -z "$item" ] && continue
        umount "$item" >/dev/null 2>&1
    done
    # eSATA umount
    for item in $(df-json | grep ${mntpath}/@eSATA/* | awk '{print $8}'); do
        [ -z "$item" ] && continue
        umount "$item" >/dev/null 2>&1
    done
    # umount iscsi
    for item in $(df-json | grep ${mntpath}/@iscsi/* | awk '{print $8}'); do
        [ -z "$item" ] && continue
        umount "$item" >/dev/null 2>&1
    done
    check_main_raid "$mntpath"
    if [ $? -eq 0 ]; then
        umount /home >/dev/null 2>&1
    fi
    umount "$mntpath" >/dev/null 2>&1
    df-json | egrep "${mntpath}$" >/dev/null
    return $?
}

main_service_stop() {
    echo "stop main process..."
    ter_service all stop ssh.service
    return 0
}

service_stop() {
    killall -9 mke2fs mkfs.btrfs >/dev/null 2>&1
    for svrname in $MUSTAPP; do
        ter_service $svrname stop >/dev/null 2>&1
    done
    sleep 1
    for svrname in $(ls /etc/sc.d/); do
        [ "$svrname" = "nginx" ] && continue
        in_Array "$svrname"
        [ $? -eq 0 ] && continue
        ter_service $svrname stop >/dev/null 2>&1
    done
    return 0
}

in_Array() {
    local keyword=$1
    for name in $MUSTAPP; do
        [ "$keyword" = "$name" ] && return 0
    done
    return 1
}
