dmu_recv_stream builds incomplete guid_to_ds_map
This issue was discovered by Anatoliy Legkodymov on nexentastor and
reproduces on Illumos as well.
Bug was in zfs code that received deduplicated stream -
when deduplicated block is arrived it requires entry
in guid_to_ds_map (that maps guid to dsl_dataset_t) in case that block refers on dataset (snapshot) with different guid.
Buggy zfs_recv_stream code did build guid_to_ds_map
only once (before first substream was recieved) by traversing existing datasets, but in fact in that time no received (and required) datasets existed.
As result "restore_write_byref" code was unable to find
dataset (snapshot) with guid it referred to.
Fix: one need to add each of received datasets to guid_to_ds_map.
Minimal steps to reproduce:
mkfile 64m /tmp/data.file
mkfile 64m /tmp/backup.file
zpool create data /tmp/data.file
zpool create backup /tmp/backup.file
zfs create data/a
zfs create data/a/b
zfs snapshot -r data/a@C
zfs destroy -r data/a/b
zfs snapshot data/a@D
zfs send -vpRD data/a@D | zfs receive -dFeu backup
sending from @ to data/a@C
sending from @C to data/a@D
cannot receive incremental stream: invalid backup stream
Updated by Alexander Stetsenko about 10 years ago
- Status changed from In Progress to Resolved
user: Alexander Stetsenko <email@example.com>
date: Fri Apr 08 14:39:40 2011 -0400
755 dmu_recv_stream builds incomplete guid_to_ds_map
Reviewed by: Matthew Ahrens <firstname.lastname@example.org>
Reviewed by: Garrett D`Amore <email@example.com>
Reviewed by: Gordon Ross <firstname.lastname@example.org>
Approved by: Gordon Ross <email@example.com>
Fix: add every snapshot from the received dedup stream into guid_to_ds_map