@ -4,7 +4,7 @@ PROGRAM="osync" # Rsync based two way sync engine with fault tolerance
AUTHOR = "(C) 2013-2016 by Orsiris de Jong"
CONTACT = "http://www.netpower.fr/osync - ozy@netpower.fr"
PROGRAM_VERSION = 1.2-beta
PROGRAM_BUILD = 201610160 1
PROGRAM_BUILD = 201610160 2
IS_STABLE = no
# Execution order #__WITH_PARANOIA_DEBUG
@ -26,18 +26,18 @@ IS_STABLE=no
# CheckLocks yes #__WITH_PARANOIA_DEBUG
# WriteLockFiles yes #__WITH_PARANOIA_DEBUG
# Sync no #__WITH_PARANOIA_DEBUG
# tree _l ist yes #__WITH_PARANOIA_DEBUG
# tree _l ist yes #__WITH_PARANOIA_DEBUG
# delete _l ist yes #__WITH_PARANOIA_DEBUG
# delete _l ist yes #__WITH_PARANOIA_DEBUG
# sync _a ttrs no #__WITH_PARANOIA_DEBUG
# _get _file_ctime_m time yes #__WITH_PARANOIA_DEBUG
# sync _u pdate no #__WITH_PARANOIA_DEBUG
# sync _u pdate no #__WITH_PARANOIA_DEBUG
# deletion _p ropagation yes #__WITH_PARANOIA_DEBUG
# deletion _p ropagation yes #__WITH_PARANOIA_DEBUG
# tree _l ist yes #__WITH_PARANOIA_DEBUG
# tree _l ist yes #__WITH_PARANOIA_DEBUG
# tree L ist yes #__WITH_PARANOIA_DEBUG
# tree L ist yes #__WITH_PARANOIA_DEBUG
# delete L ist yes #__WITH_PARANOIA_DEBUG
# delete L ist yes #__WITH_PARANOIA_DEBUG
# sync A ttrs no #__WITH_PARANOIA_DEBUG
# _get FileCtimeM time yes #__WITH_PARANOIA_DEBUG
# sync U pdate no #__WITH_PARANOIA_DEBUG
# sync U pdate no #__WITH_PARANOIA_DEBUG
# deletion P ropagation yes #__WITH_PARANOIA_DEBUG
# deletion P ropagation yes #__WITH_PARANOIA_DEBUG
# tree L ist yes #__WITH_PARANOIA_DEBUG
# tree L ist yes #__WITH_PARANOIA_DEBUG
# SoftDelete yes #__WITH_PARANOIA_DEBUG
# RunAfterHook yes #__WITH_PARANOIA_DEBUG
# UnlockReplicas yes #__WITH_PARANOIA_DEBUG
@ -613,61 +613,57 @@ function UnlockReplicas {
fi
}
#TODO : change sync core function names and variable names according to new coding standards
#TODO #WIP : change sync core function names and variable names according to new coding standards
###### Sync core functions
## Rsync does not like spaces in directory names, considering it as two different directories. Handling this schema by escaping space.
## It seems this only happens when trying to execute an rsync command through weval $rsync _c md on a remote host.
## It seems this only happens when trying to execute an rsync command through weval $rsync C md on a remote host.
## So I am using unescaped $INITIATOR_SYNC_DIR for local rsync calls and escaped $ESC_INITIATOR_SYNC_DIR for remote rsync calls like user@host:$ESC_INITIATOR_SYNC_DIR
## The same applies for target sync dir..............................................T.H.I.S..I.S..A..P.R.O.G.R.A.M.M.I.N.G..N.I.G.H.T.M.A.R.E
function tree_l ist {
local replica _p ath= " ${ 1 } " # path to the replica for which a tree needs to be constructed
function treeL ist {
local replica P ath= " ${ 1 } " # path to the replica for which a tree needs to be constructed
local replicaType = " ${ 2 } " # replica type: initiator, target
local tree _f ilename= " ${ 3 } " # filename to output tree (will be prefixed with $replicaType)
local tree F ilename= " ${ 3 } " # filename to output tree (will be prefixed with $replicaType)
local escaped_replica_p ath
local rsync_c md
local escapedReplicaP ath
local rsyncC md
__CheckArguments 3 $# ${ FUNCNAME [0] } " $@ " #__WITH_PARANOIA_DEBUG
escaped _replica_path= $( EscapeSpaces " $replica_p ath" )
escaped ReplicaPath= $( EscapeSpaces " $replicaP ath" )
Logger " Creating $replicaType replica file list [ $replica _p ath]. " "NOTICE"
Logger " Creating $replicaType replica file list [ $replica P ath]. " "NOTICE"
if [ " $REMOTE_OPERATION " = = "yes" ] && [ " $replicaType " = = " ${ TARGET [ $__type ] } " ] ; then
CheckConnectivity3rdPartyHosts
CheckConnectivityRemoteHost
rsync _c md= " $( type -p $RSYNC_EXECUTABLE ) --rsync-path=\" $RSYNC_PATH \" $RSYNC_ARGS -L $RSYNC_ATTR_ARGS $RSYNC_TYPE_ARGS -8 --exclude \" $OSYNC_DIR \" $RSYNC_PATTERNS $RSYNC_PARTIAL_EXCLUDE -e \" $RSYNC_SSH_CMD \" --list-only $REMOTE_USER @ $REMOTE_HOST :\" $escaped _replica_p ath\" 2> \" $RUN_DIR / $PROGRAM . ${ FUNCNAME [0] } . $replicaType .error. $SCRIPT_PID \" | grep \"^-\|^d\|^l\" | awk '{\$1=\$2=\$3=\$4=\"\" ;print}' | awk '{\$1=\$1 ;print}' | (grep -v \"^\. $\" || :) | sort > \" $RUN_DIR / $PROGRAM . ${ FUNCNAME [0] } . $replicaType . $SCRIPT_PID \" "
rsync C md= " $( type -p $RSYNC_EXECUTABLE ) --rsync-path=\" $RSYNC_PATH \" $RSYNC_ARGS -L $RSYNC_ATTR_ARGS $RSYNC_TYPE_ARGS -8 --exclude \" $OSYNC_DIR \" $RSYNC_PATTERNS $RSYNC_PARTIAL_EXCLUDE -e \" $RSYNC_SSH_CMD \" --list-only $REMOTE_USER @ $REMOTE_HOST :\" $escaped ReplicaP ath\" 2> \" $RUN_DIR / $PROGRAM . ${ FUNCNAME [0] } . $replicaType .error. $SCRIPT_PID \" | grep \"^-\|^d\|^l\" | awk '{\$1=\$2=\$3=\$4=\"\" ;print}' | awk '{\$1=\$1 ;print}' | (grep -v \"^\. $\" || :) | sort > \" $RUN_DIR / $PROGRAM . ${ FUNCNAME [0] } . $replicaType . $SCRIPT_PID \" "
else
rsync _c md= " $( type -p $RSYNC_EXECUTABLE ) --rsync-path=\" $RSYNC_PATH \" $RSYNC_ARGS -L $RSYNC_ATTR_ARGS $RSYNC_TYPE_ARGS -8 --exclude \" $OSYNC_DIR \" $RSYNC_PATTERNS $RSYNC_PARTIAL_EXCLUDE --list-only \" $replica _p ath\" 2> \" $RUN_DIR / $PROGRAM . ${ FUNCNAME [0] } . $replicaType .error. $SCRIPT_PID \" | grep \"^-\|^d\|^l\" | awk '{\$1=\$2=\$3=\$4=\"\" ;print}' | awk '{\$1=\$1 ;print}' | (grep -v \"^\. $\" || :) | sort > \" $RUN_DIR / $PROGRAM . ${ FUNCNAME [0] } . $replicaType . $SCRIPT_PID \" "
rsync C md= " $( type -p $RSYNC_EXECUTABLE ) --rsync-path=\" $RSYNC_PATH \" $RSYNC_ARGS -L $RSYNC_ATTR_ARGS $RSYNC_TYPE_ARGS -8 --exclude \" $OSYNC_DIR \" $RSYNC_PATTERNS $RSYNC_PARTIAL_EXCLUDE --list-only \" $replica P ath\" 2> \" $RUN_DIR / $PROGRAM . ${ FUNCNAME [0] } . $replicaType .error. $SCRIPT_PID \" | grep \"^-\|^d\|^l\" | awk '{\$1=\$2=\$3=\$4=\"\" ;print}' | awk '{\$1=\$1 ;print}' | (grep -v \"^\. $\" || :) | sort > \" $RUN_DIR / $PROGRAM . ${ FUNCNAME [0] } . $replicaType . $SCRIPT_PID \" "
fi
Logger " RSYNC_CMD: $rsync _c md" "DEBUG"
Logger " RSYNC_CMD: $rsync C md" "DEBUG"
#TODO: check the following statement
## Redirect commands stderr here to get rsync stderr output in logfile with eval "$rsync _c md" 2>> "$LOG_FILE"
## Redirect commands stderr here to get rsync stderr output in logfile with eval "$rsync C md" 2>> "$LOG_FILE"
## When log writing fails, $! is empty and WaitForTaskCompletion fails. Removing the 2>> log
eval " $rsync _c md"
eval " $rsync C md"
retval = $?
## Retval 24 = some files vanished while creating list
if ( [ $retval = = 0 ] || [ $retval = = 24 ] ) && [ -f " $RUN_DIR / $PROGRAM . ${ FUNCNAME [0] } . $replicaType . $SCRIPT_PID " ] ; then
mv -f " $RUN_DIR / $PROGRAM . ${ FUNCNAME [0] } . $replicaType . $SCRIPT_PID " " ${ INITIATOR [ $__replicaDir ] } ${ INITIATOR [ $__stateDir ] } / $replicaType $tree _f ilename"
mv -f " $RUN_DIR / $PROGRAM . ${ FUNCNAME [0] } . $replicaType . $SCRIPT_PID " " ${ INITIATOR [ $__replicaDir ] } ${ INITIATOR [ $__stateDir ] } / $replicaType $tree F ilename"
return $?
elif [ $retval = = 23 ] ; then
Logger " Some files could not be listed in [ $replica _p ath]. Check for failing symlinks. " "ERROR"
Logger " Some files could not be listed in [ $replica P ath]. Check for failing symlinks. " "ERROR"
Logger " Command output\n $( cat $RUN_DIR /$PROGRAM .${ FUNCNAME [0] } .$replicaType .error.$SCRIPT_PID ) " "NOTICE"
return 0
else
Logger " Cannot create replica file list in [ $replica _p ath]. " "CRITICAL"
Logger " Cannot create replica file list in [ $replica P ath]. " "CRITICAL"
return $retval
fi
}
# delete _l ist(replicaType): Creates a list of files vanished from last run on replica $1 (initiator/target)
function delete_l ist {
# delete L ist(replicaType): Creates a list of files vanished from last run on replica $1 (initiator/target)
function deleteL ist {
local replicaType = " ${ 1 } " # replica type: initiator, target
#local tree_file_after="${2}" # tree-file-after, will be prefixed with replica type
#local tree_file_current="${3}" # tree-file-current, will be prefixed with replica type
#local deleted_list_file="${4}" # file containing deleted file list, will be prefixed with replica type
#local deleted_failed_list_file="${5}" # file containing files that could not be deleted on last run, will be prefixed with replica type
__CheckArguments 1 $# ${ FUNCNAME [0] } " $@ " #__WITH_PARANOIA_DEBUG
local cmd
@ -695,23 +691,21 @@ function delete_list {
Logger " Cannot add failed deleted list to current deleted list for replica [ $replicaType ]. " "ERROR"
fi
fi
Logger "Its done" "WARN"
return $retval
else
Logger "Not done" "WARN"
touch " ${ INITIATOR [ $__replicaDir ] } ${ INITIATOR [ $__stateDir ] } / $replicaType ${ INITIATOR [ $__deletedListFile ] } "
return $retval
fi
}
function _get_file_ctime_mtime_l ocal {
local replica _p ath= " ${ 1 } " # Contains replica path
function _getFileCtimeMtimeL ocal {
local replica P ath= " ${ 1 } " # Contains replica path
local replicaType = " ${ 2 } " # Initiator / Target
local file _l ist= " ${ 3 } " # Contains list of files to get time attrs
local file L ist= " ${ 3 } " # Contains list of files to get time attrs
__CheckArguments 3 $# ${ FUNCNAME [0] } " $@ " #__WITH_PARANOIA_DEBUG
echo -n "" > " $RUN_DIR / $PROGRAM .ctime_mtime. $replicaType . $SCRIPT_PID "
while read -r file; do $STAT_CTIME_MTIME_CMD " $replica _p ath$file " | sort >> " $RUN_DIR / $PROGRAM .ctime_mtime. $replicaType . $SCRIPT_PID " ; done < " $file _l ist"
while read -r file; do $STAT_CTIME_MTIME_CMD " $replica P ath$file " | sort >> " $RUN_DIR / $PROGRAM .ctime_mtime. $replicaType . $SCRIPT_PID " ; done < " $file L ist"
if [ $? != 0 ] ; then
Logger " Getting file attributes failed [ $retval ] on $replicaType . Stopping execution. " "CRITICAL"
if [ -f " $RUN_DIR / $PROGRAM .ctime_mtime. $replicaType . $SCRIPT_PID " ] ; then
@ -722,15 +716,15 @@ function _get_file_ctime_mtime_local {
}
function _get_file_ctime_mtime_r emote {
local replica _ path= " ${ 1 } " # Contains replica path
function _getFileCtimeMtimeR emote {
local replica path= " ${ 1 } " # Contains replica path
local replicaType = " ${ 2 } "
local file _l ist= " ${ 3 } "
local file L ist= " ${ 3 } "
__CheckArguments 3 $# ${ FUNCNAME [0] } " $@ " #__WITH_PARANOIA_DEBUG
local cmd
cmd = 'cat "' $file _l ist'" | ' $SSH_CMD ' "while read -r file; do ' $REMOTE_STAT_CTIME_MTIME_CMD ' \"' $replica _p ath'\$file\"; done | sort" > "' $RUN_DIR /$PROGRAM .ctime_mtime.$replicaType .$SCRIPT_PID '"'
cmd = 'cat "' $file L ist'" | ' $SSH_CMD ' "while read -r file; do ' $REMOTE_STAT_CTIME_MTIME_CMD ' \"' $replica P ath'\$file\"; done | sort" > "' $RUN_DIR /$PROGRAM .ctime_mtime.$replicaType .$SCRIPT_PID '"'
Logger " CMD: $cmd " "DEBUG"
eval " $cmd "
if [ $? != 0 ] ; then
@ -744,29 +738,31 @@ function _get_file_ctime_mtime_remote {
# rsync does sync with mtime, but file attribute modifications only change ctime.
# Hence, detect newer ctime on the replica that gets updated first with CONFLICT_PREVALANCE and update all newer file attributes on this replica before real update
function sync_attrs {
local initiator_replica = " ${ 1 } "
local target_replica = " ${ 2 } "
local delete_list_filename = " ${ INITIATOR [ $__deletedListFile ] } " # Contains deleted list filename, will be prefixed with replica type
function syncAttrs {
local initiatorReplica = " ${ 1 } "
local targetReplica = " ${ 2 } "
__CheckArguments 2 $# ${ FUNCNAME [0] } " $@ " #__WITH_PARANOIA_DEBUG
local rsync_c md
local rsyncC md
local retval
local esc_source_dir
local esc_dest_dir
local sourceDir
local destDir
local escSourceDir
local escDestDir
local destReplica
Logger "Getting list of files that need updates." "NOTICE"
if [ " $REMOTE_OPERATION " = = "yes" ] ; then
CheckConnectivity3rdPartyHosts
CheckConnectivityRemoteHost
rsync _c md= " $( type -p $RSYNC_EXECUTABLE ) --rsync-path=\" $RSYNC_PATH \" -i -n -8 $RSYNC_ARGS $RSYNC_ATTR_ARGS $RSYNC_PARTIAL_EXCLUDE -e \" $RSYNC_SSH_CMD \" --exclude \" $OSYNC_DIR \" $RSYNC_PATTERNS $RSYNC_PARTIAL_EXCLUDE \" $initiator _replica\" $REMOTE_USER @ $REMOTE_HOST :\" $target_r eplica\" >> $RUN_DIR / $PROGRAM . ${ FUNCNAME [0] } . $SCRIPT_PID 2>&1 & "
rsync C md= " $( type -p $RSYNC_EXECUTABLE ) --rsync-path=\" $RSYNC_PATH \" -i -n -8 $RSYNC_ARGS $RSYNC_ATTR_ARGS $RSYNC_PARTIAL_EXCLUDE -e \" $RSYNC_SSH_CMD \" --exclude \" $OSYNC_DIR \" $RSYNC_PATTERNS $RSYNC_PARTIAL_EXCLUDE \" $initiator Replica\" $REMOTE_USER @ $REMOTE_HOST :\" $targetR eplica\" >> $RUN_DIR / $PROGRAM . ${ FUNCNAME [0] } . $SCRIPT_PID 2>&1 & "
else
rsync _c md= " $( type -p $RSYNC_EXECUTABLE ) --rsync-path=\" $RSYNC_PATH \" -i -n -8 $RSYNC_ARGS $RSYNC_ATTR_ARGS $RSYNC_PARTIAL_EXCLUDE --exclude \" $OSYNC_DIR \" $RSYNC_PATTERNS $RSYNC_PARTIAL_EXCLUDE \" $initiator _replica\" \" $target_r eplica\" >> $RUN_DIR / $PROGRAM . ${ FUNCNAME [0] } . $SCRIPT_PID 2>&1 & "
rsync C md= " $( type -p $RSYNC_EXECUTABLE ) --rsync-path=\" $RSYNC_PATH \" -i -n -8 $RSYNC_ARGS $RSYNC_ATTR_ARGS $RSYNC_PARTIAL_EXCLUDE --exclude \" $OSYNC_DIR \" $RSYNC_PATTERNS $RSYNC_PARTIAL_EXCLUDE \" $initiator Replica\" \" $targetR eplica\" >> $RUN_DIR / $PROGRAM . ${ FUNCNAME [0] } . $SCRIPT_PID 2>&1 & "
fi
Logger " RSYNC_CMD: $rsync _c md" "DEBUG"
eval " $rsync _c md"
Logger " RSYNC_CMD: $rsync C md" "DEBUG"
eval " $rsync C md"
WaitForTaskCompletion $! $SOFT_MAX_EXEC_TIME $HARD_MAX_EXEC_TIME ${ FUNCNAME [0] } false $KEEP_LOGGING
retval = $?
@ -789,15 +785,15 @@ function sync_attrs {
fi
Logger "Getting ctimes for pending files on initiator." "NOTICE"
_get_file_ctime_mtime_l ocal " ${ INITIATOR [ $__replicaDir ] } " " ${ INITIATOR [ $__type ] } " " $RUN_DIR / $PROGRAM . ${ FUNCNAME [0] } -cleaned. $SCRIPT_PID " &
_getFileCtimeMtimeL ocal " ${ INITIATOR [ $__replicaDir ] } " " ${ INITIATOR [ $__type ] } " " $RUN_DIR / $PROGRAM . ${ FUNCNAME [0] } -cleaned. $SCRIPT_PID " &
pids = " $! "
Logger "Getting ctimes for pending files on target." "NOTICE"
if [ " $REMOTE_OPERATION " != "yes" ] ; then
_get_file_ctime_mtime_l ocal " ${ TARGET [ $__replicaDir ] } " " ${ TARGET [ $__type ] } " " $RUN_DIR / $PROGRAM . ${ FUNCNAME [0] } -cleaned. $SCRIPT_PID " &
_getFileCtimeMtimeL ocal " ${ TARGET [ $__replicaDir ] } " " ${ TARGET [ $__type ] } " " $RUN_DIR / $PROGRAM . ${ FUNCNAME [0] } -cleaned. $SCRIPT_PID " &
pids = " $pids ; $! "
else
_get_file_ctime_mtime_r emote " ${ TARGET [ $__replicaDir ] } " " ${ TARGET [ $__type ] } " " $RUN_DIR / $PROGRAM . ${ FUNCNAME [0] } -cleaned. $SCRIPT_PID " &
_getFileCtimeMtimeR emote " ${ TARGET [ $__replicaDir ] } " " ${ TARGET [ $__type ] } " " $RUN_DIR / $PROGRAM . ${ FUNCNAME [0] } -cleaned. $SCRIPT_PID " &
pids = " $pids ; $! "
fi
WaitForTaskCompletion $pids 1800 0 ${ FUNCNAME [0] } true $KEEP_LOGGING
@ -809,205 +805,207 @@ function sync_attrs {
sed -i'.tmp' " s;^ ${ TARGET [ $__replicaDir ] } ;;g " " $RUN_DIR / $PROGRAM .ctime_mtime. ${ TARGET [ $__type ] } . $SCRIPT_PID "
if [ " $CONFLICT_PREVALANCE " = = " ${ TARGET [ $__type ] } " ] ; then
local source_d ir= " ${ INITIATOR [ $__replicaDir ] } "
esc _source_d ir= $( EscapeSpaces " ${ INITIATOR [ $__replicaDir ] } " )
local dest_d ir= " ${ TARGET [ $__replicaDir ] } "
esc _dest_d ir= $( EscapeSpaces " ${ TARGET [ $__replicaDir ] } " )
local dest_r eplica= " ${ TARGET [ $__type ] } "
sourceD ir= " ${ INITIATOR [ $__replicaDir ] } "
esc SourceD ir= $( EscapeSpaces " ${ INITIATOR [ $__replicaDir ] } " )
destD ir= " ${ TARGET [ $__replicaDir ] } "
esc DestD ir= $( EscapeSpaces " ${ TARGET [ $__replicaDir ] } " )
destR eplica= " ${ TARGET [ $__type ] } "
join -j 1 -t ';' -o 1.1,1.2,2.2 " $RUN_DIR / $PROGRAM .ctime_mtime. ${ INITIATOR [ $__type ] } . $SCRIPT_PID " " $RUN_DIR / $PROGRAM .ctime_mtime. ${ TARGET [ $__type ] } . $SCRIPT_PID " | awk -F';' '{if ($2 > $3) print $1}' > " $RUN_DIR / $PROGRAM . ${ FUNCNAME [0] } -ctime_files. $SCRIPT_PID "
else
local source_d ir= " ${ TARGET [ $__replicaDir ] } "
esc _source_d ir= $( EscapeSpaces " ${ TARGET [ $__replicaDir ] } " )
local dest_d ir= " ${ INITIATOR [ $__replicaDir ] } "
esc _dest_d ir= $( EscapeSpaces " ${ INITIATOR [ $__replicaDir ] } " )
local dest_r eplica= " ${ INITIATOR [ $__type ] } "
sourceD ir= " ${ TARGET [ $__replicaDir ] } "
esc SourceD ir= $( EscapeSpaces " ${ TARGET [ $__replicaDir ] } " )
destD ir= " ${ INITIATOR [ $__replicaDir ] } "
esc DestD ir= $( EscapeSpaces " ${ INITIATOR [ $__replicaDir ] } " )
destR eplica= " ${ INITIATOR [ $__type ] } "
join -j 1 -t ';' -o 1.1,1.2,2.2 " $RUN_DIR / $PROGRAM .ctime_mtime. ${ TARGET [ $__type ] } . $SCRIPT_PID " " $RUN_DIR / $PROGRAM .ctime_mtime. ${ INITIATOR [ $__type ] } . $SCRIPT_PID " | awk -F';' '{if ($2 > $3) print $1}' > " $RUN_DIR / $PROGRAM . ${ FUNCNAME [0] } -ctime_files. $SCRIPT_PID "
fi
if [ $( wc -l < " $RUN_DIR / $PROGRAM . ${ FUNCNAME [0] } -ctime_files. $SCRIPT_PID " ) -eq 0 ] ; then
Logger " Updating file attributes on $dest _r eplica not required " "NOTICE"
Logger " Updating file attributes on $dest R eplica not required " "NOTICE"
return 0
fi
Logger " Updating file attributes on $dest _r eplica. " "NOTICE"
Logger " Updating file attributes on $dest R eplica. " "NOTICE"
if [ " $REMOTE_OPERATION " = = "yes" ] ; then
CheckConnectivity3rdPartyHosts
CheckConnectivityRemoteHost
# No rsync args (hence no -r) because files are selected with --from-file
if [ " $dest _r eplica" = = " ${ INITIATOR [ $__type ] } " ] ; then
rsync _c md= " $( type -p $RSYNC_EXECUTABLE ) --rsync-path=\" $RSYNC_PATH \" $RSYNC_DRY_ARG $RSYNC_ATTR_ARGS $SYNC_OPTS -e \" $RSYNC_SSH_CMD \" --exclude \" $OSYNC_DIR \" $RSYNC_PATTERNS $RSYNC_PARTIAL_EXCLUDE --exclude-from=\" ${ INITIATOR [ $__replicaDir ] } ${ INITIATOR [ $__stateDir ] } / ${ INITIATOR [ $__type ] } $delete_list_filename \" --exclude-from=\" ${ INITIATOR [ $__replicaDir ] } ${ INITIATOR [ $__stateDir ] } / ${ TARGET [ $__type ] } $delete_list_filename \" --files-from=\" $RUN_DIR / $PROGRAM . ${ FUNCNAME [0] } -ctime_files. $SCRIPT_PID \" $REMOTE_USER @ $REMOTE_HOST :\" $esc _source_dir\" \" $dest_d ir\" >> $RUN_DIR / $PROGRAM .attr-update. $dest _r eplica. $SCRIPT_PID 2>&1 & "
if [ " $dest R eplica" = = " ${ INITIATOR [ $__type ] } " ] ; then
rsync C md= " $( type -p $RSYNC_EXECUTABLE ) --rsync-path=\" $RSYNC_PATH \" $RSYNC_DRY_ARG $RSYNC_ATTR_ARGS $SYNC_OPTS -e \" $RSYNC_SSH_CMD \" --exclude \" $OSYNC_DIR \" $RSYNC_PATTERNS $RSYNC_PARTIAL_EXCLUDE --exclude-from=\" ${ INITIATOR [ $__replicaDir ] } ${ INITIATOR [ $__stateDir ] } / ${ INITIATOR [ $__type ] } ${ INITIATOR [ $__deletedListFile ] } \" --exclude-from=\" ${ INITIATOR [ $__replicaDir ] } ${ INITIATOR [ $__stateDir ] } / ${ TARGET [ $__type ] } ${ INITIATOR [ $__deletedListFile ] } \" --files-from=\" $RUN_DIR / $PROGRAM . ${ FUNCNAME [0] } -ctime_files. $SCRIPT_PID \" $REMOTE_USER @ $REMOTE_HOST :\" $esc SourceDir\" \" $destD ir\" >> $RUN_DIR / $PROGRAM .attr-update. $dest R eplica. $SCRIPT_PID 2>&1 & "
else
rsync _c md= " $( type -p $RSYNC_EXECUTABLE ) --rsync-path=\" $RSYNC_PATH \" $RSYNC_DRY_ARG $RSYNC_ATTR_ARGS $SYNC_OPTS -e \" $RSYNC_SSH_CMD \" --exclude \" $OSYNC_DIR \" $RSYNC_PATTERNS $RSYNC_PARTIAL_EXCLUDE --exclude-from=\" ${ INITIATOR [ $__replicaDir ] } ${ INITIATOR [ $__stateDir ] } / ${ INITIATOR [ $__type ] } $delete_list_filename \" --exclude-from=\" ${ INITIATOR [ $__replicaDir ] } ${ INITIATOR [ $__stateDir ] } / ${ TARGET [ $__type ] } $delete_list_filename \" --files-from=\" $RUN_DIR / $PROGRAM . ${ FUNCNAME [0] } -ctime_files. $SCRIPT_PID \" \" $source _dir\" $REMOTE_USER @ $REMOTE_HOST :\" $esc_dest_d ir\" >> $RUN_DIR / $PROGRAM .attr-update. $dest _r eplica. $SCRIPT_PID 2>&1 & "
rsync C md= " $( type -p $RSYNC_EXECUTABLE ) --rsync-path=\" $RSYNC_PATH \" $RSYNC_DRY_ARG $RSYNC_ATTR_ARGS $SYNC_OPTS -e \" $RSYNC_SSH_CMD \" --exclude \" $OSYNC_DIR \" $RSYNC_PATTERNS $RSYNC_PARTIAL_EXCLUDE --exclude-from=\" ${ INITIATOR [ $__replicaDir ] } ${ INITIATOR [ $__stateDir ] } / ${ INITIATOR [ $__type ] } ${ INITIATOR [ $__deletedListFile ] } \" --exclude-from=\" ${ INITIATOR [ $__replicaDir ] } ${ INITIATOR [ $__stateDir ] } / ${ TARGET [ $__type ] } ${ INITIATOR [ $__deletedListFile ] } \" --files-from=\" $RUN_DIR / $PROGRAM . ${ FUNCNAME [0] } -ctime_files. $SCRIPT_PID \" \" $source Dir\" $REMOTE_USER @ $REMOTE_HOST :\" $escDestD ir\" >> $RUN_DIR / $PROGRAM .attr-update. $dest R eplica. $SCRIPT_PID 2>&1 & "
fi
else
rsync _c md= " $( type -p $RSYNC_EXECUTABLE ) --rsync-path=\" $RSYNC_PATH \" $RSYNC_DRY_ARG $RSYNC_ATTR_ARGS $SYNC_OPTS --exclude \" $OSYNC_DIR \" $RSYNC_PATTERNS $RSYNC_PARTIAL_EXCLUDE --exclude-from=\" ${ INITIATOR [ $__replicaDir ] } ${ INITIATOR [ $__stateDir ] } / ${ INITIATOR [ $__type ] } $delete_list_filename \" --exclude-from=\" ${ INITIATOR [ $__replicaDir ] } ${ INITIATOR [ $__stateDir ] } / ${ TARGET [ $__type ] } $delete_list_filename \" --files-from=\" $RUN_DIR / $PROGRAM . ${ FUNCNAME [0] } -ctime_files. $SCRIPT_PID \" \" $source _dir\" \" $dest_d ir\" >> $RUN_DIR / $PROGRAM .attr-update. $dest _r eplica. $SCRIPT_PID 2>&1 & "
rsync C md= " $( type -p $RSYNC_EXECUTABLE ) --rsync-path=\" $RSYNC_PATH \" $RSYNC_DRY_ARG $RSYNC_ATTR_ARGS $SYNC_OPTS --exclude \" $OSYNC_DIR \" $RSYNC_PATTERNS $RSYNC_PARTIAL_EXCLUDE --exclude-from=\" ${ INITIATOR [ $__replicaDir ] } ${ INITIATOR [ $__stateDir ] } / ${ INITIATOR [ $__type ] } ${ INITIATOR [ $__deletedListFile ] } \" --exclude-from=\" ${ INITIATOR [ $__replicaDir ] } ${ INITIATOR [ $__stateDir ] } / ${ TARGET [ $__type ] } ${ INITIATOR [ $__deletedListFile ] } \" --files-from=\" $RUN_DIR / $PROGRAM . ${ FUNCNAME [0] } -ctime_files. $SCRIPT_PID \" \" $source Dir\" \" $destD ir\" >> $RUN_DIR / $PROGRAM .attr-update. $dest R eplica. $SCRIPT_PID 2>&1 & "
fi
Logger " RSYNC_CMD: $rsync _c md" "DEBUG"
eval " $rsync _c md"
Logger " RSYNC_CMD: $rsync C md" "DEBUG"
eval " $rsync C md"
WaitForTaskCompletion $! $SOFT_MAX_EXEC_TIME $HARD_MAX_EXEC_TIME ${ FUNCNAME [0] } false $KEEP_LOGGING
retval = $?
if [ $retval != 0 ] && [ $retval != 24 ] ; then
Logger " Updating file attributes on $dest _r eplica [ $retval ]. Stopping execution. " "CRITICAL"
if [ -f " $RUN_DIR / $PROGRAM .attr-update. $dest _r eplica. $SCRIPT_PID " ] ; then
Logger " Rsync output:\n $( cat $RUN_DIR /$PROGRAM .attr-update.$dest _r eplica.$SCRIPT_PID ) " "NOTICE"
Logger " Updating file attributes on $dest R eplica [ $retval ]. Stopping execution. " "CRITICAL"
if [ -f " $RUN_DIR / $PROGRAM .attr-update. $dest R eplica. $SCRIPT_PID " ] ; then
Logger " Rsync output:\n $( cat $RUN_DIR /$PROGRAM .attr-update.$dest R eplica.$SCRIPT_PID ) " "NOTICE"
fi
exit 1
else
if [ -f " $RUN_DIR / $PROGRAM .attr-update. $dest _r eplica. $SCRIPT_PID " ] ; then
Logger " List:\n $( cat $RUN_DIR /$PROGRAM .attr-update.$dest _r eplica.$SCRIPT_PID ) " "VERBOSE"
if [ -f " $RUN_DIR / $PROGRAM .attr-update. $dest R eplica. $SCRIPT_PID " ] ; then
Logger " List:\n $( cat $RUN_DIR /$PROGRAM .attr-update.$dest R eplica.$SCRIPT_PID ) " "VERBOSE"
fi
Logger " Successfully updated file attributes on $dest _r eplica replica. " "NOTICE"
Logger " Successfully updated file attributes on $dest R eplica replica. " "NOTICE"
fi
}
# sync_update(source replica, destination replica, delete_list_filename)
function sync_update {
local source_replica = " ${ 1 } " # Contains replica type of source: initiator, target
local destination_replica = " ${ 2 } " # Contains replica type of destination: initiator, target
local delete_list_filename = " ${ 3 } " # Contains deleted list filename, will be prefixed with replica type
__CheckArguments 3 $# ${ FUNCNAME [0] } " $@ " #__WITH_PARANOIA_DEBUG
# syncUpdate(source replica, destination replica, delete_list_filename)
function syncUpdate {
local sourceReplica = " ${ 1 } " # Contains replica type of source: initiator, target
local destinationReplica = " ${ 2 } " # Contains replica type of destination: initiator, target
__CheckArguments 2 $# ${ FUNCNAME [0] } " $@ " #__WITH_PARANOIA_DEBUG
local rsync_c md
local rsyncC md
local retval
local esc_source_dir
local esc_dest_dir
local sourceDir
local escSourceDir
local destDir
local escDestDir
Logger " Updating $destination_replica replica. " "NOTICE"
if [ " $source_replica " = = " ${ INITIATOR [ $__type ] } " ] ; then
local source_dir = " ${ INITIATOR [ $__replicaDir ] } "
local dest_dir = " ${ TARGET [ $__replicaDir ] } "
local backup_args = " $TARGET_BACKUP "
local backupArgs
esc_source_dir = $( EscapeSpaces " ${ INITIATOR [ $__replicaDir ] } " )
esc_dest_dir = $( EscapeSpaces " ${ TARGET [ $__replicaDir ] } " )
Logger " Updating $destinationReplica replica. " "NOTICE"
if [ " $sourceReplica " = = " ${ INITIATOR [ $__type ] } " ] ; then
sourceDir = " ${ INITIATOR [ $__replicaDir ] } "
destDir = " ${ TARGET [ $__replicaDir ] } "
backupArgs = " $TARGET_BACKUP "
escSourceDir = $( EscapeSpaces " ${ INITIATOR [ $__replicaDir ] } " )
escDestDir = $( EscapeSpaces " ${ TARGET [ $__replicaDir ] } " )
else
local source_dir = " ${ TARGET [ $__replicaDir ] } "
local dest_dir = " ${ INITIATOR [ $__replicaDir ] } "
local backup_args = " $INITIATOR_BACKUP "
sourceD ir= " ${ TARGET [ $__replicaDir ] } "
destD ir= " ${ INITIATOR [ $__replicaDir ] } "
backupA rgs= " $INITIATOR_BACKUP "
esc_source_dir = $( EscapeSpaces " ${ TARGET [ $__replicaDir ] } " )
esc _dest_d ir= $( EscapeSpaces " ${ INITIATOR [ $__replicaDir ] } " )
esc SourceD ir= $( EscapeSpaces " ${ TARGET [ $__replicaDir ] } " )
esc DestD ir= $( EscapeSpaces " ${ INITIATOR [ $__replicaDir ] } " )
fi
if [ " $REMOTE_OPERATION " = = "yes" ] ; then
CheckConnectivity3rdPartyHosts
CheckConnectivityRemoteHost
if [ " $source _r eplica" = = " ${ INITIATOR [ $__type ] } " ] ; then
rsync _c md= " $( type -p $RSYNC_EXECUTABLE ) --rsync-path=\" $RSYNC_PATH \" $RSYNC_ARGS $RSYNC_DRY_ARG $RSYNC_ATTR_ARGS $RSYNC_TYPE_ARGS $SYNC_OPTS -e \" $RSYNC_SSH_CMD \" $backup _a rgs --exclude \" $OSYNC_DIR \" $RSYNC_PATTERNS $RSYNC_PARTIAL_EXCLUDE --exclude-from=\" ${ INITIATOR [ $__replicaDir ] } ${ INITIATOR [ $__stateDir ] } / $source _replica$delete_list_filename \" --exclude-from=\" ${ INITIATOR [ $__replicaDir ] } ${ INITIATOR [ $__stateDir ] } / $destination _replica$delete_list_filename \" \" $source_dir \" $REMOTE_USER @ $REMOTE_HOST :\" $esc_dest_d ir\" >> $RUN_DIR / $PROGRAM .update. $destination _r eplica. $SCRIPT_PID 2>&1 "
if [ " $source R eplica" = = " ${ INITIATOR [ $__type ] } " ] ; then
rsync C md= " $( type -p $RSYNC_EXECUTABLE ) --rsync-path=\" $RSYNC_PATH \" $RSYNC_ARGS $RSYNC_DRY_ARG $RSYNC_ATTR_ARGS $RSYNC_TYPE_ARGS $SYNC_OPTS -e \" $RSYNC_SSH_CMD \" $backup A rgs --exclude \" $OSYNC_DIR \" $RSYNC_PATTERNS $RSYNC_PARTIAL_EXCLUDE --exclude-from=\" ${ INITIATOR [ $__replicaDir ] } ${ INITIATOR [ $__stateDir ] } / $source Replica${ INITIATOR [ $__deletedListFile ] } \" --exclude-from=\" ${ INITIATOR [ $__replicaDir ] } ${ INITIATOR [ $__stateDir ] } / $destination Replica${ INITIATOR [ $__deletedListFile ] } \" \" $sourceDir \" $REMOTE_USER @ $REMOTE_HOST :\" $escDestD ir\" >> $RUN_DIR / $PROGRAM .update. $destination R eplica. $SCRIPT_PID 2>&1 "
else
rsync _c md= " $( type -p $RSYNC_EXECUTABLE ) --rsync-path=\" $RSYNC_PATH \" $RSYNC_ARGS $RSYNC_DRY_ARG $RSYNC_ATTR_ARGS $RSYNC_TYPE_ARGS $SYNC_OPTS -e \" $RSYNC_SSH_CMD \" $backup _a rgs --exclude \" $OSYNC_DIR \" $RSYNC_PATTERNS $RSYNC_PARTIAL_EXCLUDE --exclude-from=\" ${ INITIATOR [ $__replicaDir ] } ${ INITIATOR [ $__stateDir ] } / $destination _replica$delete_list_filename \" --exclude-from=\" ${ INITIATOR [ $__replicaDir ] } ${ INITIATOR [ $__stateDir ] } / $source _replica$delete_list_filename \" $REMOTE_USER @ $REMOTE_HOST :\" $esc_source_dir \" \" $dest_d ir\" >> $RUN_DIR / $PROGRAM .update. $destination _r eplica. $SCRIPT_PID 2>&1 "
rsync C md= " $( type -p $RSYNC_EXECUTABLE ) --rsync-path=\" $RSYNC_PATH \" $RSYNC_ARGS $RSYNC_DRY_ARG $RSYNC_ATTR_ARGS $RSYNC_TYPE_ARGS $SYNC_OPTS -e \" $RSYNC_SSH_CMD \" $backup A rgs --exclude \" $OSYNC_DIR \" $RSYNC_PATTERNS $RSYNC_PARTIAL_EXCLUDE --exclude-from=\" ${ INITIATOR [ $__replicaDir ] } ${ INITIATOR [ $__stateDir ] } / $destination Replica${ INITIATOR [ $__deletedListFile ] } \" --exclude-from=\" ${ INITIATOR [ $__replicaDir ] } ${ INITIATOR [ $__stateDir ] } / $source Replica${ INITIATOR [ $__deletedListFile ] } \" $REMOTE_USER @ $REMOTE_HOST :\" $escSourceDir \" \" $destD ir\" >> $RUN_DIR / $PROGRAM .update. $destination R eplica. $SCRIPT_PID 2>&1 "
fi
else
rsync _c md= " $( type -p $RSYNC_EXECUTABLE ) --rsync-path=\" $RSYNC_PATH \" $RSYNC_ARGS $RSYNC_DRY_ARG $RSYNC_ATTR_ARGS $RSYNC_TYPE_ARGS $SYNC_OPTS $backup _a rgs --exclude \" $OSYNC_DIR \" $RSYNC_PATTERNS $RSYNC_PARTIAL_EXCLUDE --exclude-from=\" ${ INITIATOR [ $__replicaDir ] } ${ INITIATOR [ $__stateDir ] } / $source _replica$delete_list_filename \" --exclude-from=\" ${ INITIATOR [ $__replicaDir ] } ${ INITIATOR [ $__stateDir ] } / $destination _replica$delete_list_filename \" \" $source_dir \" \" $dest_d ir\" >> $RUN_DIR / $PROGRAM .update. $destination _r eplica. $SCRIPT_PID 2>&1 "
rsync C md= " $( type -p $RSYNC_EXECUTABLE ) --rsync-path=\" $RSYNC_PATH \" $RSYNC_ARGS $RSYNC_DRY_ARG $RSYNC_ATTR_ARGS $RSYNC_TYPE_ARGS $SYNC_OPTS $backup A rgs --exclude \" $OSYNC_DIR \" $RSYNC_PATTERNS $RSYNC_PARTIAL_EXCLUDE --exclude-from=\" ${ INITIATOR [ $__replicaDir ] } ${ INITIATOR [ $__stateDir ] } / $source Replica${ INITIATOR [ $__deletedListFile ] } \" --exclude-from=\" ${ INITIATOR [ $__replicaDir ] } ${ INITIATOR [ $__stateDir ] } / $destination Replica${ INITIATOR [ $__deletedListFile ] } \" \" $sourceDir \" \" $destD ir\" >> $RUN_DIR / $PROGRAM .update. $destination R eplica. $SCRIPT_PID 2>&1 "
fi
Logger " RSYNC_CMD: $rsync _c md" "DEBUG"
eval " $rsync _c md"
Logger " RSYNC_CMD: $rsync C md" "DEBUG"
eval " $rsync C md"
retval = $?
if [ $retval != 0 ] && [ $retval != 24 ] ; then
Logger " Updating $destination _r eplica replica failed. Stopping execution. " "CRITICAL"
if [ -f " $RUN_DIR / $PROGRAM .update. $destination _r eplica. $SCRIPT_PID " ] ; then
Logger " Rsync output:\n $( cat $RUN_DIR /$PROGRAM .update.$destination _r eplica.$SCRIPT_PID ) " "NOTICE"
Logger " Updating $destination R eplica replica failed. Stopping execution. " "CRITICAL"
if [ -f " $RUN_DIR / $PROGRAM .update. $destination R eplica. $SCRIPT_PID " ] ; then
Logger " Rsync output:\n $( cat $RUN_DIR /$PROGRAM .update.$destination R eplica.$SCRIPT_PID ) " "NOTICE"
fi
exit 1
else
if [ -f " $RUN_DIR / $PROGRAM .update. $destination _r eplica. $SCRIPT_PID " ] ; then
Logger " List:\n $( cat $RUN_DIR /$PROGRAM .update.$destination _r eplica.$SCRIPT_PID ) " "VERBOSE"
if [ -f " $RUN_DIR / $PROGRAM .update. $destination R eplica. $SCRIPT_PID " ] ; then
Logger " List:\n $( cat $RUN_DIR /$PROGRAM .update.$destination R eplica.$SCRIPT_PID ) " "VERBOSE"
fi
Logger " Updating $destination _r eplica replica succeded. " "NOTICE"
Logger " Updating $destination R eplica replica succeded. " "NOTICE"
return 0
fi
}
# delete_local(replica dir, delete file list, delete dir, delete failed file)
function _delete_local {
local replica_dir = " ${ 1 } " # Full path to replica
local deleted_list_file = " ${ 2 } " # file containing deleted file list, will be prefixed with replica type
local deletion_dir = " ${ 3 } " # deletion dir in format .[workdir]/deleted
local deleted_failed_list_file = " ${ 4 } " # file containing files that could not be deleted on last run, will be prefixed with replica type
__CheckArguments 4 $# ${ FUNCNAME [0] } " $@ " #__WITH_PARANOIA_DEBUG
function _deleteLocal {
local replicaType = " ${ 1 } " # Replica type
local replicaDir = " ${ 2 } " # Full path to replica
local deletionDir = " ${ 3 } " # deletion dir in format .[workdir]/deleted
__CheckArguments 3 $# ${ FUNCNAME [0] } " $@ " #__WITH_PARANOIA_DEBUG
local parentdir
local previous _f ile= ""
local previous F ile= ""
local result
if [ ! -d " $replica _dir$deletion_d ir" ] && [ $_DRYRUN = = false ] ; then
$COMMAND_SUDO mkdir -p " $replica _dir$deletion_d ir"
if [ ! -d " $replica Dir$deletionD ir" ] && [ $_DRYRUN = = false ] ; then
$COMMAND_SUDO mkdir -p " $replica Dir$deletionD ir"
if [ $? != 0 ] ; then
Logger " Cannot create local replica deletion directory in [ $replica _dir$deletion_d ir]. " "ERROR"
Logger " Cannot create local replica deletion directory in [ $replica Dir$deletionD ir]. " "ERROR"
exit 1
fi
fi
while read -r files; do
## On every run, check wheter the next item is already deleted because it is included in a directory already deleted
if [ [ " $files " != " $previous _f ile/ " * ] ] && [ " $files " != "" ] ; then
if [ [ " $files " != " $previous F ile/ " * ] ] && [ " $files " != "" ] ; then
if [ " $SOFT_DELETE " != "no" ] ; then
if [ $_DRYRUN = = false ] ; then
if [ -e " $replica _dir$deletion_d ir/ $files " ] ; then
rm -rf " ${ replica _dir: ? } $deletion_d ir/ $files "
if [ -e " $replica Dir$deletionD ir/ $files " ] ; then
rm -rf " ${ replica Dir: ? } $deletionD ir/ $files "
fi
if [ -e " $replica _d ir$files " ] ; then
if [ -e " $replica D ir$files " ] ; then
# In order to keep full path on soft deletion, create parent directories before move
parentdir = " $( dirname " $files " ) "
if [ " $parentdir " != "." ] ; then
mkdir -p " $replica _dir$deletion_d ir/ $parentdir "
Logger " Moving deleted file [ $replica _dir$files ] to [ $replica_dir $deletion_d ir/ $parentdir ]. " "VERBOSE"
mv -f " $replica _dir$files " " $replica_dir $deletion_d ir/ $parentdir "
mkdir -p " $replica Dir$deletionD ir/ $parentdir "
Logger " Moving deleted file [ $replica Dir$files ] to [ $replicaDir $deletionD ir/ $parentdir ]. " "VERBOSE"
mv -f " $replica Dir$files " " $replicaDir $deletionD ir/ $parentdir "
else
Logger " Moving deleted file [ $replica _dir$files ] to [ $replica_dir $deletion_d ir]. " "VERBOSE"
mv -f " $replica _dir$files " " $replica_dir $deletion_d ir"
Logger " Moving deleted file [ $replica Dir$files ] to [ $replicaDir $deletionD ir]. " "VERBOSE"
mv -f " $replica Dir$files " " $replicaDir $deletionD ir"
fi
if [ $? != 0 ] ; then
Logger " Cannot move [ $replica _d ir$files ] to deletion directory. " "ERROR"
echo " $files " >> " ${ INITIATOR [ $__replicaDir ] } ${ INITIATOR [ $__stateDir ] } / $ deleted_failed_list_file "
Logger " Cannot move [ $replica D ir$files ] to deletion directory. " "ERROR"
echo " $files " >> " ${ INITIATOR [ $__replicaDir ] } ${ INITIATOR [ $__stateDir ] } / $ replicaType${ INITIATOR [ $__failedDeletedListFile ] } "
fi
fi
fi
else
if [ $_DRYRUN = = false ] ; then
if [ -e " $replica _d ir$files " ] ; then
rm -rf " $replica _d ir$files "
if [ -e " $replica D ir$files " ] ; then
rm -rf " $replica D ir$files "
result = $?
Logger " Deleting [ $replica _d ir$files ]. " "VERBOSE"
Logger " Deleting [ $replica D ir$files ]. " "VERBOSE"
if [ $result != 0 ] ; then
Logger " Cannot delete [ $replica _d ir$files ]. " "ERROR"
echo " $files " >> " ${ INITIATOR [ $__replicaDir ] } ${ INITIATOR [ $__stateDir ] } / $ deleted_failed_list_file "
Logger " Cannot delete [ $replica D ir$files ]. " "ERROR"
echo " $files " >> " ${ INITIATOR [ $__replicaDir ] } ${ INITIATOR [ $__stateDir ] } / $ replicaType${ INITIATOR [ $__failedDeletedListFile ] } "
fi
fi
fi
fi
previous _f ile= " $files "
previous F ile= " $files "
fi
done < " ${ INITIATOR [ $__replicaDir ] } ${ INITIATOR [ $__stateDir ] } / $ deleted_list_file "
done < " ${ INITIATOR [ $__replicaDir ] } ${ INITIATOR [ $__stateDir ] } / $ replicaType${ INITIATOR [ $__deletedListFile ] } "
}
function _delete_remote {
local replica_dir = " ${ 1 } " # Full path to replica
local deleted_list_file = " ${ 2 } " # file containing deleted file list, will be prefixed with replica type
local deletion_dir = " ${ 3 } " # deletion dir in format .[workdir]/deleted
local deleted_failed_list_file = " ${ 4 } " # file containing files that could not be deleted on last run, will be prefixed with replica type
__CheckArguments 4 $# ${ FUNCNAME [0] } " $@ " #__WITH_PARANOIA_DEBUG
function _deleteRemote {
local replicaType = " ${ 1 } " # Replica type
local replicaDir = " ${ 2 } " # Full path to replica
local deletionDir = " ${ 3 } " # deletion dir in format .[workdir]/deleted
__CheckArguments 3 $# ${ FUNCNAME [0] } " $@ " #__WITH_PARANOIA_DEBUG
local escDestDir
local rsyncCmd
local esc_dest_dir
local rsync_cmd
local escSourceFile
## This is a special coded function. Need to redelcare local functions on remote host, passing all needed variables as escaped arguments to ssh command.
## Anything beetween << ENDSSH and ENDSSH will be executed remotely
# Additionnaly, we need to copy the deletetion list to the remote state folder
esc _dest_d ir= " $( EscapeSpaces " ${ TARGET [ $__replicaDir ] } ${ TARGET [ $__stateDir ] } " ) "
rsync _c md= " $( type -p $RSYNC_EXECUTABLE ) --rsync-path=\" $RSYNC_PATH \" -e \" $RSYNC_SSH_CMD \" \" ${ INITIATOR [ $__replicaDir ] } ${ INITIATOR [ $__stateDir ] } / $ deleted_list_file\" $REMOTE_USER @ $REMOTE_HOST :\" $esc_dest_d ir/\" >> $RUN_DIR / $PROGRAM . ${ FUNCNAME [0] } .precopy. $SCRIPT_PID 2>&1 "
Logger " RSYNC_CMD: $rsync _c md" "DEBUG"
eval " $rsync _c md" 2>> " $LOG_FILE "
esc DestD ir= " $( EscapeSpaces " ${ TARGET [ $__replicaDir ] } ${ TARGET [ $__stateDir ] } " ) "
rsync C md= " $( type -p $RSYNC_EXECUTABLE ) --rsync-path=\" $RSYNC_PATH \" -e \" $RSYNC_SSH_CMD \" \" ${ INITIATOR [ $__replicaDir ] } ${ INITIATOR [ $__stateDir ] } / $ replicaType${ INITIATOR [ $__deletedListFile ] } \" $REMOTE_USER @ $REMOTE_HOST :\" $escDestD ir/\" >> $RUN_DIR / $PROGRAM . ${ FUNCNAME [0] } .precopy. $SCRIPT_PID 2>&1 "
Logger " RSYNC_CMD: $rsync C md" "DEBUG"
eval " $rsync C md" 2>> " $LOG_FILE "
if [ $? != 0 ] ; then
Logger "Cannot copy the deletion list to remote replica." "ERROR"
if [ -f " $RUN_DIR / $PROGRAM . ${ FUNCNAME [0] } .precopy. $SCRIPT_PID " ] ; then
@ -1016,7 +1014,7 @@ function _delete_remote {
exit 1
fi
$SSH_CMD ERROR_ALERT = 0 sync_on_changes = $sync_on_changes _DEBUG = $_DEBUG _DRYRUN = $_DRYRUN _VERBOSE = $_VERBOSE COMMAND_SUDO = $COMMAND_SUDO FILE_LIST = " $( EscapeSpaces " ${ TARGET [ $__replicaDir ] } ${ TARGET [ $__stateDir ] } / $ deleted_list_file " ) " REPLICA_DIR = " $( EscapeSpaces " $replica _dir" ) " SOFT_DELETE = $SOFT_DELETE DELETE_DIR = " $( EscapeSpaces " $deletion_d ir" ) " FAILED_DELETE_LIST = " $( EscapeSpaces " ${ TARGET [ $__replicaDir ] } ${ TARGET [ $__stateDir ] } / $deleted_failed_list_file " ) " 'bash -s' << 'ENDSSH' >> " $RUN_DIR / $PROGRAM .remote_deletion. $SCRIPT_PID " 2>& 1
$SSH_CMD ERROR_ALERT = 0 sync_on_changes = $sync_on_changes _DEBUG = $_DEBUG _DRYRUN = $_DRYRUN _VERBOSE = $_VERBOSE COMMAND_SUDO = $COMMAND_SUDO FILE_LIST = " $( EscapeSpaces " ${ TARGET [ $__replicaDir ] } ${ TARGET [ $__stateDir ] } / $ replicaType${ INITIATOR [ $__deletedListFile ] } " ) " REPLICA_DIR = " $( EscapeSpaces " $replica Dir" ) " SOFT_DELETE = $SOFT_DELETE DELETION_DIR = " $( EscapeSpaces " $deletionD ir" ) " FAILED_DELETE_LIST = " $( EscapeSpaces " ${ TARGET [ $__replicaDir ] } ${ TARGET [ $__stateDir ] } / ${ INITIATOR [ $__failedDeletedListFile ] } " ) " 'bash -s' << 'ENDSSH' >> " $RUN_DIR / $PROGRAM .remote_deletion. $SCRIPT_PID " 2>& 1
## The following lines are executed remotely
function _logger {
@ -1062,36 +1060,36 @@ $SSH_CMD ERROR_ALERT=0 sync_on_changes=$sync_on_changes _DEBUG=$_DEBUG _DRYRUN=$
> " $FAILED_DELETE_LIST "
parentdir =
previous _f ile= ""
previous F ile= ""
if [ ! -d " $REPLICA_DIR $DELET E _DIR" ] && [ $_DRYRUN = = false ] ; then
$COMMAND_SUDO mkdir -p " $REPLICA_DIR $DELET E _DIR"
if [ ! -d " $REPLICA_DIR $DELET ION _DIR" ] && [ $_DRYRUN = = false ] ; then
$COMMAND_SUDO mkdir -p " $REPLICA_DIR $DELET ION _DIR"
if [ $? != 0 ] ; then
Logger " Cannot create remote replica deletion directory in [ $REPLICA_DIR $DELET E _DIR]. " "ERROR"
Logger " Cannot create remote replica deletion directory in [ $REPLICA_DIR $DELET ION _DIR]. " "ERROR"
exit 1
fi
fi
while read -r files; do
## On every run, check wheter the next item is already deleted because it is included in a directory already deleted
if [ [ " $files " != " $previous _f ile/ " * ] ] && [ " $files " != "" ] ; then
if [ [ " $files " != " $previous F ile/ " * ] ] && [ " $files " != "" ] ; then
if [ " $SOFT_DELETE " != "no" ] ; then
if [ $_DRYRUN = = false ] ; then
if [ -e " $REPLICA_DIR $DELET E _DIR/ $files " ] ; then
$COMMAND_SUDO rm -rf " $REPLICA_DIR $DELET E _DIR/ $files "
if [ -e " $REPLICA_DIR $DELET ION _DIR/ $files " ] ; then
$COMMAND_SUDO rm -rf " $REPLICA_DIR $DELET ION _DIR/ $files "
fi
if [ -e " $REPLICA_DIR $files " ] ; then
# In order to keep full path on soft deletion, create parent directories before move
parentdir = " $( dirname " $files " ) "
if [ " $parentdir " != "." ] ; then
$COMMAND_SUDO mkdir -p " $REPLICA_DIR $DELET E _DIR/ $parentdir "
$COMMAND_SUDO mv -f " $REPLICA_DIR $files " " $REPLICA_DIR $DELET E _DIR/ $parentdir "
Logger " Moving deleted file [ $REPLICA_DIR $files ] to [ $REPLICA_DIR $DELET E _DIR/ $parentdir ]. " "VERBOSE"
$COMMAND_SUDO mkdir -p " $REPLICA_DIR $DELET ION _DIR/ $parentdir "
$COMMAND_SUDO mv -f " $REPLICA_DIR $files " " $REPLICA_DIR $DELET ION _DIR/ $parentdir "
Logger " Moving deleted file [ $REPLICA_DIR $files ] to [ $REPLICA_DIR $DELET ION _DIR/ $parentdir ]. " "VERBOSE"
else
$COMMAND_SUDO mv -f " $REPLICA_DIR $files " " $REPLICA_DIR $DELET E _DIR"
Logger " Moving deleted file [ $REPLICA_DIR $files ] to [ $REPLICA_DIR $DELET E _DIR]. " "VERBOSE"
$COMMAND_SUDO mv -f " $REPLICA_DIR $files " " $REPLICA_DIR $DELET ION _DIR"
Logger " Moving deleted file [ $REPLICA_DIR $files ] to [ $REPLICA_DIR $DELET ION _DIR]. " "VERBOSE"
fi
if [ $? != 0 ] ; then
Logger " Cannot move [ $REPLICA_DIR $files ] to deletion directory. " "ERROR"
@ -1112,7 +1110,7 @@ $SSH_CMD ERROR_ALERT=0 sync_on_changes=$sync_on_changes _DEBUG=$_DEBUG _DRYRUN=$
fi
fi
fi
previous _f ile= " $files "
previous F ile= " $files "
fi
done < " $FILE_LIST "
ENDSSH
@ -1123,10 +1121,10 @@ ENDSSH
fi
## Copy back the deleted failed file list
esc _source_f ile= " $( EscapeSpaces " ${ TARGET [ $__replicaDir ] } ${ TARGET [ $__stateDir ] } / $deleted_failed_list_file " ) "
rsync _c md= " $( type -p $RSYNC_EXECUTABLE ) --rsync-path=\" $RSYNC_PATH \" -e \" $RSYNC_SSH_CMD \" $REMOTE_USER @ $REMOTE_HOST :\" $esc _source_f ile\" \" ${ INITIATOR [ $__replicaDir ] } ${ INITIATOR [ $__stateDir ] } \" > \" $RUN_DIR / $PROGRAM .remote_failed_deletion_list_copy. $SCRIPT_PID \" "
Logger " RSYNC_CMD: $rsync _c md" "DEBUG"
eval " $rsync _c md" 2>> " $LOG_FILE "
esc SourceF ile= " $( EscapeSpaces " ${ TARGET [ $__replicaDir ] } ${ TARGET [ $__stateDir ] } / ${ INITIATOR [ $__failedDeletedListFile ] } " ) "
rsync C md= " $( type -p $RSYNC_EXECUTABLE ) --rsync-path=\" $RSYNC_PATH \" -e \" $RSYNC_SSH_CMD \" $REMOTE_USER @ $REMOTE_HOST :\" $esc SourceF ile\" \" ${ INITIATOR [ $__replicaDir ] } ${ INITIATOR [ $__stateDir ] } \" > \" $RUN_DIR / $PROGRAM .remote_failed_deletion_list_copy. $SCRIPT_PID \" "
Logger " RSYNC_CMD: $rsync C md" "DEBUG"
eval " $rsync C md" 2>> " $LOG_FILE "
result = $?
if [ $result != 0 ] ; then
Logger "Cannot copy back the failed deletion list to initiator replica." "CRITICAL"
@ -1138,36 +1136,34 @@ ENDSSH
return 0
}
# delete_ propagation(replica name, deleted_list_filename, deleted_failed_file_list )
function deletion_p ropagation {
# delete_ Propagation(replica type )
function deletionP ropagation {
local replicaType = " ${ 1 } " # Contains replica type: initiator, target
local deleted_list_file = " ${ 2 } " # file containing deleted file list, will be prefixed with replica type
local deleted_failed_list_file = " ${ 3 } " # file containing files that could not be deleted on last run, will be prefixed with replica type
__CheckArguments 3 $# ${ FUNCNAME [0] } " $@ " #__WITH_PARANOIA_DEBUG
__CheckArguments 1 $# ${ FUNCNAME [0] } " $@ " #__WITH_PARANOIA_DEBUG
local replica_d ir
local delete_d ir
local replicaDir
local deleteD ir
Logger " Propagating deletions to $replicaType replica. " "NOTICE"
if [ " $replicaType " = = " ${ INITIATOR [ $__type ] } " ] ; then
replica _d ir= " ${ INITIATOR [ $__replicaDir ] } "
delete _d ir= " ${ INITIATOR [ $__deleteDir ] } "
replica D ir= " ${ INITIATOR [ $__replicaDir ] } "
delete D ir= " ${ INITIATOR [ $__deleteDir ] } "
_delete_local " $replica_dir " " ${ TARGET [ $__type ] } $deleted_list_file " " $delete_dir " " ${ TARGET [ $__type ] } $deleted_failed_list_file "
_deleteLocal " $replicaType " " $replicaDir " " $deleteDir "
retval = $?
if [ $retval != 0 ] ; then
Logger " Deletion on replica $replicaType failed." "CRITICAL"
Logger " Deletion on $replicaType replica failed." "CRITICAL"
exit 1
fi
else
replica _d ir= " ${ TARGET [ $__replicaDir ] } "
delete _d ir= " ${ TARGET [ $__deleteDir ] } "
replica D ir= " ${ TARGET [ $__replicaDir ] } "
delete D ir= " ${ TARGET [ $__deleteDir ] } "
if [ " $REMOTE_OPERATION " = = "yes" ] ; then
_delete_remote " $replica_dir " " ${ INITIATOR [ $__type ] } $deleted_list_file " " $delete_dir " " ${ INITIATOR [ $__type ] } $deleted_failed_list_file "
_deleteRemote " $replicaType " " $replicaDir " " $deleteDir "
else
_delete_local " $replica_dir " " ${ INITIATOR [ $__type ] } $deleted_list_file " " $delete_dir " " ${ INITIATOR [ $__type ] } $deleted_failed_list_file "
_deleteLocal " $replicaType " " $replicaDir " " $deleteDir "
fi
retval = $?
if [ $retval = = 0 ] ; then
@ -1176,7 +1172,7 @@ function deletion_propagation {
fi
return $retval
else
Logger " Deletion on remote system failed. " "CRITICAL"
Logger " Deletion on $replicaType failed. " "CRITICAL"
if [ -f " $RUN_DIR / $PROGRAM .remote_deletion. $SCRIPT_PID " ] ; then
Logger " Remote:\n $( cat $RUN_DIR /$PROGRAM .remote_deletion.$SCRIPT_PID ) " "CRITICAL"
fi
@ -1261,12 +1257,12 @@ function Sync {
## Step 0a & 0b
if [ " $resumeInitiator " = = "none" ] || [ " $resumeTarget " = = "none" ] || [ " $resumeInitiator " = = " ${ SYNC_ACTION [0] } " ] || [ " $resumeTarget " = = " ${ SYNC_ACTION [0] } " ] ; then
if [ " $resumeInitiator " = = "none" ] || [ " $resumeInitiator " = = " ${ SYNC_ACTION [0] } " ] ; then
tree_l ist " ${ INITIATOR [ $__replicaDir ] } " " ${ INITIATOR [ $__type ] } " " ${ INITIATOR [ $__treeCurrentFile ] } " &
treeL ist " ${ INITIATOR [ $__replicaDir ] } " " ${ INITIATOR [ $__type ] } " " ${ INITIATOR [ $__treeCurrentFile ] } " &
initiatorPid = " $! "
fi
if [ " $resumeTarget " = = "none" ] || [ " $resumeTarget " = = " ${ SYNC_ACTION [0] } " ] ; then
tree_l ist " ${ TARGET [ $__replicaDir ] } " " ${ TARGET [ $__type ] } " " ${ INITIATOR [ $__treeCurrentFile ] } " &
treeL ist " ${ TARGET [ $__replicaDir ] } " " ${ TARGET [ $__type ] } " " ${ INITIATOR [ $__treeCurrentFile ] } " &
targetPid = " $! "
fi
@ -1306,12 +1302,12 @@ function Sync {
## Step 1a & 1b
if [ " $resumeInitiator " = = " ${ SYNC_ACTION [1] } " ] || [ " $resumeTarget " = = " ${ SYNC_ACTION [1] } " ] ; then
if [ " $resumeInitiator " = = " ${ SYNC_ACTION [1] } " ] ; then
delete_l ist " ${ INITIATOR [ $__type ] } " &
deleteL ist " ${ INITIATOR [ $__type ] } " &
initiatorPid = " $! "
fi
if [ " $resumeTarget " = = " ${ SYNC_ACTION [1] } " ] ; then
delete_l ist " ${ TARGET [ $__type ] } " &
deleteL ist " ${ TARGET [ $__type ] } " &
targetPid = " $! "
fi
@ -1351,7 +1347,7 @@ function Sync {
## Step 2
if [ " $resumeInitiator " = = " ${ SYNC_ACTION [2] } " ] || [ " $resumeTarget " = = " ${ SYNC_ACTION [2] } " ] ; then
if [ " $RSYNC_ATTR_ARGS " != "" ] ; then
sync_a ttrs " ${ INITIATOR [ $__replicaDir ] } " " $TARGET_SYNC_DIR "
syncA ttrs " ${ INITIATOR [ $__replicaDir ] } " " $TARGET_SYNC_DIR "
WaitForTaskCompletion $! $SOFT_MAX_EXEC_TIME $HARD_MAX_EXEC_TIME ${ FUNCNAME [0] } false $KEEP_LOGGING
if [ $? != 0 ] ; then
echo " ${ SYNC_ACTION [2] } " > " ${ INITIATOR [ $__initiatorLastActionFile ] } "
@ -1376,14 +1372,14 @@ function Sync {
if [ " $resumeInitiator " = = " ${ SYNC_ACTION [3] } " ] || [ " $resumeTarget " = = " ${ SYNC_ACTION [3] } " ] ; then
if [ " $CONFLICT_PREVALANCE " = = " ${ TARGET [ $__type ] } " ] ; then
if [ " $resumeTarget " = = " ${ SYNC_ACTION [3] } " ] ; then
sync_u pdate " ${ TARGET [ $__type ] } " " ${ INITIATOR [ $__type ] } " " ${ INITIATOR [ $__deletedListFile ] } "
syncU pdate " ${ TARGET [ $__type ] } " " ${ INITIATOR [ $__type ] } "
if [ $? = = 0 ] ; then
echo " ${ SYNC_ACTION [4] } " > " ${ INITIATOR [ $__targetLastActionFile ] } "
resumeTarget = " ${ SYNC_ACTION [4] } "
fi
fi
if [ " $resumeInitiator " = = " ${ SYNC_ACTION [3] } " ] ; then
sync_u pdate " ${ INITIATOR [ $__type ] } " " ${ TARGET [ $__type ] } " " ${ INITIATOR [ $__deletedListFile ] } "
syncU pdate " ${ INITIATOR [ $__type ] } " " ${ TARGET [ $__type ] } "
if [ $? = = 0 ] ; then
echo " ${ SYNC_ACTION [4] } " > " ${ INITIATOR [ $__initiatorLastActionFile ] } "
resumeInitiator = " ${ SYNC_ACTION [4] } "
@ -1391,14 +1387,14 @@ function Sync {
fi
else
if [ " $resumeInitiator " = = " ${ SYNC_ACTION [3] } " ] ; then
sync_u pdate " ${ INITIATOR [ $__type ] } " " ${ TARGET [ $__type ] } " " ${ INITIATOR [ $__deletedListFile ] } "
syncU pdate " ${ INITIATOR [ $__type ] } " " ${ TARGET [ $__type ] } "
if [ $? = = 0 ] ; then
echo " ${ SYNC_ACTION [4] } " > " ${ INITIATOR [ $__initiatorLastActionFile ] } "
resumeInitiator = " ${ SYNC_ACTION [4] } "
fi
fi
if [ " $resumeTarget " = = " ${ SYNC_ACTION [3] } " ] ; then
sync_u pdate " ${ TARGET [ $__type ] } " " ${ INITIATOR [ $__type ] } " " ${ INITIATOR [ $__deletedListFile ] } "
syncU pdate " ${ TARGET [ $__type ] } " " ${ INITIATOR [ $__type ] } "
if [ $? = = 0 ] ; then
echo " ${ SYNC_ACTION [4] } " > " ${ INITIATOR [ $__targetLastActionFile ] } "
resumeTarget = " ${ SYNC_ACTION [4] } "
@ -1410,12 +1406,12 @@ function Sync {
## Step 4a & 4b
if [ " $resumeInitiator " = = " ${ SYNC_ACTION [4] } " ] || [ " $resumeTarget " = = " ${ SYNC_ACTION [4] } " ] ; then
if [ " $resumeInitiator " = = " ${ SYNC_ACTION [4] } " ] ; then
deletion_p ropagation " ${ TARGET [ $__typ e] } " " ${ INITIATOR [ $__deletedListFile ] } " " ${ INITIATOR [ $__failedDeletedListFil e] } " &
deletionP ropagation " ${ TARGET [ $__typ e] } " &
initiatorPid = " $! "
fi
if [ " $resumeTarget " = = " ${ SYNC_ACTION [4] } " ] ; then
deletion_p ropagation " ${ INITIATOR [ $__typ e] } " " ${ INITIATOR [ $__deletedListFile ] } " " ${ INITIATOR [ $__failedDeletedListFil e] } " &
deletionP ropagation " ${ INITIATOR [ $__typ e] } " &
targetPid = " $! "
fi
@ -1456,12 +1452,12 @@ function Sync {
## Step 5a & 5b
if [ " $resumeInitiator " = = " ${ SYNC_ACTION [5] } " ] || [ " $resumeTarget " = = " ${ SYNC_ACTION [5] } " ] ; then
if [ " $resumeInitiator " = = " ${ SYNC_ACTION [5] } " ] ; then
tree_l ist " ${ INITIATOR [ $__replicaDir ] } " " ${ INITIATOR [ $__type ] } " " ${ INITIATOR [ $__treeAfterFile ] } " &
treeL ist " ${ INITIATOR [ $__replicaDir ] } " " ${ INITIATOR [ $__type ] } " " ${ INITIATOR [ $__treeAfterFile ] } " &
initiatorPid = " $! "
fi
if [ " $resumeTarget " = = " ${ SYNC_ACTION [5] } " ] ; then
tree_l ist " ${ TARGET [ $__replicaDir ] } " " ${ TARGET [ $__type ] } " " ${ INITIATOR [ $__treeAfterFile ] } " &
treeL ist " ${ TARGET [ $__replicaDir ] } " " ${ TARGET [ $__type ] } " " ${ INITIATOR [ $__treeAfterFile ] } " &
targetPid = " $! "
fi
@ -1504,14 +1500,14 @@ function Sync {
function _SoftDeleteLocal {
local replicaType = " ${ 1 } " # replica type (initiator, target)
local replica _deletion_p ath= " ${ 2 } " # Contains the full path to softdelete / backup directory without ending slash
local replica DeletionP ath= " ${ 2 } " # Contains the full path to softdelete / backup directory without ending slash
local changeTime = " ${ 3 } "
__CheckArguments 3 $# ${ FUNCNAME [0] } " $@ " #__WITH_PARANOIA_DEBUG
local retval
if [ -d " $replica _deletion_p ath" ] ; then
if [ -d " $replica DeletionP ath" ] ; then
if [ $_DRYRUN = = true ] ; then
Logger " Listing files older than $changeTime days on $replicaType replica. Does not remove anything. " "NOTICE"
else
@ -1520,14 +1516,14 @@ function _SoftDeleteLocal {
if [ $_VERBOSE = = true ] ; then
# Cannot launch log function from xargs, ugly hack
$COMMAND_SUDO $FIND_CMD " $replica _deletion_p ath/ " -type f -ctime +$changeTime -print0 | xargs -0 -I { } echo "Will delete file {}" >> " $RUN_DIR / $PROGRAM . ${ FUNCNAME [0] } . $SCRIPT_PID "
$COMMAND_SUDO $FIND_CMD " $replica DeletionP ath/ " -type f -ctime +$changeTime -print0 | xargs -0 -I { } echo "Will delete file {}" >> " $RUN_DIR / $PROGRAM . ${ FUNCNAME [0] } . $SCRIPT_PID "
Logger " Command output:\n $( cat $RUN_DIR /$PROGRAM .${ FUNCNAME [0] } .$SCRIPT_PID ) " "VERBOSE"
$COMMAND_SUDO $FIND_CMD " $replica _deletion_p ath/ " -type d -empty -ctime +$changeTime -print0 | xargs -0 -I { } echo "Will delete directory {}" >> " $RUN_DIR / $PROGRAM . ${ FUNCNAME [0] } . $SCRIPT_PID "
$COMMAND_SUDO $FIND_CMD " $replica DeletionP ath/ " -type d -empty -ctime +$changeTime -print0 | xargs -0 -I { } echo "Will delete directory {}" >> " $RUN_DIR / $PROGRAM . ${ FUNCNAME [0] } . $SCRIPT_PID "
Logger " Command output:\n $( cat $RUN_DIR /$PROGRAM .${ FUNCNAME [0] } .$SCRIPT_PID ) " "VERBOSE"
fi
if [ $_DRYRUN = = false ] ; then
$COMMAND_SUDO $FIND_CMD " $replica _deletion_p ath/ " -type f -ctime +$changeTime -print0 | xargs -0 -I { } $COMMAND_SUDO rm -f "{}" && $COMMAND_SUDO $FIND_CMD " $replica _deletion_p ath/ " -type d -empty -ctime +$changeTime -print0 | xargs -0 -I { } $COMMAND_SUDO rm -rf "{}" >> " $RUN_DIR / $PROGRAM . ${ FUNCNAME [0] } . $SCRIPT_PID " 2>& 1
$COMMAND_SUDO $FIND_CMD " $replica DeletionP ath/ " -type f -ctime +$changeTime -print0 | xargs -0 -I { } $COMMAND_SUDO rm -f "{}" && $COMMAND_SUDO $FIND_CMD " $replica DeletionP ath/ " -type d -empty -ctime +$changeTime -print0 | xargs -0 -I { } $COMMAND_SUDO rm -rf "{}" >> " $RUN_DIR / $PROGRAM . ${ FUNCNAME [0] } . $SCRIPT_PID " 2>& 1
else
Dummy
fi
@ -1538,16 +1534,16 @@ function _SoftDeleteLocal {
else
Logger " Cleanup complete on $replicaType replica. " "NOTICE"
fi
elif [ -d " $replica _deletion_path" ] && ! [ -w " $replica_deletion_p ath" ] ; then
Logger " The $replicaType replica dir [ $replica _deletion_p ath] is not writable. Cannot clean old files. " "ERROR"
elif [ -d " $replica DeletionPath" ] && ! [ -w " $replicaDeletionP ath" ] ; then
Logger " The $replicaType replica dir [ $replica DeletionP ath] is not writable. Cannot clean old files. " "ERROR"
else
Logger " The $replicaType replica dir [ $replica _deletion_p ath] does not exist. Skipping cleaning of old files. " "VERBOSE"
Logger " The $replicaType replica dir [ $replica DeletionP ath] does not exist. Skipping cleaning of old files. " "VERBOSE"
fi
}
function _SoftDeleteRemote {
local replicaType = " ${ 1 } "
local replica _deletion_p ath= " ${ 2 } " # Contains the full path to softdelete / backup directory without ending slash
local replica DeletionP ath= " ${ 2 } " # Contains the full path to softdelete / backup directory without ending slash
local changeTime = " ${ 3 } "
__CheckArguments 3 $# ${ FUNCNAME [0] } " $@ " #__WITH_PARANOIA_DEBUG
@ -1564,14 +1560,14 @@ function _SoftDeleteRemote {
if [ $_VERBOSE = = true ] ; then
# Cannot launch log function from xargs, ugly hack
cmd = $SSH_CMD ' "if [ -d \"' $replica _deletion_p ath'\" ]; then ' $COMMAND_SUDO ' ' $REMOTE_FIND_CMD ' \"' $replica _deletion_p ath'/\" -type f -ctime +' $changeTime ' -print0 | xargs -0 -I {} echo Will delete file {} && ' $COMMAND_SUDO ' ' $REMOTE_FIND_CMD ' \"' $replica _deletion_p ath'/\" -type d -empty -ctime ' $changeTime ' -print0 | xargs -0 -I {} echo Will delete directory {}; else echo \"The $replicaType replica dir [$replica _deletion_p ath] does not exist. Skipping cleaning of old files.\"; fi" > "'$RUN_DIR /$PROGRAM .${ FUNCNAME [0] } .$SCRIPT_PID '" 2>&1'
cmd = $SSH_CMD ' "if [ -d \"' $replica DeletionP ath'\" ]; then ' $COMMAND_SUDO ' ' $REMOTE_FIND_CMD ' \"' $replica DeletionP ath'/\" -type f -ctime +' $changeTime ' -print0 | xargs -0 -I {} echo Will delete file {} && ' $COMMAND_SUDO ' ' $REMOTE_FIND_CMD ' \"' $replica DeletionP ath'/\" -type d -empty -ctime ' $changeTime ' -print0 | xargs -0 -I {} echo Will delete directory {}; else echo \"The $replicaType replica dir [$replica DeletionP ath] does not exist. Skipping cleaning of old files.\"; fi" > "'$RUN_DIR /$PROGRAM .${ FUNCNAME [0] } .$SCRIPT_PID '" 2>&1'
Logger " cmd: $cmd " "DEBUG"
eval " $cmd "
Logger " Command output:\n $( cat $RUN_DIR /$PROGRAM .${ FUNCNAME [0] } .$SCRIPT_PID ) " "VERBOSE"
fi
if [ $_DRYRUN = = false ] ; then
cmd = $SSH_CMD ' "if [ -d \"' $replica _deletion_p ath'\" ]; then ' $COMMAND_SUDO ' ' $REMOTE_FIND_CMD ' \"' $replica _deletion_p ath'/\" -type f -ctime +' $changeTime ' -print0 | xargs -0 -I {} ' $COMMAND_SUDO ' rm -f \"{}\" && ' $COMMAND_SUDO ' ' $REMOTE_FIND_CMD ' \"' $replica _deletion_p ath'/\" -type d -empty -ctime ' $changeTime ' -print0 | xargs -0 -I {} ' $COMMAND_SUDO ' rm -rf \"{}\"; else echo \"The $replicaType replica _dir [$replica_deletion_p ath] does not exist. Skipping cleaning of old files.\"; fi" >> "'$RUN_DIR /$PROGRAM .${ FUNCNAME [0] } .$SCRIPT_PID '" 2>&1'
cmd = $SSH_CMD ' "if [ -d \"' $replica DeletionP ath'\" ]; then ' $COMMAND_SUDO ' ' $REMOTE_FIND_CMD ' \"' $replica DeletionP ath'/\" -type f -ctime +' $changeTime ' -print0 | xargs -0 -I {} ' $COMMAND_SUDO ' rm -f \"{}\" && ' $COMMAND_SUDO ' ' $REMOTE_FIND_CMD ' \"' $replica DeletionP ath'/\" -type d -empty -ctime ' $changeTime ' -print0 | xargs -0 -I {} ' $COMMAND_SUDO ' rm -rf \"{}\"; else echo \"The $replicaType replica Dir [$replicaDeletionP ath] does not exist. Skipping cleaning of old files.\"; fi" >> "'$RUN_DIR /$PROGRAM .${ FUNCNAME [0] } .$SCRIPT_PID '" 2>&1'
Logger " cmd: $cmd " "DEBUG"
eval " $cmd "
@ -1693,17 +1689,17 @@ function Init {
## Replica format
## Why the f*** does bash not have simple objects ?
# Local variables used for state filenames
local lock _f ilename= "lock"
local state _d ir= "state"
local backup _d ir= "backup"
local delete _d ir= "deleted"
local partial _d ir= "_partial"
local last _a ction= "last-action"
local resume _c ount= "resume-count"
local lock F ilename= "lock"
local state D ir= "state"
local backup D ir= "backup"
local delete D ir= "deleted"
local partial D ir= "_partial"
local last A ction= "last-action"
local resume C ount= "resume-count"
if [ " $_DRYRUN " = = true ] ; then
local dry _s uffix= "-dry"
local dry S uffix= "-dry"
else
local dry _s uffix=
local dry S uffix=
fi
# The following associative like array definitions are used for bash ver < 4 compat
@ -1726,27 +1722,27 @@ function Init {
INITIATOR = ( )
INITIATOR[ $__type ] = 'initiator'
INITIATOR[ $__replicaDir ] = " $INITIATOR_SYNC_DIR "
INITIATOR[ $__lockFile ] = " $INITIATOR_SYNC_DIR $OSYNC_DIR / $lock _f ilename"
INITIATOR[ $__stateDir ] = " $OSYNC_DIR / $state _d ir"
INITIATOR[ $__backupDir ] = " $OSYNC_DIR / $backup _d ir"
INITIATOR[ $__deleteDir ] = " $OSYNC_DIR / $delete _d ir"
INITIATOR[ $__partialDir ] = " $OSYNC_DIR / $partial _d ir"
INITIATOR[ $__initiatorLastActionFile ] = " $INITIATOR_SYNC_DIR $OSYNC_DIR / $state _dir/initiator- $last_action - $INSTANCE_ID $dry_s uffix"
INITIATOR[ $__targetLastActionFile ] = " $INITIATOR_SYNC_DIR $OSYNC_DIR / $state _dir/target- $last_action - $INSTANCE_ID $dry_s uffix"
INITIATOR[ $__resumeCount ] = " $INITIATOR_SYNC_DIR $OSYNC_DIR / $state _dir/ $resume_count - $INSTANCE_ID $dry_s uffix"
INITIATOR[ $__treeCurrentFile ] = " -tree-current- $INSTANCE_ID $dry _s uffix"
INITIATOR[ $__treeAfterFile ] = " -tree-after- $INSTANCE_ID $dry _s uffix"
INITIATOR[ $__lockFile ] = " $INITIATOR_SYNC_DIR $OSYNC_DIR / $lock F ilename"
INITIATOR[ $__stateDir ] = " $OSYNC_DIR / $state D ir"
INITIATOR[ $__backupDir ] = " $OSYNC_DIR / $backup D ir"
INITIATOR[ $__deleteDir ] = " $OSYNC_DIR / $delete D ir"
INITIATOR[ $__partialDir ] = " $OSYNC_DIR / $partial D ir"
INITIATOR[ $__initiatorLastActionFile ] = " $INITIATOR_SYNC_DIR $OSYNC_DIR / $state Dir/initiator- $lastAction - $INSTANCE_ID $dryS uffix"
INITIATOR[ $__targetLastActionFile ] = " $INITIATOR_SYNC_DIR $OSYNC_DIR / $state Dir/target- $lastAction - $INSTANCE_ID $dryS uffix"
INITIATOR[ $__resumeCount ] = " $INITIATOR_SYNC_DIR $OSYNC_DIR / $state Dir/ $resumeCount - $INSTANCE_ID $dryS uffix"
INITIATOR[ $__treeCurrentFile ] = " -tree-current- $INSTANCE_ID $dry S uffix"
INITIATOR[ $__treeAfterFile ] = " -tree-after- $INSTANCE_ID $dry S uffix"
INITIATOR[ $__treeAfterFileNoSuffix ] = " -tree-after- $INSTANCE_ID "
INITIATOR[ $__deletedListFile ] = " -deleted-list- $INSTANCE_ID $dry _s uffix"
INITIATOR[ $__failedDeletedListFile ] = " -failed-delete- $INSTANCE_ID $dry _s uffix"
INITIATOR[ $__deletedListFile ] = " -deleted-list- $INSTANCE_ID $dry S uffix"
INITIATOR[ $__failedDeletedListFile ] = " -failed-delete- $INSTANCE_ID $dry S uffix"
TARGET = ( )
TARGET[ $__type ] = 'target'
TARGET[ $__replicaDir ] = " $TARGET_SYNC_DIR "
TARGET[ $__lockFile ] = " $TARGET_SYNC_DIR $OSYNC_DIR / $lock _f ilename"
TARGET[ $__stateDir ] = " $OSYNC_DIR / $state _d ir"
TARGET[ $__backupDir ] = " $OSYNC_DIR / $backup _d ir"
TARGET[ $__deleteDir ] = " $OSYNC_DIR / $delete _d ir"
TARGET[ $__lockFile ] = " $TARGET_SYNC_DIR $OSYNC_DIR / $lock F ilename"
TARGET[ $__stateDir ] = " $OSYNC_DIR / $state D ir"
TARGET[ $__backupDir ] = " $OSYNC_DIR / $backup D ir"
TARGET[ $__deleteDir ] = " $OSYNC_DIR / $delete D ir"
PARTIAL_DIR = " ${ INITIATOR [ $__partialDir ] } "