]> git.somenet.org - root/btrfs.git/blob - cleaner.sh
GITOLITE.txt
[root/btrfs.git] / cleaner.sh
1 #!/bin/bash
2 #
3 # Copyright 2011 by Jan Vales <jan@jvales.net> (Someone <someone@somenet.org>)
4 #
5 #       This program is free software: you can redistribute it and/or modify
6 #       it under the terms of the GNU General Public License as published by
7 #       the Free Software Foundation, version 3 of the License.
8 #
9 #       This program is distributed in the hope that it will be useful,
10 #       but WITHOUT ANY WARRANTY; without even the implied warranty of
11 #       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.    See the
12 #       GNU General Public License for more details.
13 #
14 #       You should have received a copy of the GNU General Public License
15 #       along with this program.        If not, see <http://www.gnu.org/licenses/>.
16 #
17
18
19 # Purge old BTRFS snapshots
20 # 30 * * * * /root/somescripts/btrfs/cleanup.sh &> /dev/null
21 #
22 # This script will keep current/last day/month snapshots.
23 # This script will update current/last_day/week/month snapshots and will delete snapshots if needed (too many or low on space)
24
25 #set volumes to do curr/last day/month for.
26 LASTLIST="root home homeroot"
27
28 # Autosnaps to keep. Counting/Considering *.snap only. There should be adate_*.snap snapshots only.
29 let MINSNAPCNT=3*5
30 let MAXSNAPCNT=3*333
31 MAXSPACEPERCENT=80
32 MAXDELLOOP="50"
33
34 echo "***START: `date`***"
35 if [ -e /tmp/btrfs_cleaner.lock ]; then
36         echo "Lockfile found. Assuming another instance is running. exitting."
37         exit 1
38 fi
39
40 touch /tmp/btrfs_cleaner.lock
41 mount /mnt/btrfs &> /dev/null
42 cd /mnt/btrfs
43
44 # Keep current and last MONTH
45 for vol in $LASTLIST; do
46         CHECK=$(grep "`date +"%Y-%m-"`" amon_curr_${vol}.txt 2> /dev/null)
47         if [ "$CHECK" == "" ]; then
48                 echo "Autosnap cleaner: Rotating current month for ${vol}"
49                 if [ -e "amon_curr_${vol}.snp" -a -e "amon_curr_${vol}.txt" ]; then
50                         echo "Autosnap cleaner: Rotating last month for ${vol}"
51                         if [ -e "amon_last_${vol}.snp" -a -e "amon_last_${vol}.txt" ]; then
52                                 mv "amon_last_${vol}.snp" "`cat amon_last_${vol}.txt`"
53                         fi
54                         mv "amon_curr_${vol}.snp" "amon_last_${vol}.snp"
55                         mv "amon_curr_${vol}.txt" "amon_last_${vol}.txt"
56                 fi
57                 CANDIDATE=$(find . -maxdepth 1 -name 'aadate_'`date +"%Y-%m-"`'*_'${vol}'.snap' | sort | head -n 1)
58                 if [ "$CANDIDATE" != "" ]; then
59                         echo $CANDIDATE > amon_curr_${vol}.txt
60                         mv $CANDIDATE amon_curr_${vol}.snp
61                 fi
62         fi
63 done
64
65 # Keep current and last DAY
66 for vol in $LASTLIST; do
67         CHECK=$(grep "`date +"%Y-%m-%d"`" aday_curr_${vol}.txt 2> /dev/null)
68         if [ "$CHECK" == "" ]; then
69                 echo "Autosnap cleaner: Rotating current day for ${vol}"
70                 if [ -e "aday_curr_${vol}.snp" -a -e "aday_curr_${vol}.txt" ]; then
71                         echo "Autosnap cleaner: Rotating last day for ${vol}"
72                         if [ -e "aday_last_${vol}.snp" -a -e "aday_last_${vol}.txt" ]; then
73                                 mv "aday_last_${vol}.snp" "`cat aday_last_${vol}.txt`"
74                         fi
75                         mv "aday_curr_${vol}.snp" "aday_last_${vol}.snp"
76                         mv "aday_curr_${vol}.txt" "aday_last_${vol}.txt"
77                 fi
78                 CANDIDATE=$(find . -maxdepth 1 -name 'aadate_'`date +"%Y-%m-%d"`'*_'${vol}'.snap' | sort | head -n 1)
79                 if [ "$CANDIDATE" != "" ]; then
80                         echo $CANDIDATE > aday_curr_${vol}.txt
81                         mv $CANDIDATE aday_curr_${vol}.snp
82                 fi
83         fi
84 done
85
86
87 # CLEAN *.snap if needed (too many or low on space)
88 while [ $MAXDELLOOP -gt 0 ]; do
89         btrfs fi show $(mount -l | grep inthdd | cut -f1 -d ' ' | uniq) &> /tmp/btrfs_fishow.txt
90         SPACESIZE="`grep 'size' /tmp/btrfs_fishow.txt | sed -E 's~^.*?size ([0-9]+\.[0-9]*)GiB .*?$~\1~g'`"
91         SPACEUSED="`grep 'bytes used' /tmp/btrfs_fishow.txt | sed -E 's~^.*?bytes used ([0-9]+\.[0-9]*)GiB.*?$~\1~g'`"
92         SPACEALLOC="`grep 'size' /tmp/btrfs_fishow.txt | sed -E 's~^.*?GiB used ([0-9]+\.[0-9]*)GiB.*?$~\1~g'`"
93         rm /tmp/btrfs_fishow.txt
94
95         SNAPCNT="`find . -maxdepth 1 -name '*.snap' | wc -l`"
96         SPACEPERCENT="`python -c 'print int(100.0*'${SPACEUSED}'/'${SPACESIZE}')'`"
97
98         echo "Autosnap cleaner: Snap count min/curr/limit [${MINSNAPCNT}/${SNAPCNT}/${MAXSNAPCNT}]."
99         echo "Autosnap cleaner: Space used/alloc/size/limit [${SPACEUSED}/${SPACEALLOC}/${SPACESIZE}][${SPACEPERCENT}%/${MAXSPACEPERCENT}%]"
100
101         if [ $SNAPCNT -gt $MAXSNAPCNT -o $SPACEPERCENT -gt $MAXSPACEPERCENT ]; then
102                 DELFILE="`find . -maxdepth 1 -name '*.snap' | sort | head -n -${MINSNAPCNT} | head -n 1`"
103                 if [ $SNAPCNT -gt $MINSNAPCNT -a "$DELFILE" != "" ]; then
104                         btrfs subvolume delete "${DELFILE}" && MAXDELLOOP=$(echo "$MAXDELLOOP-1" | bc)
105                 fi
106         else
107                 MAXDELLOOP="-1"
108         fi
109         if [ "$1" == "noloop" ]; then
110                 MAXDELLOOP="0"
111                 echo "Autosnap cleaner: noloop flag set. forcing break."
112         fi
113         if [ $MAXDELLOOP -gt 0 ]; then
114                 sleep 60
115         fi
116         if [ $MAXDELLOOP -eq 0 ]; then
117                 echo "Autosnap cleaner: LOOP-LIMIT reached. forcing break."
118         fi
119 done
120
121 cd /tmp
122 umount /mnt/btrfs &> /dev/null
123 rm /tmp/btrfs_cleaner.lock
124 ps aux | grep "\[btrfs-cleaner\]"
125 echo "***END: `date`***"
126