9

I regularly use btrfs send and btrfs receive to copy read-only snapshots from my live system to a backup drive. On the backup drive there are already multiple snapshots. Today I wondered: Can I copy multiple of today's snapshots as incremental update from multiple older snapshots at once?

Recently I did

btrfs send -p  home_old  home_today | btrfs receive /mnt/backup/
btrfs send -p share_old share_today | btrfs receive /mnt/backup/

Could this be unified to 1 command?

So I looked into man btrfs-send and read:

In the incremental mode (options -p and -c), previously sent snapshots that are available on both the sending and receiving side can be used to reduce the amount of information that has to be sent to reconstruct the sent snapshot on a different filesystem.

That's what I want.

-p <parent>

send an incremental stream from parent to subvol

-c <clone-src>

use this snapshot as a clone source for an incremental send (multiple allowed)

It seems that only one of -p and -c supports multiple existing snapshots but I don't get the difference between them. What's the difference?

2 Answers 2

3

Here it says that with -p btrfs-send first creates snapshot of parent subvolume and then modifies that snapshot accordingly to data stream from btrfs-send. With -c option btrfs-receive creates blank subvolume and modifies it, creating reflinks for unchanged files. The difference is the size of metadata btrfs-send needs to transfer. In case of -c option all metadata is transfered, in case of -p option -- some metadata.

I tested this with snapshots of subvolume (250G, 310k files) with these results:

# time btrfs send -p server-20181031-1746 server-20181225-1144 -f /mnt/parent.diff
At subvol server-20181225-1144

real    3m12,618s

Size of parent.diff is 6418364996 bytes

# time btrfs send -c server-20181031-1746 server-20181225-1144 -f /mnt/clone.diff
At subvol server-20181225-1144

real    3m17,435s

Size of parent.diff is 6418364996 bytes

So, in my case there is almost no difference.

I don't think btrfs-send can generate streams for multiple subvolumes in one command.

2
  • Multiple subvols are allowed as per synopsis: btrfs send [-ve] [-p <parent>] [-c <clone-src>] [-f <outfile>] <subvol> [<subvol>...] Multiple -p behaviour is undocumented, but multiple -cs are allowed.
    – Tom Hale
    Aug 27, 2019 at 9:48
  • FWIW, the author of btrfs-clone clone says this is all wrong: github.com/mwilck/…
    – T Nierath
    Dec 23, 2023 at 18:53
1

I just wrote a long answer that also discusses the -p and -c options, copy and paste of the relevant section:

There can only be one parent

The man page and (old) wiki FAQ are unfortunately rather confusing. The author of btrfs-clone asserts that btrfs send and receive can only at most consider one parent for incremental transfers. The parent can either be directly specified via -p or indirectly via one or multiple -c options:

btrfs-send from btrfs-tools 4.13 selects the parent for a subvolume S and set of given clone sources C_i like this:

  1. if -p option is specified, use it
  2. if S has no parent_uuid set, or this uuid can't be found, give up
  3. if there's C_i with C_i->uuid == S->parent_uuid (the subvolume of which S is a child (snapshot), let's call it "mom"), use it
  4. if no C_i has the same parent_uuid as S, give up
  5. from all C_i that are children of "mom", choose the one that has the closest generation (actually, ctransid, what exactly is the difference to "generation"?) to "mom".

Note that the wiki is a bit misleading, because it suggests that -c without p is different from -c with -p, although -p is usually implied by the algorithm above. The only relevant exception is sending subvolumes that have no parent.

In summary, I suggest to always explicitly specify one parent via -p and to ignore -c, btrfs receive simply has no such concept as "two parents".

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .