112a8814cSTom Caputi#!/bin/ksh -p
212a8814cSTom Caputi#
312a8814cSTom Caputi# CDDL HEADER START
412a8814cSTom Caputi#
512a8814cSTom Caputi# The contents of this file are subject to the terms of the
612a8814cSTom Caputi# Common Development and Distribution License (the "License").
712a8814cSTom Caputi# You may not use this file except in compliance with the License.
812a8814cSTom Caputi#
912a8814cSTom Caputi# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
1012a8814cSTom Caputi# or http://www.opensolaris.org/os/licensing.
1112a8814cSTom Caputi# See the License for the specific language governing permissions
1212a8814cSTom Caputi# and limitations under the License.
1312a8814cSTom Caputi#
1412a8814cSTom Caputi# When distributing Covered Code, include this CDDL HEADER in each
1512a8814cSTom Caputi# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1612a8814cSTom Caputi# If applicable, add the following below this CDDL HEADER, with the
1712a8814cSTom Caputi# fields enclosed by brackets "[]" replaced with your own identifying
1812a8814cSTom Caputi# information: Portions Copyright [yyyy] [name of copyright owner]
1912a8814cSTom Caputi#
2012a8814cSTom Caputi# CDDL HEADER END
2112a8814cSTom Caputi#
2212a8814cSTom Caputi
2312a8814cSTom Caputi#
2412a8814cSTom Caputi# Copyright 2017, loli10K <ezomori.nozomu@gmail.com>. All rights reserved.
25*e4c795beSTom Caputi# Copyright 2019 Joyent, Inc.
2612a8814cSTom Caputi#
2712a8814cSTom Caputi
2812a8814cSTom Caputi. $STF_SUITE/include/libtest.shlib
2912a8814cSTom Caputi. $STF_SUITE/tests/functional/cli_root/zpool_reopen/zpool_reopen.shlib
3012a8814cSTom Caputi. $STF_SUITE/tests/functional/cli_root/zpool_scrub/zpool_scrub.cfg
3112a8814cSTom Caputi
3212a8814cSTom Caputi#
3312a8814cSTom Caputi# DESCRIPTION:
3412a8814cSTom Caputi# Scrubbing a pool with offline devices correctly preserves DTL entries
3512a8814cSTom Caputi#
3612a8814cSTom Caputi# STRATEGY:
3712a8814cSTom Caputi# 1. Create the pool
3812a8814cSTom Caputi# 2. Offline the first device
3912a8814cSTom Caputi# 3. Write to the pool
4012a8814cSTom Caputi# 4. Scrub the pool
4112a8814cSTom Caputi# 5. Online the first device and offline the second device
4212a8814cSTom Caputi# 6. Scrub the pool again
4312a8814cSTom Caputi# 7. Verify data integrity
4412a8814cSTom Caputi#
4512a8814cSTom Caputi# NOTE:
4612a8814cSTom Caputi# Ported from script used to reproduce issue #5806
4712a8814cSTom Caputi#
4812a8814cSTom Caputi
4912a8814cSTom Caputiverify_runnable "global"
5012a8814cSTom Caputi
5112a8814cSTom Caputifunction cleanup
5212a8814cSTom Caputi{
5312a8814cSTom Caputi	poolexists $TESTPOOL2 && destroy_pool $TESTPOOL2
5412a8814cSTom Caputi	log_must rm -f $DISK1 $DISK2 $DISK3 $DISK4
5512a8814cSTom Caputi}
5612a8814cSTom Caputi
5712a8814cSTom Caputi#
5812a8814cSTom Caputi# Update to [online|offline] $device status on $pool synchronously
5912a8814cSTom Caputi#
6012a8814cSTom Caputifunction zpool_do_sync # <status> <pool> <device>
6112a8814cSTom Caputi{
6212a8814cSTom Caputi	status="$1"
6312a8814cSTom Caputi	pool="$2"
6412a8814cSTom Caputi	device="$3"
6512a8814cSTom Caputi
6612a8814cSTom Caputi	if [[ $status != "online" && $status != "offline" ]]; then
6712a8814cSTom Caputi		log_fail "zpool_do_sync: invalid status $status"
6812a8814cSTom Caputi	fi
6912a8814cSTom Caputi
7012a8814cSTom Caputi	log_must zpool $status $pool $device
7112a8814cSTom Caputi	for i in {1..10}; do
7212a8814cSTom Caputi		check_state $pool $device $status && return 0
7312a8814cSTom Caputi	done
7412a8814cSTom Caputi	log_fail "Failed to $status device $device"
7512a8814cSTom Caputi}
7612a8814cSTom Caputi
7712a8814cSTom Caputi#
7812a8814cSTom Caputi# Start a scrub on $pool and wait for its completion
7912a8814cSTom Caputi#
8012a8814cSTom Caputifunction zpool_scrub_sync # <pool>
8112a8814cSTom Caputi{
8212a8814cSTom Caputi	pool="$1"
8312a8814cSTom Caputi
8412a8814cSTom Caputi	log_must zpool scrub $pool
8512a8814cSTom Caputi	while ! is_pool_scrubbed $pool; do
8612a8814cSTom Caputi		sleep 1
8712a8814cSTom Caputi	done
8812a8814cSTom Caputi}
8912a8814cSTom Caputi
9012a8814cSTom Caputilog_assert "Scrubbing a pool with offline devices correctly preserves DTLs"
9112a8814cSTom Caputilog_onexit cleanup
9212a8814cSTom Caputi
9312a8814cSTom CaputiDEVSIZE='128m'
9412a8814cSTom CaputiFILESIZE='100m'
9512a8814cSTom CaputiTESTDIR="$TEST_BASE_DIR/zpool_scrub_offline_device"
9612a8814cSTom CaputiDISK1="$TEST_BASE_DIR/zpool_disk1.dat"
9712a8814cSTom CaputiDISK2="$TEST_BASE_DIR/zpool_disk2.dat"
9812a8814cSTom CaputiDISK3="$TEST_BASE_DIR/zpool_disk3.dat"
9912a8814cSTom CaputiDISK4="$TEST_BASE_DIR/zpool_disk4.dat"
10012a8814cSTom CaputiRESILVER_TIMEOUT=40
10112a8814cSTom Caputi
10212a8814cSTom Caputi# 1. Create the pool
10312a8814cSTom Caputilog_must truncate -s $DEVSIZE $DISK1
10412a8814cSTom Caputilog_must truncate -s $DEVSIZE $DISK2
10512a8814cSTom Caputilog_must truncate -s $DEVSIZE $DISK3
10612a8814cSTom Caputilog_must truncate -s $DEVSIZE $DISK4
10712a8814cSTom Caputipoolexists $TESTPOOL2 && destroy_pool $TESTPOOL2
10812a8814cSTom Caputilog_must zpool create -O mountpoint=$TESTDIR $TESTPOOL2 \
10912a8814cSTom Caputi    raidz2 $DISK1 $DISK2 $DISK3 $DISK4
11012a8814cSTom Caputi
11112a8814cSTom Caputi# 2. Offline the first device
11212a8814cSTom Caputizpool_do_sync 'offline' $TESTPOOL2 $DISK1
11312a8814cSTom Caputi
11412a8814cSTom Caputi# 3. Write to the pool
11512a8814cSTom Caputilog_must mkfile $FILESIZE "$TESTDIR/data.bin"
11612a8814cSTom Caputi
11712a8814cSTom Caputi# 4. Scrub the pool
11812a8814cSTom Caputizpool_scrub_sync $TESTPOOL2
11912a8814cSTom Caputi
12012a8814cSTom Caputi# 5. Online the first device and offline the second device
12112a8814cSTom Caputizpool_do_sync 'online' $TESTPOOL2 $DISK1
12212a8814cSTom Caputizpool_do_sync 'offline' $TESTPOOL2 $DISK2
12312a8814cSTom Caputilog_must wait_for_resilver_end $TESTPOOL2 $RESILVER_TIMEOUT
12412a8814cSTom Caputi
12512a8814cSTom Caputi# 6. Scrub the pool again
12612a8814cSTom Caputizpool_scrub_sync $TESTPOOL2
12712a8814cSTom Caputi
12812a8814cSTom Caputi# 7. Verify data integrity
129*e4c795beSTom Caputicksum=$(zpool status $TESTPOOL2 | awk '{if ($NF == "CKSUM") {fnd=1; next} \
130*e4c795beSTom Caputi    if (fnd && NF < 1) {fnd=0; next} if (fnd) csum += $NF} END {print csum}')
13112a8814cSTom Caputiif [[ $cksum != 0 ]]; then
13212a8814cSTom Caputi	log_fail "Unexpected CKSUM errors found on $TESTPOOL2 ($cksum)"
13312a8814cSTom Caputifi
13412a8814cSTom Caputi
13512a8814cSTom Caputilog_pass "Scrubbing a pool with offline devices correctly preserves DTLs"
136