sync-functions 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. #!/bin/bash
  2. ### sync data
  3. TM=`date +%y%m%d-%H%M`
  4. WORKDIR=
  5. ROOTPATH=
  6. USERID=
  7. PASSWDFILE=
  8. HOST=
  9. OPTS=
  10. BACKUPDIR=
  11. #max deleted file summary size limit for normal backup
  12. DELLIMIT="102400000"
  13. #max deleted file count for normal backup
  14. MAXFILES=100
  15. LOGDIR="/var/log/rsync"
  16. ADMINEMAIL="root"
  17. RSYNC=`which rsync`
  18. MODE=
  19. SETLOCALE=
  20. #SETLOCALE="LANG=ru_RU.UTF-8"
  21. #SETLOCALE="LANG=ru_RU.KOI8-R"
  22. #ICONV="--iconv=KOI8-R,UTF-8"
  23. ICONV=
  24. #basename
  25. BN=`basename $0`
  26. LOG1="$LOGDIR/$BN.log"
  27. #lock file for working process
  28. LOCK1="/var/run/$BN.pid"
  29. #debug
  30. DEBUG=1
  31. DEBUG_LOG=${LOG1}
  32. [ ! -e "${LOGDIR}" ] && {
  33. mkdir -p ${LOGDIR} >/dev/null 2>&1
  34. chmod 750 ${LOGDIR} >/dev/null 2>&1
  35. }
  36. function log_debug {
  37. [ "${DEBUG}" -eq 0 ] && return
  38. TS="`date +%Y%m%d-%H%M%S` DEBUG:"
  39. echo "$1" | while read LINE; do
  40. echo "${TS} ${LINE}" >>${DEBUG_LOG}
  41. done
  42. }
  43. function log_info {
  44. TS="`date +%Y%m%d-%H%M%S` INFO:"
  45. echo "$1" | while read LINE; do
  46. echo "${TS} ${LINE}" >>${LOG1}
  47. done
  48. }
  49. function log_error {
  50. TS="`date +%Y%m%d-%H%M%S` ERROR:"
  51. echo "$1" | while read LINE; do
  52. echo "${TS} ${LINE}" >>${LOG1}
  53. done
  54. }
  55. function do_exit {
  56. log_debug "Script work $SECONDS sec. Exit code: $1"
  57. [ -n $1 ] && exit $1 || exit
  58. }
  59. function do_exec {
  60. [ -z "$1" ] && return
  61. FAIL="OK"
  62. eval "$1" || { FAIL="FAIL"; }
  63. log_debug "$1 - $FAIL"
  64. eval "FAIL=${FAIL}"
  65. }
  66. function check_run {
  67. log_debug "Check for always running - search pid-file $LOCK1"
  68. while [ -f $LOCK1 ]; do
  69. local PID=`cat $LOCK1`
  70. if [ -z `ps awx | awk '{ print $1}' | grep "^$PID$"` ]; then
  71. log_error "Найден ничейный файл блокировки! pid=$PID. Удаляю! "
  72. do_exec "rm -f $LOCK1 >/dev/null 2>&1"
  73. else
  74. log_error "Скрипт $BN уже запущен pid=$PID. Жду 5 сек..."
  75. sleep 5
  76. fi
  77. done
  78. }
  79. function create_lock {
  80. log_debug "Check for always running - search pid $LOCK1"
  81. [ -f $LOCK1 ] && {
  82. log_debug "Pid file found. Aborting..."
  83. exit 100
  84. }
  85. log_debug "Create pid file $LOCK1"
  86. do_exec "echo '$$'>$LOCK1"
  87. }
  88. function remove_lock {
  89. local PID=`cat $LOCK1`
  90. if [ $PID -ne $$ ]; then
  91. log_error "Файл блокировки принадлежит другому процессу с pid=$PID, мой pid=$$. Exiting... "
  92. do_exit 100
  93. else
  94. log_debug "Remove pid file."
  95. do_exec "rm -f $LOCK1 >/dev/null 2>&1"
  96. fi
  97. }
  98. function set_locale {
  99. [ -z "${SETLOCALE}" ] && return
  100. export LANG=${SETLOCALE}
  101. export LC_ALL=${SETLOCALE}
  102. }
  103. function send_email {
  104. BODY=$1
  105. [ ! -e "${BODY}" ] && return
  106. SUBJ=$2
  107. set_locale
  108. [ -z "${SUBJ}" ] && SUBJ="Mail from $BN at $HOSTNAME"
  109. CHARSET=`locale | grep LANG | awk -F. '{ print $2 }'`
  110. [ -z "$CHARSET" ] && CHARSET=`cat /etc/sysconfig/i18n | grep LANG | awk -F. '{ print $2 }' | sed 's/"//g;'`
  111. SUBJ=`echo -ne "${SUBJ}\nMIME-Version: 1.0\nContent-Language: ru\nContent-Type: text/html; charset=$CHARSET\nContent-Transfer-Encoding: 8bit"`
  112. cat "${BODY}" | sed 's/$/<br>/g;' | mail -s "${SUBJ}" "${ADMINEMAIL}"
  113. }
  114. #-------------------------------------------------------------------------
  115. function sync_data() {
  116. set_locale
  117. do_exec "mkdir -p /var/log/rsync"
  118. TM=`date +%y%m%d-%H%M`
  119. do_exec "$RSYNC -rltvh $ICONV $OPTS --partial --delete --delete-after --delay-updates --password-file=$1 $2@$3::$4 $5 >$LOGDIR/$3-$4-$TM.log 2>&1"
  120. send_email "$LOGDIR/$4-$TM.log" "Sync report for $4 at $HOSTNAME"
  121. }
  122. function append_data() {
  123. set_locale
  124. do_exec "mkdir -p /var/log/rsync"
  125. TM=`date +%y%m%d-%H%M`
  126. do_exec "$RSYNC -rltvh $ICONV $OPTS --partial --append --password-file=$1 $2@$3::$4 $5 >$LOGDIR/$3-$4-$TM.log 2>&1"
  127. send_email "$LOGDIR/$4-$TM.log" "Sync report for $4 at $HOSTNAME"
  128. }
  129. function check_sync() {
  130. set_locale
  131. WORKLIST=`$RSYNC -rltn $ICONV $OPTS --out-format="%o %f" --delete --delete-after --delay-updates --password-file=$1 $2@$3::$4 $5`
  132. DELLIST=`echo "${WORKLIST}" | grep -i "^del." | sed 's/^del. //'`
  133. RECVLIST=`echo "${WORKLIST}" | grep -i "^recv " | sed 's/^recv //'`
  134. TMP=`mktemp -t rsync.XXXXXXXXXX`
  135. cat /dev/null >$TMP
  136. echo "$DELLIST" | while read FN; do
  137. FF="$ROOTPATH/$WORKDIR/$FN"
  138. [ -f "$FF" ] && /usr/bin/du -b "$FF" >>$TMP
  139. done
  140. SD=`cat $TMP | awk '{ s = s + \$1 } END { print s }'`
  141. [ -z $SD ] && SD="0"
  142. DC=`echo "$DELLIST" | wc -l`
  143. rm -f $TMP
  144. LIMIT=`expr $SD / $DELLIMIT`
  145. [ -z $LIMIT ] && LIMIT="0"
  146. if [ $LIMIT -gt 1 -o $DC -gt $MAXFILES ]; then
  147. TMP=`mktemp -t rsync.XXXXXXXXXX`
  148. echo "On main share $WORKDIR deleted $DC files, total size $SD bytes. List of deleted files:" >$TMP
  149. echo >>$TMP
  150. echo "$DELLIST" >>$TMP
  151. echo >>$TMP
  152. echo "New files list: ">>$TMP
  153. echo "$RECVLIST" >>$TMP
  154. echo >>$TMP
  155. echo "Please check share and sync manyally..." >>$TMP
  156. eval "ERRFILE=${TMP}"
  157. else
  158. eval "ERRFILE="
  159. fi
  160. }
  161. function sync_share() {
  162. if [ "$MODE" != "manual" ]; then
  163. check_sync $PASSWDFILE $USERID $HOST $WORKDIR "$ROOTPATH/$BACKUPDIR"
  164. if [ -f "$ERRFILE" -a ! -z "$ERRFILE" ]; then
  165. if [ -z "$MODE" -o "$MODE" == "viewonly" ]; then
  166. cat $ERRFILE
  167. else
  168. send_email "$ERRFILE" "Warning! Sync $WORKDIR at $HOSTNAME is overlimit!"
  169. fi
  170. rm -f $ERRFILE
  171. exit 1
  172. fi
  173. fi
  174. sync_data $PASSWDFILE $USERID $HOST $WORKDIR "$ROOTPATH/$BACKUPDIR"
  175. }
  176. function append_share() {
  177. append_data $PASSWDFILE $USERID $HOST $WORKDIR "$ROOTPATH/$BACKUPDIR"
  178. }
  179. log_debug "Running $0 $*"
  180. log_debug "by user $USER($UID) with effective uid:$EUID"
  181. log_debug "Parent process id: $PPID (`ps --no-heading -o command -p $PPID`)."
  182. log_debug "Process id: $$"