add "all" option for scanning all choicepoints
[rrq/nilfs2sss.git] / sss.sh
1 #!/bin/bash
2 #
3 # Snapshot Snapping Scheme
4 #
5 # This is a cron bot to manage the snapshots of an nilfs2 file system,
6 # so as to preserve 7 most recent daily, 4 most recent weekly and 12
7 # most recent monthly snapshots, in addition to labelled ones.
8 #
9 # The cron bot is expected to run once a minute
10
11 # Name of snapshot tag file for "important" snapshots. Format:
12 # $CNO .... one line for each $CNO that should be preserved as snapshot
13 # chcp ss $CNO && echo $CNO >> $NAMELIST
14 NAMELIST=/etc/nilfs2sss.list
15
16 # The hour-of-day to preserve as daily snapshot
17 KEEPHH=12
18
19 # The day-of-month to preserve as monthly snapshot
20 KEEPDD=15
21
22 DEV=$1
23 [ "$2" = "all" ] || LSCP="-s"
24
25 if [ -z "$DEV" ] ; then
26     DEVS=( $( mount | grep nilfs2 | sed 's/ .*//' ) )
27     DEV=${DEVS[0]}
28     if [ -z "$DEV" ] ; then
29         echo "Error* cannot find a mounted nilfs2 partition" >&2
30         exit 1
31     fi
32 fi
33
34 FIVELY="$(date -d '-5 minutes' '+%Y-%m-%d %H:%M:%S')"
35 HOURLY="$(date -d '-1 hour' '+%Y-%m-%d %H:%M:%S')"
36 DAILY="$(date -d '-1 day' '+%Y-%m-%d %H:%M:%S')"
37 MONTHLY="$(date -d '-1 month' '+%Y-%m-%d %H:%M:%S')"
38 WEEKLY="$(date -d '-7 days' '+%Y-%m-%d %H:%M:%S')"
39 YEARLY="$(date -d '-1 year' '+%Y-%m-%d %H:%M:%S')"
40
41 MARK=( )
42 function marksnap() {
43     if [[ "${MARK[0]}" == "$1" ]] && [[ "${MARK[1]}" = "$2" ]] ; then
44         if [ -r "$NAMELIST" ] && grep -q ^$3 "$NAMELIST" ; then
45             : # Don't change important snapshots
46         else
47             chcp cp $DEV ${MARK[2]}
48         fi
49     fi
50     MARK=( "$1" "$2" "$3" )
51 }
52
53 { flock 9
54
55   date "+$DEV: %Y-%m-%d %H:%M:%S ---- checking" >&2
56   lscp $LSCP $DEV | while read CNO DATE TIME REST ; do
57       TS="$DATE $TIME"
58       [ "$CNO" = "CNO" ] && continue
59       if [[ ! "$TS" > "$YEARLY" ]] ; then
60           marksnap YEAR "${DATE:0:4}" $CNO
61       elif [[ ! "$TS" > "$MONTHLY" ]] ; then
62            marksnap MONTH "${DATE:5:2}" $CNO
63       elif [[ ! "$TS" > "$WEEKLY" ]] ; then
64            # For older than most recent week, keep last snapshot each week
65            marksnap WEEK "$(( 7${DATE:8:2} / 7 - 100 ))" $CNO
66       elif [[ ! "$TS" > "$DAILY" ]] ; then
67            marksnap DAY "${DATE:8:2}" $CNO
68       elif [[ ! "$TS" > "$HOURLY" ]] ; then
69            marksnap HOUR "${DATE:8:2}-${TIME:0:2}" $CNO
70       else
71           : # echo "$CNO $DATE $TIME within last hour"
72       fi
73   done | if read X ; then
74       : # snapshot within last hour
75   else
76       date "+$DEV: new snapshot at %Y-%m-%d %H:%M:%S" >&2
77       mkcp -s $DEV
78   fi
79 } 9> /var/run/lock/sss.lock