bunch of fixes, change sy host, deploy some new stuff
[distro-setup] / btrfsmaint
1 #!/bin/bash
2
3
4 [[ $EUID == 0 ]] || exec sudo -E "${BASH_SOURCE[0]}" "$@"
5
6 source /a/bin/errhandle/err
7
8 # inspired from
9 # https://github.com/kdave/btrfsmaintenance
10
11
12 # Man page says we could also use a range, i suppose it would be
13 # logical to use a pattern like 5..10 10..20,
14 # but I don't know if this would help us at all.
15 dusage="5 10"
16 musage="5"
17
18 e() { echo "cron: $*"; "$@"; }
19
20 check-idle() {
21 type -p xprintidle &>/dev/null || return 0
22 export DISPLAY=:0
23 # a hours, a movie could run that long.
24 idle_limit=$((1000 * 60 * 60 * 2))
25 idle_time=$idle_limit
26 while read -r user; do
27 new_idle_time=$(sudo -u $user xprintidle 2>/dev/null) ||:
28 if [[ $new_idle_time && $new_idle_time -lt $idle_time ]]; then
29 idle_time=$new_idle_time
30 fi
31 done < <(users | tr " " "\n" | sort -u)
32 if (( idle_time < idle_limit )); then
33 idle=false
34 else
35 idle=true
36 fi
37 }
38
39
40 usage() {
41 cat <<EOF
42 Usage: ${0##*/} args
43 Do btrfs maintence or stop if xprintidle shows a user
44
45 force Run regardless of user idle status
46 check Only check if an existing maintence should be cancelled due to
47 nonidle user. Also, runs in a loop every 20 seconds for 10
48 minutes.
49
50 Note: Uses util-linux getopt option parsing: spaces between args and
51 options, short options can be combined, options before args.
52 EOF
53 exit $1
54 }
55
56
57 force=false
58 check=false
59 if [[ $1 ]]; then
60 case $1 in
61 check)
62 check=true
63 ;;
64 force)
65 force=true
66 ;;
67 *)
68 echo "$0: error: unexpected arg" >&2
69 usage 1
70 ;;
71 esac
72 fi
73
74
75 main() {
76 idle=true
77 if ! $force; then
78 check-idle
79 fi
80
81 tmp=$(mktemp)
82
83 fnd="findmnt --types btrfs --noheading"
84 for x in $($fnd --output "SOURCE" --nofsroot | sort -u); do
85 mnt=$($fnd --output "TARGET" --first-only --source $x)
86 [[ $mnt ]] || continue
87
88 if ! btrfs dev stats -c $mnt >$tmp; then
89 if diff -q $mnt/btrfs-dev-stats $tmp; then
90 diff -u $mnt/btrfs-dev-stats $tmp | mail -s "$HOSTNAME: error: btrfs dev stats -c $mnt" root@localhost
91 cat $tmp >$mnt/btrfs-dev-stats
92 fi
93 fi
94
95 if ! $idle; then
96 btrfs scrub cancel $mnt &>/dev/null ||:
97 continue
98 fi
99 if $check; then
100 continue
101 fi
102
103 # for comparing before and after balance.
104 # the log is already fairly verbose, so commented.
105 # e btrfs filesystem df $mnt
106 # e df -H $mnt
107 if btrfs filesystem df $mnt | grep -q "Data+Metadata"; then
108 for usage in $dusage; do
109 e ionice -c 3 btrfs balance start -dusage=$usage -musage=$usage $mnt
110 done
111 else
112 e ionice -c 3 btrfs balance start -dusage=0 $mnt
113 for usage in $dusage; do
114 e ionice -c 3 btrfs balance start -dusage=$usage $mnt
115 done
116 e ionice -c 3 btrfs balance start -musage=0 $mnt
117 for usage in $musage; do
118 e ionice -c 3 btrfs balance start -musage=$usage $mnt
119 done
120 fi
121 # e btrfs filesystem df $mnt
122 # e df -H $mnt
123 date=$(
124 btrfs scrub status $mnt | \
125 sed -rn 's/^\s*scrub started at (.*) and finished.*/\1/p'
126 )
127 if [[ $date ]]; then
128 date=$(date --date="$date" +%s)
129 # if date is sooner than 90 days ago
130 # the wiki recommends 30 days or so, but
131 # it makes the comp lag like shit for a day,
132 # so I'm going with 90 days.
133 if (( date > $(date +%s) - 60*60*24*30 )); then
134 echo "cron: skiping scrub of $mnt"
135 continue
136 fi
137 fi
138 # -c 2 -n 4 is from btrfsmaintenance, does ionice
139 e btrfs scrub start -Bd -c 2 -n 4 $mnt
140 done
141 }
142
143 if $check; then
144 # this is to prevent systemd from filling up the journal
145 for (( runcount=0; runcount < 90; runcount++ )); do
146 main
147 sleep 60
148 done
149 else
150 main
151 fi