X-Git-Url: https://git.rrq.au/?a=blobdiff_plain;f=sss.sh;h=35b592530c5a7f48a71b47f32b342e937d15766a;hb=refs%2Fheads%2Fmaster;hp=c514643279ecacde1ba546a4d79bfc9ca1c60e22;hpb=9602af81a13f1706b19ae36eef2cdc8356bbc868;p=rrq%2Fnilfs2sss.git diff --git a/sss.sh b/sss.sh index c514643..35b5925 100755 --- a/sss.sh +++ b/sss.sh @@ -6,87 +6,74 @@ # so as to preserve 7 most recent daily, 4 most recent weekly and 12 # most recent monthly snapshots, in addition to labelled ones. # -# The cron bot is expected to run once an hour +# The cron bot is expected to run once a minute -# hourly = every hour -# daily = .. keep one of the hourly yesterday -# weekly = .. keep one of the daily last week -# monthly = .. keep one of the daily last month +# Name of snapshot tag file for "important" snapshots. Format: +# $CNO .... one line for each $CNO that should be preserved as snapshot +# chcp ss $CNO && echo $CNO >> $NAMELIST +NAMELIST=/etc/nilfs2sss.list -DEV=/dev/sda5 +# The hour-of-day to preserve as daily snapshot KEEPHH=12 + +# The day-of-month to preserve as monthly snapshot KEEPDD=15 +DEV=$1 +[ "$2" = "all" ] || LSCP="-s" + +if [ -z "$DEV" ] ; then + DEVS=( $( mount | grep nilfs2 | sed 's/ .*//' ) ) + DEV=${DEVS[0]} + if [ -z "$DEV" ] ; then + echo "Error* cannot find a mounted nilfs2 partition" >&2 + exit 1 + fi +fi + FIVELY="$(date -d '-5 minutes' '+%Y-%m-%d %H:%M:%S')" HOURLY="$(date -d '-1 hour' '+%Y-%m-%d %H:%M:%S')" -DAILY="$(date -d '-1 days' '+%Y-%m-%d %H:%M:%S')" -MONTHLY="$(date -d '-1 months' '+%Y-%m-%d %H:%M:%S')" +DAILY="$(date -d '-1 day' '+%Y-%m-%d %H:%M:%S')" +MONTHLY="$(date -d '-1 month' '+%Y-%m-%d %H:%M:%S')" WEEKLY="$(date -d '-7 days' '+%Y-%m-%d %H:%M:%S')" -YEARLY="$(date -d '-1 years' '+%Y-%m-%d %H:%M:%S')" +YEARLY="$(date -d '-1 year' '+%Y-%m-%d %H:%M:%S')" -date "+%Y-%m-%d %H:%M:%S ---- checking" >&2 -lscp -s | while read CNO DATE TIME REST ; do - TS="$DATE $TIME" - [ "$CNO" = "CNO" ] && continue - if [[ ! "$TS" > "$YEARLY" ]] ; then - if [ "$KEEPYY" = "${DATE:0:4}" ] ; then - echo "# discard year duplicate $CNO $DATE $TIME" >&2 - chcp cp $CNO +MARK=( ) +function marksnap() { + if [[ "${MARK[0]}" == "$1" ]] && [[ "${MARK[1]}" = "$2" ]] ; then + if [ -r "$NAMELIST" ] && grep -q ^$3 "$NAMELIST" ; then + : # Don't change important snapshots else - KEEPYY="${DATE:0:4}" + chcp cp $DEV ${MARK[2]} fi - echo "# keep first of year $CNO $DATE $TIME" >&2 - continue fi - # Within last year - if [[ ! "$TS" > "$MONTHLY" ]] ; then - if [ "$KEEPMM" = "${DATE:0:7}" ] ; then - echo "# discard month duplicate $CNO $DATE $TIME" >&2 - chcp cp $CNO - else - KEEPMM="${DATE:0:7}" - fi - fi - # Within last month - if [[ ! "$TS" > "$WEEKLY" ]] ; then - if [[ "$KEEPDD" = "${DATE:8:2}" ]] ; then - if [ -z "$KEEPWW" ] ; then - KEEPWW="${DATE:8:2}" - continue - fi - echo "# discard duplicate day $KEEPDD: $CNO $DATE $TIME" >&2 - else - echo "# discard not day $KEEPDD: $CNO $DATE $TIME" >&2 - fi - chcp cp $CNO - continue - fi - # Within last week - if [[ ! "$TS" > "$DAILY" ]] ; then - [[ "$KEEPHH" = "${TIME:0:2}" ]] && continue - echo "# discard not hour $KEEPHH: $CNO $DATE $TIME" >&2 - chcp cp $CNO - continue - fi - # Within last day - if [[ ! "$TS" > "$HOURLY" ]] ; then - if [ "$KEEP55" = "${TIME:0:2}" ] ; then - echo "# discard duplicate for hour $KEEP55: $CNO $DATE $TIME" >&2 - chcp cp $CNO - else - KEEP55="${TIME:0:2}" - #echo "# keep first of hour $KEEP55: $CNO $DATE $TIME" >&2 - fi - continue - fi - # Within last hour - #echo "# keep within last hour $CNO $DATE $TIME" >&2 - [[ ! "$TS" > "$FIVELY" ]] && continue - echo "$CNO $DATE $TIME is within last five minutes" - #echo "# $CNO is within last five minutes " >&2 -done | if read X ; then - : -elif [[ $(( $(date +%M) % 5 )) = 0 ]] ; then - date "+# new snapshot at %Y-%m-%d %H:%M:%S" >&2 - mkcp -s $DEV -fi + MARK=( "$1" "$2" "$3" ) +} + +{ flock 9 + + date "+$DEV: %Y-%m-%d %H:%M:%S ---- checking" >&2 + lscp $LSCP $DEV | while read CNO DATE TIME REST ; do + TS="$DATE $TIME" + [ "$CNO" = "CNO" ] && continue + if [[ ! "$TS" > "$YEARLY" ]] ; then + marksnap YEAR "${DATE:0:4}" $CNO + elif [[ ! "$TS" > "$MONTHLY" ]] ; then + marksnap MONTH "${DATE:5:2}" $CNO + elif [[ ! "$TS" > "$WEEKLY" ]] ; then + # For older than most recent week, keep last snapshot each week + marksnap WEEK "$(( 7${DATE:8:2} / 7 - 100 ))" $CNO + elif [[ ! "$TS" > "$DAILY" ]] ; then + marksnap DAY "${DATE:8:2}" $CNO + elif [[ ! "$TS" > "$HOURLY" ]] ; then + marksnap HOUR "${DATE:8:2}-${TIME:0:2}" $CNO + else + : # echo "$CNO $DATE $TIME within last hour" + fi + done | if read X ; then + : # snapshot within last hour + else + date "+$DEV: new snapshot at %Y-%m-%d %H:%M:%S" >&2 + mkcp -s $DEV + fi +} 9> /var/run/lock/sss.lock