1#!/usr/bin/ksh 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 2008 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/tests/functional/cli_root/zpool_create/zpool_create.shlib 33 34# 35# DESCRIPTION: 36# 'zpool create [-f]' can create a storage pool with large number of 37# file-in-zfs-filesystem-based vdevs without any errors. 38# 39# STRATEGY: 40# 1. Create assigned number of files in ZFS filesystem as vdevs 41# 2. Creating a new pool based on the vdevs should get success 42# 3. Fill in the filesystem and create a partially writen file as vdev 43# 4. Add the new file into vdevs list and create a pool 44# 5. Creating a storage pool with the new vdevs list should be failed. 45# 46 47verify_runnable "global" 48 49function cleanup 50{ 51 typeset pool="" 52 53 for pool in foo $TESTPOOL2 $TESTPOOL1; do 54 poolexists $pool && \ 55 destroy_pool $pool 56 done 57 58 if datasetexists $TESTPOOL/$TESTFS; then 59 log_must $ZFS destroy -f $TESTPOOL/$TESTFS 60 fi 61 62 if poolexists $TESTPOOL; then 63 destroy_pool $TESTPOOL 64 fi 65 66 if [[ -d $TESTDIR ]]; then 67 log_must $RM -rf $TESTDIR 68 fi 69 70 partition_disk $SIZE $disk 6 71} 72 73# 74# Create a pool and fs on the assigned disk, and dynamically create large 75# numbers of files as vdevs.(the default value is <VDEVS_NUM>) 76# 77 78function setup_vdevs #<disk> 79{ 80 typeset disk=$1 81 typeset -l largest_num=0 82 typeset -l slice_size=0 83 typeset vdev="" 84 85 86 # 87 # Get disk size for zfs filesystem 88 # 89 create_pool foo $disk 90 log_must $ZFS create foo/fs 91 typeset -l fs_size=$(get_prop "available" foo/fs) 92 destroy_pool foo 93 94 (( largest_num = fs_size / (1024 * 1024 * ${POOL_MINSIZE}) )) 95 if (( largest_num < $VDEVS_NUM )); then 96 #minus $largest_num/$MD_OVERHEAD to leave space for metadata 97 (( vdevs_num=largest_num - largest_num/$MD_OVERHEAD )) 98 file_size=$POOL_MINSIZE 99 vdev=$disk 100 else 101 vdevs_num=$VDEVS_NUM 102 (( file_size = fs_size / \ 103 (1024 * 1024 * (vdevs_num + vdevs_num/$MD_OVERHEAD)) )) 104 if (( file_size > FILE_SIZE )); then 105 # If file_size too large, the time cost will increase so 106 # we limit the file_size to $FILE_SIZE, and thus the 107 # total time spent on creating file can be controlled 108 # within the timeout. 109 file_size=$FILE_SIZE 110 fi 111 # Add $vdevs_num/$MD_OVERHEAD to provide enough space for 112 # metadata 113 (( slice_size = file_size * (vdevs_num + \ 114 vdevs_num/$MD_OVERHEAD) )) 115 set_partition 0 "" ${slice_size}m $disk 116 vdev=${disk}s0 117 fi 118 119 create_pool $TESTPOOL $vdev 120 [[ -d $TESTDIR ]] && \ 121 log_must $RM -rf $TESTDIR 122 log_must $MKDIR -p $TESTDIR 123 log_must $ZFS create $TESTPOOL/$TESTFS 124 log_must $ZFS set mountpoint=$TESTDIR $TESTPOOL/$TESTFS 125 126 typeset -l count=0 127 typeset PIDLIST="" 128 while (( count < vdevs_num )); do 129 $MKFILE ${file_size}m ${TESTDIR}/file.$count & 130 PIDLIST="$PIDLIST $!" 131 vdevs_list="$vdevs_list ${TESTDIR}/file.$count" 132 (( count = count + 1 )) 133 done 134 135 # wait all mkfiles to finish 136 wait $PIDLIST 137 if (( $? != 0 )); then 138 log_fail "create vdevs failed." 139 fi 140 141 return 0 142} 143 144log_assert " 'zpool create [-f]' can create a storage pool with large " \ 145 "numbers of vdevs without any errors." 146log_onexit cleanup 147 148if [[ -n $DISK ]]; then 149 disk=$DISK 150else 151 disk=$DISK0 152fi 153 154log_note "Create storage pool with number of $VDEVS_NUM file vdevs should " \ 155 "succeed." 156vdevs_list="" 157vdevs_num=$VDEVS_NUM 158file_size=$FILE_SIZE 159 160setup_vdevs $disk 161create_pool $TESTPOOL1 $vdevs_list 162 163if poolexists $TESTPOOL1; then 164 destroy_pool $TESTPOOL1 165else 166 log_fail " Creating pool with large numbers of file-vdevs fail." 167fi 168 169log_note "Creating storage pool with partially written file as vdev should " \ 170 "fail." 171 172left_space=$(get_prop "available" $TESTPOOL/$TESTFS) 173# Count the broken file size. make sure it should be greater than $left_space 174# so, here, we plus a number -- $file_size, this number can be any other number. 175(( file_size = left_space / (1024 * 1024) + file_size )) 176log_mustnot $MKFILE ${file_size}m ${TESTDIR}/broken_file 177vdevs_list="$vdevs_list ${TESTDIR}/broken_file" 178 179log_mustnot $ZPOOL create -f $TESTPOOL2 $vdevs_list 180 181log_pass "'zpool create [-f]' with $vdevs_num vdevs success." 182