From: Ralph Ronnquist <ralph.ronnquist@gmail.com>
Date: Tue, 8 Dec 2020 02:16:56 +0000 (+1100)
Subject: reworked logic
X-Git-Url: https://git.rrq.au/?a=commitdiff_plain;h=a95b79e5cbf15cc74b038c649365400e1f50aab7;p=rrq%2Fnilfs2sss.git

reworked logic
---

diff --git a/sss.sh b/sss.sh
index c514643..af393fb 100755
--- a/sss.sh
+++ b/sss.sh
@@ -6,87 +6,151 @@
 # 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
-
-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
+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
-	else
-	    KEEPYY="${DATE:0:4}"
-	fi
-	echo "# keep first of year $CNO $DATE $TIME" >&2
-	continue
+function older_than_a_year() {
+    #echo "--- $CNO $DATE $TIME" >&2
+    [[ ! "$TS" < "$YEARLY" ]] && return 1
+    #echo "# keep the first snapshot of older years: $CNO $DATE $TIME" >&2
+    if [ "$KEEPYY" = "${DATE:0:4}" ] ; then
+	echo "$DEV: discard year duplicate $CNO $DATE $TIME" >&2
+	chcp cp $DEV $CNO
+    else
+	KEEPYY="${DATE:0:4}"
     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
+    return 0
+}
+
+function older_than_a_month() {
+    [[ ! "$TS" < "$MONTHLY" ]] && return 1
+    #echo "# keep the first snapshot of older months" >&2
+    if [ "$KEEPMM" = "${DATE:0:7}" ] ; then
+	echo "$DEV: discard month duplicate $CNO $DATE $TIME" >&2
+	chcp cp $DEV $CNO
+    else
+	KEEPMM="${DATE:0:7}"
+    fi
+    return 0
+}
+
+function older_than_a_week() {
+    [[ ! "$TS" < "$WEEKLY" ]] && return 1
+    if [[ "${DATE:8:2}" < "$KEEPDD" ]] ; then
+	#echo "# keep latest when before choice date: $CNO $DATE $TIME" >&2
+	if [ -n "$KEEPWW0" ] ; then
+	    echo "$DEV: discard outed $KEEPWW0" >&2
+	    chcp cp $DEV $KEEPWW0
+	fi
+	KEEPWW0=( $CNO $DATE $TIME ) 
+    else
+	#echo "# keep first when at or after choice date: $CNO $DATE $TIME" >&2
+	if [ -z "$KEEPWW" ] ; then
+	    if [ -n "$KEEPWW0" ] ; then
+		echo "$DEV: discard outed $KEEPWW0" >&2
+		chcp cp $DEV $KEEPWW0
+	    fi
+	    KEEPWW=( $CNO $DATE $TIME )
+	    continue
 	else
-	    KEEPMM="${DATE:0:7}"
+	    echo "$DEV: discard monthly extras: $CNO $DATE $TIME" >&2
+	    chcp cp $DEV $CNO
 	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
+    return 0
+}
+
+function older_than_a_day() {
+    [[ ! "$TS" < "$DAILY" ]] && return 1
+    if [[ "${TIME:0:2}" < "$KEEPHH" ]] ; then
+	#echo "# keep latest when before choice hour: $CNO $DATE $TIME" >&2
+	if [ -n "$KEPTHH0" ] ; then
+            echo "$DEV: discard outed $KEPTHH0" >&2
+            chcp cp $DEV $KEPTHH0
+        fi
+        KEPTHH0=( $CNO $DATE $TIME )
+    else
+	#echo "# keep first when at/after choice hour: $CNO $DATE $TIME" >&2
+	if [ -z "$KEPTHH" ] ; then
+	    if [ -n "$KEPTHH0" ] ; then
+		echo "$DEV: discard outed $KEPTHH0" >&2
+		chcp cp $DEV $KEPTHH0
+		KEPTHH0=
+            fi
+            KEPTHH=( $CNO $DATE $TIME )
+	else
+	    echo "$DEV: discard daily extras: $CNO $DATE $TIME" >&2
+	    chcp cp $DEV $CNO
 	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
+}
+
+function older_than_an_hour() {
+    [[ ! "$TS" < "$HOURLY" ]] && return 1
+    #echo "# keep first of each hour: $CNO $DATE $TIME" >&2
+    if [[ "$KEPT55"  != "${TIME:0:2}" ]] ; then
+	KEPT55="${TIME:0:2}"
+    else
+	echo "$DEV: discard hourly duplicate: $CNO $DATE $TIME" >&2
+	chcp cp $DEV $CNO
     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
+    return 0
+}
+
+function older_than_5_minutes() {
+    if [[ ! "$TS" < "$FIVELY" ]] ; then
+	echo "$CNO $DATE $TIME is within last five minutes"
+    else
+	: # no noise here
+	if [[ "$TS" < "$NEXT" ]] ; then
+	    echo "$DEV: discard 5-minutely duplicate: $CNO $DATE $TIME" >&2
+	    chcp cp $DEV $CNO
 	else
-	    KEEP55="${TIME:0:2}"
-	    #echo "# keep first of hour $KEEP55: $CNO $DATE $TIME" >&2
+	    T=${TS:0:15}$(( ( ${TS:15:1} / 5 ) * 5 )):00
+	    NEXT="$(date -d "5 minutes $T" '+%Y-%m-%d %H:%M:%S')"
+	    #echo "NEXT=$NEXT" >&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
+}
+
+{ flock 9
+
+date "+$DEV: %Y-%m-%d %H:%M:%S ---- checking" >&2
+lscp -s $DEV | while read CNO DATE TIME REST ; do
+    TS="$DATE $TIME"
+    [ "$CNO" = "CNO" ] ||
+	older_than_a_year ||
+	older_than_a_month ||
+	older_than_a_week ||
+	older_than_a_day ||
+	older_than_an_hour ||
+	older_than_5_minutes
 done | if read X ; then
     :
-elif [[ $(( $(date +%M) % 5 )) = 0 ]] ; then
-    date "+# new snapshot at %Y-%m-%d %H:%M:%S" >&2
+elif [[ $(( $(date +%M|sed 's/^0//') % 5 )) = 0 ]] ; then
+    date "+$DEV: new snapshot at %Y-%m-%d %H:%M:%S" >&2
     mkcp -s $DEV
 fi
+} 9> /var/run/lock/sss.lock