lots of fixes and improvements
[distro-setup] / btrfsmaint
1 #!/bin/bash
2 set -eE -o pipefail
3 trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR
4
5 # inspired from
6 # https://github.com/kdave/btrfsmaintenance
7
8
9 # Man page says we could also use a range, i suppose it would be
10 # logical to use a pattern like 5..10 10..20,
11 # but I don't know if this would help us at all.
12 dusage="1 5 10 20 30 40 50"
13 musage="1 5 10 20 30"
14
15 e() { echo "cron: $*"; "$@"; }
16
17 check-idle() {
18 export DISPLAY=:0
19 idle_time=$(xprintidle 2>/dev/null) ||:
20 # 3 hours, assume a movie might run that long.
21 if [[ $idle_time ]] && (( idle_time < 1000 * 60 * 60 * 3 )); then
22 idle=false
23 else
24 idle=true
25 fi
26 }
27
28 if [[ $1 == check ]]; then
29 check=true
30 else
31 check=false
32 fi
33
34 check-idle
35
36 fnd="findmnt --types btrfs --noheading"
37 for x in $($fnd --output "SOURCE" --nofsroot | sort -u); do
38 mnt=$($fnd --output "TARGET" --first-only --source $x)
39 [[ $mnt ]] || continue
40
41 if ! $idle; then
42 btrfs scrub cancel $mnt &>/dev/null ||:
43 continue
44 fi
45 if $check; then
46 continue
47 fi
48
49 # for comparing before and after balance.
50 # the log is already fairly verbose, so commented.
51 # e btrfs filesystem df $mnt
52 # e df -H $mnt
53 if btrfs filesystem df $mnt | grep -q "Data+Metadata"; then
54 for usage in $dusage; do
55 e btrfs balance start -dusage=$usage -musage=$usage $mnt
56 done
57 else
58 e btrfs balance start -dusage=0 $mnt
59 for usage in $dusage; do
60 e btrfs balance start -dusage=$usage $mnt
61 done
62 e btrfs balance start -musage=0 $mnt
63 for usage in $musage; do
64 e btrfs balance start -musage=$usage $mnt
65 done
66 fi
67 # e btrfs filesystem df $mnt
68 # e df -H $mnt
69 date=$(
70 btrfs scrub status $mnt | \
71 sed -rn 's/^\s*scrub started at (.*) and finished.*/\1/p'
72 )
73 if [[ $date ]]; then
74 date=$(date --date="$date" +%s)
75 # if date is sooner than 90 days ago
76 # the wiki recommends 30 days or so, but
77 # it makes the comp lag like shit for a day,
78 # so I'm going with 90 days.
79 if (( $date > `date +%s` - 60*60*24*30 )); then
80 echo "cron: skiping scrub of $mnt"
81 continue
82 fi
83 fi
84 e btrfs scrub start -Bd $mnt
85 done