#! /bin/bash

############################################################################
# DESCRIPTION: makeraid for the 'install' of linx, by using command of mdadm
#              , this shell only support RAID0 1 5 and 10, others will 
#              report false. if someone need other level, please modify.
#
# SCRIPT NAME: mkraid.sh
#
# argument: 
#
# return value: 7 create or assimble raid device lose
#               6 incorrect active and spare devices name, maybe it has 
#                  been used
#               5 level0 don't need spare devices
#               4 this shell not support this RAID level
#               3 mdX has exist
#               2 this levelY need more devices
#               1 error argument from user
#               0 make raid allright
#
# AUTHOR:		ZR_Lang
#
# EMALL:		zrlang@linx-info.com
#
# DATE:			2010-08-23
#
# HISTORY:
# REVISOR		DATE			MODIFICATION
# ZR_Lang		2010-08-23		create
###########################################################################

. ./functions

#global value can be modified for some exchange
RAIDNAME=""
RAIDLEVEL=""
ACTIVELIST=""
SPARELIST=""
ACTIVENUM=""
SPARENUM=""
DEVICELIST=""

###########################################################################
# Function Name: setArgument()
# Input: $@
# Return: nothing
# Description: set the corresponding argument 
###########################################################################
setArgument(){
    local i
    local ARGV=($(getopt -l name:,level:,active:,spare:,help -o n:,l:,a:,s:,h -- $@ 2>>${DEV_LOG}))

    for((i=0; i<${#ARGV[@]}; i++))
    do
	case ${ARGV[$i]} in
	    --name|-n)
		((i++))
		RAIDNAME=${ARGV[$i]}
		;;
	    --level|-l)
		((i++))
		RAIDLEVEL=${ARGV[$i]}
		;;
	    --active|-a)
		((i++))
		ACTIVELIST=${ARGV[$i]}
		;;
	    --spare|-s)
		((i++))
		SPARELIST=${ARGV[$i]}
		;;
	    --help|-h)
		usage
		return 0
		;;
	    --)
		;;
	    *)
		info "error argument, please use help message and modify it"
		return 1
		;;
	esac
    done

    if [ -z "${ACTIVELIST}" ];then
	ACTIVENUM=0
    else
	ACTIVENUM=`echo $ACTIVELIST | tr , ' ' | wc -w`
    fi

    if [ -z "${SPARELIST}" ]; then
	SPARENUM=0
    else
	SPARENUM=`echo $SPARELIST | tr , ' ' | wc -w`
    fi
    RAIDNAME=`echo ${RAIDNAME}| sed -e s/\'//g`
    RAIDLEVEL=`echo ${RAIDLEVEL}| sed -e s/\'//g`
    SPARELIST=`echo ${SPARELIST}|sed -e s/\'//g`
    ACTIVELIST=`echo ${ACTIVELIST}|sed -e s/\'//g`
    DEVICELIST=`echo ${ACTIVELIST},${SPARELIST}|sed -e s/','/' '/g`
}

###########################################################################
# Function Name: testBeforeMkraid()
# Input: $@
# Return: 0 for success, 1 for false. if false, the ERRNO has been setted
# Description: test the condition with the order of arguments before make 
#              raid, if error echo the errno to stdout and exit
###########################################################################
testBeforeMkraid(){
    local i
	#test the "(3) mdX has exist" error
    mdadm -D $RAIDNAME >>${DEV_LOG} 2>>${DEV_LOG}
    if [ "$?" == "0" ]; then
	info "$RAIDNAME has exist"
	return 3
    fi

	#test "(2) this levelY need more devices" error
    if [ "${RAIDLEVEL}" == "0" -o "${RAIDLEVEL}" == "1" ]; then
	if [ $ACTIVENUM -lt 2 ]; then
	    info "RAID$RAIDLEVEL need more devices"
	    return 2
	fi
	#test "(5) level0 don't need spare devices"
	if [ "${SPARENUM}" != "0" -a "${RAIDLEVEL}" == "0" ];then
	    info "RAID0 donot need spare devices"
	    return 5
	fi
    elif [ "${RAIDLEVEL}" == "5" ]; then
	if [ "${ACTIVENUM}" -lt 3 ]; then
	    info "RAID$RAIDLEVEL need more devices"
	    return 2
	fi
    elif [ "${RAIDLEVEL}" == "10" ]; then
	if [ "${ACTIVENUM}" -lt 4 ]; then
	    info "RAID$RAIDLEVEL need more devices"
	    return 2
	fi
    else   #test "(4) this shell not support this RAID level" error
	info "this shell not support $RAIDNAME"
	return 4
    fi
    
	#test "(6) incorrect active and spare devices name, maybe it has been 
	#      used"
    for i in ${DEVICELIST}
    do
	if mdadm -Ds -v | grep -w $i >>${DEV_LOG} 2>>${DEV_LOG} ; then
	    info "incorrect active and spare devices name, maybe it has been used"
	    return 6
	fi
    done
    return 0
}

###########################################################################
# Function Name: testAfterCreate()
# Input: $?  -- the return value after mdadm create or mdadm add 
# Return: 0 for success, 1 for false. if false, the ERRNO has been setted
# Description: test the create or add success or lose 
###########################################################################
testAfterCreate(){
    #test "(7) create or assimble raid device lose"
    if [ "${1}" != "0" ];then
	info "create or assimble $RAIDNAME lose"
	return 7
    fi
    return 0
}

###########################################################################
# Function Name: usage()
# Input: nothing   
# Return: nothing
# Description: print the helped message  
###########################################################################
usage(){
    echo "Usage: mkraid [-h|--help] <-n|--name  raidname> <-l|--level  raidlevel>
              <-a|--active  activelist> [-s|--spare  sparelist]" 
    echo "According to the arguments,this shell make raid by create mode. Before make it, there is some testing for the arguments, and the ERRNO will be setted to the approprate value. This shell support RAID0 1 5 and 10 at present. "
    echo""
    echo "ARGUMENT:
	<raidname>          -- RAID devices name, example /dev/mdX
	<raidlevel>         -- RAID level, example 0, 1, 5, 10
	<activelist>        -- the RAID active member list, the interval symbol must be ',',example /dev/sda1,/dev/sdb1,/dev/sdc1,/dev/hda1 ... 
	<sparelist>         -- the RAID spare member list, this is not must. the interval symbol same as activelist"
    echo ""
    echo "RETURN VALUE:
	7 create or assimble raid device lose
	6 incorrect active and spare devices name, maybe it has been used
	5 level0 donot need spare devices
	4 this shell not support this RAID level
	3 the raid name has exist
	2 this levelY need more devices
	1 error argument to the mkraid from user
	0 make raid allright"
    echo ""
    echo "EXAMPLE:
If you want to make raid1 named the /dev/md0 with two active devices named /dev/sda1 /dev/sdb1 and one spare device named /dev/sdc1, you can write for this:"
    echo ""
    echo "	mkraid -n /dev/md0 -l 1 -a /dev/sda1,/dev/sdb1 -s /dev/sdc1"
    echo ""
    echo "But if you want to make raid0 with spare devices, there will be some mistake and exiting with 5. Other mistake please watch by yourself."
    echo ""
    echo ""
    echo "Report bugs to <zrlang@linx-info.com>"
}

###########################################################################
#                      main start from here                               #
###########################################################################

NOWDATE=`date`
info "${NOWDATE}"

setArgument $@; erv
testBeforeMkraid $@; erv

#make raid active devices and spare devices
if [ "${SPARENUM}" == "0" ]; then
    op_x=""
else
    op_x="-x$SPARENUM"
fi

yes| mdadm -C  -q $RAIDNAME -l$RAIDLEVEL -n$ACTIVENUM $op_x $DEVICELIST >>${DEV_LOG} 2>>${DEV_LOG}
testAfterCreate $?; erv

info "make $RAIDNAME allright"

# End of file
