X-Git-Url: https://iankelling.org/git/?a=blobdiff_plain;f=btrfsmaint;fp=btrfsmaint;h=4de4b765ea951022864c989f4b60f9885ce981a4;hb=f46ee5570766081a5a73ce0d2132c8a06ee966fb;hp=d2263257d412b4da2d9e37e5c1678641e301e8f6;hpb=ad6ea16ea6f2a8676527257fb6afb659f2cee475;p=distro-setup diff --git a/btrfsmaint b/btrfsmaint deleted file mode 100755 index d226325..0000000 --- a/btrfsmaint +++ /dev/null @@ -1,217 +0,0 @@ -#!/bin/bash - - -[[ $EUID == 0 ]] || exec sudo -E "${BASH_SOURCE[0]}" "$@" - -source /a/bin/errhandle/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="5 10" -musage="5" - -e() { - echo "cron: $*" - if ! $dryrun; then - "$@" - fi -} - -check-idle() { - type -p xprintidle &>/dev/null || return 0 - export DISPLAY=:0 - # a hours, a movie could run that long. - idle_limit=$((1000 * 60 * 60 * 2)) - idle_time=$idle_limit - while read -r user; do - new_idle_time=$(sudo -u $user xprintidle 2>/dev/null) ||: - if [[ $new_idle_time && $new_idle_time -lt $idle_time ]]; then - idle_time=$new_idle_time - fi - done < <(users | tr " " "\n" | sort -u) - if (( idle_time < idle_limit )); then - idle=false - else - idle=true - fi -} - -usage() { - cat <&2 - usage 1 - ;; - esac -fi - - -main() { - idle=true - if ! $force; then - check-idle - if ! $check; then - min=0 - max_min=300 - # When the cron kicks in, we may not be idle (physically sleeping) yet, so - # wait. - while ! $idle && (( min < max_min )); do - min=$(( min + 1 )) - sleep 60 - check-idle - done - # If we've waited a really long time for idle, just give up. - if (( min == max_min )); then - return - fi - fi - fi - - - 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 - - #### begin look for diff in stats, eg: increasing error count #### - - # Only run for $check, since it runs in parallel to non-check, avoid - # race condition. - if $check; then - tmp=$(mktemp) - # if mnt is /, avoid making a buggy looking path - stats_path=${mnt%/}/btrfs-dev-stats - if [[ ! -e $stats_path ]]; then - btrfs dev stats -c $mnt >$stats_path ||: # populate initial reading - elif ! btrfs dev stats -c $mnt >$tmp; then - if ! diff -q $stats_path $tmp; then - exim -t <$stats_path - fi - fi - rm -f $tmp - fi - #### end look for diff in stats, eg: increasing error count #### - - if $check; then - if ! $idle; then - if $dryrun; then - echo "$0: not idle. if this wasnt a dry run, btrfs scrub cancel $mnt" - else - btrfs scrub cancel $mnt &>/dev/null ||: - fi - fi - 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 ionice -c 3 btrfs balance start -dusage=$usage -musage=$usage $mnt - done - else - e ionice -c 3 btrfs balance start -dusage=0 $mnt - for usage in $dusage; do - e ionice -c 3 btrfs balance start -dusage=$usage $mnt - done - e ionice -c 3 btrfs balance start -musage=0 $mnt - for usage in $musage; do - e ionice -c 3 btrfs balance start -musage=$usage $mnt - done - fi - date= - scrub_status=$(btrfs scrub status $mnt) - if printf "%s\n" "$scrub_status" | grep -i '^status:[[:space:]]*finished$' &>/dev/null; then - date=$(printf "%s\n" "$scrub_status" | sed -rn 's/^Scrub started:[[:space:]]*(.*)/\1/p') - fi - if [[ ! $date ]]; then - # output from older versions, at least btrfs v4.15.1 - date=$( - printf "%s\n" "$scrub_status" | \ - sed -rn 's/^\s*scrub started at (.*) and finished.*/\1/p' - ) - fi - if ! $force && [[ $date ]]; then - if $dryrun; then - echo "$0: last scrub finish for $mnt: $date" - fi - date=$(date --date="$date" +%s) - # if date is sooner than 60 days ago - # the wiki recommends 30 days or so, but - # I'm going with 60 days. - if (( date > EPOCHSECONDS - 60*60*24*60 )); then - if $dryrun; then - echo "$0: skiping scrub of $mnt, last was $(( (EPOCHSECONDS - date) / 60/60/24 )) days ago, < 30 days" - fi - continue - fi - fi - # btrfsmaintenance does -c 2 -n 4, but I want lowest pri. - e btrfs scrub start -Bd -c 3 $mnt - - # We normally only do one disk since this is meant to be run while I sleep - # and if we try to do all disks, we invariably end up doing a scrub still - # after I've woken up. So, just do one per day. - if ! $force; then - return 0 - fi - done -} - -loop-main() { - while true; do - main - sleep 60 - done -} - -if $check; then - loop-main -else - main -fi diff --git a/btrfsmaint b/btrfsmaint new file mode 120000 index 0000000..4de4b76 --- /dev/null +++ b/btrfsmaint @@ -0,0 +1 @@ +/a/f/ans/roles/btrfs/files/btrfsmaint \ No newline at end of file