#!/bin/ksh # # 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, 2016 by Delphix. All rights reserved. # . $STF_SUITE/include/libtest.shlib # # DESCRIPTION: # Verify 'zfs send' drills holes appropriately when files are replaced # # STRATEGY: # 1. Create dataset # 2. Write block 0 in a bunch of files # 3. Snapshot the dataset # 4. Remove all the files and rewrite some files with just block 1 # 5. Snapshot the dataset # 6. Send both snapshots and receive them locally # 7. diff the received dataset and the old datasets. # 8. Repeat steps 1-7 above with pool that never had hole birth enabled. # verify_runnable "both" function cleanup { zfs destroy -rf $TESTPOOL/fs zfs destroy -rf $TESTPOOL/recvfs rm $streamfile rm $vdev zpool destroy tmp_pool } log_assert "Verify that 'zfs send' drills appropriate holes" log_onexit cleanup streamfile=$(mktemp /var/tmp/file.XXXXXX) vdev=$(mktemp /var/tmp/file.XXXXXX) test_pool () { POOL=$1 log_must zfs create -o recordsize=512 $POOL/fs mntpnt=$(get_prop mountpoint "$POOL/fs") log_must dd if=/dev/urandom of=${mntpnt}/file bs=512 count=1 2>/dev/null first_object=$(ls -i $mntpnt | awk '{print $1}') log_must zfs snapshot $POOL/fs@a while true; do log_must find $mntpnt -delete sync log_must mkfiles "$mntpnt/" 4000 FILE=$(ls -i $mntpnt | awk \ '{if ($1 == '$first_object') {print $2}}') if [[ -n "$FILE" ]]; then break fi done dd if=/dev/urandom of=${mntpnt}/$FILE bs=512 count=1 seek=1 2>/dev/null log_must zfs snapshot $POOL/fs@b log_must eval "zfs send $POOL/fs@a > $streamfile" cat $streamfile | log_must zfs receive $POOL/recvfs log_must eval "zfs send -i @a $POOL/fs@b > $streamfile" cat $streamfile | log_must zfs receive $POOL/recvfs recv_mntpnt=$(get_prop mountpoint "$POOL/recvfs") log_must diff -r $mntpnt $recv_mntpnt log_must zfs destroy -rf $POOL/fs log_must zfs destroy -rf $POOL/recvfs } test_pool $TESTPOOL log_must truncate --size=1G $vdev log_must zpool create -o version=1 tmp_pool $vdev test_pool tmp_pool log_must zpool destroy tmp_pool log_must zpool create -d tmp_pool $vdev test_pool tmp_pool log_must zpool destroy tmp_pool log_pass "'zfs send' drills appropriate holes"