1#!/bin/ksh 2# 3# This file and its contents are supplied under the terms of the 4# Common Development and Distribution License ("CDDL"), version 1.0. 5# You may only use this file in accordance with the terms of version 6# 1.0 of the CDDL. 7# 8# A full copy of the text of the CDDL should have accompanied this 9# source. A copy of the CDDL is also available via the Internet at 10# http://www.illumos.org/license/CDDL. 11# 12 13# 14# Copyright 2024 OmniOS Community Edition (OmniOSce) Association. 15# 16 17. $STF_SUITE/include/libtest.shlib 18 19# 20# DESCRIPTION: 21# Automated auto-spare selects lowest capacity suitable device 22# 23# STRATEGY: 24# 1. Create a redundant pool with two spare devices of different sizes, 25# one that matches the size of the other devices in the pool, and one 26# twice as large. 27# 2. Manually fault a device, wait for the hot-spare and verify that 28# the smallest device is selected. 29# 3. Repeat with the devices added to the pool in the opposite order. 30# 4. Repeat with the faulted vdev being the same size as the larger 31# spare and verify that the larger spare is selected. 32# 33 34verify_runnable "global" 35 36function cleanup { 37 log_must zinject -c all 38 poolexists $TESTPOOL && destroy_pool $TESTPOOL 39 log_must rm -f ${DATA_DEVS[*]} ${SPARE_DEVS[*]} 40} 41 42log_assert "Automated auto-spare selects lowest capacity suitable device" 43log_onexit cleanup 44 45typeset -a DATA_DEVS SPARE_DEVS 46typeset DEV 47TMPDIR='/var/tmp' 48for d in {1..4}; do 49 DEV="$TMPDIR/data-dev$d" 50 typeset -r "DATA_DEV$d"="$DEV" 51 DATA_DEVS+=($DEV) 52done 53for d in {1..2}; do 54 DEV="$TMPDIR/data-dev$d" 55 typeset -r "SPARE_DEV$d"="$TMPDIR/spare-dev$d" 56 SPARE_DEVS+=($DEV) 57done 58 59function run { 60 typeset type="$1"; shift 61 typeset ddevsize="$1"; shift # Data dev size 62 typeset spare1="$1"; shift # First spare to add 63 typeset spare2="$1"; shift # Second spare to add 64 typeset spare="$1"; shift # Expected spare that gets picked 65 66 truncate -s $ddevsize ${DATA_DEVS[*]} 67 truncate -s $SPA_MINDEVSIZE $SPARE_DEV1 68 truncate -s $((SPA_MINDEVSIZE * 2)) $SPARE_DEV2 69 70 log_must zpool create $TESTPOOL $type ${DATA_DEVS[*]} 71 log_must zpool add $TESTPOOL spare "$spare1" 72 log_must zpool add $TESTPOOL spare "$spare2" 73 74 # Fault a device, verify the right spare is kicked in 75 log_must zinject -d $DATA_DEV1 -e nxio -T all -f 100 $TESTPOOL 76 log_must zpool scrub $TESTPOOL 77 log_must wait_vdev_state $TESTPOOL $DATA_DEV1 "UNAVAIL" 60 78 log_must wait_vdev_state $TESTPOOL $spare "ONLINE" 60 79 log_must wait_hotspare_state $TESTPOOL $spare "INUSE" 80 log_must check_state $TESTPOOL "$type-0" "DEGRADED" 81 cleanup 82} 83 84for type in mirror raidz1 raidz2 raidz3; do 85 # All vdevs and spare1 are the same size, spare2 is double the size. 86 # Regardless of whether spare1 or spare2 is added to the pool first, we 87 # expect spare1 to be used for the replacement. 88 run $type $SPA_MINDEVSIZE $SPARE_DEV1 $SPARE_DEV2 $SPARE_DEV1 89 run $type $SPA_MINDEVSIZE $SPARE_DEV2 $SPARE_DEV1 $SPARE_DEV1 90 91 # All vdevs and spare2 are the same size, spare1 is half the size. 92 # Regardless of whether spare1 or spare2 is added to the pool first, we 93 # expect spare2 to be used for the replacement. spare1 is too small. 94 run $type $((SPA_MINDEVSIZE * 2)) $SPARE_DEV1 $SPARE_DEV2 $SPARE_DEV2 95 run $type $((SPA_MINDEVSIZE * 2)) $SPARE_DEV2 $SPARE_DEV1 $SPARE_DEV2 96done 97 98log_pass "Automated auto-spare selects lowest capacity suitable device" 99