1#!/bin/ksh 2# SPDX-License-Identifier: CDDL-1.0 3# 4# CDDL HEADER START 5# 6# This file and its contents are supplied under the terms of the 7# Common Development and Distribution License ("CDDL"), version 1.0. 8# You may only use this file in accordance with the terms of version 9# 1.0 of the CDDL. 10# 11# A full copy of the text of the CDDL should have accompanied this 12# source. A copy of the CDDL is also available via the Internet at 13# http://www.illumos.org/license/CDDL. 14# 15# CDDL HEADER END 16# 17 18# 19# Copyright (c) 2015, 2016 by Delphix. All rights reserved. 20# 21 22. $STF_SUITE/include/libtest.shlib 23# 24# DESCRIPTION: 25# Verify 'zfs send' drills holes appropriately when files are replaced 26# 27# STRATEGY: 28# 1. Create dataset 29# 2. Write block 0 in a bunch of files 30# 3. Snapshot the dataset 31# 4. Remove all the files and rewrite some files with just block 1 32# 5. Snapshot the dataset 33# 6. Send both snapshots and receive them locally 34# 7. diff the received dataset and the old datasets. 35# 8. Repeat steps 1-7 above with pool that never had hole birth enabled. 36# 37 38verify_runnable "both" 39 40function cleanup 41{ 42 zfs destroy -rf $TESTPOOL/fs 43 zfs destroy -rf $TESTPOOL/recvfs 44 rm $streamfile 45 rm $vdev 46 zpool destroy tmp_pool 47} 48 49 50log_assert "Verify that 'zfs send' drills appropriate holes" 51log_onexit cleanup 52streamfile=$(mktemp) 53vdev=$(mktemp) 54 55 56function test_pool 57{ 58 POOL=$1 59 log_must zfs create -o recordsize=512 $POOL/fs 60 mntpnt=$(get_prop mountpoint "$POOL/fs") 61 log_must eval "dd if=/dev/urandom of=${mntpnt}/file bs=512 count=1 2>/dev/null" 62 object=$(ls -i $mntpnt | awk '{print $1}') 63 log_must zfs snapshot $POOL/fs@a 64 while true; do 65 log_must find $mntpnt/ -type f -delete 66 sync_all_pools 67 log_must mkfiles "$mntpnt/" 4000 68 sync_all_pools 69 # check if we started reusing objects 70 object=$(ls -i $mntpnt | sort -n | awk -v object=$object \ 71 '{if ($1 <= object) {exit 1}} END {print $1}') || break 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 directory_diff $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 -s 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