1a1608e88SAlan Somers# SPDX-License-Identifier: BSD-2-Clause 2a1608e88SAlan Somers# 3a1608e88SAlan Somers# Copyright (c) 2024 Axcient 4a1608e88SAlan Somers# All rights reserved. 5a1608e88SAlan Somers# 6a1608e88SAlan Somers# Redistribution and use in source and binary forms, with or without 7a1608e88SAlan Somers# modification, are permitted provided that the following conditions 8a1608e88SAlan Somers# are met: 9a1608e88SAlan Somers# 1. Redistributions of source code must retain the above copyright 10a1608e88SAlan Somers# notice, this list of conditions and the following disclaimer. 11a1608e88SAlan Somers# 2. Redistributions in binary form must reproduce the above copyright 12a1608e88SAlan Somers# notice, this list of conditions and the following disclaimer in the 13a1608e88SAlan Somers# documentation and/or other materials provided with the distribution. 14a1608e88SAlan Somers# 15a1608e88SAlan Somers# THIS DOCUMENTATION IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16a1608e88SAlan Somers# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17a1608e88SAlan Somers# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18a1608e88SAlan Somers# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19a1608e88SAlan Somers# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20a1608e88SAlan Somers# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21a1608e88SAlan Somers# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22a1608e88SAlan Somers# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23a1608e88SAlan Somers# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24a1608e88SAlan Somers# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25a1608e88SAlan Somers 269747d11dSAlan Somers# Things that aren't tested due to lack of kernel support: 279747d11dSAlan Somers# * Creating camsim ports 289747d11dSAlan Somers# * Creating tpc ports 299747d11dSAlan Somers# * Creating camtgt ports 309747d11dSAlan Somers# * Creating umass ports 319747d11dSAlan Somers 329747d11dSAlan Somers# TODO 339747d11dSAlan Somers# * Creating nvmf ports 349747d11dSAlan Somers# * Creating ha ports 359747d11dSAlan Somers# * Creating fc ports 369747d11dSAlan Somers 37afecc74cSAlan Somers# The PGTAG can be any 16-bit number. The only constraint is that each 38afecc74cSAlan Somers# PGTAG,TARGET pair must be globally unique. 39afecc74cSAlan SomersPGTAG=30257 40afecc74cSAlan Somers 41afecc74cSAlan Somersload_cfiscsi() { 42afecc74cSAlan Somers if ! kldstat -q -m cfiscsi; then 43afecc74cSAlan Somers kldload cfiscsi || atf_skip "could not load cfscsi kernel mod" 44afecc74cSAlan Somers fi 45afecc74cSAlan Somers} 46afecc74cSAlan Somers 479747d11dSAlan Somersskip_if_ctld() { 489747d11dSAlan Somers if service ctld onestatus > /dev/null; then 499747d11dSAlan Somers # If ctld is running on this server, let's not interfere. 509747d11dSAlan Somers atf_skip "Cannot run this test while ctld is running" 519747d11dSAlan Somers fi 529747d11dSAlan Somers} 539747d11dSAlan Somers 549747d11dSAlan Somerscleanup() { 559747d11dSAlan Somers driver=$1 569747d11dSAlan Somers 57591de753SAlan Somers if [ -e port-create.txt ]; then 58afecc74cSAlan Somers case "$driver" in 59afecc74cSAlan Somers "ioctl") 60afecc74cSAlan Somers PORTNUM=`awk '/port:/ {print $2}' port-create.txt` 61afecc74cSAlan Somers ctladm port -r -d $driver -p $PORTNUM 62afecc74cSAlan Somers ;; 63afecc74cSAlan Somers "iscsi") 64afecc74cSAlan Somers TARGET=`awk '/target:/ {print $2}' port-create.txt` 657f500273SAlan Somers ctladm port -r -d $driver -O cfiscsi_portal_group_tag=$PGTAG -O cfiscsi_target=$TARGET 66afecc74cSAlan Somers ;; 67afecc74cSAlan Somers esac 689747d11dSAlan Somers fi 699747d11dSAlan Somers} 709747d11dSAlan Somers 719747d11dSAlan Somersatf_test_case create_ioctl cleanup 729747d11dSAlan Somerscreate_ioctl_head() 739747d11dSAlan Somers{ 749747d11dSAlan Somers atf_set "descr" "ctladm can create a new ioctl port" 759747d11dSAlan Somers atf_set "require.user" "root" 76*582f787eSOlivier Cochard atf_set "require.progs" ctladm 779747d11dSAlan Somers} 789747d11dSAlan Somerscreate_ioctl_body() 799747d11dSAlan Somers{ 809747d11dSAlan Somers skip_if_ctld 819747d11dSAlan Somers 82591de753SAlan Somers atf_check -o save:port-create.txt ctladm port -c -d "ioctl" 83591de753SAlan Somers atf_check egrep -q "Port created successfully" port-create.txt 84591de753SAlan Somers atf_check egrep -q "frontend: *ioctl" port-create.txt 85591de753SAlan Somers atf_check egrep -q "port: *[0-9]+" port-create.txt 86591de753SAlan Somers portnum=`awk '/port:/ {print $2}' port-create.txt` 87591de753SAlan Somers atf_check -o save:portlist.txt ctladm portlist -qf ioctl 88591de753SAlan Somers atf_check egrep -q "$portnum *YES *ioctl *ioctl" portlist.txt 899747d11dSAlan Somers} 909747d11dSAlan Somerscreate_ioctl_cleanup() 919747d11dSAlan Somers{ 929747d11dSAlan Somers cleanup ioctl 939747d11dSAlan Somers} 949747d11dSAlan Somers 95edbd489dSAlan Somersatf_test_case remove_ioctl_without_required_args cleanup 96edbd489dSAlan Somersremove_ioctl_without_required_args_head() 97edbd489dSAlan Somers{ 98edbd489dSAlan Somers atf_set "descr" "ctladm will gracefully fail to remove an ioctl target if required arguments are missing" 99edbd489dSAlan Somers atf_set "require.user" "root" 100*582f787eSOlivier Cochard atf_set "require.progs" ctladm 101edbd489dSAlan Somers} 102edbd489dSAlan Somersremove_ioctl_without_required_args_body() 103edbd489dSAlan Somers{ 104edbd489dSAlan Somers skip_if_ctld 105edbd489dSAlan Somers 106edbd489dSAlan Somers atf_check -o save:port-create.txt ctladm port -c -d "ioctl" 107edbd489dSAlan Somers atf_check egrep -q "Port created successfully" port-create.txt 108edbd489dSAlan Somers atf_check -s exit:1 -e match:"Missing required argument: port_id" ctladm port -r -d "ioctl" 109edbd489dSAlan Somers} 110edbd489dSAlan Somersremove_ioctl_without_required_args_cleanup() 111edbd489dSAlan Somers{ 112edbd489dSAlan Somers cleanup ioctl 113edbd489dSAlan Somers} 114edbd489dSAlan Somers 115afecc74cSAlan Somersatf_test_case create_iscsi cleanup 116afecc74cSAlan Somerscreate_iscsi_head() 117afecc74cSAlan Somers{ 118afecc74cSAlan Somers atf_set "descr" "ctladm can create a new iscsi port" 119afecc74cSAlan Somers atf_set "require.user" "root" 120*582f787eSOlivier Cochard atf_set "require.progs" ctladm 121afecc74cSAlan Somers} 122afecc74cSAlan Somerscreate_iscsi_body() 123afecc74cSAlan Somers{ 124afecc74cSAlan Somers skip_if_ctld 125afecc74cSAlan Somers load_cfiscsi 126afecc74cSAlan Somers 127afecc74cSAlan Somers TARGET=iqn.2018-10.myhost.create_iscsi 128afecc74cSAlan Somers atf_check -o save:port-create.txt ctladm port -c -d "iscsi" -O cfiscsi_portal_group_tag=$PGTAG -O cfiscsi_target="$TARGET" 129afecc74cSAlan Somers echo "target: $TARGET" >> port-create.txt 130afecc74cSAlan Somers atf_check egrep -q "Port created successfully" port-create.txt 131afecc74cSAlan Somers atf_check egrep -q "frontend: *iscsi" port-create.txt 132afecc74cSAlan Somers atf_check egrep -q "port: *[0-9]+" port-create.txt 133afecc74cSAlan Somers atf_check -o save:portlist.txt ctladm portlist -qf iscsi 134afecc74cSAlan Somers # Unlike the ioctl driver, the iscsi driver creates ports in a disabled 135afecc74cSAlan Somers # state, so the port's lunmap may be set before enabling it. 136afecc74cSAlan Somers atf_check egrep -q "$portnum *NO *iscsi *iscsi.*$TARGET" portlist.txt 137afecc74cSAlan Somers} 138afecc74cSAlan Somerscreate_iscsi_cleanup() 139afecc74cSAlan Somers{ 140afecc74cSAlan Somers cleanup iscsi 141afecc74cSAlan Somers} 142afecc74cSAlan Somers 143afecc74cSAlan Somersatf_test_case create_iscsi_alias cleanup 144afecc74cSAlan Somerscreate_iscsi_alias_head() 145afecc74cSAlan Somers{ 146afecc74cSAlan Somers atf_set "descr" "ctladm can create a new iscsi port with a target alias" 147afecc74cSAlan Somers atf_set "require.user" "root" 148*582f787eSOlivier Cochard atf_set "require.progs" ctladm 149afecc74cSAlan Somers} 150afecc74cSAlan Somerscreate_iscsi_alias_body() 151afecc74cSAlan Somers{ 152afecc74cSAlan Somers skip_if_ctld 153afecc74cSAlan Somers load_cfiscsi 154afecc74cSAlan Somers 155afecc74cSAlan Somers TARGET=iqn.2018-10.myhost.create_iscsi_alias 156afecc74cSAlan Somers ALIAS="foobar" 157afecc74cSAlan Somers atf_check -o save:port-create.txt ctladm port -c -d "iscsi" -O cfiscsi_portal_group_tag=$PGTAG -O cfiscsi_target="$TARGET" -O cfiscsi_target_alias="$ALIAS" 158afecc74cSAlan Somers echo "target: $TARGET" >> port-create.txt 159afecc74cSAlan Somers atf_check egrep -q "Port created successfully" port-create.txt 160afecc74cSAlan Somers atf_check egrep -q "frontend: *iscsi" port-create.txt 161afecc74cSAlan Somers atf_check egrep -q "port: *[0-9]+" port-create.txt 162afecc74cSAlan Somers atf_check -o save:portlist.txt ctladm portlist -qvf iscsi 163afecc74cSAlan Somers atf_check egrep -q "cfiscsi_target_alias=$ALIAS" portlist.txt 164afecc74cSAlan Somers} 165afecc74cSAlan Somerscreate_iscsi_alias_cleanup() 166afecc74cSAlan Somers{ 167afecc74cSAlan Somers cleanup iscsi 168afecc74cSAlan Somers} 169afecc74cSAlan Somers 170afecc74cSAlan Somersatf_test_case create_iscsi_without_required_args 171afecc74cSAlan Somerscreate_iscsi_without_required_args_head() 172afecc74cSAlan Somers{ 173afecc74cSAlan Somers atf_set "descr" "ctladm will gracefully fail to create an iSCSI target if required arguments are missing" 174afecc74cSAlan Somers atf_set "require.user" "root" 175*582f787eSOlivier Cochard atf_set "require.progs" ctladm 176afecc74cSAlan Somers} 177afecc74cSAlan Somerscreate_iscsi_without_required_args_body() 178afecc74cSAlan Somers{ 179afecc74cSAlan Somers skip_if_ctld 180afecc74cSAlan Somers load_cfiscsi 181afecc74cSAlan Somers 182afecc74cSAlan Somers TARGET=iqn.2018-10.myhost.create_iscsi 183afecc74cSAlan Somers atf_check -s exit:1 -e match:"Missing required argument: cfiscsi_target" ctladm port -c -d "iscsi" -O cfiscsi_portal_group_tag=$PGTAG 184afecc74cSAlan Somers atf_check -s exit:1 -e match:"Missing required argument: cfiscsi_portal_group_tag" ctladm port -c -d "iscsi" -O cfiscsi_target=$TARGET 185afecc74cSAlan Somers} 186afecc74cSAlan Somers 1879747d11dSAlan Somersatf_test_case create_ioctl_options cleanup 1889747d11dSAlan Somerscreate_ioctl_options_head() 1899747d11dSAlan Somers{ 1909747d11dSAlan Somers atf_set "descr" "ctladm can set options when creating a new ioctl port" 1919747d11dSAlan Somers atf_set "require.user" "root" 192*582f787eSOlivier Cochard atf_set "require.progs" ctladm 1939747d11dSAlan Somers} 1949747d11dSAlan Somerscreate_ioctl_options_body() 1959747d11dSAlan Somers{ 1969747d11dSAlan Somers skip_if_ctld 1979747d11dSAlan Somers 198591de753SAlan Somers atf_check -o save:port-create.txt ctladm port -c -d "ioctl" -O pp=101 -O vp=102 199591de753SAlan Somers atf_check egrep -q "Port created successfully" port-create.txt 200591de753SAlan Somers atf_check egrep -q "frontend: *ioctl" port-create.txt 201591de753SAlan Somers atf_check egrep -q "port: *[0-9]+" port-create.txt 202591de753SAlan Somers portnum=`awk '/port:/ {print $2}' port-create.txt` 203591de753SAlan Somers atf_check -o save:portlist.txt ctladm portlist -qf ioctl 204591de753SAlan Somers if ! egrep -q '101[[:space:]]+102' portlist.txt; then 2059747d11dSAlan Somers ctladm portlist 2069747d11dSAlan Somers atf_fail "Did not create the port with the specified options" 2079747d11dSAlan Somers fi 2089747d11dSAlan Somers} 2099747d11dSAlan Somerscreate_ioctl_options_cleanup() 2109747d11dSAlan Somers{ 2119747d11dSAlan Somers cleanup ioctl 2129747d11dSAlan Somers} 2139747d11dSAlan Somers 2149747d11dSAlan Somers 2159747d11dSAlan Somersatf_test_case disable_ioctl cleanup 2169747d11dSAlan Somersdisable_ioctl_head() 2179747d11dSAlan Somers{ 2189747d11dSAlan Somers atf_set "descr" "ctladm can disable an ioctl port" 2199747d11dSAlan Somers atf_set "require.user" "root" 220*582f787eSOlivier Cochard atf_set "require.progs" ctladm 2219747d11dSAlan Somers} 2229747d11dSAlan Somersdisable_ioctl_body() 2239747d11dSAlan Somers{ 2249747d11dSAlan Somers skip_if_ctld 2259747d11dSAlan Somers 226591de753SAlan Somers atf_check -o save:port-create.txt ctladm port -c -d "ioctl" 227591de753SAlan Somers portnum=`awk '/port:/ {print $2}' port-create.txt` 228591de753SAlan Somers atf_check -o save:portlist.txt ctladm portlist -qf ioctl 2299747d11dSAlan Somers atf_check -o ignore ctladm port -o off -p $portnum 2309747d11dSAlan Somers atf_check -o match:"^$portnum *NO" ctladm portlist -qf ioctl 2319747d11dSAlan Somers} 2329747d11dSAlan Somersdisable_ioctl_cleanup() 2339747d11dSAlan Somers{ 2349747d11dSAlan Somers cleanup ioctl 2359747d11dSAlan Somers} 2369747d11dSAlan Somers 2379747d11dSAlan Somersatf_test_case enable_ioctl cleanup 2389747d11dSAlan Somersenable_ioctl_head() 2399747d11dSAlan Somers{ 2409747d11dSAlan Somers atf_set "descr" "ctladm can enable an ioctl port" 2419747d11dSAlan Somers atf_set "require.user" "root" 242*582f787eSOlivier Cochard atf_set "require.progs" ctladm 2439747d11dSAlan Somers} 2449747d11dSAlan Somersenable_ioctl_body() 2459747d11dSAlan Somers{ 2469747d11dSAlan Somers skip_if_ctld 2479747d11dSAlan Somers 248591de753SAlan Somers atf_check -o save:port-create.txt ctladm port -c -d "ioctl" 249591de753SAlan Somers portnum=`awk '/port:/ {print $2}' port-create.txt` 250591de753SAlan Somers atf_check -o save:portlist.txt ctladm portlist -qf ioctl 2519747d11dSAlan Somers atf_check -o ignore ctladm port -o off -p $portnum 2529747d11dSAlan Somers atf_check -o ignore ctladm port -o on -p $portnum 2539747d11dSAlan Somers atf_check -o match:"^$portnum *YES" ctladm portlist -qf ioctl 2549747d11dSAlan Somers} 2559747d11dSAlan Somersenable_ioctl_cleanup() 2569747d11dSAlan Somers{ 2579747d11dSAlan Somers cleanup ioctl 2589747d11dSAlan Somers} 2599747d11dSAlan Somers 2609747d11dSAlan Somersatf_test_case remove_ioctl 2619747d11dSAlan Somersremove_ioctl_head() 2629747d11dSAlan Somers{ 2639747d11dSAlan Somers atf_set "descr" "ctladm can remove an ioctl port" 2649747d11dSAlan Somers atf_set "require.user" "root" 265*582f787eSOlivier Cochard atf_set "require.progs" ctladm 2669747d11dSAlan Somers} 2679747d11dSAlan Somersremove_ioctl_body() 2689747d11dSAlan Somers{ 2699747d11dSAlan Somers skip_if_ctld 2709747d11dSAlan Somers 271591de753SAlan Somers # Specify exact pp and vp to make the post-removal portlist check 272591de753SAlan Somers # unambiguous 273591de753SAlan Somers atf_check -o save:port-create.txt ctladm port -c -d "ioctl" -O pp=10001 -O vp=10002 274591de753SAlan Somers portnum=`awk '/port:/ {print $2}' port-create.txt` 275591de753SAlan Somers atf_check -o save:portlist.txt ctladm portlist -qf ioctl 276591de753SAlan Somers atf_check -o inline:"Port destroyed successfully\n" ctladm port -r -d ioctl -p $portnum 277591de753SAlan Somers # Check that the port was removed. A new port may have been added with 278591de753SAlan Somers # the same ID, so match against the pp and vp numbers, too. 279591de753SAlan Somers if ctladm portlist -qf ioctl | egrep -q "^${portnum} .*10001 *10002"; then 280591de753SAlan Somers ctladm portlist -qf ioctl 281591de753SAlan Somers atf_fail "port was not removed" 2829747d11dSAlan Somers fi 2839747d11dSAlan Somers} 2849747d11dSAlan Somers 285afecc74cSAlan Somersatf_test_case remove_iscsi 286afecc74cSAlan Somersremove_iscsi_head() 287afecc74cSAlan Somers{ 288afecc74cSAlan Somers atf_set "descr" "ctladm can remove an iscsi port" 289afecc74cSAlan Somers atf_set "require.user" "root" 290*582f787eSOlivier Cochard atf_set "require.progs" ctladm 291afecc74cSAlan Somers} 292afecc74cSAlan Somersremove_iscsi_body() 293afecc74cSAlan Somers{ 294afecc74cSAlan Somers skip_if_ctld 295afecc74cSAlan Somers load_cfiscsi 296afecc74cSAlan Somers 297afecc74cSAlan Somers TARGET=iqn.2018-10.myhost.remove_iscsi 298afecc74cSAlan Somers atf_check -o save:port-create.txt ctladm port -c -d "iscsi" -O cfiscsi_portal_group_tag=$PGTAG -O cfiscsi_target="$TARGET" 299afecc74cSAlan Somers portnum=`awk '/port:/ {print $2}' port-create.txt` 300afecc74cSAlan Somers atf_check -o save:portlist.txt ctladm portlist -qf iscsi 301edbd489dSAlan Somers atf_check -o inline:"Port destroyed successfully\n" ctladm port -r -d iscsi -O cfiscsi_portal_group_tag=$PGTAG -O cfiscsi_target="$TARGET" 302afecc74cSAlan Somers # Check that the port was removed. A new port may have been added with 303afecc74cSAlan Somers # the same ID, so match against the target and tag, too. 304afecc74cSAlan Somers PGTAGHEX=0x7631 # PGTAG in hex 305afecc74cSAlan Somers if ctladm portlist -qf iscsi | egrep -q "^${portnum} .*$PGTAG +[0-9]+ +$TARGET,t,$PGTAGHEX"; then 306afecc74cSAlan Somers ctladm portlist -qf iscsi 307afecc74cSAlan Somers atf_fail "port was not removed" 308afecc74cSAlan Somers fi 309afecc74cSAlan Somers} 310afecc74cSAlan Somers 311afecc74cSAlan Somersatf_test_case remove_iscsi_without_required_args cleanup 312afecc74cSAlan Somersremove_iscsi_without_required_args_head() 313afecc74cSAlan Somers{ 314afecc74cSAlan Somers atf_set "descr" "ctladm will gracefully fail to remove an iSCSI target if required arguments are missing" 315afecc74cSAlan Somers atf_set "require.user" "root" 316*582f787eSOlivier Cochard atf_set "require.progs" ctladm 317afecc74cSAlan Somers} 318afecc74cSAlan Somersremove_iscsi_without_required_args_body() 319afecc74cSAlan Somers{ 320afecc74cSAlan Somers skip_if_ctld 321afecc74cSAlan Somers load_cfiscsi 322afecc74cSAlan Somers 323afecc74cSAlan Somers TARGET=iqn.2018-10.myhost.remove_iscsi_without_required_args 324afecc74cSAlan Somers atf_check -o save:port-create.txt ctladm port -c -d "iscsi" -O cfiscsi_portal_group_tag=$PGTAG -O cfiscsi_target="$TARGET" 325afecc74cSAlan Somers echo "target: $TARGET" >> port-create.txt 326edbd489dSAlan Somers atf_check -s exit:1 -e match:"Missing required argument: cfiscsi_portal_group_tag" ctladm port -r -d iscsi -O cfiscsi_target="$TARGET" 327edbd489dSAlan Somers atf_check -s exit:1 -e match:"Missing required argument: cfiscsi_target" ctladm port -r -d iscsi -O cfiscsi_portal_group_tag=$PGTAG 328afecc74cSAlan Somers} 329afecc74cSAlan Somersremove_iscsi_without_required_args_cleanup() 330afecc74cSAlan Somers{ 331afecc74cSAlan Somers cleanup iscsi 332afecc74cSAlan Somers} 333afecc74cSAlan Somers 3349747d11dSAlan Somersatf_init_test_cases() 3359747d11dSAlan Somers{ 3369747d11dSAlan Somers atf_add_test_case create_ioctl 337afecc74cSAlan Somers atf_add_test_case create_iscsi 338afecc74cSAlan Somers atf_add_test_case create_iscsi_without_required_args 339afecc74cSAlan Somers atf_add_test_case create_iscsi_alias 3409747d11dSAlan Somers atf_add_test_case create_ioctl_options 3419747d11dSAlan Somers atf_add_test_case disable_ioctl 3429747d11dSAlan Somers atf_add_test_case enable_ioctl 3439747d11dSAlan Somers atf_add_test_case remove_ioctl 344edbd489dSAlan Somers atf_add_test_case remove_ioctl_without_required_args 345afecc74cSAlan Somers atf_add_test_case remove_iscsi 346afecc74cSAlan Somers atf_add_test_case remove_iscsi_without_required_args 3479747d11dSAlan Somers} 348