#!/bin/bash

#********************************************************************
#            Copyright (C) Huawei Technologies, 2012-6
# 
#  #FileName                : configer_backup
#  #Writter                 : 
#  #Sub Modules             : 
#  #Mudule Name             : USBKEY 
#  #Language                : shell    
#  #Environment             : EulerOS 2.0
#  #First Release Date      : 2012-7-11
#  #modify date             : 2015-7-23
#  #Description             : real backup for USB-KEY
#                           : real backup for memory rootfs
#********************************************************************
CONFIGER_BAK_CONF=/etc/configer_bak.conf
source $CONFIGER_BAK_CONF
#data partiton,default is 2
DATA_PARTITION="${BAK_PARTITION_NUM}"
#work dir 
WORKDIR=/tmp/configer_bak
#data partition mountpoint
STORAGE_DATA_MOUNTPOINT="$CONFIG_BAK_DIR"
#sub backup dir,default is conf_bak
SUB_BACKUP_DIR=conf_bak
#rtbackup operate dir
FILEBAK_DIR="${WORKDIR}/rtbackup_$$"

#file backup action
FILE_ACTION_ADD="ADD"
#file backup action
FILE_ACTION_MODIFY="MODIFY"
#file backup action
FILE_ACTION_DELETE="DELETE"
#backup user
RTBAK_USER=
#avail backup user 
RTBAK_AVAIL_USERS=("Euler" "GE" "DS" "UVP")
#dirname cmd
DIRNAME=`which dirname`
#system disk
SYSTEM_DISK=""
#rtbak filelist
RTBAKFILELIST="${WORKDIR}/rtbak_filelist_$$"
#rtbak tmplog
RTBAK_TMPLOG="/var/log/rtbak_tmplog_$$"

#errrno define
STORAGE_SPACE_FULL=2

BAK_FAILED_NUM=0

if [ ! -d "$WORKDIR" ];then
	mkdir -p $WORKDIR
fi
if [ -z "$LOGFIlE" ];then
    LOGFIlE=/var/log/configer_backup/logsysconfig
    mkdir -p /var/log/configer_backup/
else 
    if [ ! -w "$LOGFIlE" ]
    then
        echo "please check $LOGFIlE"
        exit 1
    fi   
fi 

#########################################################
#    Description: fn_usage
#    Input:          
#    Return: 
#########################################################
function fn_usage()
{
    cat << EOF
Usage: 
configer_backup -u|--user [USER] [ACTION] [FILE] ... 
 
-h, --help                       display this help and exit 
-u, --user                       backup user is necessary and must be GE|DS|UVP|Euler 
ACTION  FILE:      
    -a, --add     filename       backup a new file  
    -d, --delete  filename       backup a delete file
    -m, --modify  filename       backup a modify file
    
examples: configer_backup --user Euler --modify modify_file1 --modify modify_file2 --add add_file1

EOF

}

#########################################################
#    Description: log to tmpfile
#    Input:  
#        $1: log level
#        $2: logmsg    
#    Return: 0-success
#########################################################
function fn_log()
{
    local available_loglevel="error info debug warn"
    local echo_loglevel="error info warn"
    local default_loglevel="debug"
    local loglevel="$1"
    local logmsg=

    if [ -z "$loglevel" ]; then
        return 0
    fi   
    shift 1    
    logmsg="$@"    
    
    echo ${available_loglevel} | grep -w "${loglevel}" > /dev/null 2>&1
    if [ $? -ne 0 ]; then
        loglevel="${default_loglevel}"
    fi
    
    echo "[${loglevel}]: ${logmsg}" >> $RTBAK_TMPLOG   2> /dev/null 
    echo ${echo_loglevel} | grep -w "${loglevel}" > /dev/null 2>&1
    if [ $? -eq 0 ]; then
        echo "[${loglevel}]: ${logmsg}"
    fi
    
    return 0
}


#########################################################
#    Description:    log to $LOGFIlE
#    Input:  
#        $1: 0-rt_backup success, 1-rt_backup failded
#    Return: 0-success
#########################################################
function fn_write_900B_per()
{
    while read -n900 line
    do
        echo "$line" >> $LOGFIlE 2> /dev/null
    done <$RTBAK_TMPLOG

}
function fn_log2rtlog()
{
    #0-rt_backup success, 1-rt_backup failded
    local ret=$1
    if [ $ret -eq 0 ];then
        fn_log debug ""`date`" pid:"$$", the user $RTBAK_USER rt_backup [success] ------ end" 
    else 
        fn_log debug ""`date`" pid:"$$", the user $RTBAK_USER rt_backup [failded] ------ end"       
    fi
    
    fn_write_900B_per
    rm -rf $RTBAK_TMPLOG
    
    return 0
}
function fn_get_sysdisk(){
    local sys_disk=""
    if [ -f "/etc/fstab" ];then
        sys_disk="`cat /etc/fstab | grep "$STORAGE_DATA_MOUNTPOINT" | awk '{print $1}' `"
    fi
 
    echo $sys_disk;
}
#########################################################
#    Description: init the work environment
#    Input:  
#    Return: 0-success,1-failed
#########################################################
function fn_init()
{
    local ret=0

    if [ ! -d ${WORKDIR} ]; then
        mkdir -p ${WORKDIR}
    fi

    if [ ! -d ${STORAGE_DATA_MOUNTPOINT} ];then
        mkdir -p ${STORAGE_DATA_MOUNTPOINT}
    fi

    if [ ! -d ${FILEBAK_DIR} ];then
        mkdir -p ${FILEBAK_DIR}
    fi
    
    if [ -n "`echo "$datapart" | grep ^[1-9]$`" ];then
        DATA_PARTITION=$datapart
    fi
    
    SYSTEM_DISK="`fn_get_sysdisk`"
    [ -n "$SYSTEM_DISK" ] && \
    [ ! -z  "`cat /proc/mounts | grep "${SYSTEM_DISK}" | grep " $STORAGE_DATA_MOUNTPOINT "`" ]
    ret=$?
    if [ $ret -ne 0 ];then
        fn_log "error" "the ${STORAGE_DATA_MOUNTPOINT} is not mounted,please check the /etc/fstab !"
        return 1
    fi
    if [ ! -d $STORAGE_DATA_MOUNTPOINT/$SUB_BACKUP_DIR ];then
        mkdir -p $STORAGE_DATA_MOUNTPOINT/$SUB_BACKUP_DIR
    fi
    STORAGE_DATA_MOUNTPOINT=$STORAGE_DATA_MOUNTPOINT/$SUB_BACKUP_DIR
    return 0
    
}

#########################################################
#    Description: fn_do_clean, remove tmp file
#    Input:  
#        $1: 0-rt_backup success, 1-rt_backup failded
#    Return: 0-success
#########################################################
function fn_do_clean()
{
    local ret=$1
    
    fn_log2rtlog $ret
    
    rm -rf ${RTBAK_TMPLOG}
    rm -rf ${FILEBAK_DIR}
    rm -rf ${RTBAKFILELIST}
    
    return 0
}

#########################################################
#    Description: check_bakuser and set rt_backup user
#    Input:  
#        $1: backup user
#    Return: 0-success,1-failed
#########################################################
function check_bakuser()
{
    local bak_user=$1
    
    echo ${RTBAK_AVAIL_USERS[@]} | grep -w "${bak_user}" > /dev/null 2>&1
    if [ $? -ne 0 ]; then
        fn_log "error" "backup user must be one of \"${RTBAK_AVAIL_USERS[@]}\""
        return 1
    fi
    RTBAK_USER=$bak_user
    fn_log "info" "the backup user is $RTBAK_USER"
    
    return 0
}

#########################################################
#    Description: check_bakfile and input bakfilelist
#    Input:  
#        $1: action: modify,delete,add
#        $2: backup file
#    Return: 0-success,1-failed
#########################################################
function check_bakfile()
{
    local action=$1
    local var_file=$2
    local actionlist=    
    
    actionlist="$FILE_ACTION_ADD $FILE_ACTION_MODIFY $FILE_ACTION_DELETE"
    echo ${actionlist[@]} | grep -w "${action}" > /dev/null 2>&1
    if [ $? -ne 0 ]; then
        fn_log "warn" "the file action(--modify/--delete/--add) is invalid,ignore params ${action} $var_file"
        let BAK_FAILED_NUM+=1
        return 1
    fi
    
    echo "$var_file" | grep "^/" > /dev/null 2>&1
    if [ $? -ne 0 ]; then
        fn_log "warn" "the param backup file must be absolute path, ignore params ${action} $var_file"
        let BAK_FAILED_NUM+=1
        return 1
    fi
    
    if [ "${action}" = "$FILE_ACTION_ADD" ] || [ "${action}" = "$FILE_ACTION_MODIFY" ];then
        if [ ! -e "$var_file" ];then
            fn_log "warn" "$var_file is not exit, cannot rtbackup ${action} action, ignore params ${action} $var_file"
            let BAK_FAILED_NUM+=1
            return 1
        fi
    fi
    #ȥβб
    var_file="`echo "$var_file" | sed 's/\/\+$//g'`"
    
    echo "$action $var_file" >> $RTBAKFILELIST 2>/tmp/tmpfile_$$
    if [ $? -ne 0 ]; then
        fn_log "warn" "input $var_file to backup filelst,ignore params ${action} $var_file.`cat /tmp/tmpfile_$$ | awk -F "echo:" '{print $2}'`"
        rm -rf /tmp/tmpfile_$$
        let BAK_FAILED_NUM+=1
        return 1
    fi
    rm -rf /tmp/tmpfile_$$
    return 0
    
}

#########################################################
#    Description:  verify input param
#    Input:  
#        $@: input param
#    Return: 0-success,1-failed
#########################################################
function fn_verify_input()
{
    local input_param=$@
    
    if [ $# -lt 1 ]; then
        fn_log "error" "missing param,please check it"
        fn_do_clean 1
        fn_usage
        exit 1
    fi

    if [ -z "`echo $input_param | grep -w "\-u"`" -a -z "`echo $input_param | grep -w "\-\-user"`" -a $# -gt 1 ];then
        fn_log "error" "missing param -u or --user"
        fn_do_clean 1
        fn_usage
        exit 1
    fi
        
    while [ $# -ge 1 ]; do
        case "$1" in
        -h|--help)
            fn_usage
            fn_log "debug" "param: -h|--help,`echo $input_param`"
            fn_do_clean 1
            exit 0
        ;;
        -u|--user)
            check_bakuser $2
            if [ $? -eq 0 ]; then                 
                shift 2
            else 
                fn_do_clean 1
                fn_usage
                exit 1
            fi
        ;;
        -m|--modify)
            check_bakfile "$FILE_ACTION_MODIFY" $2
            if [ $? -ne 0 ]; then     
                fn_log "debug" "check bakfile failed,param:`echo $input_param`"
                if [ $# -ge 2 ];then
                    shift 2
                else 
                    shift 1
                fi
            else                
                shift 2
            fi
        ;;
        -d|--delete)
            check_bakfile "$FILE_ACTION_DELETE" $2
            if [ $? -ne 0 ]; then                
                fn_log "debug" "check bakfile failed,param:`echo $input_param`"
                if [ $# -ge 2 ];then
                    shift 2
                else 
                    shift 1
                fi
            else                
                shift 2
            fi
        ;;
        -a|--add)
            check_bakfile "$FILE_ACTION_ADD" $2
            if [ $? -ne 0 ]; then                
                fn_log "debug" "check bakfile failed,param:`echo $input_param`"
                if [ $# -ge 2 ];then
                    shift 2
                else 
                    shift 1
                fi
            else                
                shift 2
            fi
        ;;
        --set_subdir)
            local tmp_subdir="`cat $CONFIGER_BAK_CONF | grep 'SUB_DIR' | awk -F'=' '{print $2}'`"
            if [ -z "$tmp_subdir" ];then
                fn_log "warn" "sub backup dir is null, use default."
                shift 1
            else
                SUB_BACKUP_DIR=$tmp_subdir
                shift 1
            fi
        ;;
        *)            
            if [ $# -ge 2 ];then
                fn_log "warn" "param is invalid,ignore params $1 $2"
                shift 2
            else 
                fn_log "warn" "param is invalid,ignore params $1"
                shift 1
            fi
        ;;
        esac
    done
      
    if [ ! -f $RTBAKFILELIST ] || [ -z "cat $RTBAKFILELIST" ]; then
        fn_log "error" "no file or no action for backup,try 'configer_backup --help' for more information."
        fn_usage
        return 1

    fi
   
    return 0
}

#########################################################
#    Description:  check ramdiskspace(tmpfs)
#    Input:  
#        $1: need free ramdisk space
#    Return: 0-success,1-failed
#########################################################
function check_ramdiskspace()
{
    local need_free_space=$1
    
    #negative number or null
    if [ -n "`echo "$need_free_space" | grep "-"`" ] || [ -z "$need_free_space" ];then
        return 0
    fi
    local ramdisk_free_size="`df -kl "${WORKDIR}" | grep "tmpfs" | awk -F ' ' '{print $4}' | sed -n 1p`"
    if [ -z "$ramdisk_free_size" ];then
        fn_log "warn" "${WORKDIR}(tmpfs) don't have enough free space!"
        return 1
    fi
    
    if [ $ramdisk_free_size -lt $need_free_space ];then
        fn_log "warn" "${WORKDIR}(tmpfs) don't have enough free space!"
        return 1
    fi
    return 0
}

#########################################################
#    Description:  check space(DATA_PARTITION)
#    Input:  
#        $1: need free  space
#    Return: 0-success,1-failed
#########################################################
function check_space()
{
    local need_free_space=$1
    local old_bakfile_size=$2
    #negative number or null
    if [ -n "`echo "$need_free_space" | grep "-"`" ] || [ -z "$need_free_space" ];then
        return 0
    fi    
    local free_size="`df -kl | grep "${SYSTEM_DISK}" | awk -F ' ' '{print $4}' | sed -n 1p`"
    if [ -z "$free_size" ];then
        fn_log "warn" "no enough space left  dev!"
        return $STORAGE_SPACE_FULL
    fi
    
    if [ $free_size -lt $need_free_space -o $free_size -lt $old_bakfile_size ];then
        fn_log "warn" "no enough space left  dev!"
        rm -rf $FILEBAK_DIR/* 
        return $STORAGE_SPACE_FULL
    fi
    return 0
}

#########################################################
#    Description:  count bakfile size
#    Input:  
#        $1: backup filelist
#    Return: 0-success,1-failed
#########################################################
function count_bakfilesize()
{
    local check_filelist=$1
    local files_size=
    local tmp_checkfilelst=/tmp/tmp_checkfilelst_$$
    cat $check_filelist  | grep -v "$FILE_ACTION_DELETE" > $tmp_checkfilelst 2> /dev/null 
    while read line
    do
        bakfile="`echo $line | awk -F ' ' '{print $2}'`"            
        if [ -f $bakfile -o -L $bakfile -o -d $bakfile ];then
            file_size="`du -sk $bakfile | awk -F ' ' '{print $1}'`"
            files_size=$(($files_size + $file_size))
        fi        
    done < $tmp_checkfilelst
    rm -rf $tmp_checkfilelst
    echo "$files_size"
    return 0
}

#########################################################
#    Description:  backup add/modify file
#    Input:  
#        $1: backup file
#    Return: 0-success,1-failed
#########################################################
function bakAddModiyFile()
{
    local bakfile_tarname=
    local ret=
    local tarBakName=
    local bakfile=$1  

    if [ ! -e "$bakfile" ];then
        fn_log "warn" "$bakfile is not exit in current system"
        return 1
    fi

    #tarname: if backfile is /tmp/tmpfile,the tarname will be %#tmp%#tmpfile
    bakfile_tarname=`echo "$bakfile" | sed 's/\/\+/\%\#/g'`
    tar -zcf ${FILEBAK_DIR}/"${bakfile_tarname}.tar.gz" $bakfile > /dev/null 2>>$RTBAK_TMPLOG
    if [ $? -ne 0 ];then
        rm -f ${FILEBAK_DIR}/${bakfile_tarname}.tar.gz > /dev/null 2>>$RTBAK_TMPLOG
        fn_log "debug" "compress $bakfile failed"
        return 1
    fi
    
    #жU̿ռǷ㹻
    need_freespace=`du -sk ${FILEBAK_DIR}/"${bakfile_tarname}.tar.gz" | awk -F ' ' '{print $1}'`
    if [ -f $STORAGE_DATA_MOUNTPOINT/${bakfile_tarname}.tar.gz ];then    
        oldbakfile_tarname_size=`du -sk ${STORAGE_DATA_MOUNTPOINT}/"${bakfile_tarname}.tar.gz" | awk -F ' ' '{print $1}'`
    else
        oldbakfile_tarname_size=0
    fi
    check_space $need_freespace $oldbakfile_tarname_size
	ret=$?
    if [ $ret -ne 0 ];then
        rm -f ${FILEBAK_DIR}/${bakfile_tarname}.tar.gz
        return $ret
    fi

    ############       ${STORAGE_DATA_MOUNTPOINT} ǰ              ############
    if [ -f "${STORAGE_DATA_MOUNTPOINT}/${bakfile_tarname}.tar.gz" ]
    then
        tarBakName="${bakfile_tarname}.databackup.tar.gz"
        cp -a "${STORAGE_DATA_MOUNTPOINT}/${bakfile_tarname}.tar.gz" "${STORAGE_DATA_MOUNTPOINT}/${tarBakName}"
        if [ $? -ne 0 ]
        then
            fn_log "error" "cp -a ${STORAGE_DATA_MOUNTPOINT}/${bakfile_tarname}.tar.gz ${STORAGE_DATA_MOUNTPOINT}/${tarBakName} is failed,${bakfile} will not be backed up"
            rm -rf "${FILEBAK_DIR}/${bakfile_tarname}.tar.gz" "${STORAGE_DATA_MOUNTPOINT}/${tarBakName}" 
            return 1
        fi
        
        sync
    fi
    
    #U
    mv ${FILEBAK_DIR}/${bakfile_tarname}.tar.gz $STORAGE_DATA_MOUNTPOINT > /dev/null 2>>$RTBAK_TMPLOG
    if [ $? -ne 0 ];then
        rm -f ${FILEBAK_DIR}/${bakfile_tarname}.tar.gz  > /dev/null 2>>$RTBAK_TMPLOG
        fn_log "debug" "move ${bakfile_tarname}.tar.gz to  dev failed"
        
        #ȷ ${tarName} ģ´αʱ ${tarBakName}
        if [ -f "${STORAGE_DATA_MOUNTPOINT}/${tarBakName}" ]
        then
            mv "${STORAGE_DATA_MOUNTPOINT}/${tarBakName}" "${STORAGE_DATA_MOUNTPOINT}/${bakfile_tarname}.tar.gz"
            if [ $? -ne 0 ]
            then
                fn_log "error" "mv ${STORAGE_DATA_MOUNTPOINT}/${tarBakName} ${STORAGE_DATA_MOUNTPOINT}/${bakfile_tarname}.tar.gz is failed"
            fi
        fi
        
        sync
      
        return 1
    fi     

    sync    
    
    rm -f ${FILEBAK_DIR}/${bakfile_tarname}.tar.gz  > /dev/null 2>>$RTBAK_TMPLOG
    if [ -n "${tarBakName}" ]
    then
        rm -rf "${STORAGE_DATA_MOUNTPOINT}/${tarBakName}"
    fi
    return 0

}

#########################################################
#    Description:  backup delete file
#    Input:  
#        $1: backup file
#    Return: 0-success,1-failed
#########################################################
function bakDeleteFile()
{
    local bakfile=$1
    local pre_bakfile=
    local pre_bakfile_tmpdir=
    local old_prebakfile_tarsize=
    local ret=
    local bak_files=()                  #pre_bakfile_tmpdirtar
    local tar_name=                     #ҪݵĿ¼ɵtar   
    local tar_bak_name=                 #tarɵļ
    local tar_bak_files_list=""         #ѱݵ tar_bak_name ¼ڴַУԱʧʱһɾ
    
    bakfile_tarname="`echo "$bakfile" | sed 's/\/\+/\%\#/g'`"
    #Ŀ¼ļ    
    rm -rf ${STORAGE_DATA_MOUNTPOINT}/${bakfile_tarname}%#*.tar.gz
    if [ $? -ne 0 ];then
        fn_log "debug" "remove ${bakfile_tarname}%#*.tar.gz(subdirectory or file) failed from  dev"
        return 1
    fi
    #ݵǰҪɾĿ¼ļ
    rm -rf ${STORAGE_DATA_MOUNTPOINT}/${bakfile_tarname}.tar.gz
    if [ $? -ne 0 ];then
        fn_log "debug" "remove ${bakfile_tarname}.tar.gz failed from  dev"
        return 1
    fi
    
    #һĿ¼
    pre_bakfile_tmpdir=${WORKDIR}/pre_bakfile_tmpdir_$$
    pre_bakfile=`dirname $bakfile`    
    old_prebakfile_tarsize=0
    mkdir -p $pre_bakfile_tmpdir
    rm -rf $pre_bakfile_tmpdir/*
    
    while [ $pre_bakfile != "/" ]
    do                            
        if [ ! -d $pre_bakfile ];then
            pre_bakfile=`dirname $pre_bakfile`
            continue
        fi
        pre_bakfile_tarname="`echo "$pre_bakfile" | sed 's/\/\+/\%\#/g'`"
        if [ -f "${STORAGE_DATA_MOUNTPOINT}/"${pre_bakfile_tarname}.tar.gz"" ];then
            tar -zcf ${pre_bakfile_tmpdir}/"${pre_bakfile_tarname}.tar.gz" $pre_bakfile  > /dev/null 2>>$RTBAK_TMPLOG
            if [ $? -ne 0 ];then
                fn_log "debug" "compress $pre_bakfile failed"
                rm -rf $pre_bakfile_tmpdir
                return 1
            fi            
            oldfilesize=`du -sk ${STORAGE_DATA_MOUNTPOINT}/"${pre_bakfile_tarname}.tar.gz" | awk -F ' ' '{print $1}'`        
            old_prebakfile_tarsize=$(($old_prebakfile_tarsize + $oldfilesize))
        fi
        pre_bakfile=`dirname $pre_bakfile`
        
    done

    if [ -n "`ls ${pre_bakfile_tmpdir}`" ];then    
        #жU̿ռǷ㹻
        need_freespace=`du -sk ${pre_bakfile_tmpdir} | awk -F ' ' '{print $1}'`
        check_space $need_freespace $old_prebakfile_tarsize
		ret=$?
        if [ $ret -ne 0 ];then	
            rm -rf $pre_bakfile_tmpdir  
            return $ret
        fi
        
        #pre_bakfile_tmpdirЩtar
        bak_files=(`ls -rt ${pre_bakfile_tmpdir}`)
        
        ############       ${STORAGE_DATA_MOUNTPOINT} ǰ              ############
        for file in "${bak_files[@]}"
        do
            tar_name="`echo ${file} | awk -F '/' '{print $NF}'`"
            if [ -f "${STORAGE_DATA_MOUNTPOINT}/${tar_name}" ]
            then
                tar_bak_name="`echo ${file} | sed "s/.tar.gz$/.databackup.tar.gz/"`"
                tar_bak_files_list="${tar_bak_files_list} ${tar_bak_name}"
                cp -a "${STORAGE_DATA_MOUNTPOINT}/${tar_name}" "${STORAGE_DATA_MOUNTPOINT}/${tar_bak_name}"
                if [ $? -ne 0 ]
                then
                    fn_log "error" "cp -a ${STORAGE_DATA_MOUNTPOINT}/${tar_name} ${STORAGE_DATA_MOUNTPOINT}/${tar_bak_name} is failed,${bakfile} will not be backed up"
                    rm -rf "${pre_bakfile_tmpdir}"
                    if [ -n "${tar_bak_files_list}" ]
                    then
                        cd ${STORAGE_DATA_MOUNTPOINT} > /dev/null 2>>$RTBAK_TMPLOG
                        rm -rf ${tar_bak_files_list}
                        cd - > /dev/null 2>>$RTBAK_TMPLOG
                    fi
                    return 1
                fi
                
                sync
            fi
        done
    
        mv ${pre_bakfile_tmpdir}/* ${STORAGE_DATA_MOUNTPOINT} > /dev/null 2>>$RTBAK_TMPLOG
        if [ $? -ne 0 ];then
            fn_log "debug" "backup parent directory to  failed"
            
            #ȷ ${tarName} ģ´αʱ ${tarBakName}
            if [ -n "${tar_bak_files_list}" ]
            then
                cd ${STORAGE_DATA_MOUNTPOINT} > /dev/null 2>>$RTBAK_TMPLOG
                rename .databackup.tar.gz .tar.gz ${tar_bak_files_list}
                if [ $? -ne 0 ]
                then
                    fn_log "error" "rename .databackup.tar.gz .tar.gz ${tar_bak_files_list} is error"
                fi
                cd - > /dev/null 2>>$RTBAK_TMPLOG
            fi
            
            sync
                               
            rm -rf $pre_bakfile_tmpdir
            return 1
        fi
        
        sync
            
    fi
    
    if [ -n "${tar_bak_files_list}" ]
    then
        cd ${STORAGE_DATA_MOUNTPOINT} > /dev/null 2>>$RTBAK_TMPLOG
        rm -rf ${tar_bak_files_list}
        cd - > /dev/null 2>>$RTBAK_TMPLOG
    fi
    rm -rf $pre_bakfile_tmpdir    
    return 0
}

#########################################################
#    Description:  backup File to Storage
#    Input:  
#        $1: backup fileList
#    Return: 0-success,1-failed
#########################################################
function bakFile2Storage()
{
    local fileList=$1
    local files_size=
    local ret=	
	
    if [ ! -f "$fileList" ] || [ -z "cat $filelist" ]; then
        fn_log "error" "no file for backup"
        return 1
    fi

    files_size="`count_bakfilesize $fileList`"

    fn_log "info" "starting backup file to  storage"    
    
    while read line
    do
        bakaction="`echo $line | awk -F ' ' '{print $1}'`"
        bakfile="`echo $line | awk -F ' ' '{print $2}'`"    
        
        if [ "$bakaction" = "$FILE_ACTION_MODIFY" ] || [ "$bakaction" = "$FILE_ACTION_ADD" ];then
            bakAddModiyFile $bakfile  
        elif [ "$bakaction" = "$FILE_ACTION_DELETE" ];then                
            bakDeleteFile $bakfile
        fi
		ret=$?
		if [ $ret -eq 0 ];then
			fn_log "info" "backup $bakfile ($bakaction) ------ [success]"
		else
			fn_log "warn" "backup $bakfile ($bakaction) ------ [failed]"
			let BAK_FAILED_NUM+=1
			if [ $ret -eq $STORAGE_SPACE_FULL ];then
				return 1
			fi
		fi   
        
    done < $fileList
   
    rm -rf $FILEBAK_DIR/*
	
	if [ $BAK_FAILED_NUM -eq 0 ];then
		return 0
	else
		return 1
	fi

}

#########################################################
#    Description:  main
#    Input:  
#    Return: 0-success,1-failed
#########################################################
function fn_main()
{
    local ret=
    
 
    fn_log "debug" ""`date`" pid:"$$", rt_backup --------------------------- starting"
    fn_log "info" "check input params"
    fn_verify_input $@
    if [ $? -ne 0 ]; then
        fn_do_clean 1
        return 1
    fi
	
	fn_log "info" "init the work environment"
	fn_init
    if [ $? -ne 0 ]; then
        fn_do_clean 1
        return 1
    fi
    
    bakFile2Storage $RTBAKFILELIST
    ret=$?
    if [ $ret -ne 0 ]; then
        fn_log "error" "rt_backup failed"
        fn_do_clean $ret
        return 1
    fi
    fn_log "info" "rt_backup end"    
    fn_do_clean $ret

    return 0
    
}

fn_main $@
exit $?
