[HowTo] use btrfs send / receive

Difficulty: ★★★☆☆
This is a wiki post, so feel free to contribute :wink: (but please stay on topic)

Btrfs is a very different file system (compared to others). Some parts even look weird. send/receive btrfs is weird !

Btrfs send

Takes an existing snapshot (read-only) and converts it to a data stream.

Btrfs receive

Takes a data stream and creates a snapshot (and makes it read-only)


Every command on this wiki must be run as root, or with sudo


Copy

If you pipe send to receive, a copy of the snapshot will be made.

This is the easiest way to copy an snapshot from one btrfs-volume to another

Provided

  • You have snapshots of /home at /home/.snapshots/ like snapper does
  • There is a snapshot named /home/.snapshots/23/snapshot
  • You mounted a Btrfs subvolume in /mnt/BACKUP
  • There is a directory /mnt/BACKUP/23/
btrfs send /home/.snapshots/23/snapshot | btrfs receive /mnt/BACKUP/23    

The snapshot present in /home/.snapshots/23/ is copied to /mnt/BACKUP/23 .

Copy with progress

Since btrfs send / receive does not show any progress, and this can take some time (!), I suggest to use pv to show the progress. ( pv must be installed beforehand)

btrfs send /home/.snapshots/24/snapshot | pv | btrfs receive /mnt/BACKUP/24    

Use the parent snapshot

  • to speed things up
  • to save space

You now have two snapshots on your backup that contain mostly the same files. But they don’t share a single byte of storage! The second one is nearly the same size as the first. This is not space saving. And the copy of the second snapshot took almost as long to copy as the first. That’s is not efficient!

When sending a snapshot, btrfs send can send differences between snapshots if you specify which snapshot was the “parent”.

Assumed:

  • You have an snapshot of /home at /home/.snapshots/24/snapshot
  • You have a copy(backup) of this snapshot at /mnt/BACKUP/24/snapshot
  • You have a snapshot of /home at /home/.snapshots/25/snapshot
btrfs send -p /home/.snapshots/24/snapshot /home/.snapshots/25/snapshot | pv | btrfs receive /mnt/BACKUP/25    

Btrfs send searches for the parent and only transmits the parent UUID and the stream of changed files.
Btrfs receive looks for the existing copy of the parent using the UUID. Then it creates a new snapshot depending on the copy of the parent snapshot.

This is work in progress as of 8.3.23

2 Likes

Are those snapshots read-only by default?

If you use Snapper, snapshots are read-only by default after snapper-creation.

TimeShift creates writable snapshots.
Btrbk creates read-only or writable snapshots.


This tutorial is for Snapper users with “custom flat layout”. Not for TimeShift users.

1 Like

By default btrfs creates readonly snapshots.

According to btrfs Subvolume Flags, Subvolumes and Snapshots are the same structure. The only difference is that a Snapshot is kept readonly by flags.

readonly (called Snapshot)

Snapshot can be transferred by btrfs send / receive
If your snapshots are r/w, you need to change them before using btrfs send/receive to readonly, and afterwards back to r/w. Btrfs send only works with readonly snapshots.

writable (called Subvolume)

Snapshot can be booted by grub (for rollback)

layout

Using different layouts is no limit to btrfs send/receive. You only have to change the paths in the command accordingly.

What if I don’t have the subvolume mounted on the same machine, but on another machine in local network? Let’s say at user@192.168.0.2:/mnt/BACKUP and you can connect to the machine via ssh. Can we use the btrfs send/receive through network somehow?

Yes

  • But you have to be root to use btrfs send/receive
  • Or you would have to get the necessary permissions in other ways (sudo / wheel)

One possibility is to:

  • Use ssh-keys (with password)
  • Use ssh-assistant to unlock a key temporary
  • execute btrfs over ssh (which will use the unlocked key)

Please have a look at:

If you are familiar with ssh, you can send /receive via ssh.
I do this once a week with 5 PCs :wink: (and have collected over 1600 differential snapshots this way)

(But be aware, this is work in progress)

2 Likes

If you use TimeShift you just have to take that into account.

Snapper does:

  • create readonly snapshots
  • mount the snapshots in the file system

TimeShift does:

  • create writable snapshots
  • not mount the snapshots in the file system

To use this with btrfs send you just have to:

  • mount the btrfs volume with the snapshots
  • make the snapshots readonly
  • transfer the snapshots with btrfs send
  • make the snapshots writeable again
  • umount the btrfs volume with the snapshots

Otherwise everything said above applies.

BackSnap does support timeshift from now on