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
Fix dryrun and intra-pool resumable 'zfs send' #6623
Conversation
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. Signed-off-by: loli10K <ezomori.nozomu@gmail.com>
Codecov Report
@@ Coverage Diff @@
## master #6623 +/- ##
==========================================
+ Coverage 74.07% 74.07% +<.01%
==========================================
Files 295 295
Lines 93883 93884 +1
==========================================
+ Hits 69543 69544 +1
Misses 24340 24340
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice fix!
@pcd1193182 could you please review this fix. I would expect OpenZFS to suffer from this same problem. |
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
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
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
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
Description
This PR fixes a couple of issue with resumable
zfs send
.zfs send -n -t <token>
should dump its output to stdout, not stderr, for consistency with other dry-run commands.zfs send -t <token>
for an incremental send should be able to resume successfully when sending to the same pool: a subtle issue inzfs_iter_children()
doesn't currently allow this.Because resuming from a token requires "guid" -> "dataset" mapping (
guid_to_name()
), we have to walk the whole hierarchy to find the right snapshots to send.When resuming an incremental send both source and destination live in the same pool and have the same guid: this is where
zfs_iter_children()
gets confused and picks up the wrong snapshot, so we end up trying to send an incremental "destination@snap1 -> source@snap2" stream instead of "source@snap1 -> source@snap2": this fails with an "Invalid cross-device link" (EXDEV
) error.EDIT: just to reiterate, the second bug looks like this
We need to know which snapshot to send from by its guid (fromguid = 0x46f626fea92a89af). Both testpool/fs@snap1 and testpool/fs/newfs@snap1 are good candidates:
zfs_iter_children(testpool/fs)
currently walks the dataset hierarchy in this order (children first, then snapshots)when it should be doing (snapshot first, then children)
to find the correct snapshot (testpool/fs@snap1).
NOTE: i've yet to add a new test case to the ZTS but don't know where the best place would be ("rsend" or "zfs_send"?).
rsend_019_pos
would probably be a good choice but it's currently disabled.EDIT: waiting for #6632 to get merged so
rsend_019_pos
is back in business.Motivation and Context
Fix #6618
Fix #6619
How Has This Been Tested?
Types of changes
Checklist:
Signed-off-by
.