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