168ecb2ecSPaul Dagnelie#!/bin/ksh -p
268ecb2ecSPaul Dagnelie#
368ecb2ecSPaul Dagnelie# CDDL HEADER START
468ecb2ecSPaul Dagnelie#
568ecb2ecSPaul Dagnelie# The contents of this file are subject to the terms of the
668ecb2ecSPaul Dagnelie# Common Development and Distribution License (the "License").
768ecb2ecSPaul Dagnelie# You may not use this file except in compliance with the License.
868ecb2ecSPaul Dagnelie#
968ecb2ecSPaul Dagnelie# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
1068ecb2ecSPaul Dagnelie# or http://www.opensolaris.org/os/licensing.
1168ecb2ecSPaul Dagnelie# See the License for the specific language governing permissions
1268ecb2ecSPaul Dagnelie# and limitations under the License.
1368ecb2ecSPaul Dagnelie#
1468ecb2ecSPaul Dagnelie# When distributing Covered Code, include this CDDL HEADER in each
1568ecb2ecSPaul Dagnelie# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1668ecb2ecSPaul Dagnelie# If applicable, add the following below this CDDL HEADER, with the
1768ecb2ecSPaul Dagnelie# fields enclosed by brackets "[]" replaced with your own identifying
1868ecb2ecSPaul Dagnelie# information: Portions Copyright [yyyy] [name of copyright owner]
1968ecb2ecSPaul Dagnelie#
2068ecb2ecSPaul Dagnelie# CDDL HEADER END
2168ecb2ecSPaul Dagnelie#
2268ecb2ecSPaul Dagnelie
2368ecb2ecSPaul Dagnelie#
24b868f5d2SPaul Dagnelie# Copyright (c) 2015, 2016 by Delphix. All rights reserved.
2568ecb2ecSPaul Dagnelie#
2668ecb2ecSPaul Dagnelie
2768ecb2ecSPaul Dagnelie. $STF_SUITE/include/libtest.shlib
2868ecb2ecSPaul Dagnelie
2968ecb2ecSPaul Dagnelie#
3068ecb2ecSPaul Dagnelie# DESCRIPTION:
3168ecb2ecSPaul Dagnelie# Test that receiving a full send as a clone works correctly.
3268ecb2ecSPaul Dagnelie#
3368ecb2ecSPaul Dagnelie# STRATEGY:
3468ecb2ecSPaul Dagnelie# 1. Create pool and filesystems.
3568ecb2ecSPaul Dagnelie# 2. Send filesystem, receive as clone of itself.
3668ecb2ecSPaul Dagnelie# 3. Verify that nop-write saves space.
3768ecb2ecSPaul Dagnelie# 4. Send filesystem, receive as clone of other filesystem.
3868ecb2ecSPaul Dagnelie# 5. Verify that contents are correct.
3968ecb2ecSPaul Dagnelie# 6. Repeat steps 4 and 5 with filesystems swapped.
4068ecb2ecSPaul Dagnelie#
4168ecb2ecSPaul Dagnelie
4268ecb2ecSPaul Dagnelieverify_runnable "both"
4368ecb2ecSPaul Dagnelie
4468ecb2ecSPaul Dagneliefs=$TESTPOOL/$TESTFS/base/fs
4568ecb2ecSPaul Dagneliefs2=$TESTPOOL/$TESTFS/base/fs2
4668ecb2ecSPaul Dagnelierfs=$TESTPOOL/$TESTFS/base/rfs
4768ecb2ecSPaul Dagnelie
4868ecb2ecSPaul Dagneliefunction make_object
4968ecb2ecSPaul Dagnelie{
5068ecb2ecSPaul Dagnelie	local objnum=$1
5168ecb2ecSPaul Dagnelie	local mntpnt=$2
5268ecb2ecSPaul Dagnelie	local type=$3
5368ecb2ecSPaul Dagnelie	if [[ $type == "file" ]]; then
54*1d32ba66SJohn Wren Kennedy		dd if=/dev/urandom of=${mntpnt}/f$objnum bs=512 count=16
5568ecb2ecSPaul Dagnelie	elif [[ $type == "hole1" ]]; then
56*1d32ba66SJohn Wren Kennedy		dd if=/dev/urandom of=${mntpnt}/fh$objnum bs=512 count=5 stride=4
5768ecb2ecSPaul Dagnelie	elif [[ $type == "hole2" ]]; then
58*1d32ba66SJohn Wren Kennedy		dd if=/dev/urandom of=${mntpnt}/fh$objnum bs=512 count=4 stride=5
5968ecb2ecSPaul Dagnelie	elif [[ $type == "directory" ]]; then
60*1d32ba66SJohn Wren Kennedy		mkdir ${mntpnt}/d$objnum
6168ecb2ecSPaul Dagnelie	elif [[ $type == "missing" ]]; then
62*1d32ba66SJohn Wren Kennedy		touch ${mntpnt}/h$objnum
6368ecb2ecSPaul Dagnelie	fi
6468ecb2ecSPaul Dagnelie}
6568ecb2ecSPaul Dagnelie
6668ecb2ecSPaul Dagneliefunction create_pair
6768ecb2ecSPaul Dagnelie{
6868ecb2ecSPaul Dagnelie	local objnum=$1
6968ecb2ecSPaul Dagnelie	local mntpnt1=$2
7068ecb2ecSPaul Dagnelie	local mntpnt2=$3
7168ecb2ecSPaul Dagnelie	local type1=$4
7268ecb2ecSPaul Dagnelie	local type2=$5
7368ecb2ecSPaul Dagnelie	make_object $objnum $mntpnt1 $type1
7468ecb2ecSPaul Dagnelie	make_object $objnum $mntpnt2 $type2
7568ecb2ecSPaul Dagnelie}
7668ecb2ecSPaul Dagnelie
7768ecb2ecSPaul Dagneliefunction cleanup
7868ecb2ecSPaul Dagnelie{
79*1d32ba66SJohn Wren Kennedy	zfs destroy -Rf $TESTPOOL/$TESTFS/base
8068ecb2ecSPaul Dagnelie	rm /tmp/zr010p*
8168ecb2ecSPaul Dagnelie}
8268ecb2ecSPaul Dagnelie
8368ecb2ecSPaul Dagnelielog_assert "zfs receive of full send as clone should work"
8468ecb2ecSPaul Dagnelielog_onexit cleanup
85*1d32ba66SJohn Wren Kennedylog_must zfs create -o checksum=sha256 -o compression=gzip -o recordsize=512 \
8668ecb2ecSPaul Dagnelie	$TESTPOOL/$TESTFS/base
8768ecb2ecSPaul Dagnelie
88*1d32ba66SJohn Wren Kennedylog_must zfs create $fs
89*1d32ba66SJohn Wren Kennedylog_must zfs create $fs2
9068ecb2ecSPaul Dagneliemntpnt=$(get_prop mountpoint $fs)
9168ecb2ecSPaul Dagneliemntpnt2=$(get_prop mountpoint $fs2)
9268ecb2ecSPaul Dagnelie
9368ecb2ecSPaul Dagnelie#
9468ecb2ecSPaul Dagnelie# Now, we create the two filesystems.  By creating objects with
9568ecb2ecSPaul Dagnelie# different types and the same object number in each filesystem, we
9668ecb2ecSPaul Dagnelie# create a situation where, when you receive the full send of each as
9768ecb2ecSPaul Dagnelie# a clone of the other, we will test to ensure that the code correctly
9868ecb2ecSPaul Dagnelie# handles receiving all object types onto all other object types.
9968ecb2ecSPaul Dagnelie#
10068ecb2ecSPaul Dagnelie
10168ecb2ecSPaul Dagnelie# Receive a file onto a file (and vice versa).
10268ecb2ecSPaul Dagneliecreate_pair 8 $mntpnt $mntpnt2 "file" "file"
10368ecb2ecSPaul Dagnelie
10468ecb2ecSPaul Dagnelie# Receive a file onto a file with holes (and vice versa).
10568ecb2ecSPaul Dagneliecreate_pair 9 $mntpnt $mntpnt2 "file" "hole1"
10668ecb2ecSPaul Dagnelie
10768ecb2ecSPaul Dagnelie# Receive a file onto a directory (and vice versa).
10868ecb2ecSPaul Dagneliecreate_pair 10 $mntpnt $mntpnt2 "file" "directory"
10968ecb2ecSPaul Dagnelie
11068ecb2ecSPaul Dagnelie# Receive a file onto a missing object (and vice versa).
11168ecb2ecSPaul Dagneliecreate_pair 11 $mntpnt $mntpnt2 "file" "missing"
11268ecb2ecSPaul Dagnelie
11368ecb2ecSPaul Dagnelie# Receive a file with holes onto a file with holes (and vice versa).
11468ecb2ecSPaul Dagneliecreate_pair 12 $mntpnt $mntpnt2 "hole1" "hole2"
11568ecb2ecSPaul Dagnelie
11668ecb2ecSPaul Dagnelie# Receive a file with holes onto a directory (and vice versa).
11768ecb2ecSPaul Dagneliecreate_pair 13 $mntpnt $mntpnt2 "hole1" "directory"
11868ecb2ecSPaul Dagnelie
11968ecb2ecSPaul Dagnelie# Receive a file with holes onto a missing object (and vice versa).
12068ecb2ecSPaul Dagneliecreate_pair 14 $mntpnt $mntpnt2 "hole1" "missing"
12168ecb2ecSPaul Dagnelie
12268ecb2ecSPaul Dagnelie# Receive a directory onto a directory (and vice versa).
12368ecb2ecSPaul Dagneliecreate_pair 15 $mntpnt $mntpnt2 "directory" "directory"
12468ecb2ecSPaul Dagnelie
12568ecb2ecSPaul Dagnelie# Receive a directory onto a missing object (and vice versa).
12668ecb2ecSPaul Dagneliecreate_pair 16 $mntpnt $mntpnt2 "directory" "missing"
12768ecb2ecSPaul Dagnelie
12868ecb2ecSPaul Dagnelie# Receive a missing object onto a missing object (and vice versa).
12968ecb2ecSPaul Dagneliecreate_pair 17 $mntpnt $mntpnt2 "missing" "missing"
13068ecb2ecSPaul Dagnelie
13168ecb2ecSPaul Dagnelie# Receive a file with a different record size onto a file (and vice versa).
132*1d32ba66SJohn Wren Kennedylog_must zfs set recordsize=128k $fs
133*1d32ba66SJohn Wren Kennedydd if=/dev/urandom of=$mntpnt/f18 bs=128k count=64
134*1d32ba66SJohn Wren Kennedytouch $mntpnt2/f18
13568ecb2ecSPaul Dagnelie
13668ecb2ecSPaul Dagnelie# Remove objects that are intended to be missing.
137*1d32ba66SJohn Wren Kennedyrm $mntpnt/h17
138*1d32ba66SJohn Wren Kennedyrm $mntpnt2/h*
13968ecb2ecSPaul Dagnelie
140286ef713SPaul Dagnelie# Add empty objects to $fs to exercise dmu_traverse code
141b868f5d2SPaul Dagneliefor i in {1..100}; do
142286ef713SPaul Dagnelie	log_must touch $mntpnt/uf$i
143286ef713SPaul Dagneliedone
144286ef713SPaul Dagnelie
145*1d32ba66SJohn Wren Kennedylog_must zfs snapshot $fs@s1
146*1d32ba66SJohn Wren Kennedylog_must zfs snapshot $fs2@s1
14768ecb2ecSPaul Dagnelie
148*1d32ba66SJohn Wren Kennedylog_must zfs send $fs@s1 > /tmp/zr010p
149*1d32ba66SJohn Wren Kennedylog_must zfs send $fs2@s1 > /tmp/zr010p2
15068ecb2ecSPaul Dagnelie
15168ecb2ecSPaul Dagnelie
15268ecb2ecSPaul Dagnelie#
15368ecb2ecSPaul Dagnelie# Test that, when we receive a full send as a clone of itself,
15468ecb2ecSPaul Dagnelie# nop-write saves us all the space used by data blocks.
15568ecb2ecSPaul Dagnelie#
156*1d32ba66SJohn Wren Kennedycat /tmp/zr010p | log_must zfs receive -o origin=$fs@s1 $rfs
15768ecb2ecSPaul Dagneliesize=$(get_prop used $rfs)
15868ecb2ecSPaul Dagneliesize2=$(get_prop used $fs)
15968ecb2ecSPaul Dagnelieif [[ $size -ge $(($size2 / 10)) ]] then
16068ecb2ecSPaul Dagnelie        log_fail "nop-write failure; expected usage less than "\
16168ecb2ecSPaul Dagnelie		"$(($size2 / 10)), but is using $size"
16268ecb2ecSPaul Dagneliefi
163*1d32ba66SJohn Wren Kennedylog_must zfs destroy -fr $rfs
16468ecb2ecSPaul Dagnelie
16568ecb2ecSPaul Dagnelie# Correctness testing: receive each full send as a clone of the other fiesystem.
166*1d32ba66SJohn Wren Kennedycat /tmp/zr010p | log_must zfs receive -o origin=$fs2@s1 $rfs
16768ecb2ecSPaul Dagneliemntpnt_old=$(get_prop mountpoint $fs)
16868ecb2ecSPaul Dagneliemntpnt_new=$(get_prop mountpoint $rfs)
169*1d32ba66SJohn Wren Kennedylog_must diff -r $mntpnt_old $mntpnt_new
170*1d32ba66SJohn Wren Kennedylog_must zfs destroy -r $rfs
17168ecb2ecSPaul Dagnelie
172*1d32ba66SJohn Wren Kennedycat /tmp/zr010p2 | log_must zfs receive -o origin=$fs@s1 $rfs
17368ecb2ecSPaul Dagneliemntpnt_old=$(get_prop mountpoint $fs2)
17468ecb2ecSPaul Dagneliemntpnt_new=$(get_prop mountpoint $rfs)
175*1d32ba66SJohn Wren Kennedylog_must diff -r $mntpnt_old $mntpnt_new
17668ecb2ecSPaul Dagnelie
17768ecb2ecSPaul Dagnelielog_pass "zfs receive of full send as clone works"
178