4 [[ $EUID == 0 ]] ||
exec sudo
-E "${BASH_SOURCE[0]}" "$@"
6 source /a
/bin
/errhandle
/err
9 # https://github.com/kdave/btrfsmaintenance
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.
26 type -p xprintidle
&>/dev
/null ||
return 0
28 # a hours, a movie could run that long.
29 idle_limit
=$
((1000 * 60 * 60 * 2))
31 while read -r user
; do
32 new_idle_time
=$
(sudo
-u $user xprintidle
2>/dev
/null
) ||
:
33 if [[ $new_idle_time && $new_idle_time -lt $idle_time ]]; then
34 idle_time
=$new_idle_time
36 done < <(users |
tr " " "\n" |
sort -u)
37 if (( idle_time
< idle_limit
)); then
47 Usage: ${0##*/} [ARGS]
48 Do btrfs maintence or stop if xprintidle shows a user
50 force Run regardless of user idle status
51 check Only check if an existing maintence should be cancelled due to
52 nonidle user. Also, runs in a loop every 20 seconds for 10
55 Note: Uses util-linux getopt option parsing: spaces between args and
56 options, short options can be combined, options before args.
77 echo "$0: error: unexpected arg" >&2
92 fnd
="findmnt --types btrfs --noheading"
93 for x
in $
($fnd --output "SOURCE" --nofsroot |
sort -u); do
94 mnt
=$
($fnd --output "TARGET" --first-only --source $x)
95 [[ $mnt ]] ||
continue
97 if ! btrfs dev stats
-c $mnt >$tmp; then
98 if diff -q $mnt/btrfs-dev-stats
$tmp; then
99 diff -u $mnt/btrfs-dev-stats
$tmp |
mail -s "$HOSTNAME: error: btrfs dev stats -c $mnt" root@localhost
100 cat $tmp >$mnt/btrfs-dev-stats
106 echo "$0: not idle. if this wasnt a dry run, btrfs scrub cancel $mnt"
108 btrfs scrub cancel
$mnt &>/dev
/null ||
:
116 # for comparing before and after balance.
117 # the log is already fairly verbose, so commented.
118 # e btrfs filesystem df $mnt
120 if btrfs filesystem df
$mnt |
grep -q "Data+Metadata"; then
121 for usage
in $dusage; do
122 e ionice
-c 3 btrfs balance start
-dusage=$usage -musage=$usage $mnt
125 e ionice
-c 3 btrfs balance start
-dusage=0 $mnt
126 for usage
in $dusage; do
127 e ionice
-c 3 btrfs balance start
-dusage=$usage $mnt
129 e ionice
-c 3 btrfs balance start
-musage=0 $mnt
130 for usage
in $musage; do
131 e ionice
-c 3 btrfs balance start
-musage=$usage $mnt
135 scrub_status
=$
(btrfs scrub status
$mnt)
136 if printf "%s\n" "$scrub_status" |
grep -i '^status:[[:space:]]*finished$' &>/dev
/null
; then
137 date=$
(printf "%s\n" "$scrub_status" |
sed -rn 's/^Scrub started:[[:space:]]*(.*)/\1/p')
139 if [[ ! $date ]]; then
140 # output from older versions, at least btrfs v4.15.1
142 printf "%s\n" "$scrub_status" | \
143 sed -rn 's/^\s*scrub started at (.*) and finished.*/\1/p'
148 echo "$0: last scrub finish for $mnt: $date"
150 date=$
(date --date="$date" +%s
)
151 # if date is sooner than 90 days ago
152 # the wiki recommends 30 days or so, but
153 # it makes the comp lag like shit for a day,
154 # so I'm going with 90 days.
155 if (( date > $
(date +%s
) - 60*60*24*30 )); then
157 echo "$0: skiping scrub of $mnt, last was $(( ($(date +%s) - date) / 60/60/24 )) days ago, < 30 days"
162 # -c 2 -n 4 is from btrfsmaintenance, does ionice
163 e btrfs scrub start
-Bd -c 2 -n 4 $mnt