1 #!/usr/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 2008 Sun Microsystems, Inc.  All rights reserved.
  25 # Use is subject to license terms.
  26 #
  27 
  28 #
  29 # Copyright (c) 2013, 2016 by Delphix. All rights reserved.
  30 # Copyright 2015 Nexenta Systems, Inc. All rights reserved.
  31 #
  32 
  33 . $STF_SUITE/include/libtest.shlib
  34 . $STF_SUITE/tests/functional/replacement/replacement.cfg
  35 
  36 #
  37 # DESCRIPTION:
  38 #       Replacing disks during I/O should pass for supported pools.
  39 #
  40 # STRATEGY:
  41 #       1. Create multidisk pools (stripe/mirror/raidz) and
  42 #          start some random I/O
  43 #       2. Replace a disk in the pool with anbother disk.
  44 #       3. Verify the integrity of the file system and the resilvering.
  45 #
  46 
  47 verify_runnable "global"
  48 
  49 function cleanup
  50 {
  51         if [[ -n "$child_pids" ]]; then
  52                 for wait_pid in $child_pids
  53                 do
  54                         kill $wait_pid
  55                 done
  56         fi
  57 
  58         if poolexists $TESTPOOL1; then
  59                 destroy_pool $TESTPOOL1
  60         fi
  61 
  62         [[ -e $TESTDIR1 ]] && log_must rm -rf $TESTDIR1
  63         [[ -e $TESTDIR ]] && log_must rm -rf $TESTDIR/*
  64 }
  65 
  66 log_assert "Replacing a disk during I/O completes."
  67 
  68 options=""
  69 options_display="default options"
  70 
  71 log_onexit cleanup
  72 
  73 [[ -n "$HOLES_FILESIZE" ]] && options=" $options -f $HOLES_FILESIZE "
  74 
  75 [[ -n "$HOLES_BLKSIZE" ]] && options="$options -b $HOLES_BLKSIZE "
  76 
  77 [[ -n "$HOLES_COUNT" ]] && options="$options -c $HOLES_COUNT "
  78 
  79 [[ -n "$HOLES_SEED" ]] && options="$options -s $HOLES_SEED "
  80 
  81 [[ -n "$HOLES_FILEOFFSET" ]] && options="$options -o $HOLES_FILEOFFSET "
  82 
  83 options="$options -r "
  84 
  85 [[ -n "$options" ]] && options_display=$options
  86 
  87 child_pids=""
  88 
  89 function replace_test
  90 {
  91         typeset -i iters=2
  92         typeset -i index=0
  93         typeset opt=$1
  94         typeset disk1=$2
  95         typeset disk2=$3
  96 
  97         typeset i=0
  98         while [[ $i -lt $iters ]]; do
  99                 log_note "Invoking file_trunc with: $options_display"
 100                 file_trunc $options $TESTDIR/$TESTFILE.$i &
 101                 typeset pid=$!
 102 
 103                 sleep 1
 104                 if ! ps -p $pid > /dev/null 2>&1; then
 105                         log_fail "file_trunc $options $TESTDIR/$TESTFILE.$i"
 106                 fi
 107 
 108                 child_pids="$child_pids $pid"
 109                 ((i = i + 1))
 110         done
 111 
 112         log_must zpool replace $opt $TESTPOOL1 $disk1 $disk2
 113 
 114         sleep 10
 115 
 116         for wait_pid in $child_pids
 117         do
 118                 kill $wait_pid
 119         done
 120         child_pids=""
 121 
 122         log_must zpool export $TESTPOOL1
 123         log_must zpool import -d $TESTDIR $TESTPOOL1
 124         log_must zfs umount $TESTPOOL1/$TESTFS1
 125         log_must zdb -cdui $TESTPOOL1/$TESTFS1
 126         log_must zfs mount $TESTPOOL1/$TESTFS1
 127 
 128 }
 129 
 130 specials_list=""
 131 i=0
 132 while [[ $i != 2 ]]; do
 133         mkfile $MINVDEVSIZE $TESTDIR/$TESTFILE1.$i
 134         specials_list="$specials_list $TESTDIR/$TESTFILE1.$i"
 135 
 136         ((i = i + 1))
 137 done
 138 
 139 #
 140 # Create a replacement disk special file.
 141 #
 142 mkfile $MINVDEVSIZE $TESTDIR/$REPLACEFILE
 143 
 144 for type in "" "raidz" "raidz1" "mirror"; do
 145         for op in "" "-f"; do
 146                 create_pool $TESTPOOL1 $type $specials_list
 147                 log_must zfs create $TESTPOOL1/$TESTFS1
 148                 log_must zfs set mountpoint=$TESTDIR1 $TESTPOOL1/$TESTFS1
 149 
 150                 replace_test "$opt" $TESTDIR/$TESTFILE1.1 $TESTDIR/$REPLACEFILE
 151 
 152                 zpool iostat -v $TESTPOOL1 | grep "$TESTDIR/$REPLACEFILE"
 153                 if [[ $? -ne 0 ]]; then
 154                         log_fail "$REPLACEFILE is not present."
 155                 fi
 156 
 157                 destroy_pool $TESTPOOL1
 158                 log_must rm -rf /$TESTPOOL1
 159         done
 160 done
 161 
 162 log_pass