Sat Feb 11 14:35:15 EST 2017

btrfs migration, cont

Restoring symmetry in btrfs send/receive:

Assuming that both source and destination have the same structure.

What needs to be done is to give that structure a unique identifier,
so we can later force the received UUID to correspond to what we are

How to create identity?  It would be the {subvol_id,filesystem_id}
pair, i.e. the subvol at the point of origin.

Since we're never going to merge (forks are fine for now - use version
control if merges are needed), its ok to trace this as identity.
Where to store the identity?  Best to do this in a file inside the
readonly snapshot.  This way it is guaranteed protected.

Names are easy to change, so don't put information there.

While it's easy to tage the uuid of the filesystem (e.g. in .origin
file), it's not possible to seal the subvol id inside the snapshot.

So there are two options: use the received uuid, or encode it in the

What this needs is:

- the reliance on filenames (like rsync, know what you're doing): both
  sides agree on current and parent based uniquely on name.

- receiving end requests the parent id of the sender's parent, and
  sets the parent id of its own parent

- regular send/receive proceeds

The missing bit is something that can set the received uuid and
transaction id.

receiving snapshot core_20170211_1513_tp uuid=b2398ef1-e891-d34f-8fb8-869ca93c5d76, ctransid=174483 parent_uuid=448a0808-d404-2946-8577-0b301321ef39, parent_ctransid=174414
BTRFS_IOC_SET_RECEIVED_SUBVOL uuid=b2398ef1-e891-d34f-8fb8-869ca93c5d76, stransid=174483

some commands gathered, but i'm still not sure what stransid should be.


struct btrfs_ioctl_received_subvol_args rs_args;
memset(&rs_args, 0, sizeof(rs_args));
memcpy(rs_args.uuid, r->cur_subvol->received_uuid, BTRFS_UUID_SIZE);
rs_args.stransid = r->cur_subvol->stransid;

int mnt_fd = open(mnt_path, O_RDONLY | O_NOATIME);
int subvol_fd = openat(mnt_fd, subvol_path, O_RDONLY | O_NOATIME);
ret = ioctl(subvol_fd, BTRFS_IOC_SET_RECEIVED_SUBVOL, &rs_args);

EDIT: Since I'm not sure I know what I'm doing, keep using rsync for
migration.  Maybe take best of both worlds: create btrfs snapshots,
then use rsync to transfer them.

Or this:

- define core location, with backups going to spares
- once core is disabled, initalize one of the spares

Hard to accept defeat here.  rsync combined with snapshots would be
fine, however it seems as if using send/receive would somehow be more
elegant, and a whole lot faster.

Anyway.  Doesn't matter.  I'm too tired now anyway.

EDIT: rsync with only metadata checks (timestamp,size) is doable.  But
it's a hack that's not necessarily correct...