1#! /bin/ksh -p
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) 2019, 2022 by Delphix. All rights reserved.
19#
20
21. $STF_SUITE/include/libtest.shlib
22. $STF_SUITE/tests/functional/removal/removal.kshlib
23. $STF_SUITE/tests/functional/nopwrite/nopwrite.shlib
24
25default_setup_noexit "$DISKS"
26log_onexit default_cleanup_noexit
27
28#
29# Randomly pick a device to remove
30#
31DISK_TOKENS=( $DISKS )
32DISK_INDEX_TO_REMOVE=$((RANDOM%${#DISK_TOKENS[@]}))
33DISK_TO_REMOVE=${DISK_TOKENS[${DISK_INDEX_TO_REMOVE}]}
34
35origin="$TESTPOOL/$TESTFS"
36
37log_must zfs set compress=on $origin
38log_must zfs set checksum=skein $origin
39
40log_must zfs set copies=1 $origin
41log_must zfs set recordsize=8k $origin
42dd if=/dev/urandom of=$TESTDIR/file_8k bs=1024k count=$MEGS oflag=sync \
43    conv=notrunc >/dev/null 2>&1 || log_fail "dd into $TESTDIR/file failed."
44log_must zfs set copies=3 $origin
45dd if=/dev/urandom of=$TESTDIR/file_8k_copies bs=1024k count=$MEGS oflag=sync \
46    conv=notrunc >/dev/null 2>&1 || log_fail "dd into $TESTDIR/file failed."
47
48log_must zfs set copies=1 $origin
49log_must zfs set recordsize=128k $origin
50dd if=/dev/urandom of=$TESTDIR/file_128k bs=1024k count=$MEGS oflag=sync \
51    conv=notrunc >/dev/null 2>&1 || log_fail "dd into $TESTDIR/file failed."
52log_must zfs set copies=3 $origin
53dd if=/dev/urandom of=$TESTDIR/file_128k_copies bs=1024k \
54    count=$MEGS oflag=sync conv=notrunc >/dev/null 2>&1 || \
55    log_fail "dd into $TESTDIR/file failed."
56
57zfs snapshot $origin@a || log_fail "zfs snap failed"
58log_must zfs clone $origin@a $origin/clone
59
60#
61# Verify that nopwrites work prior to removal
62#
63log_must zfs set copies=1 $origin/clone
64log_must zfs set recordsize=8k $origin/clone
65dd if=/$TESTDIR/file_8k of=/$TESTDIR/clone/file_8k bs=1024k \
66     oflag=sync conv=notrunc >/dev/null 2>&1 || log_fail "dd failed."
67log_must verify_nopwrite $origin $origin@a $origin/clone
68log_must zfs set copies=3 $origin/clone
69dd if=/$TESTDIR/file_8k_copies of=/$TESTDIR/clone/file_8k_copies bs=1024k \
70     oflag=sync conv=notrunc >/dev/null 2>&1 || log_fail "dd failed."
71log_must verify_nopwrite $origin $origin@a $origin/clone
72
73log_must zfs set copies=1 $origin/clone
74log_must zfs set recordsize=128k $origin/clone
75dd if=/$TESTDIR/file_128k of=/$TESTDIR/clone/file_128k bs=1024k \
76     oflag=sync conv=notrunc >/dev/null 2>&1 || log_fail "dd failed."
77log_must verify_nopwrite $origin $origin@a $origin/clone
78log_must zfs set copies=3 $origin/clone
79dd if=/$TESTDIR/file_128k_copies of=/$TESTDIR/clone/file_128k_copies bs=1024k \
80     oflag=sync conv=notrunc >/dev/null 2>&1 || log_fail "dd failed."
81log_must verify_nopwrite $origin $origin@a $origin/clone
82
83#
84# Remove a device before testing nopwrites again
85#
86log_note "Removing: $DISK_TO_REMOVE"
87log_must zpool remove $TESTPOOL $DISK_TO_REMOVE
88log_must wait_for_removal $TESTPOOL
89log_mustnot vdevs_in_pool $TESTPOOL $DISK_TO_REMOVE
90
91#
92# Normally, we expect nopwrites to avoid allocating new blocks, but
93# after a device has been removed the DVAs will get remapped when
94# a L0's indirect block is written. This will negate the effects
95# of nopwrite and should result in new allocations.
96#
97
98#
99# Perform a direct zil nopwrite test
100#
101log_must zfs set copies=1 $origin/clone
102log_must zfs set recordsize=8k $origin/clone
103dd if=/$TESTDIR/file_8k of=/$TESTDIR/clone/file_8k bs=1024k \
104     oflag=sync conv=notrunc >/dev/null 2>&1 || log_fail "dd failed."
105log_mustnot verify_nopwrite $origin $origin@a $origin/clone
106log_must zfs set copies=3 $origin/clone
107dd if=/$TESTDIR/file_8k_copies of=/$TESTDIR/clone/file_8k_copies bs=1024k \
108     oflag=sync conv=notrunc >/dev/null 2>&1 || log_fail "dd failed."
109log_mustnot verify_nopwrite $origin $origin@a $origin/clone
110
111#
112# Perform an indirect zil nopwrite test
113#
114log_must zfs set copies=1 $origin/clone
115log_must zfs set recordsize=128k $origin/clone
116dd if=/$TESTDIR/file_128k of=/$TESTDIR/clone/file_128k bs=1024k \
117     oflag=sync conv=notrunc >/dev/null 2>&1 || log_fail "dd failed."
118log_mustnot verify_nopwrite $origin $origin@a $origin/clone
119log_must zfs set copies=3 $origin/clone
120dd if=/$TESTDIR/file_128k_copies of=/$TESTDIR/clone/file_128k_copies bs=1024k \
121     oflag=sync conv=notrunc >/dev/null 2>&1 || log_fail "dd failed."
122log_mustnot verify_nopwrite $origin $origin@a $origin/clone
123
124log_pass "Remove works with nopwrite."
125