1#!/usr/bin/env bash 2 3testdir=$(readlink -f "$(dirname "$0")") 4rootdir=$(readlink -f "$testdir/../..") 5 6source "$rootdir/test/common/autotest_common.sh" 7source "$testdir/common.sh" 8 9smac="$rootdir/scripts/sma-client.py" 10 11device_nvmf_tcp=3 12limit_reserved=$(printf '%u' $((2 ** 64 - 1))) 13 14cleanup() { 15 killprocess $tgtpid 16 killprocess $smapid 17} 18 19create_device() { 20 $smac <<- EOF 21 { 22 "method": "CreateDevice", 23 "params": { 24 "nvmf_tcp": { 25 "subnqn": "nqn.2016-06.io.spdk:cnode0", 26 "adrfam": "ipv4", 27 "traddr": "127.0.0.1", 28 "trsvcid": "4420" 29 }, 30 "volume": { 31 "volume_id": "$(uuid2base64 $1)" 32 } 33 } 34 } 35 EOF 36} 37 38trap "cleanup; exit 1" SIGINT SIGTERM EXIT 39 40$rootdir/build/bin/spdk_tgt & 41tgtpid=$! 42 43$rootdir/scripts/sma.py -c <( 44 cat <<- EOF 45 address: 127.0.0.1 46 port: 8080 47 devices: 48 - name: 'nvmf_tcp' 49 EOF 50) & 51smapid=$! 52 53sma_waitforlisten 54 55# Prepare a device with a volume 56rpc_cmd bdev_null_create null0 100 4096 57uuid=$(rpc_cmd bdev_get_bdevs -b null0 | jq -r '.[].uuid') 58device=$(create_device $uuid | jq -r '.handle') 59 60# First check the capabilities 61diff <(get_qos_caps $device_nvmf_tcp | jq --sort-keys) <( 62 jq --sort-keys <<- EOF 63 { 64 "max_volume_caps": { 65 "rw_iops": true, 66 "rd_bandwidth": true, 67 "wr_bandwidth": true, 68 "rw_bandwidth": true 69 } 70 } 71 EOF 72) 73 74# Make sure that invalid device type causes an error 75NOT get_qos_caps 1234 76 77# Set a single limit and make sure it's changed (and nothing else was changed) 78$smac <<- EOF 79 { 80 "method": "SetQos", 81 "params": { 82 "device_handle": "$device", 83 "volume_id": "$(uuid2base64 $uuid)", 84 "maximum": { 85 "rw_iops": 1 86 } 87 } 88 } 89EOF 90diff <(rpc_cmd bdev_get_bdevs -b null0 | jq --sort-keys '.[].assigned_rate_limits') <( 91 jq --sort-keys <<- EOF 92 { 93 "rw_ios_per_sec": 1000, 94 "rw_mbytes_per_sec": 0, 95 "r_mbytes_per_sec": 0, 96 "w_mbytes_per_sec": 0 97 } 98 EOF 99) 100 101# Change two limits at the same time 102$smac <<- EOF 103 { 104 "method": "SetQos", 105 "params": { 106 "device_handle": "$device", 107 "volume_id": "$(uuid2base64 $uuid)", 108 "maximum": { 109 "rw_iops": 2, 110 "rd_bandwidth": 8 111 } 112 } 113 } 114EOF 115diff <(rpc_cmd bdev_get_bdevs -b null0 | jq --sort-keys '.[].assigned_rate_limits') <( 116 jq --sort-keys <<- EOF 117 { 118 "rw_ios_per_sec": 2000, 119 "rw_mbytes_per_sec": 0, 120 "r_mbytes_per_sec": 8, 121 "w_mbytes_per_sec": 0 122 } 123 EOF 124) 125 126# Check that it's possible to preserve existing values by specifying limit=UINT64_MAX 127$smac <<- EOF 128 { 129 "method": "SetQos", 130 "params": { 131 "device_handle": "$device", 132 "volume_id": "$(uuid2base64 $uuid)", 133 "maximum": { 134 "rw_iops": $limit_reserved, 135 "rd_bandwidth": $limit_reserved, 136 "rw_bandwidth": 6 137 } 138 } 139 } 140EOF 141diff <(rpc_cmd bdev_get_bdevs -b null0 | jq --sort-keys '.[].assigned_rate_limits') <( 142 jq --sort-keys <<- EOF 143 { 144 "rw_ios_per_sec": 2000, 145 "rw_mbytes_per_sec": 6, 146 "r_mbytes_per_sec": 8, 147 "w_mbytes_per_sec": 0 148 } 149 EOF 150) 151 152# Check that specyfing an unsupported limit results in an error 153unsupported_max_limits=(rd_iops wr_iops) 154 155for limit in "${unsupported_max_limits[@]}"; do 156 NOT $smac <<- EOF 157 { 158 "method": "SetQos", 159 "params": { 160 "device_handle": "$device", 161 "volume_id": "$(uuid2base64 $uuid)", 162 "maximum": { 163 "rw_iops": $limit_reserved, 164 "rd_bandwidth": $limit_reserved, 165 "rw_bandwidth": $limit_reserved, 166 "$limit": 1 167 } 168 } 169 } 170 EOF 171done 172 173# Check non-existing device handle/volume_id 174NOT $smac <<- EOF 175 { 176 "method": "SetQos", 177 "params": { 178 "device_handle": "${device}-invalid", 179 "volume_id": "$(uuid2base64 $uuid)", 180 "maximum": { 181 "rw_iops": 1 182 } 183 } 184 } 185EOF 186 187NOT $smac <<- EOF 188 { 189 "method": "SetQos", 190 "params": { 191 "device_handle": "$device", 192 "volume_id": "$(uuid2base64 $(uuidgen))", 193 "maximum": { 194 "rw_iops": 1 195 } 196 } 197 } 198EOF 199 200# Check that it's not possible to set limits without specyfing a volume/device 201NOT $smac <<- EOF 202 { 203 "method": "SetQos", 204 "params": { 205 "device_handle": "$device", 206 "maximum": { 207 "rw_iops": 1 208 } 209 } 210 } 211EOF 212 213NOT $smac <<- EOF 214 { 215 "method": "SetQos", 216 "params": { 217 "volume_id": "$(uuid2base64 $uuid)", 218 "maximum": { 219 "rw_iops": 1 220 } 221 } 222 } 223EOF 224 225# Make sure that none of the limits were changed 226diff <(rpc_cmd bdev_get_bdevs -b null0 | jq --sort-keys '.[].assigned_rate_limits') <( 227 jq --sort-keys <<- EOF 228 { 229 "rw_ios_per_sec": 2000, 230 "rw_mbytes_per_sec": 6, 231 "r_mbytes_per_sec": 8, 232 "w_mbytes_per_sec": 0 233 } 234 EOF 235) 236 237trap - SIGINT SIGTERM EXIT 238cleanup 239