xref: /spdk/test/sma/qos.sh (revision dfc54617412c492a4145b7490404933abc91bf52)
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