696 lines
24 KiB
Bash
Executable File
696 lines
24 KiB
Bash
Executable File
#!/bin/sh
|
|
# $1 [$2 $3 $4] = Schedule0...ScheduleN [ user_name ip_addr host_name ]
|
|
#
|
|
#
|
|
|
|
ERROR_DESC[0]="Success."
|
|
ERROR_DESC[1]="Unexpected error."
|
|
ERROR_DESC[41]="Remote host does not exist."
|
|
ERROR_DESC[42]="Connection refused. Remote service is not enabled or the port number is incorrect."
|
|
ERROR_DESC[43]="Authentication failed. Please check the user name and password."
|
|
ERROR_DESC[44]="The destination folder path does not exist."
|
|
ERROR_DESC[45]="Connection reset by peer. Remote backup service might be restarted/stopped."
|
|
ERROR_DESC[46]="Connection timed out, please check the connectivity."
|
|
ERROR_DESC[47]="Some files have been vanished, the source files might be removed during backup."
|
|
ERROR_DESC[48]="Replication job has been terminated by user."
|
|
ERROR_DESC[49]="The source folder path does not exist."
|
|
ERROR_DESC[50]="The previous scheduled job has not been finished yet."
|
|
|
|
# Check if a string contains the specified prefix
|
|
# Is_Prefix_Matched string prefix
|
|
Is_Prefix_Matched()
|
|
{
|
|
cbPrefix=`/usr/bin/expr length "$2"`
|
|
SubStr=`/usr/bin/expr substr "$1" 1 $cbPrefix`
|
|
if [ "$SubStr" == "$2" ]; then
|
|
echo "1"
|
|
else
|
|
echo "0"
|
|
fi
|
|
}
|
|
|
|
# Check if a string contains the specified postfix
|
|
# Is_Prefix_Matched string postfix
|
|
Is_Postfix_Matched()
|
|
{
|
|
cbString=`/usr/bin/expr length "$1"`
|
|
cbPostfix=`/usr/bin/expr length "$2"`
|
|
nbPos=`/usr/bin/expr $cbString - $cbPostfix + 1`
|
|
SubStr=`/usr/bin/expr substr "$1" $nbPos $cbPostfix`
|
|
if [ "$SubStr" == "$2" ]; then
|
|
echo "1"
|
|
else
|
|
nbPos=`/usr/bin/expr $cbString - $cbPostfix`
|
|
SubStr=`/usr/bin/expr substr "$1" $nbPos $cbPostfix`
|
|
if [ "$SubStr" == "$2" ]; then
|
|
echo "1"
|
|
else
|
|
echo "0"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# Check the rsync error by comparing the key words
|
|
# Is_Error_Pattern_Matched string prefix postfix
|
|
Is_Error_Pattern_Matched()
|
|
{
|
|
if [ "1" == $(Is_Prefix_Matched "$1" "$2") ] && [ "1" == $(Is_Postfix_Matched "$1" "$3") ]; then
|
|
echo "1"
|
|
else
|
|
echo "0"
|
|
fi
|
|
}
|
|
|
|
# Is_Contain_Substring() string substr
|
|
Is_Contain_Substring()
|
|
{
|
|
[ ${#2} -eq 0 ] && { echo "0"; return; }
|
|
case "$1" in
|
|
*$2*) echo "1";;
|
|
*) echo "0";;
|
|
esac
|
|
}
|
|
|
|
# Filter_Log_Msg() msg_from msg_to
|
|
Filter_Log_Msg()
|
|
{
|
|
/bin/rm -f "$2" 1>/dev/null 2>/dev/null
|
|
/bin/touch "$2" 1>/dev/null 2>/dev/null
|
|
if [ -s "$1" ]; then
|
|
while read szLine
|
|
do
|
|
if [ "1" == $( Is_Contain_Substring "$szLine" "Warning: Permanently added" ) ]; then
|
|
continue
|
|
elif [ "1" == $( Is_Error_Pattern_Matched "$szLine" "rsync: mkstemp " " Invalid argument (22)" ) ]; then
|
|
continue
|
|
elif [ "1" == $( Is_Error_Pattern_Matched "$szLine" "rsync: recv_generator: mkdir " " Invalid argument (22)" ) ]; then
|
|
continue
|
|
elif [ "1" == $( Is_Contain_Substring "$szLine" "*** Skipping any contents from this failed directory ***" ) ]; then
|
|
continue
|
|
elif [ "1" == $( Is_Error_Pattern_Matched "$szLine" "Could not create directory" "admin/.ssh'." ) ]; then
|
|
continue
|
|
elif [ "1" == $( Is_Error_Pattern_Matched "$szLine" "Failed to add the host to the list of known hosts" ".ssh/known_hosts)." ) ]; then
|
|
continue
|
|
|
|
fi
|
|
/bin/echo "$szLine" >> "$2"
|
|
done < "$1"
|
|
fi
|
|
}
|
|
|
|
# SetStatus() "Schedule${i}" 2
|
|
SetStatus()
|
|
{
|
|
local iCnt=0
|
|
while [ $iCnt -le 5 ]
|
|
do
|
|
iCnt=$(($iCnt+1))
|
|
/sbin/setcfg "${1}" "Status" "${2}" -f "${RR_CONF}"
|
|
if [ $? = 0 ]; then
|
|
break
|
|
else
|
|
/bin/sleep 1
|
|
fi
|
|
done
|
|
}
|
|
|
|
# Get a message line from the error log file.
|
|
Get_First_Error_Msg()
|
|
{
|
|
SZLINE=""
|
|
while read szLine
|
|
do
|
|
if [ "1" == $( Is_Error_Pattern_Matched "$szLine" "rsync: mkstemp " " Invalid argument (22)" ) ]; then
|
|
continue
|
|
fi
|
|
|
|
if [ "1" == $( Is_Contain_Substring "$szLine" "Warning: " ) ]; then
|
|
continue
|
|
fi
|
|
|
|
if [ "1" == $( Is_Contain_Substring "$szLine" "Operation not permitted (1)" ) ]; then
|
|
continue
|
|
fi
|
|
|
|
if [ "1" == $( Is_Contain_Substring "$szLine" "some files/attrs were not transferred" ) ]; then
|
|
continue
|
|
fi
|
|
|
|
if [ "1" == $( Is_Error_Pattern_Matched "$szLine" "rsync: recv_generator: mkdir " " Invalid argument (22)" ) ]; then
|
|
continue
|
|
fi
|
|
|
|
if [ "1" == $( Is_Contain_Substring "$szLine" "*** Skipping any contents from this failed directory ***" ) ]; then
|
|
continue
|
|
fi
|
|
|
|
SZLINE="$szLine"
|
|
break
|
|
done < "$1"
|
|
}
|
|
|
|
# Check the rsync error code by parsing the rsync error log file. Will set error code to $iError.
|
|
# Parse_Error_Log_File rsync_error_log_file
|
|
Parse_Error_Log_File()
|
|
{
|
|
SZLINE=""
|
|
Get_First_Error_Msg "$1"
|
|
|
|
if [ "x" == "x$SZLINE" ]; then
|
|
iError=0
|
|
echo ""
|
|
elif [ "1" == $( Is_Error_Pattern_Matched "$SZLINE" "rsync: failed to connect to " " No route to host (113)" ) ]; then
|
|
iError=41
|
|
echo ERROR_NO_ROUTE_TO_HOST
|
|
elif [ "1" == $( Is_Error_Pattern_Matched "$SZLINE" "rsync: failed to connect to " " Invalid argument (22)" ) ]; then
|
|
iError=41
|
|
echo ERROR_NO_ROUTE_TO_HOST
|
|
elif [ "1" == $( Is_Error_Pattern_Matched "$SZLINE" "ssh: connect to host " ": No route to host" ) ]; then
|
|
iError=41
|
|
echo ERROR_NO_ROUTE_TO_HOST
|
|
elif [ "1" == $( Is_Error_Pattern_Matched "$SZLINE" "rsync: failed to connect to " " Connection refused (111)" ) ]; then
|
|
iError=42
|
|
echo ERROR_NO_REMOTE_SERVICE
|
|
elif [ "1" == $( Is_Error_Pattern_Matched "$SZLINE" "ssh: connect to host " ": Connection refused" ) ]; then
|
|
iError=42
|
|
echo ERROR_NO_REMOTE_SERVICE
|
|
elif [ "1" == $(Is_Prefix_Matched "$SZLINE" "@ERROR: auth failed on module") ]; then
|
|
iError=43
|
|
echo ERROR_AUTH_FAILED
|
|
elif [ "1" == $(Is_Prefix_Matched "$SZLINE" "@ERROR: Unknown module") ]; then
|
|
iError=44
|
|
echo ERROR_PATH_NOT_FOUND
|
|
elif [ "1" == $(Is_Prefix_Matched "$SZLINE" "@ERROR: chroot failed") ]; then
|
|
iError=44
|
|
echo ERROR_PATH_NOT_FOUND
|
|
elif [ "1" == $( Is_Error_Pattern_Matched "$SZLINE" "rsync: " " Input/output error (5)" ) ]; then
|
|
iError=44
|
|
echo ERROR_PATH_NOT_FOUND
|
|
elif [ "1" == $( Is_Error_Pattern_Matched "$SZLINE" "rsync: " " No such file or directory (2)" ) ]; then
|
|
iError=44
|
|
echo ERROR_PATH_NOT_FOUND
|
|
elif [ "1" == $( Is_Error_Pattern_Matched "$SZLINE" "rsync: " " Connection reset by peer (104)" ) ]; then
|
|
iError=45
|
|
echo ERROR_CONN_RESET
|
|
elif [ "1" == $( Is_Error_Pattern_Matched "$SZLINE" "io timeout after " " exiting" ) ]; then
|
|
iError=46
|
|
echo ERROR_CONN_TIMEOUT
|
|
elif [ "1" == $(Is_Prefix_Matched "$SZLINE" "file has vanished: ") ]; then
|
|
iError=47
|
|
echo ERROR_FILE_NOT_EXISTED
|
|
elif [ "1" == $(Is_Prefix_Matched "$SZLINE" "rsync: cancelled by user") ]; then
|
|
iError=48
|
|
echo ERROR_OPER_CANCELLED
|
|
elif [ "1" == $(Is_Prefix_Matched "$SZLINE" "rsync error: received SIGINT, SIGTERM, or SIGHUP") ]; then
|
|
iError=48
|
|
echo ERROR_OPER_CANCELLED
|
|
elif [ "1" == $(Is_Prefix_Matched "$SZLINE" "ERROR: ${ERROR_DESC[49]}") ]; then
|
|
iError=49
|
|
echo ERROR_SOURCE_PATH_NOT_FOUND
|
|
else
|
|
iError=1
|
|
ERROR_DESC[1]="$SZLINE"
|
|
echo ERROR_UNEXPECTED
|
|
fi
|
|
}
|
|
|
|
stop_network()
|
|
{
|
|
/etc/init.d/smb.sh stop &
|
|
/etc/init.d/atalk.sh stop &
|
|
/etc/init.d/ftp.sh stop &
|
|
}
|
|
|
|
start_network()
|
|
{
|
|
# kenttest=0
|
|
|
|
/etc/init.d/smb.sh start &
|
|
/etc/init.d/atalk.sh start &
|
|
/etc/init.d/ftp.sh start &
|
|
}
|
|
|
|
# Update the finished status, time, error code and log after remote backup finished.
|
|
# Update_Status $schedule $szUser $szAddr $szHost $szRetry
|
|
Update_Status()
|
|
{
|
|
if [ "80" == "$RR_result" ]; then
|
|
iError=50
|
|
echo "ERROR_JOB_ALREADY_RUNNING"
|
|
else
|
|
Parse_Error_Log_File "$SZF_ERROR"
|
|
fi
|
|
szName=`/sbin/getcfg "$1" "Name" -f "${RR_CONF}" -d ""`
|
|
/sbin/setcfg "$1" "ErrorCode" "$iError" -f "${RR_CONF}"
|
|
szFinishedTime=`/bin/date +%s`
|
|
/sbin/setcfg "$1" "Finished Time" "$szFinishedTime" -f "${RR_CONF}"
|
|
if [ "0" == "$iError" ]; then
|
|
# /sbin/setcfg "$1" "Status" "2" -f "${RR_CONF}"
|
|
SetStatus "$1" "2"
|
|
/sbin/log_tool -t 0 -u "$2" -p "$3" -m "$4" -a "[Remote Replication] $szName finished."
|
|
elif [ "48" == "$iError" ]; then
|
|
# /sbin/setcfg "$1" "Status" "2" -f "${RR_CONF}"
|
|
SetStatus "$1" "2"
|
|
/sbin/log_tool -t 0 -u "$2" -p "$3" -m "$4" -a "[Remote Replication] $szName stopped."
|
|
elif [ "50" == "$iError" ]; then
|
|
# /sbin/setcfg "$1" "Status" "2" -f "${RR_CONF}"
|
|
SetStatus "$1" "2"
|
|
/sbin/log_tool -t 0 -u "$2" -p "$3" -m "$4" -a "[Remote Replication] $szName has been cancelled, because the previous scheduled job has not been finished yet."
|
|
elif [ "43" == "$iError" ] || [ "44" == "$iError" ] || [ "49" == "$iError" ]; then
|
|
# /sbin/setcfg "$1" "Status" "7" -f "${RR_CONF}"
|
|
SetStatus "$1" "7"
|
|
/sbin/log_tool -t 2 -u "$2" -p "$3" -m "$4" -a "[Remote Replication] $szName failed: ${ERROR_DESC[$iError]}"
|
|
else
|
|
# /sbin/setcfg "$1" "Status" "7" -f "${RR_CONF}"
|
|
SetStatus "$1" "7"
|
|
/sbin/log_tool -t 2 -u "$2" -p "$3" -m "$4" -a "[Remote Replication] $szName failed: ${ERROR_DESC[$iError]}.$5"
|
|
fi
|
|
}
|
|
|
|
Replace_Date()
|
|
{
|
|
SZ_RETURN="$1"
|
|
SZ_RETURN=${SZ_RETURN//\$YEAR/`/bin/date +%Y`}
|
|
SZ_RETURN=${SZ_RETURN//\$MONTH/`/bin/date +%m`}
|
|
SZ_RETURN=${SZ_RETURN//\$DAY/`/bin/date +%d`}
|
|
SZ_RETURN=${SZ_RETURN//\$HOUR/`/bin/date +%H`}
|
|
SZ_RETURN=${SZ_RETURN//\$MINUTE/`/bin/date +%M`}
|
|
echo $SZ_RETURN
|
|
}
|
|
|
|
check_rsync_error()
|
|
{
|
|
local ret=0
|
|
out_msg=`cut -d ' ' -f 2 ${SZF_OUTPUT}`
|
|
out_msg2=`/usr/bin/expr substr "$out_msg" 1 5`
|
|
if [ $out_msg2 = "auth" ]; then
|
|
ret=1
|
|
fi
|
|
if [ $out_msg2 = "Unknown" ]; then
|
|
ret=2
|
|
fi
|
|
return $ret
|
|
}
|
|
|
|
modify_known_hosts()
|
|
{
|
|
/bin/ps | /bin/grep ${Remote_IP} > "/tmp/rsync-tmp"
|
|
/bin/grep /usr/bin/ssh "/tmp/rsync-tmp" >> /dev/null
|
|
if [ $? != 0 ]; then
|
|
/usr/bin/ssh-keygen -R ${Remote_IP}
|
|
fi
|
|
}
|
|
|
|
write_err_log() {
|
|
case "x$1" in
|
|
"x5")
|
|
check_rsync_error ${SZF_OUTPUT}
|
|
if [ $? = 1 ]; then
|
|
msg="[Remote Replication] Remote backup schedule $2 failed. (Authentication failure)"
|
|
else
|
|
msg="[Remote Replication] Remote backup schedule $2 failed. (Error starting client-server protocol, maybe the destination path is nonexistent.)"
|
|
fi
|
|
;;
|
|
"x10")
|
|
msg="[Remote Replication] Remote backup schedule $2 failed. (Error in socket IO, maybe the network connection is disconnect.)"
|
|
;;
|
|
"x11")
|
|
msg="[Remote Replication] Remote backup schedule $2 failed. (Error in file IO)"
|
|
;;
|
|
"x12")
|
|
if [ "x${RR_opt_SSH}" = "xTRUE" ]; then
|
|
msg="[Remote Replication] Remote backup schedule $2 failed. (Error in SSH , maybe SSH of the server is disconnect.)"
|
|
else
|
|
msg="[Remote Replication] Remote backup schedule $2 failed. (Error in rsync protocol data stream, maybe the capacity of destination is full.)"
|
|
fi
|
|
;;
|
|
"x23")
|
|
msg="[Remote Replication] Remote backup schedule $2 failed. (Some files could not be transfered, maybe the source path is incorrect.)"
|
|
;;
|
|
*)
|
|
msg="[Remote Replication] Remote backup schedule $2 failed. (Other error with error code $1)"
|
|
esac
|
|
|
|
/sbin/write_log "$msg" 1
|
|
}
|
|
|
|
|
|
report_error()
|
|
{
|
|
if [ "${LOG_FILE_NAME}+log" = "log" ]; then
|
|
echo "Please provide log file name"
|
|
else # no log file name specified
|
|
qnap_rsync_log="${LOG_FILE_NAME}"
|
|
|
|
while read LINE
|
|
do
|
|
if [ "`/bin/echo $LINE | /usr/bin/cut -c1-1`" = "[" ]; then
|
|
/sbin/write_log "[Remote Replication] Failed to copy $LINE" 1
|
|
[ "$DEBUG" = "yes" ] && echo "Error : $LINE"
|
|
else # the final result
|
|
RESULT_STRING=$LINE
|
|
fi
|
|
done < $qnap_rsync_log
|
|
fi
|
|
|
|
case "x${RR_result}" in
|
|
"x0")
|
|
echo "RR [${RR_name}] succeed..."
|
|
RR_Num=`/sbin/getcfg "global" "Schedule Number" -f "${RR_CONF}" -d "0"`
|
|
i=0
|
|
while [ ${i} -lt ${RR_Num} ]
|
|
do
|
|
RR_name2=`/sbin/getcfg "Schedule${i}" Name -f "${RR_CONF}" -d ""`
|
|
if [ "x${RR_name}" = "x${RR_name2}" ]; then
|
|
# /sbin/setcfg "Schedule${i}" Status 2 -f "${RR_CONF}"
|
|
SetStatus "Schedule${i}" "2"
|
|
RR_finished_time_s=`/bin/date +%s`
|
|
/sbin/setcfg "Schedule${i}" "Finished Time" ${RR_finished_time_s} -f "${RR_CONF}"
|
|
break
|
|
fi
|
|
i=`/usr/bin/expr ${i} + 1`
|
|
done
|
|
/sbin/write_log "[Remote Replication] Remote backup schedule ${RR_name} finished successfully." 4
|
|
;;
|
|
# Remove file level backup Paul chen
|
|
# "x10"|"x13")
|
|
# echo "rsync failed, trying ${RR_name} with old RR method..."
|
|
# /sbin/write_log "[Remote Replication] Remote NAS doesn't support block level replication, trying file level replication." 4
|
|
# #/sbin/backup2nas -j "${RR_name}" & Ricky remarked 2005/3/16 this script has run at backupground!
|
|
# /sbin/backup2nas -j "${RR_name}"
|
|
# RR_Num=`/sbin/getcfg "global" "Schedule Number" -f "${RR_CONF}" -d "0"`
|
|
# i=0
|
|
# while [ ${i} -lt ${RR_Num} ]
|
|
# do
|
|
# RR_name2=`/sbin/getcfg "Schedule${i}" Name -f "${RR_CONF}" -d ""`
|
|
# if [ "x${RR_name}" = "x${RR_name2}" ]; then
|
|
# /sbin/setcfg "Schedule${i}" Status 2 -f "${RR_CONF}"
|
|
# RR_finished_time_s=`/bin/date +%s`
|
|
# /sbin/setcfg "Schedule${i}" "Finished Time" ${RR_finished_time_s} -f "${RR_CONF}"
|
|
# break
|
|
# fi
|
|
# i=`/usr/bin/expr ${i} + 1`
|
|
# done
|
|
# ;;
|
|
# Paul Chen ends
|
|
*)
|
|
echo "RR [${RR_name}] failed... Error Code=${RR_result}"
|
|
RR_Num=`/sbin/getcfg "global" "Schedule Number" -f "${RR_CONF}" -d "0"`
|
|
i=0
|
|
while [ ${i} -lt ${RR_Num} ]
|
|
do
|
|
RR_name2=`/sbin/getcfg "Schedule${i}" Name -f "${RR_CONF}" -d ""`
|
|
if [ "x${RR_name}" = "x${RR_name2}" ]; then
|
|
# /sbin/setcfg "Schedule${i}" Status 7 -f "${RR_CONF}"
|
|
SetStatus "Schedule${i}" "7"
|
|
RR_finished_time_s=`/bin/date +%s`
|
|
/sbin/setcfg "Schedule${i}" "Finished Time" ${RR_finished_time_s} -f "${RR_CONF}"
|
|
break
|
|
fi
|
|
i=`/usr/bin/expr ${i} + 1`
|
|
done
|
|
write_err_log $RR_result "$RR_name"
|
|
esac
|
|
}
|
|
|
|
|
|
function signal_handler()
|
|
{
|
|
bAbort="1"
|
|
iProcPid=`/sbin/getcfg "$1" "PID" -f "${RR_CONF}" -d "0"`
|
|
if [ "$iProcPid" -gt 0 ]; then
|
|
/bin/kill -9 "$iProcPid"
|
|
fi
|
|
}
|
|
|
|
|
|
# Setup conf file pathes.
|
|
SMB_CONF="/etc/smb.conf"
|
|
RR_CONF="/etc/config/rsync_schedule.conf"
|
|
|
|
# Exit if there is no schedule specified.
|
|
RR_sche=${1}
|
|
[ "x${RR_sche}" = "x" ] && exit -1
|
|
|
|
# Exit if I am not the first instance launched.
|
|
iPid="$$"
|
|
iPrevPid=`/sbin/getcfg "$RR_sche" "ScriptPID" -f "${RR_CONF}" -d "0"`
|
|
if [ "$iPrevPid" -gt 0 ]; then
|
|
/bin/kill -0 "$iPrevPid" 2> /dev/null
|
|
if [ "$?" -eq "0" ]; then
|
|
szName=`/sbin/getcfg "$1" "Name" -f "${RR_CONF}" -d ""`
|
|
/sbin/log_tool -t 0 -u "$2" -p "$3" -m "$4" -a "[Remote Replication] $szName started."
|
|
/sbin/log_tool -t 0 -u "$2" -p "$3" -m "$4" -a "[Remote Replication] $szName has been cancelled, because the previous scheduled job has not been finished yet."
|
|
exit -1
|
|
fi
|
|
fi
|
|
/sbin/setcfg "$RR_sche" "ScriptPID" "$iPid" -f "${RR_CONF}"
|
|
/sbin/setcfg "$RR_sche" "ErrorCode" "0" -f "${RR_CONF}"
|
|
|
|
bAbort=0
|
|
trap 'signal_handler' 2
|
|
trap 'signal_handler' 15
|
|
|
|
# 20090925: keep stdout and stderr to logs files
|
|
SZD_LOGS="/etc/logs/rsync"
|
|
SZF_OUTPUT="$SZD_LOGS/rsync-out-$1"
|
|
SZF_ERROR="$SZD_LOGS/rsync-err-$1"
|
|
SZF_ERROR_TMP="$SZD_LOGS/rsync-tmp-$1"
|
|
|
|
/bin/mkdir $SZD_LOGS 1>/dev/null 2>/dev/null
|
|
/bin/rm -f $SZF_ERROR 1>/dev/null 2>/dev/null
|
|
/bin/touch $SZF_ERROR 1>/dev/null 2>/dev/null
|
|
|
|
DEBUG=no
|
|
|
|
# setup user name, ip addres and host name from parameters
|
|
szUser="System"
|
|
szAddr="127.0.0.1"
|
|
szHost="localhost"
|
|
if [ 4 -le $# ]; then
|
|
szUser="$2"
|
|
szAddr="$3"
|
|
szHost="$4"
|
|
fi
|
|
|
|
RR_name=`/sbin/getcfg "${RR_sche}" Name -f "${RR_CONF}" -d ""`
|
|
#[ "x${RR_name}" = "x" ] && exit -1
|
|
Remote_IP=`/sbin/getcfg "${RR_sche}" "Remote IP" -f ${RR_CONF} -d "0.0.0.0"`
|
|
#[ "x${Remote_IP}" = "x0.0.0.0" ] && exit -1
|
|
Remote_IP=`/sbin/get_domain_ip ${Remote_IP}`
|
|
|
|
Local_vol=`/sbin/getcfg "${RR_sche}" "Local Volume" -f ${RR_CONF} -d ""`
|
|
Local_path=`/sbin/getcfg "${RR_sche}" "Local Path" -f ${RR_CONF} -d ""`
|
|
SMB_path=`/sbin/getcfg "${Local_vol}" "path" -f ${SMB_CONF} -d ""`
|
|
RR_PORT=`/sbin/getcfg "${RR_sche}" "Rsync Port" -f ${RR_CONF} -d "873"`
|
|
|
|
if [ "x${Local_path}" = "x/" ]
|
|
then
|
|
RR_local_path="${SMB_path}"
|
|
else
|
|
RR_local_path="${SMB_path}${Local_path}"
|
|
fi
|
|
|
|
Remote_vol=`/sbin/getcfg "${RR_sche}" "Remote Volume" -f ${RR_CONF} -d ""`
|
|
Remote_path=`/sbin/getcfg "${RR_sche}" "Remote Path" -f ${RR_CONF} -d ""`
|
|
Remote_path=$(Replace_Date "$Remote_path")
|
|
if [ "x${Remote_path}" = "x/" ]
|
|
then
|
|
RR_remote_path="${Remote_vol}"
|
|
else
|
|
RR_remote_path="${Remote_vol}${Remote_path}"
|
|
fi
|
|
|
|
# Verify User/Pwd through samba / added by KenChen 20060418
|
|
UserName=`/sbin/getcfg "${RR_sche}" "User Name" -f ${RR_CONF} -d ""`
|
|
Passwd=`/sbin/getcfg "${RR_sche}" "Password" -f ${RR_CONF} -d ""`
|
|
# RichardChang 20070917 disable for check user by rsync
|
|
#RemotePath=`/sbin/getcfg "${RR_sche}" "Remote Path" -f ${RR_CONF} -d ""`
|
|
#smbtmp=`/bin/mktemp -d '/tmp/temp.XXXXXX'`
|
|
#/bin/mount -t cifs "//${Remote_IP}/${Remote_vol}" "${smbtmp}" -o lfs,username="${UserName}",password="${Passwd}",iocharset=utf8
|
|
#if [ $? = 0 ]; then
|
|
# #/bin/ls "${smbtmp}${RemotePath}"
|
|
# #if [ $? = 0 ]; then
|
|
# if [ -d "${smbtmp}${RemotePath}" ]; then
|
|
# /bin/umount "${smbtmp}"
|
|
# if [ $? = 0 ]; then
|
|
# /bin/rm "${smbtmp}" -rf
|
|
# fi
|
|
# else
|
|
# /sbin/write_log "[Remote Replication] Remote backup schedule "$RR_name" failed. (Remote destination path does not exist.)" 1
|
|
# /bin/umount "${smbtmp}"
|
|
# if [ $? = 0 ]; then
|
|
# /bin/rm "${smbtmp}" -rf
|
|
# fi
|
|
# exit -1
|
|
# fi
|
|
#else
|
|
# /sbin/write_log "[Remote Replication] Remote backup schedule "$RR_name" failed. (Authentication failure)" 1
|
|
# /bin/rm "${smbtmp}" -rf
|
|
# exit -1
|
|
#fi
|
|
# End here
|
|
|
|
RR_opt_sparse=`/sbin/getcfg "${RR_sche}" "Sparse" -f ${RR_CONF} -d "FALSE" -u`
|
|
[ "x${RR_opt_sparse}" = "xTRUE" ] && RR_options=${RR_options}"--sparse "
|
|
RR_opt_compress=`/sbin/getcfg "${RR_sche}" "Compressed" -f ${RR_CONF} -d "FALSE" -u`
|
|
[ "x${RR_opt_compress}" = "xTRUE" ] && RR_options=${RR_options}"--compress "
|
|
RR_opt_sync=`/sbin/getcfg "${RR_sche}" "Delete Extra" -f "${RR_CONF}" -d "FALSE" -u`
|
|
[ "x${RR_opt_sync}" = "xTRUE" ] && RR_options=${RR_options}"--delete "
|
|
RR_opt_inc=`/sbin/getcfg ${RR_sche} "Incremental" -f ${RR_CONF} -d "FALSE" -u`
|
|
[ "x${RR_opt_inc}" = "xFALSE" ] && RR_options=${RR_options}"--whole-file -I "
|
|
RR_opt_KBPS=`/sbin/getcfg ${RR_sche} "Bandwith KBPS" -f ${RR_CONF} -d "0" -u`
|
|
RR_opt_KBPS=`/bin/echo "${RR_opt_KBPS}" | /bin/sed -e 's/[^0-9]//g'`
|
|
RR_opt_KBPS=$((${RR_opt_KBPS} + 0))
|
|
[ "x${RR_opt_KBPS}" != "x0" ] && RR_options=${RR_options}"--bwlimit=${RR_opt_KBPS} "
|
|
RR_opt_stopnet=`/sbin/getcfg ${RR_sche} "Stop Net" -f ${RR_CONF} -d "FALSE" -u`
|
|
|
|
#Richard add 20070608 for rsync of ssh
|
|
RR_opt_SSH=`/sbin/getcfg "${RR_sche}" "Use of SSH" -f ${RR_CONF} -d "FALSE" -u`
|
|
RR_SSH_PORT=`/sbin/getcfg "${RR_sche}" "SSH PORT" -f ${RR_CONF} -d "22"`
|
|
RR_com_ssh="/usr/bin/ssh -o StrictHostKeyChecking=no -l ${UserName} -j ${Passwd} -p ${RR_SSH_PORT}"
|
|
|
|
#Richard add 20080409 for rsync mode
|
|
RR_MODE=`/sbin/getcfg "${RR_sche}" "RSYNC MODE" -f ${RR_CONF} -d "1" -u`
|
|
|
|
[ "x${RR_opt_stopnet}" = "xTRUE" ] && stop_network
|
|
|
|
# set status to "Replicating"
|
|
szName=`/sbin/getcfg "$1" "Name" -f "${RR_CONF}" -d ""`
|
|
if [ "$szUser" != "System" ]; then
|
|
/sbin/log_tool -t 0 -u "$2" -p "$3" -m "$4" -a "[Remote Replication] $szName started."
|
|
else
|
|
/sbin/log_tool -t 0 -u "$2" -p "$3" -m "$4" -a "[Remote Replication] $szName started."
|
|
fi
|
|
|
|
if [ "x${SMB_path}" = "x" ]; then
|
|
#write_err_log 23 "$RR_name"
|
|
echo "ERROR: ${ERROR_DESC[49]}" > "$SZF_ERROR"
|
|
Update_Status $1 $szUser $szAddr $szHost
|
|
/sbin/setcfg "$RR_sche" "ScriptPID" "0" -f "${RR_CONF}"
|
|
exit -1
|
|
fi
|
|
|
|
#/sbin/setcfg "${RR_sche}" Status 9 -f ${RR_CONF}
|
|
SetStatus "${RR_sche}" "9"
|
|
|
|
LOG_FILE_NAME="/tmp/${RR_name}_`/bin/date +'%Y%m%d%H%M'`.log"
|
|
touch "${LOG_FILE_NAME}"
|
|
|
|
# 2010/01/20 Add retry / timeout options.
|
|
iRetry=0
|
|
xsTimeout=`/sbin/getcfg "Global" "Timeout" -f "${RR_CONF}" -d "600"`
|
|
xnRetry=`/sbin/getcfg "Global" "Retry Times" -f "${RR_CONF}" -d "3"`
|
|
xsInterval=`/sbin/getcfg "Global" "Retry Intervals" -f "${RR_CONF}" -d "60"`
|
|
|
|
if [ "x${RR_opt_KBPS}" = "x0" ]; then
|
|
RR_options=${RR_options}"--qnap-bwlimit "
|
|
if [ "x${RR_opt_SSH}" = "xTRUE" ]; then
|
|
/usr/bin/rsync --sever-mode=1 --dry-run -e "${RR_com_ssh}" --qnap-ssh-bwlimit --timeout=${xsTimeout} --password="${Passwd}" "${UserName}"@[${Remote_IP}]::
|
|
if [ "x$?" = "x0" ]; then
|
|
RR_options=${RR_options}"--qnap-ssh-bwlimit "
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
while [ $iRetry -le "$xnRetry" ]
|
|
do
|
|
# Increment $iRetry
|
|
iRetry=$(($iRetry+1))
|
|
|
|
Remote_IP=`/sbin/getcfg "${RR_sche}" "Remote IP" -f ${RR_CONF} -d "0.0.0.0"`
|
|
Remote_IP=`/sbin/get_domain_ip ${Remote_IP}`
|
|
|
|
if [ "$bAbort" -eq "0" ]; then
|
|
if [ "$DEBUG" = "yes" ]; then
|
|
echo "Debuging mode"
|
|
# /usr/bin/rsync -a ${RR_options} --timeout=0 --port=873 --qnap_log_file="${LOG_FILE_NAME}" "${RR_local_path}/" ${Remote_IP}::"${RR_remote_path}" -v -v -v
|
|
# /usr/bin/rsync -a ${RR_options} --timeout=0 --port=873 "${RR_local_path}/" ${Remote_IP}::"${RR_remote_path}" -v -v -v
|
|
# /usr/bin/rsync -a ${RR_options} --password="${Passwd}" --timeout=0 --port=873 "${RR_local_path}" "${UserName}"@${Remote_IP}::"${RR_remote_path}" -v -v -v
|
|
if [ "x${RR_opt_SSH}" = "xTRUE" ]; then
|
|
modify_known_hosts
|
|
LC_ALL=en_US.UTF-8 /usr/bin/rsync -H -a --sever-mode=${RR_MODE} -e "${RR_com_ssh}" ${RR_options} --exclude=':2eDS_Store' --exclude='.AppleDB/' --exclude='.AppleDesktop/' --exclude='.AppleDouble/' --schedule="$1" --password="${Passwd}" --timeout=${xsTimeout} "${RR_local_path}/" "${UserName}"@[${Remote_IP}]::"${RR_remote_path}" -v -v -v 1>${SZF_OUTPUT} 2>"$SZF_ERROR_TMP"
|
|
else
|
|
LC_ALL=en_US.UTF-8 /usr/bin/rsync -H -a --sever-mode=${RR_MODE} ${RR_options} --exclude=':2eDS_Store' --exclude='.AppleDB/' --exclude='.AppleDesktop/' --exclude='.AppleDouble/' --schedule="$1" --password="${Passwd}" --timeout=${xsTimeout} --port=${RR_PORT} "${RR_local_path}/" "${UserName}"@[${Remote_IP}]::"${RR_remote_path}" -v -v -v 1>${SZF_OUTPUT} 2>"$SZF_ERROR_TMP"
|
|
fi
|
|
else
|
|
echo "Normal mode"
|
|
# /usr/bin/rsync -a ${RR_options} --timeout=0 --port=873 --qnap_log_file="${LOG_FILE_NAME}" "${RR_local_path}/" ${Remote_IP}::"${RR_remote_path}"
|
|
# /usr/bin/rsync -a ${RR_options} --timeout=0 --port=873 "${RR_local_path}/" ${Remote_IP}::"${RR_remote_path}"
|
|
# /usr/bin/rsync -a ${RR_options} --password="${Passwd}" --timeout=0 --port=873 "${RR_local_path}" "${UserName}"@${Remote_IP}::"${RR_remote_path}"
|
|
if [ "x${RR_opt_SSH}" = "xTRUE" ]; then
|
|
modify_known_hosts
|
|
LC_ALL=en_US.UTF-8 /usr/bin/rsync -H -a --sever-mode=${RR_MODE} -e "${RR_com_ssh}" ${RR_options} --exclude=':2eDS_Store' --exclude='.AppleDB/' --exclude='.AppleDesktop/' --exclude='.AppleDouble/' --schedule="$1" --password="${Passwd}" --timeout=${xsTimeout} "${RR_local_path}/" "${UserName}"@[${Remote_IP}]::"${RR_remote_path}" 1>${SZF_OUTPUT} 2>"$SZF_ERROR_TMP"
|
|
else
|
|
LC_ALL=en_US.UTF-8 /usr/bin/rsync -H -a --sever-mode=${RR_MODE} ${RR_options} --exclude=':2eDS_Store' --exclude='.AppleDB/' --exclude='.AppleDesktop/' --exclude='.AppleDouble/' --schedule="$1" --password="${Passwd}" --timeout=${xsTimeout} --port=${RR_PORT} "${RR_local_path}/" "${UserName}"@[${Remote_IP}]::"${RR_remote_path}" 1>${SZF_OUTPUT} 2>"$SZF_ERROR_TMP"
|
|
fi
|
|
fi
|
|
|
|
# report errors to log
|
|
RR_result=$?
|
|
/sbin/setcfg "$RR_sche" "PID" "0" -f "${RR_CONF}"
|
|
Filter_Log_Msg "$SZF_ERROR_TMP" "$SZF_ERROR"
|
|
else
|
|
RR_result="137"
|
|
fi
|
|
|
|
/bin/rm -f $SZF_ERROR_TMP
|
|
|
|
# rsync is stopped by kill
|
|
if [ "137" == "$RR_result" ]; then
|
|
echo "rsync: cancelled by user" > "$SZF_ERROR"
|
|
fi
|
|
|
|
[ "$DEBUG" = "yes" ] && echo "log file = ${LOG_FILE_NAME}"
|
|
|
|
if [ "$iRetry" -gt "$xnRetry" ]; then
|
|
szRetry=""
|
|
elif [ "$iRetry" -eq 1 ]; then
|
|
szRetry=" Begin 1st retry."
|
|
elif [ "$iRetry" -eq 2 ]; then
|
|
szRetry=" Begin 2nd retry."
|
|
elif [ "$iRetry" -eq 3 ]; then
|
|
szRetry=" Begin 3rd retry."
|
|
else
|
|
szRetry=" Begin ${iRetry}th retry."
|
|
fi
|
|
|
|
#report_error
|
|
Update_Status "$1" "$szUser" "$szAddr" "$szHost" "$szRetry"
|
|
|
|
[ -f "${LOG_FILE_NAME}" -a "$DEBUG" = "no" ] && /bin/rm "${LOG_FILE_NAME}"
|
|
|
|
# Don't retry on the following cases.
|
|
if [ "$iError" -eq 0 ] || [ "$iError" -eq 43 ] || [ "$iError" -eq 44 ] || [ "$iError" -eq 48 ] || [ "$iError" -eq 49 ] || [ "$iError" -eq 50 ]; then
|
|
break
|
|
fi
|
|
|
|
# Sleep a while before the next try.
|
|
/sbin/setcfg "$RR_sche" "Retry" "$iRetry" -f "${RR_CONF}"
|
|
if [ $iRetry -le "$xnRetry" ] && [ "$xsInterval" -gt 0 ]; then
|
|
iInterval=$xsInterval
|
|
while [ $iInterval -gt 0 ]
|
|
do
|
|
if [ "$bAbort" -ne "0" ]; then
|
|
break
|
|
fi
|
|
/sbin/setcfg "$RR_sche" "RemainTime" "$iInterval" -f "${RR_CONF}"
|
|
|
|
if [ $iInterval -gt 4 ]; then
|
|
iInterval=$(($iInterval-5))
|
|
/bin/sleep 5
|
|
else
|
|
iInterval=$(($iInterval-1))
|
|
/bin/sleep 1
|
|
fi
|
|
done
|
|
/sbin/setcfg "$RR_sche" "RemainTime" "$iInterval" -f "${RR_CONF}"
|
|
fi
|
|
done
|
|
|
|
[ "x${RR_opt_stopnet}" = "xTRUE" ] && start_network
|
|
|
|
# Clear PID and ScriptPID before exit.
|
|
/sbin/setcfg "$RR_sche" "PID" "0" -f "${RR_CONF}"
|
|
/sbin/setcfg "$RR_sche" "ScriptPID" "0" -f "${RR_CONF}"
|