+#!/bin/ksh -p
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2018, loli10K <ezomori.nozomu@gmail.com>. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/include/math.shlib
+
+#
+# DESCRIPTION:
+# 'zpool split' should only work on mirrors. Every other VDEV layout is not
+# supported.
+#
+# STRATEGY:
+# Create pools with various VDEV layouts and verify only mirrors can be split
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ destroy_pool $TESTPOOL
+ destroy_pool $TESTPOOL2
+ rm -f $FILEDEV_PREFIX*
+}
+
+#
+# Given a vdev type generate a pool configuration which can be immediately
+# used as "zpool create $poolname $config" or "zpool add $poolname $config".
+# Supported vdev types are:
+# "d" - single disk
+# "t" - stripe
+# "m" - mirror
+# "m3" - 3-way mirror
+# "z1" - raidz1
+# "z2" - raidz2
+# "z3" - raidz3
+# "s" - spare
+# "l" - log
+# "ll" - mirrored log
+# "c" - cache
+#
+function pool_config # <vdev-type>
+{
+ typeset config=""
+ typeset -A disks
+ disks[d]="d1"
+ disks[t]="t1 t2"
+ disks[m]="m1 m2"
+ disks[m3]="m1 m2 m3"
+ disks[z1]="z1 z2"
+ disks[z2]="z1 z2 z3"
+ disks[z3]="z1 z2 z3 z4"
+ disks[s]="s1"
+ disks[l]="l1"
+ disks[ll]="l1 l2"
+ disks[c]="c1"
+ case $1 in
+ d|t) # single disk or stripe
+ vdev='' ;;
+ m|m3) # 2-way or 3-way mirror
+ vdev='mirror';;
+ z1) # raidz1
+ vdev='raidz1';;
+ z2) # raidz2
+ vdev='raidz2';;
+ z3) # raidz3
+ vdev='raidz3';;
+ s) # spare
+ vdev='spare';;
+ l) # log
+ vdev='log';;
+ ll) # mirrored log
+ vdev='log mirror';;
+ c) # cache
+ vdev='cache';;
+ *)
+ log_fail "setup_pool: unsupported vdev type '$1'"
+ esac
+ config="$vdev"
+ for tok in ${disks[$1]}; do
+ filedev="$FILEDEV_PREFIX-$tok"
+ # if $filedev exists we are requesting the same vdev type twice
+ # in a row (eg. pool of striped mirrors): add a random suffix.
+ while [[ -f $filedev ]]; do
+ filedev="$filedev.$RANDOM"
+ done
+ truncate -s $SPA_MINDEVSIZE "$filedev"
+ config="$config $filedev"
+ done
+ echo "$config"
+}
+
+log_assert "'zpool split' should work only on mirror VDEVs"
+log_onexit cleanup
+
+# "good" and "bad" pool layouts
+# first token is always used with "zpool create"
+# second to last tokens, if any, are used with "zpool add"
+typeset -a goodconfs=("m" "m l" "m s" "m c" "m m" "m3" "m3 m3" "m m3 l s c")
+typeset -a badconfs=("d" "z1" "z2" "z3" "m d" "m3 d" "m z1" "m z2" "m z3")
+typeset FILEDEV_PREFIX="$TEST_BASE_DIR/filedev"
+typeset altroot="$TESTDIR/altroot-$TESTPOOL2"
+
+# Create pools with various VDEV layouts and verify only mirrors can be split
+for config in "${goodconfs[@]}"
+do
+ create_config="${config%% *}"
+ add_config="$(awk '{$1= "";print $0}' <<< $config)"
+ log_must zpool create $TESTPOOL $(pool_config $create_config)
+ for vdev in $add_config; do
+ log_must zpool add $TESTPOOL -f $(pool_config $vdev)
+ done
+ log_must zpool split -R $altroot $TESTPOOL $TESTPOOL2
+ log_must poolexists $TESTPOOL2
+ log_must test "$(get_pool_prop 'altroot' $TESTPOOL2)" == "$altroot"
+ cleanup
+done
+
+# Every other pool layout should *not* be splittable
+for config in "${badconfs[@]}"
+do
+ create_config="${config%% *}"
+ add_config="$(awk '{$1= "";print $0}' <<< $config)"
+ log_must zpool create $TESTPOOL $(pool_config $create_config)
+ for vdev in $add_config; do
+ log_must zpool add $TESTPOOL -f $(pool_config $vdev)
+ done
+ log_mustnot zpool split -R $altroot $TESTPOOL $TESTPOOL2
+ log_mustnot poolexists $TESTPOOL2
+ cleanup
+done
+
+log_pass "'zpool split' works only on mirror VDEVs"