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 http://www.opensolaris.org/os/licensing. 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 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 62set -A vdevs "" "mirror" "raidz" 63 64function verify 65{ 66 typeset pool=$1 67 typeset fs=$2 68 typeset mtpt=$3 69 typeset health=$4 70 typeset file=$5 71 typeset checksum1=$6 72 73 typeset myhealth 74 typeset mymtpt 75 typeset checksum2 76 77 log_must poolexists $pool 78 79 myhealth=$($ZPOOL list -H -o health $pool) 80 81 [[ $myhealth == $health ]] || \ 82 log_fail "$pool: Incorrect health ($myhealth), " \ 83 "expected ($health)." 84 85 log_must ismounted $pool/$fs 86 87 mymtpt=$(get_prop mountpoint $pool/$fs) 88 [[ $mymtpt == $mtpt ]] || \ 89 log_fail "$pool/$fs: Incorrect mountpoint ($mymtpt), " \ 90 "expected ($mtpt)." 91 92 [[ ! -e $mtpt/$file ]] && \ 93 log_fail "$mtpt/$file missing after import." 94 95 checksum2=$($SUM $mymtpt/$file | $AWK '{print $1}') 96 [[ "$checksum1" != "$checksum2" ]] && \ 97 log_fail "Checksums differ ($checksum1 != $checksum2)" 98 99 return 0 100 101} 102 103function cleanup 104{ 105 cd $DEVICE_DIR || log_fail "Unable change directory to $DEVICE_DIR" 106 107 for pool in $TESTPOOL1 $TESTPOOL2; do 108 if poolexists "$pool" ; then 109 cleanup_filesystem $pool $TESTFS 110 destroy_pool $pool 111 fi 112 done 113 114 [[ -e $DEVICE_DIR/$DEVICE_ARCHIVE ]] && \ 115 log_must $TAR xf $DEVICE_DIR/$DEVICE_ARCHIVE 116} 117 118function cleanup_all 119{ 120 cleanup 121 122 # recover dev files 123 typeset i=0 124 while (( i < $MAX_NUM )); do 125 typeset file=${DEVICE_DIR}/${DEVICE_FILE}$i 126 if [[ -e $file ]]; then 127 log_must $RM $file 128 fi 129 log_must $MKFILE $FILE_SIZE $file 130 ((i += 1)) 131 done 132 133 log_must $RM -f $DEVICE_DIR/$DEVICE_ARCHIVE 134 cd $CWD || log_fail "Unable change directory to $CWD" 135 136} 137 138log_onexit cleanup_all 139 140log_assert "Verify that import could handle device overlapped." 141 142CWD=$PWD 143 144cd $DEVICE_DIR || log_fail "Unable change directory to $DEVICE_DIR" 145log_must $TAR cf $DEVICE_DIR/$DEVICE_ARCHIVE ${DEVICE_FILE}* 146 147checksum1=$($SUM $MYTESTFILE | $AWK '{print $1}') 148 149typeset -i i=0 150typeset -i j=0 151typeset -i count=0 152typeset -i num=0 153typeset vdev1="" 154typeset vdev2="" 155typeset action 156 157while (( num < $GROUP_NUM )); do 158 vdev1="$vdev1 ${DEVICE_DIR}/${DEVICE_FILE}$num" 159 (( num = num + 1 )) 160done 161 162while (( i < ${#vdevs[*]} )); do 163 j=0 164 while (( j < ${#vdevs[*]} )); do 165 166 (( j != 0 )) && \ 167 log_must $TAR xf $DEVICE_DIR/$DEVICE_ARCHIVE 168 169 typeset -i overlap=1 170 typeset -i begin 171 typeset -i end 172 173 while (( overlap <= $GROUP_NUM )); do 174 vdev2="" 175 (( begin = $GROUP_NUM - overlap )) 176 (( end = 2 * $GROUP_NUM - overlap - 1 )) 177 (( num = begin )) 178 while (( num <= end )); do 179 vdev2="$vdev2 ${DEVICE_DIR}/${DEVICE_FILE}$num" 180 (( num = num + 1 )) 181 done 182 183 setup_filesystem "$vdev1" $TESTPOOL1 $TESTFS $TESTDIR1 \ 184 "" ${vdevs[i]} 185 log_must $CP $MYTESTFILE $TESTDIR1/$TESTFILE0 186 log_must $ZFS umount $TESTDIR1 187 poolexists $TESTPOOL1 && \ 188 log_must $ZPOOL export $TESTPOOL1 189 190 setup_filesystem "$vdev2" $TESTPOOL2 $TESTFS $TESTDIR2 \ 191 "" ${vdevs[j]} 192 log_must $CP $MYTESTFILE $TESTDIR2/$TESTFILE0 193 log_must $ZFS umount $TESTDIR2 194 poolexists $TESTPOOL2 && \ 195 log_must $ZPOOL export $TESTPOOL2 196 197 action=log_must 198 case "${vdevs[i]}" in 199 'mirror') (( overlap == $GROUP_NUM )) && \ 200 action=log_mustnot 201 ;; 202 'raidz') (( overlap > 1 )) && \ 203 action=log_mustnot 204 ;; 205 '') action=log_mustnot 206 ;; 207 esac 208 209 $action $ZPOOL import -d $DEVICE_DIR $TESTPOOL1 210 log_must $ZPOOL import -d $DEVICE_DIR $TESTPOOL2 211 212 if [[ $action == log_must ]]; then 213 verify "$TESTPOOL1" "$TESTFS" "$TESTDIR1" \ 214 "DEGRADED" "$TESTFILE0" "$checksum1" 215 fi 216 217 verify "$TESTPOOL2" "$TESTFS" "$TESTDIR2" \ 218 "ONLINE" "$TESTFILE0" "$checksum1" 219 220 cleanup 221 222 (( overlap = overlap + 1 )) 223 224 done 225 226 ((j = j + 1)) 227 done 228 229 ((i = i + 1)) 230done 231 232log_pass "Import could handle device overlapped." 233