#!/bin/sh

#############################################################
# script description:
# umount clear and re-make disk partions
#
# disk partions:
# | -- swap area -- | -- base area -- | -- user area -- |
# auth: jalin
# time: 2019-05-01
# copyright: terra-master tec
#############################################################

source /etc/tos/scripts/scripts
script_get_lock >/dev/null
[ $? -ne 0 ] && exit 1

usage="Usage:$(basename $0) -l[level] -b [TOS_DEVICES]\n\tlevel: [0, 1, 5, single, 6, 10, linear]\n"

# get parameter list
bitmap=0
TOS_DEVICES=""
TOS_DEVICES_NUMBER=0
while getopts "l:b" opt; do
    case $opt in
    l) level=$OPTARG ;; # get raid level
    b) bitmap=1 ;;      # open raid 1 bitmap
    esac
done
# fix 4.19.165 bug
check_raid0_default_layout

# parameters check
coresize=$(iniparse -c -f ${TOS_RAID_CONF} -s tos -k coresize)
swapsize=$(iniparse -c -f ${TOS_RAID_CONF} -s tos -k swapsize)

TOS_POOL_ROOT=/tmp/storage
[ ! -e $TOS_POOL_ROOT ] && mkdir $TOS_POOL_ROOT

# get TOS_DEVICES
for item in $@; do
    if [ -b $item ]; then
        TOS_DEVICES=$TOS_DEVICES' '$item
        let TOS_DEVICES_NUMBER=TOS_DEVICES_NUMBER+1
    fi
done

if [ $TOS_DEVICES_NUMBER -lt 1 -o -z "$level" ]; then
    echo -e $usage
    script_put_lock >/dev/null
    exit 1
fi

TOS_RAID_NAME=""
TOS_RAID_SORT=""
for i in $(seq 0 7); do
    [ -b /dev/md${i} ] && continue
    TOS_RAID_SORT=${i}
    TOS_RAID_NAME=/dev/md${i}
    break
done
TOS_VG_NAME=vg${TOS_RAID_SORT}
# create new uuid
TOS_LABEL="TOS_VOL_$(date +'%Y%m%d')"
TOS_UUID_STR=$(uuidgen -t -r)

# storage pools max ... 8
if [ -z "$TOS_RAID_NAME" -o -z "$TOS_RAID_SORT" ]; then
    echo -e $usage
    script_put_lock >/dev/null
    exit 2
fi

baseparts=""
swapparts=""
userparts=""
debugFile=$TOS_POOL_ROOT/$TOS_VG_NAME
process=0
echo "makeVolumeGroup:${TOS_VG_NAME}:${TOS_RAID_NAME}:${TOS_UUID_STR}:0:${process}" >$debugFile
sleep 2

blkparted() {
    local blk=$1
    local offset=0
    local offend=0
    parted -s $blk mktable gpt
    [ $? -ne 0 ] && return 1

    let offend=$offset+$TOS_BOOT_SIZE
    parted -s $blk mkpart primary ext2 0% $offend
    [ $? -ne 0 ] && return 1

    let offset=$offend
    let offend=$offset+$TOS_CORE_SIZE
    parted -s $blk mkpart primary ext2 $offset $offend
    [ $? -ne 0 ] && return 1

    let offset=$offend
    let offend=$offset+$TOS_SWAP_SIZE
    parted -s $blk mkpart primary ext2 $offset $offend
    [ $? -ne 0 ] && return 1

    let offset=$offend
    parted -s $blk mkpart primary ext2 $offset 100%
    [ $? -ne 0 ] && return 1

    mdev -s
    return 0
}

InitDisk() {
    local space=30
    if [ $TOS_DEVICES_NUMBER -gt 0 ]; then
        let space=30/$TOS_DEVICES_NUMBER
    fi
    for sd in $TOS_DEVICES; do
        local blk=$(basename ${sd})
        # local bootblk=${sd}1
        local coreblk=${sd}2
        local swapblk=${sd}3
        local userblk=${sd}4
        baseparts="${baseparts} ${coreblk}"
        swapparts="${swapparts} ${swapblk}"
        userparts="${userparts} ${userblk}"
        let process=process+space
        echo "makeVolumeGroup:${TOS_VG_NAME}:${TOS_RAID_NAME}:${TOS_UUID_STR}:0:${process}" >$debugFile

        mdadm --misc -W ${TOS_RAID_CORE}

        local part_number=$(ls -d /sys/block/${blk}/${blk}[1-4] | wc -l)
        if [ $part_number -eq 4 ]; then
            mdadm -D ${TOS_RAID_CORE} | grep ${coreblk} >/dev/null
            if [ $? -ne 0 ]; then # not in md9
                local needpart=1
                if [ -b ${coreblk} ]; then
                    mdadm -E ${coreblk} | grep ${TOS_CORE_SIGN}
                    if [ $? -eq 0 ]; then
                        mdadm -r ${TOS_RAID_CORE} ${coreblk} >/dev/null
                        mdadm -a ${TOS_RAID_CORE} ${coreblk} >/dev/null
                        needpart=0
                    fi
                fi
                # need to parted...
                if [ $needpart -eq 1 ]; then
                    mdadm -f ${TOS_RAID_SWAP} ${swapblk} >/dev/null 2>&1
                    mdadm -r ${TOS_RAID_SWAP} ${swapblk} >/dev/null 2>&1
                    blkparted ${sd}
                    if [ $? -ne 0 ]; then
                        echo "makeVolumeGroup:${TOS_VG_NAME}:${TOS_RAID_NAME}:${TOS_UUID_STR}:1:make_partion_failed" >$debugFile
                        script_put_lock >/dev/null
                        exit 1
                    fi
                fi
            fi
        else
            if [ -b ${coreblk} ]; then
                mdadm -f ${TOS_RAID_CORE} ${coreblk} >/dev/null 2>&1
                mdadm -r ${TOS_RAID_CORE} ${coreblk} >/dev/null 2>&1
            fi
            if [ -b ${swapblk} ]; then
                mdadm -f ${TOS_RAID_SWAP} ${swapblk} >/dev/null 2>&1
                mdadm -r ${TOS_RAID_SWAP} ${swapblk} >/dev/null 2>&1
            fi
            blkparted ${sd}
        fi

        mkdir -p /boot/bootdisk >/dev/null
        # local bootlabel=$(e2label ${bootblk} 2>/dev/null)
        # if [ -z "${bootlabel}" ]; then
        #     /etc/tos/scripts/initboot "$sd"
        # fi
    done
}

RaidFix() {
    local raid=$1
    local blk=$2
    local raidname=$(basename $raid)
    #cat /proc/mdstat | grep $raidname | grep ${blk}
    mdadm -D ${raid} | grep ${blk} >/dev/null
    if [ $? -ne 0 ]; then
        echo "insert $blk to ${raid}"
        mdadm -r ${raid} ${blk}
        mdadm --zero-superblock ${blk}
        mdadm -a ${raid} ${blk}
    fi
}

RaidCreate() {
    local raid=$1
    local sign=$2
    local disks=$3
    local disklist=${disks//,/ }
    echo -e "y\n" | mdadm -C ${raid} -l1 -c512 -n${TOS_DEVICES_NUMBER} -N${sign} $disklist --force
    if [ $? -ne 0 ]; then
        echo "makeVolumeGroup:${TOS_VG_NAME}:${TOS_RAID_NAME}:${TOS_UUID_STR}:1:make_base_failed" >$debugFile
        script_put_lock >/dev/null
        exit 1
    fi
    wait $!
}

RaidBitmap() {
    local raid=$1
    echo "makeVolumeGroup:${TOS_VG_NAME}:${TOS_RAID_NAME}:${TOS_UUID_STR}:0:${process}" >$debugFile
    mdadm --misc -W ${raid}
    # mdadm --grow ${raid} --raid-devices=$TOS_SYS_NUMBER --force
    # mdadm --grow ${raid} --bitmap=internal --force
}

# init disks
InitDisk

# make base raid
if [ -b ${TOS_RAID_CORE} ]; then
    echo ${TOS_RAID_CORE} 'already created'
    # mdadm --grow ${TOS_RAID_CORE} --raid-devices=$TOS_SYS_NUMBER --force
    for i in $baseparts; do
        RaidFix ${TOS_RAID_CORE} ${i}
    done
else
    baselist=${baseparts// /,}
    RaidCreate ${TOS_RAID_CORE} ${TOS_CORE_SIGN} ${baselist}
    echo -e "y\n" | mke2fs -t ext4 -m .5 -b 4096 -E stride=128,stripe-width=256 ${TOS_RAID_CORE}
    sleep 2 # wait disk sync
fi
process=40
RaidBitmap ${TOS_RAID_CORE}

# make swap raid
if [ -b ${TOS_RAID_SWAP} ]; then
    echo ${TOS_RAID_SWAP} 'already created'
    # mdadm --grow ${TOS_RAID_SWAP} --raid-devices=$TOS_SYS_NUMBER --force
    for i in $swapparts; do
        RaidFix ${TOS_RAID_SWAP} ${i}
    done
else
    swaplist=${swapparts// /,}
    RaidCreate ${TOS_RAID_SWAP} ${TOS_SWAP_SIGN} ${swaplist}
    sleep 2 # wait disk sync
fi
process=50
RaidBitmap ${TOS_RAID_SWAP}

# init swap raid
if [ -b ${TOS_RAID_SWAP} ]; then
    cat /proc/swaps | grep ${TOS_RAID_SWAP}
    if [ $? -ne 0 ]; then
        mkswap ${TOS_RAID_SWAP} # format swapblock
        swapon ${TOS_RAID_SWAP} # Enable swap
    fi
fi

sleep 1
# make user raid
process=60
echo "makeVolumeGroup:${TOS_VG_NAME}:${TOS_RAID_NAME}:${TOS_UUID_STR}:0:${process}" >$debugFile
TOS_PLUGS="--chunk=128"
TOS_BITMAP=""
[ $bitmap -eq 1 ] && TOS_BITMAP="--bitmap=internal"

if [ $TOS_DEVICES_NUMBER -eq 1 ]; then
    TOS_PLUGS="$TOS_PLUGS $TOS_BITMAP --level=1"
elif [ $level -eq 5 -o $level -eq 1 -o $level -eq 10 -o $level -eq 6 ]; then
    TOS_PLUGS="$TOS_PLUGS $TOS_BITMAP --level=$level"
else
    TOS_PLUGS="$TOS_PLUGS --level=$level"
fi
echo Y | mdadm --create $TOS_RAID_NAME $TOS_PLUGS -n$TOS_DEVICES_NUMBER -N${TOS_USER_SIGN} ${userparts} --force
# wait for create raid...
while [ 1 ]; do
    sleep 2
    [ -b $TOS_RAID_NAME ] && break
done
mdadm -Ds >/etc/mdadm.conf
process=80
echo "makeVolumeGroup:${TOS_VG_NAME}:${TOS_RAID_NAME}:${TOS_UUID_STR}:0:${process}" >$debugFile

# optimization resync speed for raid5 & raid6...
mdname=$(basename $TOS_RAID_NAME)
cache_size=/sys/block/$mdname/md/stripe_cache_size
[ -e $cache_size ] && echo $TOS_TRIP_SIZE >$cache_size

# clean old vg & pv
pvs -o pv_name $TOS_LVM_OPTS 2>/dev/null | grep ${TOS_RAID_NAME}
if [ $? -eq 0 ]; then
    vg_uuid=$(pvs -o vg_uuid $TOS_LVM_OPTS ${TOS_RAID_NAME} 2>/dev/null)
    if [ ! -z "$vg_uuid" ]; then
        vgrename $vg_uuid vg_temp
        vgremove -f vg_temp
    fi
    pvremove -ff ${TOS_RAID_NAME}
fi

# pv create...
pvcreate -ff ${TOS_RAID_NAME} >/dev/null
pvs $TOS_LVM_OPTS | grep "${TOS_RAID_NAME}" >/dev/null
if [ $? -ne 0 ]; then
    echo "makeVolumeGroup:${TOS_VG_NAME}:${TOS_RAID_NAME}:${TOS_UUID_STR}:1:create_pv_failed" >$debugFile
    script_put_lock >/dev/null
    exit 1
fi
process=90
echo "makeVolumeGroup:${TOS_VG_NAME}:${TOS_RAID_NAME}:${TOS_UUID_STR}:0:${process}" >$debugFile

# vg create...
vgcreate --addtag ${TOS_UUID_STR} -y ${TOS_VG_NAME} ${TOS_RAID_NAME} >/dev/null
vgs $TOS_LVM_OPTS | grep "${TOS_VG_NAME}" >/dev/null
if [ $? -ne 0 ]; then
    echo "makeVolumeGroup:${TOS_VG_NAME}:${TOS_RAID_NAME}:${TOS_UUID_STR}:1:create_vg_failed" >$debugFile
    script_put_lock >/dev/null
    exit 1
fi
# modify the storage config
iniparse -a -f /etc/volume/storage.conf -s "$TOS_UUID_STR" -system

process=100
echo "makeVolumeGroup:${TOS_VG_NAME}:${TOS_RAID_NAME}:${TOS_UUID_STR}:0:${process}" >$debugFile
echo "VolumeGroupName:$TOS_VG_NAME"
# the end ...
script_put_lock >/dev/null
exit 0
