3 # Clean old BTRFS snapshots
4 # 30 * * * * /root/somescripts/btrfs/cleanup.sh &> /dev/null
6 # This script will keep current/last day/month snapshots.
7 # This script will update current/last_day/week/month snapshots and will delete snapshots if needed (too many or low on space)
9 #set volumes to do curr/last day/month for.
10 LASTLIST="root home homeroot"
12 # Autosnaps to keep. Counting/Considering *.snap only. There should be adate_*.snap snapshots only.
17 echo "***START: `date`***"
18 if [ -e /tmp/btrfs_cleaner.lock ]; then
19 echo "Lockfile found. Assuming another instance is running. exitting."
23 touch /tmp/btrfs_cleaner.lock
24 mount /mnt/btrfs &> /dev/null
27 # Keep current and last MONTH
28 for vol in $LASTLIST; do
29 CHECK=$(grep "`date +"%Y-%m-"`" amon_curr_${vol}.txt 2> /dev/null)
30 if [ "$CHECK" == "" ]; then
31 echo "Autosnap cleaner: Rotating current month for ${vol}"
32 if [ -e "amon_curr_${vol}.snp" -a -e "amon_curr_${vol}.txt" ]; then
33 echo "Autosnap cleaner: Rotating last month for ${vol}"
34 if [ -e "amon_last_${vol}.snp" -a -e "amon_last_${vol}.txt" ]; then
35 mv "amon_last_${vol}.snp" "`cat amon_last_${vol}.txt`"
37 mv "amon_curr_${vol}.snp" "amon_last_${vol}.snp"
38 mv "amon_curr_${vol}.txt" "amon_last_${vol}.txt"
40 CANDIDATE=$(find . -maxdepth 1 -name 'aadate_'`date +"%Y-%m-"`'*_'${vol}'.snap' | sort | head -n 1)
41 if [ "$CANDIDATE" != "" ]; then
42 echo $CANDIDATE > amon_curr_${vol}.txt
43 mv $CANDIDATE amon_curr_${vol}.snp
48 # Keep current and last DAY
49 for vol in $LASTLIST; do
50 CHECK=$(grep "`date +"%Y-%m-%d"`" aday_curr_${vol}.txt 2> /dev/null)
51 if [ "$CHECK" == "" ]; then
52 echo "Autosnap cleaner: Rotating current day for ${vol}"
53 if [ -e "aday_curr_${vol}.snp" -a -e "aday_curr_${vol}.txt" ]; then
54 echo "Autosnap cleaner: Rotating last day for ${vol}"
55 if [ -e "aday_last_${vol}.snp" -a -e "aday_last_${vol}.txt" ]; then
56 mv "aday_last_${vol}.snp" "`cat aday_last_${vol}.txt`"
58 mv "aday_curr_${vol}.snp" "aday_last_${vol}.snp"
59 mv "aday_curr_${vol}.txt" "aday_last_${vol}.txt"
61 CANDIDATE=$(find . -maxdepth 1 -name 'aadate_'`date +"%Y-%m-%d"`'*_'${vol}'.snap' | sort | head -n 1)
62 if [ "$CANDIDATE" != "" ]; then
63 echo $CANDIDATE > aday_curr_${vol}.txt
64 mv $CANDIDATE aday_curr_${vol}.snp
70 # CLEAN *.snap if needed (too many or low on space)
72 while [ $LOOPDEL -eq 2 ]; do
75 btrfs fi show inthdd &> /tmp/btrfs_fishow.txt
76 SPACESIZE="`grep 'size' /tmp/btrfs_fishow.txt | sed -E 's~^.*?size ([0-9]+\.[0-9]*)GB .*?$~\1~g'`"
77 SPACEUSED="`grep 'bytes used' /tmp/btrfs_fishow.txt | sed -E 's~^.*?bytes used ([0-9]+\.[0-9]*)GB.*?$~\1~g'`"
78 SPACEALLOC="`grep 'size' /tmp/btrfs_fishow.txt | sed -E 's~^.*?GB used ([0-9]+\.[0-9]*)GB.*?$~\1~g'`"
79 rm /tmp/btrfs_fishow.txt
81 SNAPCNT="`find . -maxdepth 1 -name '*.snap' | wc -l`"
82 SPACEPERCENT="`python -c 'print int(100.0*'${SPACEUSED}'/'${SPACESIZE}')'`"
84 echo "Autosnap cleaner: Snap count min/curr/limit [${MINSNAPCNT}/${SNAPCNT}/${MAXSNAPCNT}]."
85 echo "Autosnap cleaner: Space used/alloc/size/limit [${SPACEUSED}/${SPACEALLOC}/${SPACESIZE}][${SPACEPERCENT}%/${MAXSPACEPERCENT}%]"
87 if [ $SNAPCNT -gt $MAXSNAPCNT -o $SPACEPERCENT -gt $MAXSPACEPERCENT ]; then
88 DELFILE="`find . -maxdepth 1 -name '*.snap' | sort | head -n -${MINSNAPCNT} | head -n 1`"
89 if [ $SNAPCNT -gt $MINSNAPCNT -a "$DELFILE" != "" ]; then
90 btrfs subvolume delete "${DELFILE}" && LOOPDEL=2
93 if [ $LOOPDEL -eq 2 ]; then
98 umount /mnt/btrfs &> /dev/null
99 rm /tmp/btrfs_cleaner.lock
100 echo "***END: `date`***"