1#!/bin/ksh -p 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 2018, loli10K <ezomori.nozomu@gmail.com>. All rights reserved. 15# 16 17. $STF_SUITE/include/libtest.shlib 18. $STF_SUITE/tests/functional/cli_root/zpool_split/zpool_split.cfg 19. $STF_SUITE/include/math.shlib 20 21# 22# DESCRIPTION: 23# 'zpool split' should only work on mirrors. Every other VDEV layout is not 24# supported. 25# 26# STRATEGY: 27# Create pools with various VDEV layouts and verify only mirrors can be split 28# 29 30verify_runnable "both" 31 32function cleanup 33{ 34 destroy_pool $TESTPOOL 35 destroy_pool $TESTPOOL2 36 rm -fd $FILEDEV_PREFIX* $altroot 37} 38 39# 40# Given a vdev type generate a pool configuration which can be immediately 41# used as "zpool create $poolname $config" or "zpool add $poolname $config". 42# Supported vdev types are: 43# "d" - single disk 44# "t" - stripe 45# "m" - mirror 46# "m3" - 3-way mirror 47# "z1" - raidz1 48# "z2" - raidz2 49# "z3" - raidz3 50# "s" - spare 51# "l" - log 52# "ll" - mirrored log 53# "c" - cache 54# "sc" - special class 55# 56function pool_config # <vdev-type> 57{ 58 typeset config="" 59 typeset -A disks 60 disks[d]="d1" 61 disks[t]="t1 t2" 62 disks[m]="m1 m2" 63 disks[m3]="m1 m2 m3" 64 disks[z1]="z1 z2" 65 disks[z2]="z1 z2 z3" 66 disks[z3]="z1 z2 z3 z4" 67 disks[s]="s1" 68 disks[l]="l1" 69 disks[ll]="l1 l2" 70 disks[c]="c1" 71 disks[sc]="sc1 sc2" 72 case $1 in 73 d|t) # single disk or stripe 74 vdev='' ;; 75 m|m3) # 2-way or 3-way mirror 76 vdev='mirror';; 77 z1) # raidz1 78 vdev='raidz1';; 79 z2) # raidz2 80 vdev='raidz2';; 81 z3) # raidz3 82 vdev='raidz3';; 83 s) # spare 84 vdev='spare';; 85 l) # log 86 vdev='log';; 87 ll) # mirrored log 88 vdev='log mirror';; 89 c) # cache 90 vdev='cache';; 91 sc) # mirrored special class 92 vdev='special mirror';; 93 *) 94 log_fail "setup_pool: unsupported vdev type '$1'" 95 esac 96 config="$vdev" 97 for tok in ${disks[$1]}; do 98 filedev="$FILEDEV_PREFIX-$tok" 99 # if $filedev exists we are requesting the same vdev type twice 100 # in a row (eg. pool of striped mirrors): add a random suffix. 101 while [[ -f $filedev ]]; do 102 filedev="$filedev.$RANDOM" 103 done 104 truncate -s $SPA_MINDEVSIZE "$filedev" 105 config="$config $filedev" 106 done 107 echo "$config" 108} 109 110log_assert "'zpool split' should work only on mirror VDEVs" 111log_onexit cleanup 112 113# "good" and "bad" pool layouts 114# first token is always used with "zpool create" 115# second to last tokens, if any, are used with "zpool add" 116typeset -a goodconfs=("m" "m l" "m s" "m c" "m m" "m3" "m3 m3" "m m3 l s c" "m m sc") 117typeset -a badconfs=("d" "z1" "z2" "z3" "m d" "m3 d" "m z1" "m z2" "m z3") 118typeset FILEDEV_PREFIX="$TEST_BASE_DIR/filedev" 119typeset altroot="$TESTDIR/altroot-$TESTPOOL2" 120 121# Create pools with various VDEV layouts and verify only mirrors can be split 122for config in "${goodconfs[@]}" 123do 124 create_config="${config%% *}" 125 add_config="$(awk '{$1=""; print $0}' <<< $config)" 126 log_must zpool create $TESTPOOL $(pool_config $create_config) 127 for vdev in $add_config; do 128 log_must zpool add -f $TESTPOOL $(pool_config $vdev) 129 done 130 log_must zpool split -R $altroot $TESTPOOL $TESTPOOL2 131 log_must poolexists $TESTPOOL2 132 log_must test "$(get_pool_prop 'altroot' $TESTPOOL2)" == "$altroot" 133 cleanup 134done 135 136# Every other pool layout should *not* be splittable 137for config in "${badconfs[@]}" 138do 139 create_config="${config%% *}" 140 add_config="$(awk '{$1=""; print $0}' <<< $config)" 141 log_must zpool create $TESTPOOL $(pool_config $create_config) 142 for vdev in $add_config; do 143 log_must zpool add -f $TESTPOOL $(pool_config $vdev) 144 done 145 log_mustnot zpool split -R $altroot $TESTPOOL $TESTPOOL2 146 log_mustnot poolexists $TESTPOOL2 147 cleanup 148done 149 150log_pass "'zpool split' works only on mirror VDEVs" 151