Documentation

Source: https://btrfs.readthedocs.io/en/latest/index.html

Copy on Write

Btrfs is a filesystem using the Copy on Write mechanism. This makes many other features of btrfs possible.

Copy on Write basically optimizes the usage of copies of data. If the system accesses data and / or creates a copy of it this data will not be written again at a given location. Only if an actually change is applied to the copied data a write command is executed. Thus, copies of data are at first only links to the old location. Only upon change of the data it will be written.

This is useful for the snapshots feature of Btrfs subvolumes, since those snapshots do not take up much space as they are only links to existing data. Those snapshots can even be configured to be read-only. In this case they will always point to the original data and can be used for backup purposes, i.e. export the snapshot data to external storage.

Snapshots

Source: https://fedoramagazine.org/btrfs-snapshots-backup-incremental/

Cheatsheet

Make subvolume read-only

btrfs property set -ts /path/to/snapshot ro true

Create snapshot

sudo btrfs subvolume snapshot -r <path_to_target_folder> <path_to_target_folder>/@<snapshot_name>

List all available snapshots:

sudo btrfs subvolume list <path_to_snapshot_location> 

However, if the snapshot was created using the above command without a special subvolume mount also the standard ls command will work and show the snapshot.

Send / Receive a snapshot

btrfs send /home/.snapshots/23/snapshot | pv | btrfs receive /mnt/BACKUP/23
btrfs send -p /mnt/data/old_snaphot /mnt/data/new_snaphot | ssh root@ip "btrfs receive /mnt/backups"

Make a already exiting folder to a subvolume

It is not possible to make a normal folder a btrfs subvolume unfortunately. But there is a more or less easy way around that. First create a temporary folder that holds the data of the folder that should be changed to a subvolume:

mv <path_to_target_folder> <path_to_temp_folder>

Now create a subvolume at the spot where the target folder was before:

btrfs sub create <path_to_target_folder>

Now use btrfs reflinks based on Copy on Write to do an instant copy of the data. This basically creates a link to the datas position while keeping the existing links independent - unlike with a hardlink, where changes of the data through one link would also change the data accessible through Al other hardlinks.

cp -aT --reflink=always <path_to_temp_folder> <path_to_target_folder>

Delete the tmeporary folder

rm -r <path_to_temp_folder>

btrbk

Source:

The tool btrbk is an easy way to automate snapshots and backups with Btrfs. Setting this tool up for offsite backups via SSH is also very easy, since the target server address, the SSH user and the SSH key can be defined it the corresponding btrbk configuration file.

Btrbk itself is a tool consisting of just one file. For every backup job a configuration file has to be created that defines

  • the target to backup to,
  • the disk that should be backupped,
  • all subvolumes from the disk that should be backupped,
  • the backup retention information and
  • several optional parameters. A minimal setup however is easy to set up.

Upon setup of the tool just make sure that perl, wget and buffer are installed. To set it up create a new folder for the btrbk base script. For instance at /etc/btrbk/. Then run the following commands:

wget https://raw.githubusercontent.com/digint/btrbk/master/btrbk
chmod +x btrbk
sudo ./btrbk ls /

When you have set up a configuration file you can dry-run it to see if the output is as expected and of no errors occur. Make sure that you are in the btrbk folder you set up earlier. The option -n in this case declares the dry-run.

./btrbk -c /path/to/myconfig -v -n run

With the option --progress progress information will be displayed during the backup. This however only works if mbuffer was installed beforehand.

Here is an example btrbk configuration file where a local machine will backup the specified subvolumes to an external machine via SSH:

#
# Example btrbk configuration file
#
#
# Please refer to the btrbk.conf(5) man-page for a complete
# description of all configuration options.
# For more examples, see README.md included with this package.
#
#   btrbk.conf(5): <https://digint.ch/btrbk/doc/btrbk.conf.5.html>
#   README.md:     <https://digint.ch/btrbk/doc/readme.html>
#
# Note that the options can be overridden per volume/subvolume/target
# in the corresponding sections.
#
 
# Enable transaction log
transaction_log            /var/log/btrbk.log
 
# Specify SSH private key for remote connections
ssh_identity               /root/.ssh/id_rsa
ssh_user                   root
 
# Enable stream buffer. Adding a buffer between the sending and
# receiving side is generally a good idea.
# NOTE: If enabled, make sure to install the "mbuffer" package!
stream_buffer              256m
 
#
# Example retention policy:
#
snapshot_preserve_min   2d
snapshot_preserve       14d
 
target_preserve_min     no
target_preserve         20d 10w *m
 
 
#
# Simple setup: Backup root and home to external disk
#
# the snapshot directory is prefereably not inside the folder
# that shall be backed up.
snapshot_dir <snapshot_directory>
target       ssh://<ip_of_target_machine>:<ssh_port><target_directory>
subvolume    <first_target_subvolume>
subvolume    <second_target_subvolume>
subvolume    <third_target_subvolume>