xref: /illumos-gate/usr/src/test/nvme-tests/tests/unit/nsmgmt.c (revision 608eb926e14f4ba4736b2d59e891335f1cba9e1e)
1 /*
2  * This file and its contents are supplied under the terms of the
3  * Common Development and Distribution License ("CDDL"), version 1.0.
4  * You may only use this file in accordance with the terms of version
5  * 1.0 of the CDDL.
6  *
7  * A full copy of the text of the CDDL should have accompanied this
8  * source.  A copy of the CDDL is also available via the Internet at
9  * http://www.illumos.org/license/CDDL.
10  */
11 
12 /*
13  * Copyright 2025 Oxide Computer Company
14  */
15 
16 /*
17  * Namespace Management unit tests.
18  */
19 
20 #include <stdlib.h>
21 #include <sys/sysmacros.h>
22 #include <err.h>
23 
24 #include "nvme_unit.h"
25 
26 static const nvme_unit_field_test_t ns_attach_field_tests[] = { {
27 	.nu_desc = "invalid selector (1)",
28 	.nu_fields = nvme_ns_attach_fields,
29 	.nu_index = NVME_NS_ATTACH_REQ_FIELD_SEL,
30 	.nu_data = &nvme_ctrl_ns_1v2,
31 	.nu_value = 0x7777,
32 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
33 }, {
34 	.nu_desc = "invalid selector (2)",
35 	.nu_fields = nvme_ns_attach_fields,
36 	.nu_index = NVME_NS_ATTACH_REQ_FIELD_SEL,
37 	.nu_data = &nvme_ctrl_ns_1v2,
38 	.nu_value = NVME_NS_ATTACH_CTRL_DETACH + 1,
39 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
40 }, {
41 	.nu_desc = "valid selector (1)",
42 	.nu_fields = nvme_ns_attach_fields,
43 	.nu_index = NVME_NS_ATTACH_REQ_FIELD_SEL,
44 	.nu_data = &nvme_ctrl_ns_1v2,
45 	.nu_value = NVME_NS_ATTACH_CTRL_DETACH,
46 	.nu_ret = NVME_FIELD_ERR_OK
47 }, {
48 	.nu_desc = "valid selector (2)",
49 	.nu_fields = nvme_ns_attach_fields,
50 	.nu_index = NVME_NS_ATTACH_REQ_FIELD_SEL,
51 	.nu_data = &nvme_ctrl_ns_1v2,
52 	.nu_value = NVME_NS_ATTACH_CTRL_ATTACH,
53 	.nu_ret = NVME_FIELD_ERR_OK
54 }, {
55 	.nu_desc = "invalid NSID (1)",
56 	.nu_fields = nvme_ns_attach_fields,
57 	.nu_index = NVME_NS_ATTACH_REQ_FIELD_NSID,
58 	.nu_data = &nvme_ctrl_ns_1v2,
59 	.nu_value = 0x0,
60 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
61 }, {
62 	.nu_desc = "invalid NSID (2)",
63 	.nu_fields = nvme_ns_attach_fields,
64 	.nu_index = NVME_NS_ATTACH_REQ_FIELD_NSID,
65 	.nu_data = &nvme_ctrl_ns_1v2,
66 	.nu_value = 0x7777,
67 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
68 }, {
69 	.nu_desc = "valid NSID (1)",
70 	.nu_fields = nvme_ns_attach_fields,
71 	.nu_index = NVME_NS_ATTACH_REQ_FIELD_NSID,
72 	.nu_data = &nvme_ctrl_ns_1v2,
73 	.nu_value = 0x1,
74 	.nu_ret = NVME_FIELD_ERR_OK
75 }, {
76 	.nu_desc = "valid NSID (2)",
77 	.nu_fields = nvme_ns_attach_fields,
78 	.nu_index = NVME_NS_ATTACH_REQ_FIELD_NSID,
79 	.nu_data = &nvme_ctrl_ns_1v2,
80 	.nu_value = NVME_NSID_BCAST,
81 	.nu_ret = NVME_FIELD_ERR_OK
82 } };
83 
84 static const nvme_unit_field_test_t ns_delete_field_tests[] = { {
85 	.nu_desc = "invalid NSID (1)",
86 	.nu_fields = nvme_ns_delete_fields,
87 	.nu_index = NVME_NS_DELETE_REQ_FIELD_NSID,
88 	.nu_data = &nvme_ctrl_ns_1v4,
89 	.nu_value = 0x0,
90 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
91 }, {
92 	.nu_desc = "invalid NSID (2)",
93 	.nu_fields = nvme_ns_delete_fields,
94 	.nu_index = NVME_NS_DELETE_REQ_FIELD_NSID,
95 	.nu_data = &nvme_ctrl_ns_1v4,
96 	.nu_value = 0x7777,
97 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
98 }, {
99 	.nu_desc = "valid NSID (1)",
100 	.nu_fields = nvme_ns_delete_fields,
101 	.nu_index = NVME_NS_DELETE_REQ_FIELD_NSID,
102 	.nu_data = &nvme_ctrl_ns_1v4,
103 	.nu_value = 0x1,
104 	.nu_ret = NVME_FIELD_ERR_OK
105 }, {
106 	.nu_desc = "valid NSID (2)",
107 	.nu_fields = nvme_ns_delete_fields,
108 	.nu_index = NVME_NS_DELETE_REQ_FIELD_NSID,
109 	.nu_data = &nvme_ctrl_ns_1v4,
110 	.nu_value = NVME_NSID_BCAST,
111 	.nu_ret = NVME_FIELD_ERR_OK
112 } };
113 
114 static const nvme_unit_field_test_t ns_create_field_tests[] = { {
115 	.nu_desc = "valid CSI (1)",
116 	.nu_fields = nvme_ns_create_fields,
117 	.nu_index = NVME_NS_CREATE_REQ_FIELD_CSI,
118 	.nu_data = &nvme_ctrl_ns_2v0,
119 	.nu_value = NVME_CSI_NVM,
120 	.nu_ret = NVME_FIELD_ERR_OK
121 }, {
122 	.nu_desc = "valid CSI (2)",
123 	.nu_fields = nvme_ns_create_fields,
124 	.nu_index = NVME_NS_CREATE_REQ_FIELD_CSI,
125 	.nu_data = &nvme_ctrl_ns_2v0,
126 	.nu_value = NVME_CSI_ZNS,
127 	.nu_ret = NVME_FIELD_ERR_OK
128 }, {
129 	.nu_desc = "invalid CSI (1)",
130 	.nu_fields = nvme_ns_create_fields,
131 	.nu_index = NVME_NS_CREATE_REQ_FIELD_CSI,
132 	.nu_data = &nvme_ctrl_ns_2v0,
133 	.nu_value = 0x7777,
134 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
135 }, {
136 	.nu_desc = "invalid CSI (2)",
137 	.nu_fields = nvme_ns_create_fields,
138 	.nu_index = NVME_NS_CREATE_REQ_FIELD_CSI,
139 	.nu_data = &nvme_ctrl_ns_1v2,
140 	.nu_value = NVME_CSI_ZNS,
141 	.nu_ret = NVME_FIELD_ERR_UNSUP_VERSION
142 }, {
143 	.nu_desc = "invalid CSI (3)",
144 	.nu_fields = nvme_ns_create_fields,
145 	.nu_index = NVME_NS_CREATE_REQ_FIELD_CSI,
146 	.nu_data = &nvme_ctrl_ns_1v4,
147 	.nu_value = NVME_CSI_NVM,
148 	.nu_ret = NVME_FIELD_ERR_UNSUP_VERSION
149 }, {
150 	.nu_desc = "invalid NSZE (1)",
151 	.nu_fields = nvme_ns_create_fields,
152 	.nu_index = NVME_NS_CREATE_REQ_FIELD_NSZE,
153 	.nu_data = &nvme_ctrl_ns_2v0,
154 	.nu_value = 0,
155 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
156 }, {
157 	.nu_desc = "valid NSZE (1)",
158 	.nu_fields = nvme_ns_create_fields,
159 	.nu_index = NVME_NS_CREATE_REQ_FIELD_NSZE,
160 	.nu_data = &nvme_ctrl_ns_2v0,
161 	.nu_value = 1,
162 	.nu_ret = NVME_FIELD_ERR_OK
163 }, {
164 	.nu_desc = "valid NSZE (2)",
165 	.nu_fields = nvme_ns_create_fields,
166 	.nu_index = NVME_NS_CREATE_REQ_FIELD_NSZE,
167 	.nu_data = &nvme_ctrl_ns_2v0,
168 	.nu_value = UINT64_MAX,
169 	.nu_ret = NVME_FIELD_ERR_OK
170 }, {
171 	.nu_desc = "valid NSZE (3)",
172 	.nu_fields = nvme_ns_create_fields,
173 	.nu_index = NVME_NS_CREATE_REQ_FIELD_NSZE,
174 	.nu_data = &nvme_ctrl_ns_2v0,
175 	.nu_value = 0xaabbccddeeff,
176 	.nu_ret = NVME_FIELD_ERR_OK
177 }, {
178 	.nu_desc = "valid NSZE (4)",
179 	.nu_fields = nvme_ns_create_fields,
180 	.nu_index = NVME_NS_CREATE_REQ_FIELD_NSZE,
181 	.nu_data = &nvme_ctrl_ns_2v0,
182 	.nu_value = 0x7777,
183 	.nu_ret = NVME_FIELD_ERR_OK
184 }, {
185 	.nu_desc = "invalid NCAP (1)",
186 	.nu_fields = nvme_ns_create_fields,
187 	.nu_index = NVME_NS_CREATE_REQ_FIELD_NCAP,
188 	.nu_data = &nvme_ctrl_ns_2v0,
189 	.nu_value = 0,
190 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
191 }, {
192 	.nu_desc = "valid NCAP (1)",
193 	.nu_fields = nvme_ns_create_fields,
194 	.nu_index = NVME_NS_CREATE_REQ_FIELD_NCAP,
195 	.nu_data = &nvme_ctrl_ns_2v0,
196 	.nu_value = 1,
197 	.nu_ret = NVME_FIELD_ERR_OK
198 }, {
199 	.nu_desc = "valid NCAP (2)",
200 	.nu_fields = nvme_ns_create_fields,
201 	.nu_index = NVME_NS_CREATE_REQ_FIELD_NCAP,
202 	.nu_data = &nvme_ctrl_ns_2v0,
203 	.nu_value = UINT64_MAX,
204 	.nu_ret = NVME_FIELD_ERR_OK
205 }, {
206 	.nu_desc = "valid NCAP (3)",
207 	.nu_fields = nvme_ns_create_fields,
208 	.nu_index = NVME_NS_CREATE_REQ_FIELD_NCAP,
209 	.nu_data = &nvme_ctrl_ns_2v0,
210 	.nu_value = 0xaabbccddeeff,
211 	.nu_ret = NVME_FIELD_ERR_OK
212 }, {
213 	.nu_desc = "valid NCAP (4)",
214 	.nu_fields = nvme_ns_create_fields,
215 	.nu_index = NVME_NS_CREATE_REQ_FIELD_NCAP,
216 	.nu_data = &nvme_ctrl_ns_2v0,
217 	.nu_value = 0x7777,
218 	.nu_ret = NVME_FIELD_ERR_OK
219 }, {
220 	.nu_desc = "invalid FLBAS (1)",
221 	.nu_fields = nvme_ns_create_fields,
222 	.nu_index = NVME_NS_CREATE_REQ_FIELD_FLBAS,
223 	.nu_data = &nvme_ctrl_ns_2v0,
224 	.nu_value = 0x2bb2,
225 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
226 }, {
227 	.nu_desc = "invalid FLBAS (2)",
228 	.nu_fields = nvme_ns_create_fields,
229 	.nu_index = NVME_NS_CREATE_REQ_FIELD_FLBAS,
230 	.nu_data = &nvme_ctrl_ns_2v0,
231 	.nu_value = UINT32_MAX,
232 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
233 }, {
234 	.nu_desc = "valid FLBAS (1)",
235 	.nu_fields = nvme_ns_create_fields,
236 	.nu_index = NVME_NS_CREATE_REQ_FIELD_FLBAS,
237 	.nu_data = &nvme_ctrl_ns_2v0,
238 	.nu_value = 0,
239 	.nu_ret = NVME_FIELD_ERR_OK
240 }, {
241 	.nu_desc = "valid FLBAS (2)",
242 	.nu_fields = nvme_ns_create_fields,
243 	.nu_index = NVME_NS_CREATE_REQ_FIELD_FLBAS,
244 	.nu_data = &nvme_ctrl_ns_2v0,
245 	.nu_value = 0xf,
246 	.nu_ret = NVME_FIELD_ERR_OK
247 }, {
248 	.nu_desc = "valid FLBAS (3)",
249 	.nu_fields = nvme_ns_create_fields,
250 	.nu_index = NVME_NS_CREATE_REQ_FIELD_FLBAS,
251 	.nu_data = &nvme_ctrl_ns_2v0,
252 	.nu_value = 0x7,
253 	.nu_ret = NVME_FIELD_ERR_OK
254 }, {
255 	.nu_desc = "valid NMIC (1)",
256 	.nu_fields = nvme_ns_create_fields,
257 	.nu_index = NVME_NS_CREATE_REQ_FIELD_NMIC,
258 	.nu_data = &nvme_ctrl_ns_1v2,
259 	.nu_value = 0x0,
260 	.nu_ret = NVME_FIELD_ERR_OK
261 }, {
262 	.nu_desc = "valid NMIC (1)",
263 	.nu_fields = nvme_ns_create_fields,
264 	.nu_index = NVME_NS_CREATE_REQ_FIELD_NMIC,
265 	.nu_data = &nvme_ctrl_ns_1v2,
266 	.nu_value = 0x1,
267 	.nu_ret = NVME_FIELD_ERR_OK
268 }, {
269 	.nu_desc = "valid NMIC (2)",
270 	.nu_fields = nvme_ns_create_fields,
271 	.nu_index = NVME_NS_CREATE_REQ_FIELD_NMIC,
272 	.nu_data = &nvme_ctrl_ns_1v2,
273 	.nu_value = 0x1,
274 	.nu_ret = NVME_FIELD_ERR_OK
275 }, {
276 	.nu_desc = "invalid NMIC (1)",
277 	.nu_fields = nvme_ns_create_fields,
278 	.nu_index = NVME_NS_CREATE_REQ_FIELD_NMIC,
279 	.nu_data = &nvme_ctrl_ns_1v2,
280 	.nu_value = 0x23,
281 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
282 }, {
283 	.nu_desc = "invalid NMIC (2)",
284 	.nu_fields = nvme_ns_create_fields,
285 	.nu_index = NVME_NS_CREATE_REQ_FIELD_NMIC,
286 	.nu_data = &nvme_ctrl_ns_1v2,
287 	.nu_value = 0x400,
288 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
289 }, {
290 	.nu_desc = "invalid NMIC (3)",
291 	.nu_fields = nvme_ns_create_fields,
292 	.nu_index = NVME_NS_CREATE_REQ_FIELD_NMIC,
293 	.nu_data = &nvme_ctrl_ns_1v2,
294 	.nu_value = UINT32_MAX,
295 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
296 }, {
297 	.nu_desc = "invalid NMIC (4)",
298 	.nu_fields = nvme_ns_create_fields,
299 	.nu_index = NVME_NS_CREATE_REQ_FIELD_NMIC,
300 	.nu_data = &nvme_ctrl_ns_1v2,
301 	.nu_value = 0x2,
302 	.nu_ret = NVME_FIELD_ERR_BAD_VALUE
303 } };
304 
305 typedef struct {
306 	const char *nii_desc;
307 	const nvme_valid_ctrl_data_t *nii_data;
308 	bool nii_impl;
309 } nsmgmt_impl_test_t;
310 
311 static const nsmgmt_impl_test_t nsmgmt_impl_tests[] = { {
312 	.nii_desc = "Basic 1.0 controller unsupported",
313 	.nii_data = &nvme_ctrl_base_1v0,
314 	.nii_impl = false
315 }, {
316 	.nii_desc = "Basic 1.1 controller unsupported",
317 	.nii_data = &nvme_ctrl_base_1v1,
318 	.nii_impl = false
319 }, {
320 	.nii_desc = "Basic 1.2 controller unsupported",
321 	.nii_data = &nvme_ctrl_base_1v2,
322 	.nii_impl = false
323 }, {
324 	.nii_desc = "Basic 2.0 controller unsupported",
325 	.nii_data = &nvme_ctrl_base_2v0,
326 	.nii_impl = false
327 }, {
328 	.nii_desc = "Fancy 1.2 controller supported",
329 	.nii_data = &nvme_ctrl_ns_1v2,
330 	.nii_impl = true
331 }, {
332 	.nii_desc = "Fancy 1.3 controller supported",
333 	.nii_data = &nvme_ctrl_ns_1v3,
334 	.nii_impl = true
335 }, {
336 	.nii_desc = "Fancy 1.4 controller supported",
337 	.nii_data = &nvme_ctrl_ns_1v4,
338 	.nii_impl = true
339 }, {
340 	.nii_desc = "Fancy 2.0 controller supported",
341 	.nii_data = &nvme_ctrl_ns_1v4,
342 	.nii_impl = true
343 }, {
344 	.nii_desc = "Fancy 1.4 w/o nsmgmt unsupported",
345 	.nii_data = &nvme_ctrl_nons_1v4,
346 	.nii_impl = false
347 } };
348 
349 static bool
350 nsmgmt_impl_test_one(const nsmgmt_impl_test_t *test)
351 {
352 	bool impl = nvme_nsmgmt_cmds_supported(test->nii_data);
353 
354 	if (impl != test->nii_impl) {
355 		warnx("TEST FAILED: %s: expected impl %u, found %u",
356 		    test->nii_desc, test->nii_impl, impl);
357 		return (false);
358 	}
359 
360 	(void) printf("TEST PASSED: %s: got correct impl\n", test->nii_desc);
361 	return (true);
362 }
363 
364 int
365 main(void)
366 {
367 	int ret = EXIT_SUCCESS;
368 
369 	if (!nvme_unit_field_test(ns_attach_field_tests,
370 	    ARRAY_SIZE(ns_attach_field_tests))) {
371 		ret = EXIT_FAILURE;
372 	}
373 
374 	if (!nvme_unit_field_test(ns_delete_field_tests,
375 	    ARRAY_SIZE(ns_delete_field_tests))) {
376 		ret = EXIT_FAILURE;
377 	}
378 
379 	if (!nvme_unit_field_test(ns_create_field_tests,
380 	    ARRAY_SIZE(ns_create_field_tests))) {
381 		ret = EXIT_FAILURE;
382 	}
383 
384 	for (size_t i = 0; i < ARRAY_SIZE(nsmgmt_impl_tests); i++) {
385 		if (!nsmgmt_impl_test_one(&nsmgmt_impl_tests[i])) {
386 			ret = EXIT_FAILURE;
387 		}
388 	}
389 
390 	if (ret == EXIT_SUCCESS) {
391 		(void) printf("All tests passed successfully!\n");
392 	}
393 
394 	return (ret);
395 }
396