1#!/bin/ksh 2# 3# CDDL HEADER START 4# 5# This file and its contents are supplied under the terms of the 6# Common Development and Distribution License ("CDDL"), version 1.0. 7# You may only use this file in accordance with the terms of version 8# 1.0 of the CDDL. 9# 10# A full copy of the text of the CDDL should have accompanied this 11# source. A copy of the CDDL is also available via the Internet at 12# http://www.illumos.org/license/CDDL. 13# 14# CDDL HEADER END 15# 16 17# 18# Copyright (c) 2015, 2016 by Delphix. All rights reserved. 19# 20 21. $STF_SUITE/include/libtest.shlib 22# 23# DESCRIPTION: 24# Verify 'zfs send' drills holes appropriately when files are replaced 25# 26# STRATEGY: 27# 1. Create dataset 28# 2. Write block 0 in a bunch of files 29# 3. Snapshot the dataset 30# 4. Remove all the files and rewrite some files with just block 1 31# 5. Snapshot the dataset 32# 6. Send both snapshots and receive them locally 33# 7. diff the received dataset and the old datasets. 34# 8. Repeat steps 1-7 above with pool that never had hole birth enabled. 35# 36 37verify_runnable "both" 38 39function cleanup 40{ 41 zfs destroy -rf $TESTPOOL/fs 42 zfs destroy -rf $TESTPOOL/recvfs 43 rm $streamfile 44 rm $vdev 45 zpool destroy tmp_pool 46} 47 48 49log_assert "Verify that 'zfs send' drills appropriate holes" 50log_onexit cleanup 51streamfile=$(mktemp /var/tmp/file.XXXXXX) 52vdev=$(mktemp /var/tmp/file.XXXXXX) 53 54 55test_pool () 56{ 57 POOL=$1 58 log_must zfs create -o recordsize=512 $POOL/fs 59 mntpnt=$(get_prop mountpoint "$POOL/fs") 60 log_must dd if=/dev/urandom of=${mntpnt}/file bs=512 count=1 2>/dev/null 61 first_object=$(ls -i $mntpnt | awk '{print $1}') 62 log_must zfs snapshot $POOL/fs@a 63 while true; do 64 log_must find $mntpnt -delete 65 sync 66 log_must mkfiles "$mntpnt/" 4000 67 FILE=$(ls -i $mntpnt | awk \ 68 '{if ($1 == '$first_object') {print $2}}') 69 if [[ -n "$FILE" ]]; then 70 break 71 fi 72 done 73 dd if=/dev/urandom of=${mntpnt}/$FILE bs=512 count=1 seek=1 2>/dev/null 74 75 log_must zfs snapshot $POOL/fs@b 76 77 log_must eval "zfs send $POOL/fs@a > $streamfile" 78 cat $streamfile | log_must zfs receive $POOL/recvfs 79 80 log_must eval "zfs send -i @a $POOL/fs@b > $streamfile" 81 cat $streamfile | log_must zfs receive $POOL/recvfs 82 83 recv_mntpnt=$(get_prop mountpoint "$POOL/recvfs") 84 log_must diff -r $mntpnt $recv_mntpnt 85 log_must zfs destroy -rf $POOL/fs 86 log_must zfs destroy -rf $POOL/recvfs 87} 88 89test_pool $TESTPOOL 90log_must truncate --size=1G $vdev 91log_must zpool create -o version=1 tmp_pool $vdev 92test_pool tmp_pool 93log_must zpool destroy tmp_pool 94log_must zpool create -d tmp_pool $vdev 95test_pool tmp_pool 96log_must zpool destroy tmp_pool 97 98log_pass "'zfs send' drills appropriate holes" 99