aboutsummaryrefslogtreecommitdiff
path: root/zb-cleanup
blob: 9761ebfc0fb5d27f49684ed1b6f3c472f6e6b6ea (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#!/bin/bash

if [[ -z "$1" || -z "$2" ]] ; then
	echo "usage: $0 <zfs_object> <density_percent> [max_age]" >&2
	exit 1
fi

if [[ "$2" -lt 100 ]] ; then
	echo "density must be >= 100" >&2
	exit 2
fi

timestamp () {
	t="`echo \"$1\" |sed -ne 's/^.*@zb-//p' |tr 'p_' '+ '`"
	[[ -z "$t" ]] && return 1
	date --date="$t" +%s
	return $?
}

max_age=0
if [[ -n "$3" ]] ; then
	max_age=`date --date="$3" +%s`
fi

density="$2"
timenow=`date +%s`
lasttime=0

# list snapshots
zfs list -t snapshot -r -d 1 -H "$1" |awk '{print $1;}' | while read l ; do
	#link unix timestamps
	unixtime=`timestamp "$l"` || continue
	echo "$unixtime" "$l"
done |sort -n | while read l ; do
	curtime=${l%% *}
	snapname=${l#* }

	if [ "$curtime" -lt "$max_age" ] ; then
		#too old
		zfs destroy "$snapname"
		continue
	fi

	if [ "$curtime" -ge "$timenow" ] ; then
		#this actually shouldn't happen, but who knows
		break
	fi
	
	#if it's too dense, delete the closer snapshot
	if [ $(( ($density*($curtime-$lasttime))/($timenow-$lasttime) )) -lt 100 ]
	then
		zfs destroy "$snapname"
	else
		lasttime="$curtime"
	fi
done