Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resuming incremental send results in "invalid cross-device link" #6619

Closed
dsnet opened this issue Sep 8, 2017 · 0 comments · Fixed by #6623
Closed

Resuming incremental send results in "invalid cross-device link" #6619

dsnet opened this issue Sep 8, 2017 · 0 comments · Fixed by #6623

Comments

@dsnet
Copy link

dsnet commented Sep 8, 2017

Type Version/Name
Distribution Name Ubuntu
Distribution Version 16.04.2
Linux Kernel 4.4.0-62-generic
Architecture x64
SPL Version 0.7.0-12_g9df9692
ZFS Version 0.7.0-50_g1ea8942

I ran the following:

# Create a new pool.
$ truncate -s 1G ~/dev
$ sudo zpool create tank ~/dev

# Add some data and snapshot.
$ sudo dd if=/dev/urandom of=/tank/foo bs=1M count=50
$ sudo zfs snapshot tank@snap1

# Create a mirror.
$ sudo zfs send tank@snap1 | sudo zfs recv -s tank/mirror

# Add some data and snapshot.
$ sudo dd if=/dev/urandom of=/tank/bar bs=1M count=50
$ sudo zfs snapshot tank@snap2

# Intentionally create a partial send.
$ sudo zfs send -i tank@snap1 tank@snap2 | head -c 20000000 | sudo zfs recv -s tank/mirror
$ TOKEN=$(sudo zfs get -H receive_resume_token tank/mirror | cut -f 3)

# Just try and send the partial snapshot.
$ sudo zfs send -t $TOKEN > /dev/null
warning: cannot send 'tank@snap2': Invalid cross-device link

$ sudo zfs send -nP -t $TOKEN
resume token contents:
nvlist version: 0
	fromguid = 0x7eb9f6bf27d4bfc1
	object = 0x4
	offset = 0x12e0000
	bytes = 0x130cbd8
	toguid = 0xf121966674ca8619
	toname = tank@snap2
incremental	tank/mirror@snap1	tank@snap2

$ echo $?
18

Several strange occurrences:

  • The zfs send -t fails with "Invalid cross-device link" warning, which should really be an error.
  • The zfs send -nP -t reports that the source is tank/mirror@snap1 instead of tank@snap1. This is probably what causes zfs to think this is a "cross-device link" problem. It is impossible for it to satisfy this token request since that mirror doesn't have the data!
  • The zfs send -nP -t prints no error, but the return value is EXDEV
@loli10K loli10K self-assigned this Sep 9, 2017
behlendorf pushed a commit that referenced this issue Oct 10, 2017
Because resuming from a token requires "guid" -> "snapshot" mapping
we have to walk the whole dataset hierarchy to find the right snapshot
to send; when both source and destination exists, for an incremental
resumable stream, libzfs gets confused and picks up the wrong snapshot
to send from: this results in attempting to send

   "destination@snap1 -> source@snap2"

instead of

   "source@snap1 -> source@snap2"

which fails with a "Invalid cross-device link" error (EXDEV).

Fix this by adjusting the logic behind dataset traversal in
zfs_iter_children() to pick the right snapshot to send from.

Additionally update dry-run 'zfs send -t' to print its output to
stderr: this is consistent with other dry-run commands.

Reviewed-by: George Melikov <mail@gmelikov.ru>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: loli10K <ezomori.nozomu@gmail.com>
Closes #6618
Closes #6619
Closes #6623
aerusso pushed a commit to aerusso/zfs that referenced this issue Oct 11, 2017
Because resuming from a token requires "guid" -> "snapshot" mapping
we have to walk the whole dataset hierarchy to find the right snapshot
to send; when both source and destination exists, for an incremental
resumable stream, libzfs gets confused and picks up the wrong snapshot
to send from: this results in attempting to send

   "destination@snap1 -> source@snap2"

instead of

   "source@snap1 -> source@snap2"

which fails with a "Invalid cross-device link" error (EXDEV).

Fix this by adjusting the logic behind dataset traversal in
zfs_iter_children() to pick the right snapshot to send from.

Additionally update dry-run 'zfs send -t' to print its output to
stderr: this is consistent with other dry-run commands.

Reviewed-by: George Melikov <mail@gmelikov.ru>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: loli10K <ezomori.nozomu@gmail.com>
Closes openzfs#6618
Closes openzfs#6619
Closes openzfs#6623
aerusso pushed a commit to aerusso/zfs that referenced this issue Oct 12, 2017
Because resuming from a token requires "guid" -> "snapshot" mapping
we have to walk the whole dataset hierarchy to find the right snapshot
to send; when both source and destination exists, for an incremental
resumable stream, libzfs gets confused and picks up the wrong snapshot
to send from: this results in attempting to send

   "destination@snap1 -> source@snap2"

instead of

   "source@snap1 -> source@snap2"

which fails with a "Invalid cross-device link" error (EXDEV).

Fix this by adjusting the logic behind dataset traversal in
zfs_iter_children() to pick the right snapshot to send from.

Additionally update dry-run 'zfs send -t' to print its output to
stderr: this is consistent with other dry-run commands.

Reviewed-by: George Melikov <mail@gmelikov.ru>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: loli10K <ezomori.nozomu@gmail.com>
Closes openzfs#6618
Closes openzfs#6619
Closes openzfs#6623
tonyhutter pushed a commit that referenced this issue Oct 16, 2017
Because resuming from a token requires "guid" -> "snapshot" mapping
we have to walk the whole dataset hierarchy to find the right snapshot
to send; when both source and destination exists, for an incremental
resumable stream, libzfs gets confused and picks up the wrong snapshot
to send from: this results in attempting to send

   "destination@snap1 -> source@snap2"

instead of

   "source@snap1 -> source@snap2"

which fails with a "Invalid cross-device link" error (EXDEV).

Fix this by adjusting the logic behind dataset traversal in
zfs_iter_children() to pick the right snapshot to send from.

Additionally update dry-run 'zfs send -t' to print its output to
stderr: this is consistent with other dry-run commands.

Reviewed-by: George Melikov <mail@gmelikov.ru>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: loli10K <ezomori.nozomu@gmail.com>
Closes #6618
Closes #6619
Closes #6623
FransUrbo pushed a commit to FransUrbo/zfs that referenced this issue Apr 28, 2019
Because resuming from a token requires "guid" -> "snapshot" mapping
we have to walk the whole dataset hierarchy to find the right snapshot
to send; when both source and destination exists, for an incremental
resumable stream, libzfs gets confused and picks up the wrong snapshot
to send from: this results in attempting to send

   "destination@snap1 -> source@snap2"

instead of

   "source@snap1 -> source@snap2"

which fails with a "Invalid cross-device link" error (EXDEV).

Fix this by adjusting the logic behind dataset traversal in
zfs_iter_children() to pick the right snapshot to send from.

Additionally update dry-run 'zfs send -t' to print its output to
stderr: this is consistent with other dry-run commands.

Reviewed-by: George Melikov <mail@gmelikov.ru>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: loli10K <ezomori.nozomu@gmail.com>
Closes openzfs#6618
Closes openzfs#6619
Closes openzfs#6623
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants