source: src-sh/lpreserver/backend/runsnap.sh @ 37adeaf

releng/10.0.1releng/10.0.2releng/10.0.3releng/10.1
Last change on this file since 37adeaf was 37adeaf, checked in by Kris Moore <kris@…>, 10 months ago

Improve the logic behind replication, don't prune snaps which havn't been sent over
the wire yet

  • Property mode set to 100755
File size: 6.0 KB
Line 
1#!/bin/sh
2# Do the cron snapshot
3######################################################################
4
5# Set our vars
6PROGDIR="/usr/local/share/lpreserver"
7
8# Source our functions
9. /usr/local/share/pcbsd/scripts/functions.sh
10. ${PROGDIR}/backend/functions.sh
11
12do_auto_prune() {
13  echo_log "Pruning old snapshot: $2"
14  rmZFSSnap "$1" "$2"
15  if [ $? -ne 0 ] ; then
16     echo_log "ERROR: Failed pruning snapshot $2 on ${1}"
17     queue_msg "ERROR: Failed pruning snapshot $2 on ${1} @ `date`\n\r`cat $CMDLOG`"
18     snapStat=1
19  else
20     queue_msg "Success pruning snapshot $2 on ${1} @ `date`\n\r`cat $CMDLOG`"
21  fi
22}
23
24do_numeric_prune()
25{
26
27  # Get our list of snaps
28  snaps=$(snaplist "${DATASET}")
29
30  # Reverse the list
31  for tmp in $snaps
32  do
33     rSnaps="$tmp $rSnaps"
34  done
35
36  # Do any pruning
37  num=0
38  for snap in $rSnaps
39  do
40     # Only remove snapshots which are auto-created, so we don't delete one the user
41     # made specifically
42     cur="`echo $snap | cut -d '-' -f 1`"
43     if [ "$cur" != "auto" ] ; then continue; fi
44
45     num=`expr $num + 1`
46     if [ $num -gt $KEEP ] ; then
47        do_auto_prune "$DATASET" "$snap"
48     fi
49  done
50}
51
52# Function to do automatic rotation / pruning
53do_automatic_prune()
54{
55  curEpoc=`date +%s`
56  lastYear=""; lastMon=""; lastDay=""; lastHour="" lastMin="" ; lastSec=""
57  # Get our list of snaps
58  snaps=$(snaplist "${DATASET}")
59
60  # Reverse the list, sort from newest to oldest
61  for tmp in $snaps
62  do
63     rSnaps="$tmp $rSnaps"
64  done
65
66  # Get the last replicated snapshot
67  lastSEND=`zfs get -r backup:lpreserver ${LDATA} | grep LATEST | awk '{$1=$1}1' OFS=" " | tail -1 | cut -d '@' -f 2 | cut -d ' ' -f 1`
68  if [ -n "$lastSend" ] ; then
69     sec="`echo $lastSend | cut -d '-' -f 7`"
70     min="`echo $lastSend | cut -d '-' -f 6`"
71     hour="`echo $lastSend | cut -d '-' -f 5`"
72     day="`echo $lastSend | cut -d '-' -f 4`"
73     mon="`echo $lastSend | cut -d '-' -f 3`"
74     year="`echo $lastSend | cut -d '-' -f 2`"
75     sendEpoc=`date -j -f "%Y %m %d %H %M %S" "$year $mon $day $hour $min $sec" "+%s"`
76  fi
77
78  num=0
79  for snap in $rSnaps
80  do
81     # Skip snaps not created by life-preserver
82     cur="`echo $snap | cut -d '-' -f 1`"
83     if [ "$cur" != "auto" ] ; then continue; fi
84
85     # If this snapshot is the last one replicated, lets skip pruning it for now
86     if [ "$cur" = "$lastSEND" ]; then continue; fi
87
88     sec="`echo $snap | cut -d '-' -f 7`"
89     min="`echo $snap | cut -d '-' -f 6`"
90     hour="`echo $snap | cut -d '-' -f 5`"
91     day="`echo $snap | cut -d '-' -f 4`"
92     mon="`echo $snap | cut -d '-' -f 3`"
93     year="`echo $snap | cut -d '-' -f 2`"
94
95     # Convert this snap to epoc time
96     snapEpoc=`date -j -f "%Y %m %d %H %M %S" "$year $mon $day $hour $min $sec" "+%s"`
97
98     # If we are replicating, don't prune anything which hasn't gone out yet
99     if [ -n "$sendEpoc" ] ; then
100        if [ $sendEpoc -gt $snapEpoc ] ; then continue; fi
101     fi
102
103     # Get the epoch time elapsed
104     check=`expr $curEpoc - $snapEpoc`
105     pruned=0
106
107     # Looking for snaps older than 12 months
108     if [ $check -gt 31536000 ]; then
109        do_auto_prune "$DATASET" "$snap"
110        pruned=1
111     fi
112
113     # Looking for multiple snaps older than 30 days
114     if [ $check -gt 2592000 -a $pruned -eq 0 ]; then
115        # Did we already have a snapshot from this month?
116        if [ "$year" = "$lastYear" -a "$mon" = "$lastMon" ] ; then
117          do_auto_prune "$DATASET" "$snap"
118          pruned=1
119        fi
120     fi
121
122     # Looking for multiple snaps older than a day
123     if [ $check -gt 86400 -a $pruned -eq 0 ]; then
124        if [ "$year" = "$lastYear" -a "$mon" = "$lastMon" -a "$day" = "$lastDay" ] ; then
125          do_auto_prune "$DATASET" "$snap"
126          pruned=1
127        fi
128     fi
129
130     # Looking for multiple snaps older than an hour
131     if [ $check -gt 3600 -a $pruned -eq 0 ]; then
132        if [ "$year" = "$lastYear" -a "$mon" = "$lastMon" -a "$day" = "$lastDay" -a "$hour" = "$lastHour" ] ; then
133          do_auto_prune "$DATASET" "$snap"
134          pruned=1
135        fi
136     fi
137
138     # Save values of this snapshot for next pass
139     lastYear="$year" ; lastMon="$mon" ; lastDay="$day" ; lastHour="$hour"
140     lastMin="$min" ; lastSec="$sec"
141  done
142
143}
144
145# Now run the main script
146DATASET="${1}"
147KEEP="${2}"
148snapStat=0
149
150if [ -z "${DATASET}" ]; then
151  exit_err "No dataset specified!"
152fi
153
154# Make sure this is a valid DATASET
155zfs list ${DATASET} >/dev/null 2>/dev/null
156if [ $? -ne 0 ] ; then
157   exit_err "Invalid dataset specified ${DATASET}"
158fi
159
160# Create the snapshot now with the "auto-" tag
161echo_log "Creating snapshot on ${DATASET}"
162mkZFSSnap "${DATASET}" "auto-"
163if [ $? -ne 0 ] ; then
164  echo_log "ERROR: Failed creating snapshot on ${DATASET}"
165  queue_msg "ERROR: Failed creating snapshot on ${DATASET} @ `date`\n\r`cat $CMDLOG`"
166  snapStat=1
167else
168  queue_msg "Success creating snapshot on ${DATASET} @ `date`\n\r`cat $CMDLOG`"
169fi
170
171# Before we start pruning, check if any replication is running
172skipPrune=0
173export pidFile="${DBDIR}/.reptask-`echo ${DATASET} | sed 's|/|-|g'`"
174if [ -e "${pidFile}" ] ; then
175   pgrep -F ${pidFile} >/dev/null 2>/dev/null
176   if [ $? -eq 0 ] ; then skipPrune=1; fi
177fi
178
179if [ $skipPrune -eq 1 ] ; then
180  # No pruning since replication is currently running
181  echo_log "WARNING: Skipped pruning snapshots on ${DATASET} while replication is running."
182  queue_msg "WARNING: Skipped pruning snapshots on ${DATASET} while replication is running."
183else
184  # Safe to do the pruning, no replication is in progress
185  if [ "$KEEP" = "auto" ] ; then
186     do_automatic_prune
187  else
188     do_numeric_prune
189  fi
190fi
191
192# If we failed at any point, sent out a notice
193if [ $snapStat -ne 0 ] ; then
194   email_msg "FAILED - Automated Snapshot" "`echo_queue_msg`"
195fi
196
197# If we are successful and user wants all notifications, send out a message
198if [ $snapStat -eq 0 -a "$EMAILMODE" = "ALL" ] ; then
199   email_msg "Success - Automated Snapshot" "`echo_queue_msg`"
200else
201   rm ${MSGQUEUE} 2>/dev/null
202fi
203
204# Check if we need to run a replication task for this dataset
205${PROGDIR}/backend/runrep.sh ${DATASET} sync
Note: See TracBrowser for help on using the repository browser.