HOWTO set up Btrfs scrub when using suspend

Copyright © 2020 Andrew Pam <andrew@sericyb.com.au>

Please email comments to the author at the above address.

First draft 4 Jul 2020

Introduction

Btrfs users should enable periodically running btrfs scrub to validate the filesystem, typically in the /etc/default/btrfsmaintenance file. On large filesystems this could take quite some time (perhaps several hours) to run. Unfortunately Btrfs currently interacts poorly with suspend. As of at least Linux kernel 5.4.0 and earlier, while a scrub is running it will prevent the system from suspending.

My solution

Create a file called /usr/lib/systemd/system-sleep/btrfs-scrub with the following contents:

								
#!/bin/sh
MOUNTPOINT='/btrfs'

case $1 in
  pre)
    btrfs scrub cancel $MOUNTPOINT
    killall -s0 -w btrfs
    ;;
  post)
    if btrfs scrub status $MOUNTPOINT | grep aborted ; then
      echo "btrfs scrub resume -c3 $MOUNTPOINT" | at -qZ now + 5 minutes ;
    fi
    ;;
esac
				
				

This will cancel the scrub and wait for it to preserve the status in /var/lib/btrfs before attempting the suspend using wait for signal zero to check that the btrfs command has exited. Then when resuming if the last scrub was aborted it will use at to schedule the scrub to resume once system load is low (capital letter queues check system load), at least five minutes in the future. This is necessary because the btrfs scrub will not resume immediately after a resume from suspend.

If you have multiple Btrfs mountpoints you will need to extend this code with for loops.