-
Notifications
You must be signed in to change notification settings - Fork 1
/
snapreport
executable file
·120 lines (113 loc) · 3.36 KB
/
snapreport
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#!/bin/bash
function format_data ()
{
local amount="$1"
local suffixes=(" " "K" "M" "G" "T" "P" "E" "Z" "Y")
local testnum="$amount"
local divisor="1"
local suffix=""
#bash arithmetic uses 64bit, so use bc
for ((index = 0; index < ${#suffixes[@]}; ++index))
do
suffix="${suffixes[$index]}"
testnum=`echo "$amount/($divisor)" | bc`
if ((testnum < 1000))
then
break
fi
divisor="$divisor*1024"
done
local prespace=" "
if ((testnum >= 100))
then
prespace=""
else
if ((testnum >= 10))
then
prespace=" "
fi
fi
if [[ "$divisor" == "1" ]]
then
#don't use bc for non-fractional cases
local displaydata="$amount "
else
local displaydata=`echo "scale = 2; $amount/($divisor)" | bc -l`
#we switch at 1000, not 1024, so check for having no digit before decimal point
if [[ "$displaydata" == .* ]]
then
#because leading zero behavor is unspecified in bc
displaydata=0"$displaydata"
fi
fi
echo "$prespace$displaydata$suffix"
}
if (($# < 1))
then
echo "usage: $0 <filesystem>@<snapshot>"
exit 1
fi
if [[ "$1" != ?*@* || "$1" == /* ]]
then
echo "Input must be a snapshot with filesystem name"
echo "usage: $0 <filesystem>@<snapshot>"
exit 1
fi
filesystem=`echo "$1" | cut -f1 -d@`
mysnap=`echo "$1" | cut -f2- -d@`
allsnaps=`zfs list -Hd 1 -t snapshot -o name "$filesystem" | cut -f2- -d@`
position=`echo "$allsnaps" | grep -n "^$mysnap\$" | cut -f1 -d:`
if [[ $position == "" ]]
then
echo "snapshot not found"
exit 1
fi
latersnaps=`echo "$allsnaps" | tail -n +$((position + 1))`
#unique
if ((position > 1))
then
prevsnap=`echo "$allsnaps" | tail -n +$((position - 1)) | head -n 1`
#we have, and must account for, previous snapshots
remaining[0]=`zfs get -Hp written@"$prevsnap" "$filesystem"@"$mysnap" | awk '{print $3}'`
else
#no previous snapshot, the referenced property provides the number we want (ie, assume a "previous snapshot" of zero usage)
remaining[0]=`zfs get -Hp referenced "$filesystem"@"$mysnap" | awk '{print $3}'`
fi
names[0]="unique"
#other snaps
index=1
for snap in $latersnaps
do
if ((position > 1))
then
prevwritten=`zfs get -Hp written@"$prevsnap" "$filesystem"@"$snap" | awk '{print $3}'`
else
prevwritten=`zfs get -Hp referenced "$filesystem"@"$snap" | awk '{print $3}'`
fi
snapwritten=`zfs get -Hp written@"$mysnap" "$filesystem"@"$snap" | awk '{print $3}'`
remaining[index]=$((prevwritten - snapwritten))
names[index]="$snap"
index=$((index + 1))
done
#data not yet snapshotted
if ((position > 1))
then
prevwritten=`zfs get -Hp written@"$prevsnap" "$filesystem" | awk '{print $3}'`
else
prevwritten=`zfs get -Hp referenced "$filesystem" | awk '{print $3}'`
fi
curwritten=`zfs get -Hp written@"$mysnap" "$filesystem" | awk '{print $3}'`
remaining[index]=$((prevwritten - curwritten))
#allow the display loop to report the "active" line, rather than as a special case
remaining[index + 1]=0
names[index]="active"
end=$index
echo " SIZE ENDING SNAPSHOT"
for ((index = 0; index <= end; ++index))
do
amount=$((remaining[index] - remaining[index + 1]))
if ((amount != 0))
then
echo "$(format_data $amount) ${names[$index]}"
fi
done