#!/bin/bash set -eE -o pipefail trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR # inspired from # https://github.com/kdave/btrfsmaintenance # Man page says we could also use a range, i suppose it would be # logical to use a pattern like 5..10 10..20, # but I don't know if this would help us at all. dusage="1 5 10 20 30 40 50" musage="1 5 10 20 30" e() { echo "cron: $*"; "$@"; } check-idle() { export DISPLAY=:0 # 3 hours, assume a movie might run that long. idle_limit=$((1000 * 60 * 60 * 3)) idle_time=$idle_limit id=999 while id $((++id)) &>/dev/null; do new_idle_time=$(sudo -u \#$id xprintidle 2>/dev/null) ||: if [[ $new_idle_time && $new_idle_time -lt $idle_time ]]; then idle_time=$new_idle_time fi done if (( idle_time < idle_limit )); then idle=false else idle=true fi } if [[ $1 == check ]]; then check=true else check=false fi check-idle fnd="findmnt --types btrfs --noheading" for x in $($fnd --output "SOURCE" --nofsroot | sort -u); do mnt=$($fnd --output "TARGET" --first-only --source $x) [[ $mnt ]] || continue if ! $idle; then btrfs scrub cancel $mnt &>/dev/null ||: continue fi if $check; then continue fi # for comparing before and after balance. # the log is already fairly verbose, so commented. # e btrfs filesystem df $mnt # e df -H $mnt if btrfs filesystem df $mnt | grep -q "Data+Metadata"; then for usage in $dusage; do e btrfs balance start -dusage=$usage -musage=$usage $mnt done else e btrfs balance start -dusage=0 $mnt for usage in $dusage; do e btrfs balance start -dusage=$usage $mnt done e btrfs balance start -musage=0 $mnt for usage in $musage; do e btrfs balance start -musage=$usage $mnt done fi # e btrfs filesystem df $mnt # e df -H $mnt date=$( btrfs scrub status $mnt | \ sed -rn 's/^\s*scrub started at (.*) and finished.*/\1/p' ) if [[ $date ]]; then date=$(date --date="$date" +%s) # if date is sooner than 90 days ago # the wiki recommends 30 days or so, but # it makes the comp lag like shit for a day, # so I'm going with 90 days. if (( $date > `date +%s` - 60*60*24*30 )); then echo "cron: skiping scrub of $mnt" continue fi fi e btrfs scrub start -Bd $mnt done