1#!/usr/bin/env bash 2# SPDX-License-Identifier: BSD-3-Clause 3# Copyright (C) 2022 Intel Corporation 4# All rights reserved. 5# 6testdir=$(readlink -f "$(dirname "$0")") 7rootdir=$(readlink -f "$testdir/../..") 8 9source "$rootdir/test/common/autotest_common.sh" 10source "$testdir/common.sh" 11 12function cleanup() { 13 killprocess $tgtpid 14 killprocess $smapid 15} 16 17function create_device() { 18 "$rootdir/scripts/sma-client.py" <<- EOF 19 { 20 "method": "CreateDevice", 21 "params": { 22 "nvmf_tcp": { 23 "subnqn": "$1", 24 "adrfam": "ipv4", 25 "traddr": "127.0.0.1", 26 "trsvcid": "4420" 27 } 28 } 29 } 30 EOF 31} 32 33function delete_device() { 34 "$rootdir/scripts/sma-client.py" <<- EOF 35 { 36 "method": "DeleteDevice", 37 "params": { 38 "handle": "$1" 39 } 40 } 41 EOF 42} 43 44function attach_volume() { 45 "$rootdir/scripts/sma-client.py" <<- EOF 46 { 47 "method": "AttachVolume", 48 "params": { 49 "device_handle": "$1", 50 "volume": { 51 "volume_id": "$(uuid2base64 $2)" 52 } 53 } 54 } 55 EOF 56} 57 58function detach_volume() { 59 "$rootdir/scripts/sma-client.py" <<- EOF 60 { 61 "method": "DetachVolume", 62 "params": { 63 "device_handle": "$1", 64 "volume_id": "$(uuid2base64 $2)" 65 } 66 } 67 EOF 68} 69 70trap "cleanup; exit 1" SIGINT SIGTERM EXIT 71 72$rootdir/build/bin/spdk_tgt & 73tgtpid=$! 74 75$rootdir/scripts/sma.py -c <( 76 cat <<- EOF 77 address: 127.0.0.1 78 port: 8080 79 devices: 80 - name: 'nvmf_tcp' 81 EOF 82) & 83smapid=$! 84 85# Wait until the SMA starts listening 86sma_waitforlisten 87 88# Prepare the target 89rpc_cmd bdev_null_create null0 100 4096 90 91# Make sure a TCP transport has been created 92rpc_cmd nvmf_get_transports --trtype tcp 93 94# Create a couple of devices and verify them via RPC 95devid0=$(create_device nqn.2016-06.io.spdk:cnode0 | jq -r '.handle') 96rpc_cmd nvmf_get_subsystems nqn.2016-06.io.spdk:cnode0 97 98devid1=$(create_device nqn.2016-06.io.spdk:cnode1 | jq -r '.handle') 99rpc_cmd nvmf_get_subsystems nqn.2016-06.io.spdk:cnode0 100rpc_cmd nvmf_get_subsystems nqn.2016-06.io.spdk:cnode1 101[[ "$devid0" != "$devid1" ]] 102 103# Check that there are three subsystems (2 created above + discovery) 104[[ $(rpc_cmd nvmf_get_subsystems | jq -r '. | length') -eq 3 ]] 105 106# Verify the method is idempotent and sending the same gRPCs won't create new 107# devices and will return the same handles 108tmp0=$(create_device nqn.2016-06.io.spdk:cnode0 | jq -r '.handle') 109tmp1=$(create_device nqn.2016-06.io.spdk:cnode1 | jq -r '.handle') 110 111[[ $(rpc_cmd nvmf_get_subsystems | jq -r '. | length') -eq 3 ]] 112[[ "$tmp0" == "$devid0" ]] 113[[ "$tmp1" == "$devid1" ]] 114 115# Now delete both of them verifying via RPC 116delete_device "$devid0" 117NOT rpc_cmd nvmf_get_subsystems nqn.2016-06.io.spdk:cnode0 118[[ $(rpc_cmd nvmf_get_subsystems | jq -r '. | length') -eq 2 ]] 119 120delete_device "$devid1" 121NOT rpc_cmd nvmf_get_subsystems nqn.2016-06.io.spdk:cnode1 122[[ $(rpc_cmd nvmf_get_subsystems | jq -r '. | length') -eq 1 ]] 123 124# Finally check that removing a non-existing device is also successful 125delete_device "$devid0" 126delete_device "$devid1" 127 128# Check volume attach/detach 129devid0=$(create_device nqn.2016-06.io.spdk:cnode0 | jq -r '.handle') 130devid1=$(create_device nqn.2016-06.io.spdk:cnode1 | jq -r '.handle') 131uuid=$(rpc_cmd bdev_get_bdevs -b null0 | jq -r '.[].uuid') 132 133# Attach the volume to a first device 134attach_volume "$devid0" "$uuid" 135[[ $(rpc_cmd nvmf_get_subsystems nqn.2016-06.io.spdk:cnode0 | jq -r '.[0].namespaces | length') -eq 1 ]] 136[[ $(rpc_cmd nvmf_get_subsystems nqn.2016-06.io.spdk:cnode1 | jq -r '.[0].namespaces | length') -eq 0 ]] 137[[ $(rpc_cmd nvmf_get_subsystems nqn.2016-06.io.spdk:cnode0 | jq -r '.[0].namespaces[0].uuid') == "$uuid" ]] 138 139# Attach the same device again and see that it won't fail 140attach_volume "$devid0" "$uuid" 141[[ $(rpc_cmd nvmf_get_subsystems nqn.2016-06.io.spdk:cnode0 | jq -r '.[0].namespaces | length') -eq 1 ]] 142[[ $(rpc_cmd nvmf_get_subsystems nqn.2016-06.io.spdk:cnode1 | jq -r '.[0].namespaces | length') -eq 0 ]] 143[[ $(rpc_cmd nvmf_get_subsystems nqn.2016-06.io.spdk:cnode0 | jq -r '.[0].namespaces[0].uuid') == "$uuid" ]] 144 145# Detach it and verify it's removed from the subsystem 146detach_volume "$devid0" "$uuid" 147[[ $(rpc_cmd nvmf_get_subsystems nqn.2016-06.io.spdk:cnode0 | jq -r '.[0].namespaces | length') -eq 0 ]] 148[[ $(rpc_cmd nvmf_get_subsystems nqn.2016-06.io.spdk:cnode1 | jq -r '.[0].namespaces | length') -eq 0 ]] 149 150# Detach it again and verify it succeeds 151detach_volume "$devid0" "$uuid" 152 153cleanup 154trap - SIGINT SIGTERM EXIT 155