BTRFS Filesystem Maintenance Automation with btrfsmaintenance Package

btrfsmaintenance

This post covers setup of the btrfsmaintenance package to automate sensible and recommended filesystem maintenance tasks of the btrfs filesystem. The common use case covered here is a single btrfs root filesystem mounted at /. This is the expected use case which allows a user to use the Storage Snapshots app built into Freedombox. A user using a more complex btrfs configuration such as a non-root btrfs or multiple btrfs filesystems is expected to be able to adapt these notes to their situation.

This does not apply to other filesystems such as ext4.

You will be able to schedule BTRFS filesystem maintenance tasks, confirm their future execution times, and observe that they have been completed using Cockpit and the system journal.

Does this apply to my freedombox?

The mount command will tell you the filesystem type (btrfs, ext4, etc.) you are using. you can run this command as an ordinary user:

mount | grep btrfs

The output will contain a line such as this if you are using btrfs:

/dev/sde3 on / type btrfs (rw,relatime,space_cache,subvolid=5,subvol=/)

If there is no output from the command you are not using btrfs and this post will not apply to your FreedomBox.

References

Configuration Files:

  • /etc/default/btrfsmaintenance

Goals

We will use the btrfsmaintenance package to automate sensible filesystem maintenance tasks and communicate diagnostic messages to the journal. Available tasks are:

  • scrub should be run periodically on all btrfs filesystems and we will schedule this monthly.
  • defrag is helpful for mechanical disk users as btrfs copy-on-write (COW) will create fragmented files which increase hard drive seeking which reduces performance. Solid state devices do not seek, but may still see a benefit from reduced metadata size.
  • balance is appropriate for btrfs volumes having multiple storage devices, but is not frequently (if ever) necessary. This can be run manually when needed, but even a monthly schedule may be too frequent.
  • trim is an operation used with solid state storage devices which marks unused cells as inactive and can increase device life.

Install btrfsmaintenance

btrfsmaintenance is part of Debian and may be installed from apt:
sudo apt install btrfsmaintenance

Configure btrfsmaintenance

btrfsmaintenance will not be report to the journal on installation and no maintenance tasks will be scheduled. We will modify the /etc/default/btrfsmaintenance configuration file to create the desired behavior. Btrfsmaintenance-refresh service will need to be restarted to enable changes to the configuration file. All changed configuration keys will be in bold.

Enabling btrfsmaintenance configuration changes

You may restart the service with this command:
sudo systemctl restart btrfsmaintenance-refresh

Report messages to the journal

We change the BTRFS_LOG_OUTPUT key to use the systemd journal.

## Path: System/File systems/btrfs
## Type: string(none,stdout,journal,syslog)
## Default: “stdout”
#
# Output target for messages. Journal and syslog messages are tagged by the task name like
# ‘btrfs-scrub’ etc.
BTRFS_LOG_OUTPUT=“journal”

Enable defragmentation

Defragment is does not have a default period set, so we will select monthly to be conservative. There are different recommendations for mechanical disk versus solid state devices.

Mechanical Disks

We change the BTRFS_DEFRAG keys to enable monthly defragmentation.

## Path: System/File systems/btrfs
## Type: string(none,daily,weekly,monthly)
## Default: “none”
## ServiceRestart: btrfsmaintenance-refresh
#
# Frequency of defrag.
BTRFS_DEFRAG_PERIOD=“monthly”

Restart the service and observe a defrag message after the first of the month in the journal.

Solid state devices such as SD Card, SSD, nvme…

Solid state devices will not benefit from defrag in the same way as for mechanical disks owing to the fact that solid state devices do not seek. Seeking is the act of changing the spindle position in a mechanical disk to the appropriate track and then waiting for the rotation of the disk to present the desired blocks to the spindle for reading. Defrag solid state devices manually if needed. You may see a benefit on a filesystem which has been operational for months or years and when you are starting to feel some storage capacity pressure. I would not expect this to solve your storage capacity issue, but it appears that it can help somewhat by reducing the size of metadata. There will be many metadata entries to locate each fragment of a fragmented file - so this reduces the metadata load. Here is a manual defragment command:

sudo btrfs filesystem defragment -r /

I would not schedule this on a solid state device to avoid unnecessary wear on the device.

Balance - let’s not schedule that.

Users having multiple devices for a btrfs filesystem may wish to run the balance operation when the devices are not being used about equally. Balancing happens automatically with btrfs, but you should balance if you add or replace a device. Confirm that you see BTRFS_BALANCE_PERIOD=“none”.

## Path: System/File systems/btrfs
## Type: string(none,daily,weekly,monthly)
## Default: “none”
## ServiceRestart: btrfsmaintenance-refresh
#
# Frequency of periodic balance. Periodic balance is not required,
# nor useful, in most cases. Cases where it is beneficial should be
# reported upstream.
#
# The frequency may be specified using one of the listed values or
# in the format documented in the “Calendar Events” section of systemd.time(7),
# if available.
BTRFS_BALANCE_PERIOD=“none”

We can check to see if a balance is appropriate…
$sudo btrfs filesystem show /
Label: ‘sdc btrfs’ uuid: 0877d8d1-c66e-49dc-8b26-53ee22faadf6
Total devices 5 FS bytes used 941.10GiB
devid 1 size 435.03GiB used 0.00B path /dev/sde3
devid 2 size 3.64TiB used 527.03GiB path /dev/sda1
devid 3 size 3.64TiB used 527.03GiB path /dev/sdb1
devid 5 size 3.64TiB used 526.00GiB path /dev/sdd
devid 6 size 3.64TiB used 526.00GiB path /dev/sdc

Here we see that there are five disks:

  • devid 1 of 500GB
  • devid 2-6 of 4TB (skipping devid4 which failed in the past)

The five disks are a BTRFS Raid 1 and we see that data is equally distributed across the 4TB disks with 526-527 GB per disk. This is balanced. btrfs is not using the capacity on the 500GB drive, and that’s okay in this case as the filesystem is creating two copies of every file on equally sized disks. No balance is needed here. If there were a disk with unequal usage (such as a new or replacement disk) then balance would be in order and is done like this:

sudo btrfs-balance start --background /

This operation will take time and create a high I/O load while it runs. You can monitor progress with:
sudo btrfs-balance status /

Alternatively, if you read the configuration file closely you an schedule balance to run conditionally with the BTRFS_BALANCE_DUSAGE and BTRFS_BALANCE_MUSAGE keys and maybe start with the defaults.

Enable scrub

Scrub is recommended for everybody. It is not an fsck, but you can think of it this way. The scrub page in the wiki explains this. Do this monthly (which appears to be the default). You may not need to change this, but do confirm that this is scheduled monthly.

## Path: System/File systems/btrfs
## Type: string(none,weekly,monthly)
## Default: “monthly”
## ServiceRestart: btrfsmaintenance-refresh
#
# Frequency of periodic scrub.
#
# The frequency may be specified using one of the listed values or
# in the format documented in the “Calendar Events” section of systemd.time(7),
# if available.
BTRFS_SCRUB_PERIOD=“monthly”

## Path: System/File systems/btrfs
## Type: string(idle,normal)
## Default: “idle”
#
# Priority of IO at which the scrub process will run. Idle should not degrade
# performance but may take longer to finish.
BTRFS_SCRUB_PRIORITY=“idle”

## Path: System/File systems/btrfs
## Type: boolean
## Default: “false”
#
# Do read-only scrub and don’t try to repair anything.
BTRFS_SCRUB_READ_ONLY=“false”

Enable trim for solid state devices such as SD Card, SSD, nvme…

Trim will deactivate memory cells in the solid state device which will reduce wear and increase device life. This is not needed for mechanical disks. Weekly is recommended.

## Path: System/File systems/btrfs
## Description: Configuration for periodic fstrim
## Type: string(none,daily,weekly,monthly)
## Default: “none”
## ServiceRestart: btrfsmaintenance-refresh
#
# Frequency of periodic trim. Off by default so it does not collide with
# fstrim.timer . If you do not use the timer, turn it on here. The recommended
# period is ‘weekly’.
#
# The frequency may be specified using one of the listed values or
# in the format documented in the “Calendar Events” section of systemd.time(7),
# if available.
BTRFS_TRIM_PERIOD=“weekly”

## Path: System/File systems/btrfs
## Description: Configuration for periodic fstrim - mountpoints
## Type: string
## Default: “/”
#
# Which mountpoints/filesystems to trim periodically.
# (Colon separated paths)
# The special word/mountpoint “auto” will evaluate all mounted btrfs
# filesystems
BTRFS_TRIM_MOUNTPOINTS=“/”

Leave concurrency off

The default is to disable concurrent operations so you are not trying to balance, defrag, and scrub all at the same time. This seems prudent. Confirm this is the case.

## Path: System/File systems/btrfs
## Description: Configuration to allow concurrent jobs
## Type: boolean
## Default: “false”
#
# These maintenance tasks may compete for resources with each other, blocking
# out other tasks from using the file systems. This option will force
# these jobs to run in FIFO order when scheduled at overlapping times. This
# may include tasks scheduled to run when a system resumes or boots when
# the timer for these tasks(s) elapsed while the system was suspended
# or powered off.
BTRFS_ALLOW_CONCURRENCY=“false”

Enable your changes

If you have made one or more changes to the configuration file don’t forget to restart the service:
sudo systemctl restart btrfsmaintenance-refresh

Check the service timers to see that the tasks are scheduled

Using the Cockpit Services app you can look at the timers and see that your btrfsmaintenance tasks are scheduled. In this case several are scheduled for the same moment, but I’ll rely on the BTRFS_ALLOW_CONCURRENCY=“false” statement to prevent them from running at the same time.

Check the journal after the tasks should have run

Using Cockpit check the logs searching for priority “Info and above” and filter for “btrfs”. You will see that the scheduled tasks were executed as expected.

3 Likes