Skip to content
Permalink
Browse files

7247 zfs receive of deduplicated stream fails

Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed by: Dan Kimmel <dan.kimmel@delphix.com>
Approved by: Robert Mustacchi <rm@joyent.com>
  • Loading branch information...
cwill authored and ahrens committed Aug 30, 2016
1 parent 9cfb65f commit 2ad25b4055c18f39b3fb20bd5c8c61057e34f377
@@ -710,6 +710,9 @@ file \
file \
path=opt/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_012_pos \
mode=0555
file \
path=opt/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_013_pos \
mode=0555
file path=opt/zfs-tests/tests/functional/cli_root/zfs_rename/cleanup mode=0555
file path=opt/zfs-tests/tests/functional/cli_root/zfs_rename/setup mode=0555
file path=opt/zfs-tests/tests/functional/cli_root/zfs_rename/zfs_rename.cfg \
@@ -150,7 +150,8 @@ tests = ['zfs_written_property_001_pos']
tests = ['zfs_receive_001_pos', 'zfs_receive_002_pos', 'zfs_receive_003_pos',
'zfs_receive_005_neg', 'zfs_receive_006_pos',
'zfs_receive_007_neg', 'zfs_receive_008_pos', 'zfs_receive_009_neg',
'zfs_receive_010_pos', 'zfs_receive_011_pos', 'zfs_receive_012_pos']
'zfs_receive_010_pos', 'zfs_receive_011_pos', 'zfs_receive_012_pos',
'zfs_receive_013_pos']

[/opt/zfs-tests/tests/functional/cli_root/zfs_rename]
tests = ['zfs_rename_001_pos', 'zfs_rename_002_pos', 'zfs_rename_003_pos',
@@ -32,7 +32,8 @@ PROGS = cleanup \
zfs_receive_009_neg \
zfs_receive_010_pos \
zfs_receive_011_pos \
zfs_receive_012_pos
zfs_receive_012_pos \
zfs_receive_013_pos

CMDS = $(PROGS:%=$(TESTDIR)/%)
$(CMDS) := FILEMODE = 0555
@@ -0,0 +1,73 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source. A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#
# CDDL HEADER END
#

#
# Copyright (c) 2015 by Delphix. All rights reserved.
#

. $STF_SUITE/tests/functional/cli_root/cli_common.kshlib

#
# DESCRIPTION:
# Verifying 'zfs receive' works correctly on deduplicated streams
#
# STRATEGY:
# 1. Create some snapshots with duplicated data
# 2. Send a deduplicated stream of the last snapshot
# 3. Attempt to receive the deduplicated stream
#

src_fs=$TESTPOOL/drecvsrc
temppool=recvtank
dst_fs=$temppool/drecvdest
streamfile=/var/tmp/drecvstream.$$
tpoolfile=/temptank.$$

function cleanup
{
for fs in $src_fs $dst_fs; do
datasetexists $fs && log_must $ZFS destroy -rf $fs
done
zpool destroy $temppool
[[ -f $streamfile ]] && log_must $RM -f $streamfile
[[ -f $tpoolfile ]] && log_must $RM -f $tpoolfile
}

log_assert "Verifying 'zfs receive' works correctly on deduplicated streams"
log_onexit cleanup

truncate -s 100M $tpoolfile
log_must zpool create $temppool $tpoolfile
log_must $ZFS create $src_fs
src_mnt=$(get_prop mountpoint $src_fs) || log_fail "get_prop mountpoint $src_fs"

echo blah > $src_mnt/blah
$ZFS snapshot $src_fs@base

echo grumble > $src_mnt/grumble
echo blah > $src_mnt/blah2
$ZFS snapshot $src_fs@snap2

echo grumble > $src_mnt/mumble
echo blah > $src_mnt/blah3
$ZFS snapshot $src_fs@snap3

log_must eval "$ZFS send -D -R $src_fs@snap3 > $streamfile"
log_must eval "$ZFS receive -v $dst_fs < $streamfile"

cleanup

log_pass "Verifying 'zfs receive' works correctly on deduplicated streams"
@@ -3047,6 +3047,9 @@ dmu_recv_end_sync(void *arg, dmu_tx_t *tx)
dsl_dataset_phys(origin_head)->ds_flags &=
~DS_FLAG_INCONSISTENT;

drc->drc_newsnapobj =
dsl_dataset_phys(origin_head)->ds_prev_snap_obj;

dsl_dataset_rele(origin_head, FTAG);
dsl_destroy_head_sync_impl(drc->drc_ds, tx);

@@ -3082,8 +3085,9 @@ dmu_recv_end_sync(void *arg, dmu_tx_t *tx)
(void) zap_remove(dp->dp_meta_objset, ds->ds_object,
DS_FIELD_RESUME_TONAME, tx);
}
drc->drc_newsnapobj =
dsl_dataset_phys(drc->drc_ds)->ds_prev_snap_obj;
}
drc->drc_newsnapobj = dsl_dataset_phys(drc->drc_ds)->ds_prev_snap_obj;
/*
* Release the hold from dmu_recv_begin. This must be done before
* we return to open context, so that when we free the dataset's dnode,
@@ -3126,8 +3130,6 @@ static int dmu_recv_end_modified_blocks = 3;
static int
dmu_recv_existing_end(dmu_recv_cookie_t *drc)
{
int error;

#ifdef _KERNEL
/*
* We will be destroying the ds; make sure its origin is unmounted if
@@ -3138,23 +3140,30 @@ dmu_recv_existing_end(dmu_recv_cookie_t *drc)
zfs_destroy_unmount_origin(name);
#endif

error = dsl_sync_task(drc->drc_tofs,
return (dsl_sync_task(drc->drc_tofs,
dmu_recv_end_check, dmu_recv_end_sync, drc,
dmu_recv_end_modified_blocks, ZFS_SPACE_CHECK_NORMAL);

if (error != 0)
dmu_recv_cleanup_ds(drc);
return (error);
dmu_recv_end_modified_blocks, ZFS_SPACE_CHECK_NORMAL));
}

static int
dmu_recv_new_end(dmu_recv_cookie_t *drc)
{
return (dsl_sync_task(drc->drc_tofs,
dmu_recv_end_check, dmu_recv_end_sync, drc,
dmu_recv_end_modified_blocks, ZFS_SPACE_CHECK_NORMAL));
}

int
dmu_recv_end(dmu_recv_cookie_t *drc, void *owner)
{
int error;

error = dsl_sync_task(drc->drc_tofs,
dmu_recv_end_check, dmu_recv_end_sync, drc,
dmu_recv_end_modified_blocks, ZFS_SPACE_CHECK_NORMAL);
drc->drc_owner = owner;

if (drc->drc_newfs)
error = dmu_recv_new_end(drc);
else
error = dmu_recv_existing_end(drc);

if (error != 0) {
dmu_recv_cleanup_ds(drc);
@@ -3166,17 +3175,6 @@ dmu_recv_new_end(dmu_recv_cookie_t *drc)
return (error);
}

int
dmu_recv_end(dmu_recv_cookie_t *drc, void *owner)
{
drc->drc_owner = owner;

if (drc->drc_newfs)
return (dmu_recv_new_end(drc));
else
return (dmu_recv_existing_end(drc));
}

/*
* Return TRUE if this objset is currently being received into.
*/

0 comments on commit 2ad25b4

Please sign in to comment.
You can’t perform that action at this time.