02.02.2021 00:53, Chris Murphy пишет: > It needs testing but I think -c option can work for this case, because > the parent on both source and destination are identical, even if the > new destination (the old source) has an unexpected received subvolume > uuid. >
Incremental send requires base snapshot. It is given either as -p option or "btrfs send" tries to find "best" base snapshot among those given by -c. This works only if both target snapshot and (some) snapshots given by -c are created from the same subvolume. So "btrfs send -c foo bar" is entirely equivalent to "btrfs send -p foo bar" as long as both foo and bar have the same parent subvolume. > At least for me, it worked once and I didn't explore it further. I > also don't know if it'll set received uuid, such that subsequent send > can use -p instead of -c. > On receive side "btrfs receive" will always set received_uuid to snapshot given as "btrfs send" argument. The question is whether receive side will be able to find base (parent) snapshot. As far as I can tell, "btrfs receive" will first search for subvolume with matching received_uuid and if nothing is found it will repeat searching for subvolume with matching uuid. "btrfs send" will send received_uuid instead of uuid if it is set. Which means that in case btrfs subvolume snapshot -r source base btrfs send base btrfs subvolume snapshot -r source diff btrfs send -p base diff you should be able to reverse replication by doing on destination btrfs subvolume snapshot diff new-source this creates writable clone of replication snapshot that will be used to actually store data. You cannot use replication snapshot itself because you need its uuid and it must remain read-only btrfs subvolume snapshot -r new-source diff2 btrfs send -p diff diff2 This should find "diff" on source that has uuid matching received_uuid of "diff" on destination. The key here is to not attempt to directly use snapshots involved in replication. They must remain immutable. > -c generally still confuses me... in particular multiple instances of -c > Well, it allows you to optimize transfer. if you know that large amount of data in subvolume foo is reflinked to data in subvolume bar, you can use btrfs send -c bar foo and instead of sending (duplicate copy) of data in foo "btrfs receive" will reflink it from bar on destination. Consider tw:/mnt/src # btrfs subvolume create source Create subvolume './source' tw:/mnt/src # btrfs subvolume create clone Create subvolume './clone' tw:/mnt/src # dd if=/dev/urandom of=clone/cln bs=8k count=2 2+0 records in 2+0 records out 16384 bytes (16 kB, 16 KiB) copied, 0.000495937 s, 33.0 MB/s tw:/mnt/src # btrfs sub snap -r source source-base Create a readonly snapshot of 'source' in './source-base' tw:/mnt/src # btrfs sub snap -r clone clone-base Create a readonly snapshot of 'clone' in './clone-base' tw:/mnt/src # btrfs send source-base/ | btrfs receive ../dst At subvol source-base/ At subvol source-base tw:/mnt/src # btrfs send clone-base/ | btrfs receive ../dst At subvol clone-base/ At subvol clone-base tw:/mnt/src # cp --reflink=always clone/cln source tw:/mnt/src # btrfs sub snap -r source source-diff Create a readonly snapshot of 'source' in './source-diff' tw:/mnt/src # btrfs send -p source-base source-diff | btrfs receive --dump At subvol source-diff ... write ./source-diff/cln offset=0 len=16384 ... tw:/mnt/src # btrfs send -p source-base -c clone-base source-diff | btrfs receive --dump At subvol source-diff ... clone ./source-diff/cln offset=0 len=16384 from=./source-diff/cln clone_offset=0 ... tw:/mnt/src # Ignore weird clone from= in "btrfs receive --dump". It should have printed clone uuid instead (it does not really have name at this point).