1#!/bin/ksh -p 2# 3# CDDL HEADER START 4# 5# The contents of this file are subject to the terms of the 6# Common Development and Distribution License (the "License"). 7# You may not use this file except in compliance with the License. 8# 9# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10# or https://opensource.org/licenses/CDDL-1.0. 11# See the License for the specific language governing permissions 12# and limitations under the License. 13# 14# When distributing Covered Code, include this CDDL HEADER in each 15# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16# If applicable, add the following below this CDDL HEADER, with the 17# fields enclosed by brackets "[]" replaced with your own identifying 18# information: Portions Copyright [yyyy] [name of copyright owner] 19# 20# CDDL HEADER END 21# 22 23# 24# Copyright 2007 Sun Microsystems, Inc. All rights reserved. 25# Use is subject to license terms. 26# 27 28# 29# Copyright (c) 2012, 2016 by Delphix. All rights reserved. 30# 31 32. $STF_SUITE/include/libtest.shlib 33. $STF_SUITE/tests/functional/cli_root/zfs_mount/zfs_mount.kshlib 34. $STF_SUITE/tests/functional/cli_root/zpool_import/zpool_import.cfg 35 36# 37# DESCRIPTION: 38# Once a pool has been exported, but one or more devices are 39# overlapped with other exported pool, import should handle 40# this kind of situation properly. 41# 42# STRATEGY: 43# 1. Repeat 1-3, create two test pools upon device files separately. 44# These two pools should have one or more devices are overlapped. 45# using the various combinations. 46# - Regular pool 47# - Mirror 48# - Raidz 49# 2. Create necessary filesystem and test files. 50# 3. Export the test pool. 51# 4. Verify 'zpool import -d' with these two pools will have results 52# as described: 53# - Regular, report error while any number of devices failing. 54# - Mirror could withstand (N-1) devices failing 55# before data integrity is compromised 56# - Raidz could withstand one devices failing 57# before data integrity is compromised 58# 59 60verify_runnable "global" 61 62# See issue: https://github.com/openzfs/zfs/issues/6839 63if ! is_illumos; then 64 log_unsupported "Test case may be slow" 65fi 66 67set -A vdevs "" "mirror" "raidz" "draid" 68 69function verify 70{ 71 typeset pool=$1 72 typeset fs=$2 73 typeset mtpt=$3 74 typeset health=$4 75 typeset file=$5 76 typeset checksum1=$6 77 78 typeset myhealth 79 typeset mymtpt 80 typeset checksum2 81 82 log_must poolexists $pool 83 84 myhealth=$(zpool list -H -o health $pool) 85 86 [[ $myhealth == $health ]] || \ 87 log_fail "$pool: Incorrect health ($myhealth), " \ 88 "expected ($health)." 89 90 log_must ismounted $pool/$fs 91 92 mymtpt=$(get_prop mountpoint $pool/$fs) 93 [[ $mymtpt == $mtpt ]] || \ 94 log_fail "$pool/$fs: Incorrect mountpoint ($mymtpt), " \ 95 "expected ($mtpt)." 96 97 [[ ! -e $mtpt/$file ]] && \ 98 log_fail "$mtpt/$file missing after import." 99 100 read -r checksum2 _ < <(cksum $mymtpt/$file) 101 log_must [ "$checksum1" = "$checksum2" ] 102 103 return 0 104 105} 106 107function cleanup 108{ 109 log_must cd $DEVICE_DIR 110 111 for pool in $TESTPOOL1 $TESTPOOL2; do 112 if poolexists "$pool" ; then 113 cleanup_filesystem $pool $TESTFS 114 destroy_pool $pool 115 fi 116 done 117 118 [[ -e $DEVICE_DIR/$DEVICE_ARCHIVE ]] && \ 119 log_must tar xf $DEVICE_DIR/$DEVICE_ARCHIVE 120} 121 122function cleanup_all 123{ 124 cleanup 125 126 # recover dev files 127 typeset i=0 128 while (( i < $MAX_NUM )); do 129 typeset file=${DEVICE_DIR}/${DEVICE_FILE}$i 130 if [[ -e $file ]]; then 131 log_must rm $file 132 fi 133 log_must mkfile $FILE_SIZE $file 134 ((i += 1)) 135 done 136 137 log_must rm -f $DEVICE_DIR/$DEVICE_ARCHIVE 138 log_must cd $CWD 139 140} 141 142log_onexit cleanup_all 143 144log_assert "Verify that import could handle device overlapped." 145 146CWD=$PWD 147 148log_must cd $DEVICE_DIR 149log_must tar cf $DEVICE_DIR/$DEVICE_ARCHIVE ${DEVICE_FILE}* 150 151read -r checksum1 < <(cksum $MYTESTFILE) 152 153typeset -i i=0 154typeset -i j=0 155typeset -i count=0 156typeset -i num=0 157typeset vdev1="" 158typeset vdev2="" 159typeset action 160 161while (( num < $GROUP_NUM )); do 162 vdev1="$vdev1 ${DEVICE_DIR}/${DEVICE_FILE}$num" 163 (( num = num + 1 )) 164done 165 166while (( i < ${#vdevs[*]} )); do 167 j=0 168 while (( j < ${#vdevs[*]} )); do 169 170 (( j != 0 )) && \ 171 log_must tar xf $DEVICE_DIR/$DEVICE_ARCHIVE 172 173 typeset -i overlap=1 174 typeset -i begin 175 typeset -i end 176 177 while (( overlap <= $GROUP_NUM )); do 178 vdev2="" 179 (( begin = $GROUP_NUM - overlap )) 180 (( end = 2 * $GROUP_NUM - overlap - 1 )) 181 (( num = begin )) 182 while (( num <= end )); do 183 vdev2="$vdev2 ${DEVICE_DIR}/${DEVICE_FILE}$num" 184 (( num = num + 1 )) 185 done 186 187 setup_filesystem "$vdev1" $TESTPOOL1 $TESTFS $TESTDIR1 \ 188 "" ${vdevs[i]} 189 log_must cp $MYTESTFILE $TESTDIR1/$TESTFILE0 190 log_must zfs umount $TESTDIR1 191 poolexists $TESTPOOL1 && \ 192 log_must zpool export $TESTPOOL1 193 194 setup_filesystem "$vdev2" $TESTPOOL2 $TESTFS $TESTDIR2 \ 195 "" ${vdevs[j]} 196 log_must cp $MYTESTFILE $TESTDIR2/$TESTFILE0 197 log_must zfs umount $TESTDIR2 198 poolexists $TESTPOOL2 && \ 199 log_must zpool export $TESTPOOL2 200 201 action=log_must 202 case "${vdevs[i]}" in 203 'mirror') (( overlap == $GROUP_NUM )) && \ 204 action=log_mustnot 205 ;; 206 'raidz') (( overlap > 1 )) && \ 207 action=log_mustnot 208 ;; 209 'draid') (( overlap > 1 )) && \ 210 action=log_mustnot 211 ;; 212 '') action=log_mustnot 213 ;; 214 esac 215 216 $action zpool import -d $DEVICE_DIR $TESTPOOL1 217 log_must zpool import -d $DEVICE_DIR $TESTPOOL2 218 219 if [[ $action == log_must ]]; then 220 verify "$TESTPOOL1" "$TESTFS" "$TESTDIR1" \ 221 "DEGRADED" "$TESTFILE0" "$checksum1" 222 fi 223 224 verify "$TESTPOOL2" "$TESTFS" "$TESTDIR2" \ 225 "ONLINE" "$TESTFILE0" "$checksum1" 226 227 cleanup 228 229 (( overlap = overlap + 1 )) 230 231 done 232 233 ((j = j + 1)) 234 done 235 236 ((i = i + 1)) 237done 238 239log_pass "Import could handle device overlapped." 240