xref: /spdk/test/unit/lib/nvmf/subsystem.c/subsystem_ut.c (revision 7506a7aa53d239f533af3bc768f0d2af55e735fe)
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright (c) Intel Corporation. All rights reserved.
5  *   Copyright (c) 2019 Mellanox Technologies LTD. All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #include "spdk/stdinc.h"
35 
36 #include "common/lib/ut_multithread.c"
37 #include "spdk_cunit.h"
38 #include "spdk_internal/mock.h"
39 
40 #include "spdk/bdev_module.h"
41 #include "nvmf/subsystem.c"
42 #include <uuid/uuid.h>
43 
44 SPDK_LOG_REGISTER_COMPONENT(nvmf)
45 
46 DEFINE_STUB(spdk_bdev_module_claim_bdev,
47 	    int,
48 	    (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc,
49 	     struct spdk_bdev_module *module), 0);
50 
51 DEFINE_STUB_V(spdk_bdev_module_release_bdev,
52 	      (struct spdk_bdev *bdev));
53 
54 DEFINE_STUB(spdk_bdev_get_block_size, uint32_t,
55 	    (const struct spdk_bdev *bdev), 512);
56 
57 DEFINE_STUB(spdk_bdev_get_md_size, uint32_t,
58 	    (const struct spdk_bdev *bdev), 0);
59 
60 DEFINE_STUB(spdk_bdev_is_md_interleaved, bool,
61 	    (const struct spdk_bdev *bdev), false);
62 
63 DEFINE_STUB(spdk_bdev_io_type_supported, bool,
64 	    (struct spdk_bdev *bdev,
65 	     enum spdk_bdev_io_type io_type), false);
66 
67 DEFINE_STUB(spdk_nvmf_transport_stop_listen,
68 	    int,
69 	    (struct spdk_nvmf_transport *transport,
70 	     const struct spdk_nvme_transport_id *trid), 0);
71 
72 DEFINE_STUB_V(nvmf_update_discovery_log,
73 	      (struct spdk_nvmf_tgt *tgt, const char *hostnqn));
74 
75 DEFINE_STUB(spdk_nvmf_qpair_disconnect,
76 	    int,
77 	    (struct spdk_nvmf_qpair *qpair,
78 	     nvmf_qpair_disconnect_cb cb_fn, void *ctx), 0);
79 
80 DEFINE_STUB(nvmf_transport_find_listener,
81 	    struct spdk_nvmf_listener *,
82 	    (struct spdk_nvmf_transport *transport,
83 	     const struct spdk_nvme_transport_id *trid), NULL);
84 
85 DEFINE_STUB(spdk_nvmf_transport_get_first,
86 	    struct spdk_nvmf_transport *,
87 	    (struct spdk_nvmf_tgt *tgt), NULL);
88 
89 DEFINE_STUB(spdk_nvmf_transport_get_next,
90 	    struct spdk_nvmf_transport *,
91 	    (struct spdk_nvmf_transport *transport), NULL);
92 
93 DEFINE_STUB(spdk_nvmf_request_complete,
94 	    int,
95 	    (struct spdk_nvmf_request *req), 0);
96 
97 DEFINE_STUB(nvmf_ctrlr_async_event_ana_change_notice,
98 	    int,
99 	    (struct spdk_nvmf_ctrlr *ctrlr), 0);
100 
101 DEFINE_STUB(spdk_nvme_transport_id_trtype_str,
102 	    const char *,
103 	    (enum spdk_nvme_transport_type trtype), NULL);
104 
105 int
106 spdk_nvmf_transport_listen(struct spdk_nvmf_transport *transport,
107 			   const struct spdk_nvme_transport_id *trid, struct spdk_nvmf_listen_opts *opts)
108 {
109 	return 0;
110 }
111 
112 void
113 nvmf_transport_listener_discover(struct spdk_nvmf_transport *transport,
114 				 struct spdk_nvme_transport_id *trid,
115 				 struct spdk_nvmf_discovery_log_page_entry *entry)
116 {
117 	entry->trtype = 42;
118 }
119 
120 static struct spdk_nvmf_transport g_transport = {};
121 
122 struct spdk_nvmf_transport *
123 spdk_nvmf_transport_create(const char *transport_name,
124 			   struct spdk_nvmf_transport_opts *tprt_opts)
125 {
126 	if (strcasecmp(transport_name, spdk_nvme_transport_id_trtype_str(SPDK_NVME_TRANSPORT_RDMA))) {
127 		return &g_transport;
128 	}
129 
130 	return NULL;
131 }
132 
133 struct spdk_nvmf_subsystem *
134 spdk_nvmf_tgt_find_subsystem(struct spdk_nvmf_tgt *tgt, const char *subnqn)
135 {
136 	return NULL;
137 }
138 
139 struct spdk_nvmf_transport *
140 spdk_nvmf_tgt_get_transport(struct spdk_nvmf_tgt *tgt, const char *transport_name)
141 {
142 	if (strncmp(transport_name, SPDK_NVME_TRANSPORT_NAME_RDMA, SPDK_NVMF_TRSTRING_MAX_LEN)) {
143 		return &g_transport;
144 	}
145 
146 	return NULL;
147 }
148 
149 int
150 nvmf_poll_group_update_subsystem(struct spdk_nvmf_poll_group *group,
151 				 struct spdk_nvmf_subsystem *subsystem)
152 {
153 	return 0;
154 }
155 
156 int
157 nvmf_poll_group_add_subsystem(struct spdk_nvmf_poll_group *group,
158 			      struct spdk_nvmf_subsystem *subsystem,
159 			      spdk_nvmf_poll_group_mod_done cb_fn, void *cb_arg)
160 {
161 	return 0;
162 }
163 
164 void
165 nvmf_poll_group_remove_subsystem(struct spdk_nvmf_poll_group *group,
166 				 struct spdk_nvmf_subsystem *subsystem,
167 				 spdk_nvmf_poll_group_mod_done cb_fn, void *cb_arg)
168 {
169 }
170 
171 void
172 nvmf_poll_group_pause_subsystem(struct spdk_nvmf_poll_group *group,
173 				struct spdk_nvmf_subsystem *subsystem,
174 				uint32_t nsid,
175 				spdk_nvmf_poll_group_mod_done cb_fn, void *cb_arg)
176 {
177 }
178 
179 void
180 nvmf_poll_group_resume_subsystem(struct spdk_nvmf_poll_group *group,
181 				 struct spdk_nvmf_subsystem *subsystem,
182 				 spdk_nvmf_poll_group_mod_done cb_fn, void *cb_arg)
183 {
184 }
185 
186 int
187 spdk_nvme_transport_id_parse_trtype(enum spdk_nvme_transport_type *trtype, const char *str)
188 {
189 	if (trtype == NULL || str == NULL) {
190 		return -EINVAL;
191 	}
192 
193 	if (strcasecmp(str, "PCIe") == 0) {
194 		*trtype = SPDK_NVME_TRANSPORT_PCIE;
195 	} else if (strcasecmp(str, "RDMA") == 0) {
196 		*trtype = SPDK_NVME_TRANSPORT_RDMA;
197 	} else {
198 		return -ENOENT;
199 	}
200 	return 0;
201 }
202 
203 int
204 spdk_nvme_transport_id_compare(const struct spdk_nvme_transport_id *trid1,
205 			       const struct spdk_nvme_transport_id *trid2)
206 {
207 	return 0;
208 }
209 
210 int32_t
211 spdk_nvme_ctrlr_process_admin_completions(struct spdk_nvme_ctrlr *ctrlr)
212 {
213 	return -1;
214 }
215 
216 int32_t
217 spdk_nvme_qpair_process_completions(struct spdk_nvme_qpair *qpair, uint32_t max_completions)
218 {
219 	return -1;
220 }
221 
222 int
223 spdk_nvme_detach(struct spdk_nvme_ctrlr *ctrlr)
224 {
225 	return -1;
226 }
227 
228 void
229 nvmf_ctrlr_destruct(struct spdk_nvmf_ctrlr *ctrlr)
230 {
231 }
232 
233 static struct spdk_nvmf_ctrlr *g_ns_changed_ctrlr = NULL;
234 static uint32_t g_ns_changed_nsid = 0;
235 void
236 nvmf_ctrlr_ns_changed(struct spdk_nvmf_ctrlr *ctrlr, uint32_t nsid)
237 {
238 	g_ns_changed_ctrlr = ctrlr;
239 	g_ns_changed_nsid = nsid;
240 }
241 
242 static struct spdk_bdev g_bdevs[] = {
243 	{ .name = "bdev1" },
244 	{ .name = "bdev2" },
245 };
246 
247 struct spdk_bdev_desc {
248 	struct spdk_bdev	*bdev;
249 };
250 
251 int
252 spdk_bdev_open_ext(const char *bdev_name, bool write, spdk_bdev_event_cb_t event_cb,
253 		   void *event_ctx, struct spdk_bdev_desc **_desc)
254 {
255 	struct spdk_bdev_desc *desc;
256 	size_t i;
257 
258 	for (i = 0; i < sizeof(g_bdevs); i++) {
259 		if (strcmp(bdev_name, g_bdevs[i].name) == 0) {
260 
261 			desc = calloc(1, sizeof(*desc));
262 			SPDK_CU_ASSERT_FATAL(desc != NULL);
263 
264 			desc->bdev = &g_bdevs[i];
265 			*_desc = desc;
266 			return 0;
267 		}
268 	}
269 
270 	return -EINVAL;
271 }
272 
273 void
274 spdk_bdev_close(struct spdk_bdev_desc *desc)
275 {
276 	free(desc);
277 }
278 
279 struct spdk_bdev *
280 spdk_bdev_desc_get_bdev(struct spdk_bdev_desc *desc)
281 {
282 	return desc->bdev;
283 }
284 
285 const char *
286 spdk_bdev_get_name(const struct spdk_bdev *bdev)
287 {
288 	return "test";
289 }
290 
291 const struct spdk_uuid *
292 spdk_bdev_get_uuid(const struct spdk_bdev *bdev)
293 {
294 	return &bdev->uuid;
295 }
296 
297 static void
298 test_spdk_nvmf_subsystem_add_ns(void)
299 {
300 	struct spdk_nvmf_tgt tgt = {};
301 	struct spdk_nvmf_subsystem subsystem = {
302 		.max_nsid = 1024,
303 		.ns = NULL,
304 		.tgt = &tgt,
305 	};
306 	struct spdk_nvmf_ns_opts ns_opts;
307 	uint32_t nsid;
308 	int rc;
309 
310 	subsystem.ns = calloc(subsystem.max_nsid, sizeof(struct spdk_nvmf_subsystem_ns *));
311 	SPDK_CU_ASSERT_FATAL(subsystem.ns != NULL);
312 	subsystem.ana_group = calloc(subsystem.max_nsid, sizeof(uint32_t));
313 	SPDK_CU_ASSERT_FATAL(subsystem.ana_group != NULL);
314 
315 	tgt.max_subsystems = 1024;
316 	tgt.subsystems = calloc(tgt.max_subsystems, sizeof(struct spdk_nvmf_subsystem *));
317 	SPDK_CU_ASSERT_FATAL(tgt.subsystems != NULL);
318 
319 	/* Request a specific NSID */
320 	spdk_nvmf_ns_opts_get_defaults(&ns_opts, sizeof(ns_opts));
321 	ns_opts.nsid = 5;
322 	nsid = spdk_nvmf_subsystem_add_ns_ext(&subsystem, "bdev2", &ns_opts, sizeof(ns_opts), NULL);
323 	CU_ASSERT(nsid == 5);
324 	CU_ASSERT(subsystem.max_nsid == 1024);
325 	SPDK_CU_ASSERT_FATAL(subsystem.ns[nsid - 1] != NULL);
326 	CU_ASSERT(subsystem.ns[nsid - 1]->bdev == &g_bdevs[1]);
327 
328 	/* Request an NSID that is already in use */
329 	spdk_nvmf_ns_opts_get_defaults(&ns_opts, sizeof(ns_opts));
330 	ns_opts.nsid = 5;
331 	nsid = spdk_nvmf_subsystem_add_ns_ext(&subsystem, "bdev2", &ns_opts, sizeof(ns_opts), NULL);
332 	CU_ASSERT(nsid == 0);
333 	CU_ASSERT(subsystem.max_nsid == 1024);
334 
335 	/* Request 0xFFFFFFFF (invalid NSID, reserved for broadcast) */
336 	spdk_nvmf_ns_opts_get_defaults(&ns_opts, sizeof(ns_opts));
337 	ns_opts.nsid = 0xFFFFFFFF;
338 	nsid = spdk_nvmf_subsystem_add_ns_ext(&subsystem, "bdev2", &ns_opts, sizeof(ns_opts), NULL);
339 	CU_ASSERT(nsid == 0);
340 	CU_ASSERT(subsystem.max_nsid == 1024);
341 
342 	rc = spdk_nvmf_subsystem_remove_ns(&subsystem, 5);
343 	CU_ASSERT(rc == 0);
344 
345 	free(subsystem.ns);
346 	free(subsystem.ana_group);
347 	free(tgt.subsystems);
348 }
349 
350 static void
351 nvmf_test_create_subsystem(void)
352 {
353 	struct spdk_nvmf_tgt tgt = {};
354 	char nqn[256];
355 	struct spdk_nvmf_subsystem *subsystem;
356 	int rc;
357 
358 	tgt.max_subsystems = 1024;
359 	tgt.subsystems = calloc(tgt.max_subsystems, sizeof(struct spdk_nvmf_subsystem *));
360 	SPDK_CU_ASSERT_FATAL(tgt.subsystems != NULL);
361 
362 	snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk:subsystem1");
363 	subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0);
364 	SPDK_CU_ASSERT_FATAL(subsystem != NULL);
365 	CU_ASSERT_STRING_EQUAL(subsystem->subnqn, nqn);
366 	rc = spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL);
367 	CU_ASSERT(rc == 0);
368 
369 	/* valid name with complex reverse domain */
370 	snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk-full--rev-domain.name:subsystem1");
371 	subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0);
372 	SPDK_CU_ASSERT_FATAL(subsystem != NULL);
373 	CU_ASSERT_STRING_EQUAL(subsystem->subnqn, nqn);
374 	rc = spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL);
375 	CU_ASSERT(rc == 0);
376 
377 	/* Valid name discovery controller */
378 	snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk:subsystem1");
379 	subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0);
380 	SPDK_CU_ASSERT_FATAL(subsystem != NULL);
381 	CU_ASSERT_STRING_EQUAL(subsystem->subnqn, nqn);
382 	rc = spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL);
383 	CU_ASSERT(rc == 0);
384 
385 	/* Invalid name, no user supplied string */
386 	snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk:");
387 	subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0);
388 	SPDK_CU_ASSERT_FATAL(subsystem == NULL);
389 
390 	/* Valid name, only contains top-level domain name */
391 	snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk:subsystem1");
392 	subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0);
393 	SPDK_CU_ASSERT_FATAL(subsystem != NULL);
394 	CU_ASSERT_STRING_EQUAL(subsystem->subnqn, nqn);
395 	rc = spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL);
396 	CU_ASSERT(rc == 0);
397 
398 	/* Invalid name, domain label > 63 characters */
399 	snprintf(nqn, sizeof(nqn),
400 		 "nqn.2016-06.io.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz:sub");
401 	subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0);
402 	SPDK_CU_ASSERT_FATAL(subsystem == NULL);
403 
404 	/* Invalid name, domain label starts with digit */
405 	snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.3spdk:sub");
406 	subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0);
407 	SPDK_CU_ASSERT_FATAL(subsystem == NULL);
408 
409 	/* Invalid name, domain label starts with - */
410 	snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.-spdk:subsystem1");
411 	subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0);
412 	SPDK_CU_ASSERT_FATAL(subsystem == NULL);
413 
414 	/* Invalid name, domain label ends with - */
415 	snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk-:subsystem1");
416 	subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0);
417 	SPDK_CU_ASSERT_FATAL(subsystem == NULL);
418 
419 	/* Invalid name, domain label with multiple consecutive periods */
420 	snprintf(nqn, sizeof(nqn), "nqn.2016-06.io..spdk:subsystem1");
421 	subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0);
422 	SPDK_CU_ASSERT_FATAL(subsystem == NULL);
423 
424 	/* Longest valid name */
425 	snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk:");
426 	memset(nqn + strlen(nqn), 'a', 223 - strlen(nqn));
427 	nqn[223] = '\0';
428 	CU_ASSERT(strlen(nqn) == 223);
429 	subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0);
430 	SPDK_CU_ASSERT_FATAL(subsystem != NULL);
431 	CU_ASSERT_STRING_EQUAL(subsystem->subnqn, nqn);
432 	rc = spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL);
433 	CU_ASSERT(rc == 0);
434 
435 	/* Invalid name, too long */
436 	snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk:");
437 	memset(nqn + strlen(nqn), 'a', 224 - strlen(nqn));
438 	nqn[224] = '\0';
439 	CU_ASSERT(strlen(nqn) == 224);
440 	subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0);
441 	CU_ASSERT(subsystem == NULL);
442 
443 	/* Valid name using uuid format */
444 	snprintf(nqn, sizeof(nqn), "nqn.2014-08.org.nvmexpress:uuid:11111111-aaaa-bbdd-FFEE-123456789abc");
445 	subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0);
446 	SPDK_CU_ASSERT_FATAL(subsystem != NULL);
447 	CU_ASSERT_STRING_EQUAL(subsystem->subnqn, nqn);
448 	rc = spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL);
449 	CU_ASSERT(rc == 0);
450 
451 	/* Invalid name user string contains an invalid utf-8 character */
452 	snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk:\xFFsubsystem1");
453 	subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0);
454 	SPDK_CU_ASSERT_FATAL(subsystem == NULL);
455 
456 	/* Valid name with non-ascii but valid utf-8 characters */
457 	snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk:\xe1\x8a\x88subsystem1\xca\x80");
458 	subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0);
459 	SPDK_CU_ASSERT_FATAL(subsystem != NULL);
460 	CU_ASSERT_STRING_EQUAL(subsystem->subnqn, nqn);
461 	rc = spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL);
462 	CU_ASSERT(rc == 0);
463 
464 	/* Invalid uuid (too long) */
465 	snprintf(nqn, sizeof(nqn),
466 		 "nqn.2014-08.org.nvmexpress:uuid:11111111-aaaa-bbdd-FFEE-123456789abcdef");
467 	subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0);
468 	SPDK_CU_ASSERT_FATAL(subsystem == NULL);
469 
470 	/* Invalid uuid (dashes placed incorrectly) */
471 	snprintf(nqn, sizeof(nqn), "nqn.2014-08.org.nvmexpress:uuid:111111-11aaaa-bbdd-FFEE-123456789abc");
472 	subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0);
473 	SPDK_CU_ASSERT_FATAL(subsystem == NULL);
474 
475 	/* Invalid uuid (invalid characters in uuid) */
476 	snprintf(nqn, sizeof(nqn), "nqn.2014-08.org.nvmexpress:uuid:111hg111-aaaa-bbdd-FFEE-123456789abc");
477 	subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0);
478 	SPDK_CU_ASSERT_FATAL(subsystem == NULL);
479 
480 	free(tgt.subsystems);
481 }
482 
483 static void
484 test_spdk_nvmf_subsystem_set_sn(void)
485 {
486 	struct spdk_nvmf_subsystem subsystem = {};
487 
488 	/* Basic valid serial number */
489 	CU_ASSERT(spdk_nvmf_subsystem_set_sn(&subsystem, "abcd xyz") == 0);
490 	CU_ASSERT(strcmp(subsystem.sn, "abcd xyz") == 0);
491 
492 	/* Exactly 20 characters (valid) */
493 	CU_ASSERT(spdk_nvmf_subsystem_set_sn(&subsystem, "12345678901234567890") == 0);
494 	CU_ASSERT(strcmp(subsystem.sn, "12345678901234567890") == 0);
495 
496 	/* 21 characters (too long, invalid) */
497 	CU_ASSERT(spdk_nvmf_subsystem_set_sn(&subsystem, "123456789012345678901") < 0);
498 
499 	/* Non-ASCII characters (invalid) */
500 	CU_ASSERT(spdk_nvmf_subsystem_set_sn(&subsystem, "abcd\txyz") < 0);
501 }
502 
503 /*
504  * Reservation Unit Test Configuration
505  *       --------             --------    --------
506  *      | Host A |           | Host B |  | Host C |
507  *       --------             --------    --------
508  *      /        \               |           |
509  *  --------   --------       -------     -------
510  * |Ctrlr1_A| |Ctrlr2_A|     |Ctrlr_B|   |Ctrlr_C|
511  *  --------   --------       -------     -------
512  *    \           \              /           /
513  *     \           \            /           /
514  *      \           \          /           /
515  *      --------------------------------------
516  *     |            NAMESPACE 1               |
517  *      --------------------------------------
518  */
519 static struct spdk_nvmf_subsystem g_subsystem;
520 static struct spdk_nvmf_ctrlr g_ctrlr1_A, g_ctrlr2_A, g_ctrlr_B, g_ctrlr_C;
521 static struct spdk_nvmf_ns g_ns;
522 static struct spdk_bdev g_bdev;
523 struct spdk_nvmf_subsystem_pg_ns_info g_ns_info;
524 
525 void
526 nvmf_ctrlr_async_event_reservation_notification(struct spdk_nvmf_ctrlr *ctrlr)
527 {
528 }
529 
530 static void
531 ut_reservation_init(void)
532 {
533 
534 	TAILQ_INIT(&g_subsystem.ctrlrs);
535 
536 	memset(&g_ns, 0, sizeof(g_ns));
537 	TAILQ_INIT(&g_ns.registrants);
538 	g_ns.subsystem = &g_subsystem;
539 	g_ns.ptpl_file = NULL;
540 	g_ns.ptpl_activated = false;
541 	spdk_uuid_generate(&g_bdev.uuid);
542 	g_ns.bdev = &g_bdev;
543 
544 	/* Host A has two controllers */
545 	spdk_uuid_generate(&g_ctrlr1_A.hostid);
546 	TAILQ_INIT(&g_ctrlr1_A.log_head);
547 	g_ctrlr1_A.subsys = &g_subsystem;
548 	g_ctrlr1_A.num_avail_log_pages = 0;
549 	TAILQ_INSERT_TAIL(&g_subsystem.ctrlrs, &g_ctrlr1_A, link);
550 	spdk_uuid_copy(&g_ctrlr2_A.hostid, &g_ctrlr1_A.hostid);
551 	TAILQ_INIT(&g_ctrlr2_A.log_head);
552 	g_ctrlr2_A.subsys = &g_subsystem;
553 	g_ctrlr2_A.num_avail_log_pages = 0;
554 	TAILQ_INSERT_TAIL(&g_subsystem.ctrlrs, &g_ctrlr2_A, link);
555 
556 	/* Host B has 1 controller */
557 	spdk_uuid_generate(&g_ctrlr_B.hostid);
558 	TAILQ_INIT(&g_ctrlr_B.log_head);
559 	g_ctrlr_B.subsys = &g_subsystem;
560 	g_ctrlr_B.num_avail_log_pages = 0;
561 	TAILQ_INSERT_TAIL(&g_subsystem.ctrlrs, &g_ctrlr_B, link);
562 
563 	/* Host C has 1 controller */
564 	spdk_uuid_generate(&g_ctrlr_C.hostid);
565 	TAILQ_INIT(&g_ctrlr_C.log_head);
566 	g_ctrlr_C.subsys = &g_subsystem;
567 	g_ctrlr_C.num_avail_log_pages = 0;
568 	TAILQ_INSERT_TAIL(&g_subsystem.ctrlrs, &g_ctrlr_C, link);
569 }
570 
571 static void
572 ut_reservation_deinit(void)
573 {
574 	struct spdk_nvmf_registrant *reg, *tmp;
575 	struct spdk_nvmf_reservation_log *log, *log_tmp;
576 	struct spdk_nvmf_ctrlr *ctrlr, *ctrlr_tmp;
577 
578 	TAILQ_FOREACH_SAFE(reg, &g_ns.registrants, link, tmp) {
579 		TAILQ_REMOVE(&g_ns.registrants, reg, link);
580 		free(reg);
581 	}
582 	TAILQ_FOREACH_SAFE(log, &g_ctrlr1_A.log_head, link, log_tmp) {
583 		TAILQ_REMOVE(&g_ctrlr1_A.log_head, log, link);
584 		free(log);
585 	}
586 	g_ctrlr1_A.num_avail_log_pages = 0;
587 	TAILQ_FOREACH_SAFE(log, &g_ctrlr2_A.log_head, link, log_tmp) {
588 		TAILQ_REMOVE(&g_ctrlr2_A.log_head, log, link);
589 		free(log);
590 	}
591 	g_ctrlr2_A.num_avail_log_pages = 0;
592 	TAILQ_FOREACH_SAFE(log, &g_ctrlr_B.log_head, link, log_tmp) {
593 		TAILQ_REMOVE(&g_ctrlr_B.log_head, log, link);
594 		free(log);
595 	}
596 	g_ctrlr_B.num_avail_log_pages = 0;
597 	TAILQ_FOREACH_SAFE(log, &g_ctrlr_C.log_head, link, log_tmp) {
598 		TAILQ_REMOVE(&g_ctrlr_C.log_head, log, link);
599 		free(log);
600 	}
601 	g_ctrlr_C.num_avail_log_pages = 0;
602 
603 	TAILQ_FOREACH_SAFE(ctrlr, &g_subsystem.ctrlrs, link, ctrlr_tmp) {
604 		TAILQ_REMOVE(&g_subsystem.ctrlrs, ctrlr, link);
605 	}
606 }
607 
608 static struct spdk_nvmf_request *
609 ut_reservation_build_req(uint32_t length)
610 {
611 	struct spdk_nvmf_request *req;
612 
613 	req = calloc(1, sizeof(*req));
614 	assert(req != NULL);
615 
616 	req->data = calloc(1, length);
617 	assert(req->data != NULL);
618 	req->length = length;
619 
620 	req->cmd = (union nvmf_h2c_msg *)calloc(1, sizeof(union nvmf_h2c_msg));
621 	assert(req->cmd != NULL);
622 
623 	req->rsp = (union nvmf_c2h_msg *)calloc(1, sizeof(union nvmf_c2h_msg));
624 	assert(req->rsp != NULL);
625 
626 	return req;
627 }
628 
629 static void
630 ut_reservation_free_req(struct spdk_nvmf_request *req)
631 {
632 	free(req->cmd);
633 	free(req->rsp);
634 	free(req->data);
635 	free(req);
636 }
637 
638 static void
639 ut_reservation_build_register_request(struct spdk_nvmf_request *req,
640 				      uint8_t rrega, uint8_t iekey,
641 				      uint8_t cptpl, uint64_t crkey,
642 				      uint64_t nrkey)
643 {
644 	struct spdk_nvme_reservation_register_data key;
645 	struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd;
646 
647 	key.crkey = crkey;
648 	key.nrkey = nrkey;
649 	cmd->cdw10 = 0;
650 	cmd->cdw10_bits.resv_register.rrega = rrega;
651 	cmd->cdw10_bits.resv_register.iekey = iekey;
652 	cmd->cdw10_bits.resv_register.cptpl = cptpl;
653 	memcpy(req->data, &key, sizeof(key));
654 }
655 
656 static void
657 ut_reservation_build_acquire_request(struct spdk_nvmf_request *req,
658 				     uint8_t racqa, uint8_t iekey,
659 				     uint8_t rtype, uint64_t crkey,
660 				     uint64_t prkey)
661 {
662 	struct spdk_nvme_reservation_acquire_data key;
663 	struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd;
664 
665 	key.crkey = crkey;
666 	key.prkey = prkey;
667 	cmd->cdw10 = 0;
668 	cmd->cdw10_bits.resv_acquire.racqa = racqa;
669 	cmd->cdw10_bits.resv_acquire.iekey = iekey;
670 	cmd->cdw10_bits.resv_acquire.rtype = rtype;
671 	memcpy(req->data, &key, sizeof(key));
672 }
673 
674 static void
675 ut_reservation_build_release_request(struct spdk_nvmf_request *req,
676 				     uint8_t rrela, uint8_t iekey,
677 				     uint8_t rtype, uint64_t crkey)
678 {
679 	struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd;
680 
681 	cmd->cdw10 = 0;
682 	cmd->cdw10_bits.resv_release.rrela = rrela;
683 	cmd->cdw10_bits.resv_release.iekey = iekey;
684 	cmd->cdw10_bits.resv_release.rtype = rtype;
685 	memcpy(req->data, &crkey, sizeof(crkey));
686 }
687 
688 /*
689  * Construct four registrants for other test cases.
690  *
691  * g_ctrlr1_A register with key 0xa1.
692  * g_ctrlr2_A register with key 0xa1.
693  * g_ctrlr_B register with key 0xb1.
694  * g_ctrlr_C register with key 0xc1.
695  * */
696 static void
697 ut_reservation_build_registrants(void)
698 {
699 	struct spdk_nvmf_request *req;
700 	struct spdk_nvme_cpl *rsp;
701 	struct spdk_nvmf_registrant *reg;
702 	uint32_t gen;
703 
704 	req = ut_reservation_build_req(16);
705 	rsp = &req->rsp->nvme_cpl;
706 	SPDK_CU_ASSERT_FATAL(req != NULL);
707 	gen = g_ns.gen;
708 
709 	/* TEST CASE: g_ctrlr1_A register with a new key */
710 	ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY,
711 					      0, 0, 0, 0xa1);
712 	nvmf_ns_reservation_register(&g_ns, &g_ctrlr1_A, req);
713 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
714 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid);
715 	SPDK_CU_ASSERT_FATAL(reg->rkey == 0xa1);
716 	SPDK_CU_ASSERT_FATAL(g_ns.gen == gen + 1);
717 
718 	/* TEST CASE: g_ctrlr2_A register with a new key, because it has same
719 	 * Host Identifier with g_ctrlr1_A, so the register key should same.
720 	 */
721 	ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY,
722 					      0, 0, 0, 0xa2);
723 	nvmf_ns_reservation_register(&g_ns, &g_ctrlr2_A, req);
724 	/* Reservation conflict for other key than 0xa1 */
725 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_RESERVATION_CONFLICT);
726 
727 	/* g_ctrlr_B register with a new key */
728 	ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY,
729 					      0, 0, 0, 0xb1);
730 	nvmf_ns_reservation_register(&g_ns, &g_ctrlr_B, req);
731 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
732 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_B.hostid);
733 	SPDK_CU_ASSERT_FATAL(reg->rkey == 0xb1);
734 	SPDK_CU_ASSERT_FATAL(g_ns.gen == gen + 2);
735 
736 	/* g_ctrlr_C register with a new key */
737 	ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY,
738 					      0, 0, 0, 0xc1);
739 	nvmf_ns_reservation_register(&g_ns, &g_ctrlr_C, req);
740 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
741 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_C.hostid);
742 	SPDK_CU_ASSERT_FATAL(reg->rkey == 0xc1);
743 	SPDK_CU_ASSERT_FATAL(g_ns.gen == gen + 3);
744 
745 	ut_reservation_free_req(req);
746 }
747 
748 static void
749 test_reservation_register(void)
750 {
751 	struct spdk_nvmf_request *req;
752 	struct spdk_nvme_cpl *rsp;
753 	struct spdk_nvmf_registrant *reg;
754 	uint32_t gen;
755 
756 	ut_reservation_init();
757 
758 	req = ut_reservation_build_req(16);
759 	rsp = &req->rsp->nvme_cpl;
760 	SPDK_CU_ASSERT_FATAL(req != NULL);
761 
762 	ut_reservation_build_registrants();
763 
764 	/* TEST CASE: Replace g_ctrlr1_A with a new key */
765 	ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REPLACE_KEY,
766 					      0, 0, 0xa1, 0xa11);
767 	nvmf_ns_reservation_register(&g_ns, &g_ctrlr1_A, req);
768 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
769 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid);
770 	SPDK_CU_ASSERT_FATAL(reg->rkey == 0xa11);
771 
772 	/* TEST CASE: Host A with g_ctrlr1_A get reservation with
773 	 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE
774 	 */
775 	ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0,
776 					     SPDK_NVME_RESERVE_WRITE_EXCLUSIVE, 0xa11, 0x0);
777 	gen = g_ns.gen;
778 	nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr1_A, req);
779 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
780 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid);
781 	SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE);
782 	SPDK_CU_ASSERT_FATAL(g_ns.crkey == 0xa11);
783 	SPDK_CU_ASSERT_FATAL(g_ns.holder == reg);
784 	SPDK_CU_ASSERT_FATAL(g_ns.gen == gen);
785 
786 	/* TEST CASE: g_ctrlr_C unregister with IEKEY enabled */
787 	ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_UNREGISTER_KEY,
788 					      1, 0, 0, 0);
789 	nvmf_ns_reservation_register(&g_ns, &g_ctrlr_C, req);
790 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
791 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_C.hostid);
792 	SPDK_CU_ASSERT_FATAL(reg == NULL);
793 
794 	/* TEST CASE: g_ctrlr_B unregister with correct key */
795 	ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_UNREGISTER_KEY,
796 					      0, 0, 0xb1, 0);
797 	nvmf_ns_reservation_register(&g_ns, &g_ctrlr_B, req);
798 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
799 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_B.hostid);
800 	SPDK_CU_ASSERT_FATAL(reg == NULL);
801 
802 	/* TEST CASE: No registrant now, g_ctrlr_B replace new key with IEKEY disabled */
803 	ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REPLACE_KEY,
804 					      0, 0, 0, 0xb1);
805 	nvmf_ns_reservation_register(&g_ns, &g_ctrlr_B, req);
806 	SPDK_CU_ASSERT_FATAL(rsp->status.sc != SPDK_NVME_SC_SUCCESS);
807 
808 	/* TEST CASE: No registrant now, g_ctrlr_B replace new key with IEKEY enabled */
809 	ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REPLACE_KEY,
810 					      1, 0, 0, 0xb1);
811 	nvmf_ns_reservation_register(&g_ns, &g_ctrlr_B, req);
812 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
813 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_B.hostid);
814 	SPDK_CU_ASSERT_FATAL(reg != NULL);
815 
816 	/* TEST CASE: g_ctrlr_B replace new key with IEKEY enabled and wrong crkey  */
817 	ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REPLACE_KEY,
818 					      1, 0, 0xff, 0xb2);
819 	nvmf_ns_reservation_register(&g_ns, &g_ctrlr_B, req);
820 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
821 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_B.hostid);
822 	SPDK_CU_ASSERT_FATAL(reg != NULL);
823 	SPDK_CU_ASSERT_FATAL(reg->rkey == 0xb2);
824 
825 	/* TEST CASE: g_ctrlr1_A unregister with correct key,
826 	 * reservation should be removed as well.
827 	 */
828 	ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_UNREGISTER_KEY,
829 					      0, 0, 0xa11, 0);
830 	nvmf_ns_reservation_register(&g_ns, &g_ctrlr1_A, req);
831 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
832 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid);
833 	SPDK_CU_ASSERT_FATAL(reg == NULL);
834 	SPDK_CU_ASSERT_FATAL(g_ns.rtype == 0);
835 	SPDK_CU_ASSERT_FATAL(g_ns.crkey == 0);
836 	SPDK_CU_ASSERT_FATAL(g_ns.holder == NULL);
837 
838 	ut_reservation_free_req(req);
839 	ut_reservation_deinit();
840 }
841 
842 static void
843 test_reservation_register_with_ptpl(void)
844 {
845 	struct spdk_nvmf_request *req;
846 	struct spdk_nvme_cpl *rsp;
847 	struct spdk_nvmf_registrant *reg;
848 	bool update_sgroup = false;
849 	int rc;
850 	struct spdk_nvmf_reservation_info info;
851 
852 	ut_reservation_init();
853 
854 	req = ut_reservation_build_req(16);
855 	rsp = &req->rsp->nvme_cpl;
856 	SPDK_CU_ASSERT_FATAL(req != NULL);
857 
858 	/* TEST CASE: No persistent file, register with PTPL enabled will fail */
859 	g_ns.ptpl_file = NULL;
860 	ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY, 0,
861 					      SPDK_NVME_RESERVE_PTPL_PERSIST_POWER_LOSS, 0, 0xa1);
862 	update_sgroup = nvmf_ns_reservation_register(&g_ns, &g_ctrlr1_A, req);
863 	SPDK_CU_ASSERT_FATAL(update_sgroup == false);
864 	SPDK_CU_ASSERT_FATAL(rsp->status.sc != SPDK_NVME_SC_SUCCESS);
865 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid);
866 	SPDK_CU_ASSERT_FATAL(reg == NULL);
867 
868 	/* TEST CASE: Enable PTPL */
869 	g_ns.ptpl_file = "/tmp/Ns1PR.cfg";
870 	ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY, 0,
871 					      SPDK_NVME_RESERVE_PTPL_PERSIST_POWER_LOSS, 0, 0xa1);
872 	update_sgroup = nvmf_ns_reservation_register(&g_ns, &g_ctrlr1_A, req);
873 	SPDK_CU_ASSERT_FATAL(update_sgroup == true);
874 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
875 	SPDK_CU_ASSERT_FATAL(g_ns.ptpl_activated == true);
876 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid);
877 	SPDK_CU_ASSERT_FATAL(reg != NULL);
878 	SPDK_CU_ASSERT_FATAL(!spdk_uuid_compare(&g_ctrlr1_A.hostid, &reg->hostid));
879 	/* Load reservation information from configuration file */
880 	memset(&info, 0, sizeof(info));
881 	rc = nvmf_ns_load_reservation(g_ns.ptpl_file, &info);
882 	SPDK_CU_ASSERT_FATAL(rc == 0);
883 	SPDK_CU_ASSERT_FATAL(info.ptpl_activated == true);
884 
885 	/* TEST CASE: Disable PTPL */
886 	rsp->status.sc = SPDK_NVME_SC_INVALID_FIELD;
887 	ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY, 0,
888 					      SPDK_NVME_RESERVE_PTPL_CLEAR_POWER_ON, 0, 0xa1);
889 	update_sgroup = nvmf_ns_reservation_register(&g_ns, &g_ctrlr1_A, req);
890 	SPDK_CU_ASSERT_FATAL(update_sgroup == true);
891 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
892 	SPDK_CU_ASSERT_FATAL(g_ns.ptpl_activated == false);
893 	rc = nvmf_ns_load_reservation(g_ns.ptpl_file, &info);
894 	SPDK_CU_ASSERT_FATAL(rc < 0);
895 	unlink(g_ns.ptpl_file);
896 
897 	ut_reservation_free_req(req);
898 	ut_reservation_deinit();
899 }
900 
901 static void
902 test_reservation_acquire_preempt_1(void)
903 {
904 	struct spdk_nvmf_request *req;
905 	struct spdk_nvme_cpl *rsp;
906 	struct spdk_nvmf_registrant *reg;
907 	uint32_t gen;
908 
909 	ut_reservation_init();
910 
911 	req = ut_reservation_build_req(16);
912 	rsp = &req->rsp->nvme_cpl;
913 	SPDK_CU_ASSERT_FATAL(req != NULL);
914 
915 	ut_reservation_build_registrants();
916 
917 	gen = g_ns.gen;
918 	/* ACQUIRE: Host A with g_ctrlr1_A acquire reservation with
919 	 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE.
920 	 */
921 	ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0,
922 					     SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xa1, 0x0);
923 	nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr1_A, req);
924 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
925 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid);
926 	SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY);
927 	SPDK_CU_ASSERT_FATAL(g_ns.crkey == 0xa1);
928 	SPDK_CU_ASSERT_FATAL(g_ns.holder == reg);
929 	SPDK_CU_ASSERT_FATAL(g_ns.gen == gen);
930 
931 	/* TEST CASE: g_ctrlr1_A holds the reservation, g_ctrlr_B preempt g_ctrl1_A,
932 	 * g_ctrl1_A registrant is unregistered.
933 	 */
934 	gen = g_ns.gen;
935 	ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_PREEMPT, 0,
936 					     SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS, 0xb1, 0xa1);
937 	nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_B, req);
938 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
939 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid);
940 	SPDK_CU_ASSERT_FATAL(reg == NULL);
941 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_B.hostid);
942 	SPDK_CU_ASSERT_FATAL(reg != NULL);
943 	SPDK_CU_ASSERT_FATAL(g_ns.holder == reg);
944 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_C.hostid);
945 	SPDK_CU_ASSERT_FATAL(reg != NULL);
946 	SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS);
947 	SPDK_CU_ASSERT_FATAL(g_ns.gen > gen);
948 
949 	/* TEST CASE: g_ctrlr_B holds the reservation, g_ctrlr_C preempt g_ctrlr_B
950 	 * with valid key and PRKEY set to 0, all registrants other the host that issued
951 	 * the command are unregistered.
952 	 */
953 	gen = g_ns.gen;
954 	ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_PREEMPT, 0,
955 					     SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS, 0xc1, 0x0);
956 	nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_C, req);
957 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
958 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr2_A.hostid);
959 	SPDK_CU_ASSERT_FATAL(reg == NULL);
960 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_B.hostid);
961 	SPDK_CU_ASSERT_FATAL(reg == NULL);
962 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_C.hostid);
963 	SPDK_CU_ASSERT_FATAL(reg != NULL);
964 	SPDK_CU_ASSERT_FATAL(g_ns.holder == reg);
965 	SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS);
966 	SPDK_CU_ASSERT_FATAL(g_ns.gen > gen);
967 
968 	ut_reservation_free_req(req);
969 	ut_reservation_deinit();
970 }
971 
972 static void
973 test_reservation_acquire_release_with_ptpl(void)
974 {
975 	struct spdk_nvmf_request *req;
976 	struct spdk_nvme_cpl *rsp;
977 	struct spdk_nvmf_registrant *reg;
978 	bool update_sgroup = false;
979 	struct spdk_uuid holder_uuid;
980 	int rc;
981 	struct spdk_nvmf_reservation_info info;
982 
983 	ut_reservation_init();
984 
985 	req = ut_reservation_build_req(16);
986 	rsp = &req->rsp->nvme_cpl;
987 	SPDK_CU_ASSERT_FATAL(req != NULL);
988 
989 	/* TEST CASE: Enable PTPL */
990 	g_ns.ptpl_file = "/tmp/Ns1PR.cfg";
991 	ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY, 0,
992 					      SPDK_NVME_RESERVE_PTPL_PERSIST_POWER_LOSS, 0, 0xa1);
993 	update_sgroup = nvmf_ns_reservation_register(&g_ns, &g_ctrlr1_A, req);
994 	SPDK_CU_ASSERT_FATAL(update_sgroup == true);
995 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
996 	SPDK_CU_ASSERT_FATAL(g_ns.ptpl_activated == true);
997 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid);
998 	SPDK_CU_ASSERT_FATAL(reg != NULL);
999 	SPDK_CU_ASSERT_FATAL(!spdk_uuid_compare(&g_ctrlr1_A.hostid, &reg->hostid));
1000 	/* Load reservation information from configuration file */
1001 	memset(&info, 0, sizeof(info));
1002 	rc = nvmf_ns_load_reservation(g_ns.ptpl_file, &info);
1003 	SPDK_CU_ASSERT_FATAL(rc == 0);
1004 	SPDK_CU_ASSERT_FATAL(info.ptpl_activated == true);
1005 
1006 	/* TEST CASE: Acquire the reservation */
1007 	rsp->status.sc = SPDK_NVME_SC_INVALID_FIELD;
1008 	ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0,
1009 					     SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xa1, 0x0);
1010 	update_sgroup = nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr1_A, req);
1011 	SPDK_CU_ASSERT_FATAL(update_sgroup == true);
1012 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
1013 	memset(&info, 0, sizeof(info));
1014 	rc = nvmf_ns_load_reservation(g_ns.ptpl_file, &info);
1015 	SPDK_CU_ASSERT_FATAL(rc == 0);
1016 	SPDK_CU_ASSERT_FATAL(info.ptpl_activated == true);
1017 	SPDK_CU_ASSERT_FATAL(info.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY);
1018 	SPDK_CU_ASSERT_FATAL(info.crkey == 0xa1);
1019 	spdk_uuid_parse(&holder_uuid, info.holder_uuid);
1020 	SPDK_CU_ASSERT_FATAL(!spdk_uuid_compare(&g_ctrlr1_A.hostid, &holder_uuid));
1021 
1022 	/* TEST CASE: Release the reservation */
1023 	rsp->status.sc = SPDK_NVME_SC_INVALID_FIELD;
1024 	ut_reservation_build_release_request(req, SPDK_NVME_RESERVE_RELEASE, 0,
1025 					     SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xa1);
1026 	update_sgroup = nvmf_ns_reservation_release(&g_ns, &g_ctrlr1_A, req);
1027 	SPDK_CU_ASSERT_FATAL(update_sgroup == true);
1028 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
1029 	memset(&info, 0, sizeof(info));
1030 	rc = nvmf_ns_load_reservation(g_ns.ptpl_file, &info);
1031 	SPDK_CU_ASSERT_FATAL(rc == 0);
1032 	SPDK_CU_ASSERT_FATAL(info.rtype == 0);
1033 	SPDK_CU_ASSERT_FATAL(info.crkey == 0);
1034 	SPDK_CU_ASSERT_FATAL(info.ptpl_activated == true);
1035 	unlink(g_ns.ptpl_file);
1036 
1037 	ut_reservation_free_req(req);
1038 	ut_reservation_deinit();
1039 }
1040 
1041 static void
1042 test_reservation_release(void)
1043 {
1044 	struct spdk_nvmf_request *req;
1045 	struct spdk_nvme_cpl *rsp;
1046 	struct spdk_nvmf_registrant *reg;
1047 
1048 	ut_reservation_init();
1049 
1050 	req = ut_reservation_build_req(16);
1051 	rsp = &req->rsp->nvme_cpl;
1052 	SPDK_CU_ASSERT_FATAL(req != NULL);
1053 
1054 	ut_reservation_build_registrants();
1055 
1056 	/* ACQUIRE: Host A with g_ctrlr1_A get reservation with
1057 	 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS
1058 	 */
1059 	ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0,
1060 					     SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS, 0xa1, 0x0);
1061 	nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr1_A, req);
1062 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
1063 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid);
1064 	SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS);
1065 	SPDK_CU_ASSERT_FATAL(g_ns.holder == reg);
1066 
1067 	/* Test Case: Host B release the reservation */
1068 	ut_reservation_build_release_request(req, SPDK_NVME_RESERVE_RELEASE, 0,
1069 					     SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS, 0xb1);
1070 	nvmf_ns_reservation_release(&g_ns, &g_ctrlr_B, req);
1071 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
1072 	SPDK_CU_ASSERT_FATAL(g_ns.rtype == 0);
1073 	SPDK_CU_ASSERT_FATAL(g_ns.crkey == 0);
1074 	SPDK_CU_ASSERT_FATAL(g_ns.holder == NULL);
1075 
1076 	/* Test Case: Host C clear the registrants */
1077 	ut_reservation_build_release_request(req, SPDK_NVME_RESERVE_CLEAR, 0,
1078 					     0, 0xc1);
1079 	nvmf_ns_reservation_release(&g_ns, &g_ctrlr_C, req);
1080 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
1081 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid);
1082 	SPDK_CU_ASSERT_FATAL(reg == NULL);
1083 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr2_A.hostid);
1084 	SPDK_CU_ASSERT_FATAL(reg == NULL);
1085 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_B.hostid);
1086 	SPDK_CU_ASSERT_FATAL(reg == NULL);
1087 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_C.hostid);
1088 	SPDK_CU_ASSERT_FATAL(reg == NULL);
1089 
1090 	ut_reservation_free_req(req);
1091 	ut_reservation_deinit();
1092 }
1093 
1094 void
1095 nvmf_ctrlr_reservation_notice_log(struct spdk_nvmf_ctrlr *ctrlr,
1096 				  struct spdk_nvmf_ns *ns,
1097 				  enum spdk_nvme_reservation_notification_log_page_type type)
1098 {
1099 	ctrlr->num_avail_log_pages++;
1100 }
1101 
1102 static void
1103 test_reservation_unregister_notification(void)
1104 {
1105 	struct spdk_nvmf_request *req;
1106 	struct spdk_nvme_cpl *rsp;
1107 
1108 	ut_reservation_init();
1109 
1110 	req = ut_reservation_build_req(16);
1111 	SPDK_CU_ASSERT_FATAL(req != NULL);
1112 	rsp = &req->rsp->nvme_cpl;
1113 
1114 	ut_reservation_build_registrants();
1115 
1116 	/* ACQUIRE: Host B with g_ctrlr_B get reservation with
1117 	 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY
1118 	 */
1119 	rsp->status.sc = 0xff;
1120 	ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0,
1121 					     SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xb1, 0x0);
1122 	nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_B, req);
1123 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
1124 	SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY);
1125 
1126 	/* Test Case : g_ctrlr_B holds the reservation, g_ctrlr_B unregister the registration.
1127 	 * Reservation release notification sends to g_ctrlr1_A/g_ctrlr2_A/g_ctrlr_C only for
1128 	 * SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY or SPDK_NVME_RESERVE_EXCLUSIVE_ACCESS_REG_ONLY
1129 	 * type.
1130 	 */
1131 	rsp->status.sc = 0xff;
1132 	g_ctrlr1_A.num_avail_log_pages = 0;
1133 	g_ctrlr2_A.num_avail_log_pages = 0;
1134 	g_ctrlr_B.num_avail_log_pages = 5;
1135 	g_ctrlr_C.num_avail_log_pages = 0;
1136 	ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_UNREGISTER_KEY,
1137 					      0, 0, 0xb1, 0);
1138 	nvmf_ns_reservation_register(&g_ns, &g_ctrlr_B, req);
1139 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
1140 	SPDK_CU_ASSERT_FATAL(g_ns.rtype == 0);
1141 	SPDK_CU_ASSERT_FATAL(1 == g_ctrlr1_A.num_avail_log_pages);
1142 	SPDK_CU_ASSERT_FATAL(1 == g_ctrlr2_A.num_avail_log_pages);
1143 	SPDK_CU_ASSERT_FATAL(5 == g_ctrlr_B.num_avail_log_pages);
1144 	SPDK_CU_ASSERT_FATAL(1 == g_ctrlr_C.num_avail_log_pages);
1145 
1146 	ut_reservation_free_req(req);
1147 	ut_reservation_deinit();
1148 }
1149 
1150 static void
1151 test_reservation_release_notification(void)
1152 {
1153 	struct spdk_nvmf_request *req;
1154 	struct spdk_nvme_cpl *rsp;
1155 
1156 	ut_reservation_init();
1157 
1158 	req = ut_reservation_build_req(16);
1159 	SPDK_CU_ASSERT_FATAL(req != NULL);
1160 	rsp = &req->rsp->nvme_cpl;
1161 
1162 	ut_reservation_build_registrants();
1163 
1164 	/* ACQUIRE: Host B with g_ctrlr_B get reservation with
1165 	 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY
1166 	 */
1167 	rsp->status.sc = 0xff;
1168 	ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0,
1169 					     SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xb1, 0x0);
1170 	nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_B, req);
1171 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
1172 	SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY);
1173 
1174 	/* Test Case : g_ctrlr_B holds the reservation, g_ctrlr_B release the reservation.
1175 	 * Reservation release notification sends to g_ctrlr1_A/g_ctrlr2_A/g_ctrlr_C.
1176 	 */
1177 	rsp->status.sc = 0xff;
1178 	g_ctrlr1_A.num_avail_log_pages = 0;
1179 	g_ctrlr2_A.num_avail_log_pages = 0;
1180 	g_ctrlr_B.num_avail_log_pages = 5;
1181 	g_ctrlr_C.num_avail_log_pages = 0;
1182 	ut_reservation_build_release_request(req, SPDK_NVME_RESERVE_RELEASE, 0,
1183 					     SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xb1);
1184 	nvmf_ns_reservation_release(&g_ns, &g_ctrlr_B, req);
1185 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
1186 	SPDK_CU_ASSERT_FATAL(g_ns.rtype == 0);
1187 	SPDK_CU_ASSERT_FATAL(1 == g_ctrlr1_A.num_avail_log_pages);
1188 	SPDK_CU_ASSERT_FATAL(1 == g_ctrlr2_A.num_avail_log_pages);
1189 	SPDK_CU_ASSERT_FATAL(5 == g_ctrlr_B.num_avail_log_pages);
1190 	SPDK_CU_ASSERT_FATAL(1 == g_ctrlr_C.num_avail_log_pages);
1191 
1192 	ut_reservation_free_req(req);
1193 	ut_reservation_deinit();
1194 }
1195 
1196 static void
1197 test_reservation_release_notification_write_exclusive(void)
1198 {
1199 	struct spdk_nvmf_request *req;
1200 	struct spdk_nvme_cpl *rsp;
1201 
1202 	ut_reservation_init();
1203 
1204 	req = ut_reservation_build_req(16);
1205 	SPDK_CU_ASSERT_FATAL(req != NULL);
1206 	rsp = &req->rsp->nvme_cpl;
1207 
1208 	ut_reservation_build_registrants();
1209 
1210 	/* ACQUIRE: Host B with g_ctrlr_B get reservation with
1211 	 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE
1212 	 */
1213 	rsp->status.sc = 0xff;
1214 	ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0,
1215 					     SPDK_NVME_RESERVE_WRITE_EXCLUSIVE, 0xb1, 0x0);
1216 	nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_B, req);
1217 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
1218 	SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE);
1219 
1220 	/* Test Case : g_ctrlr_B holds the reservation, g_ctrlr_B release the reservation.
1221 	 * Because the reservation type is SPDK_NVME_RESERVE_WRITE_EXCLUSIVE,
1222 	 * no reservation notification occurs.
1223 	 */
1224 	rsp->status.sc = 0xff;
1225 	g_ctrlr1_A.num_avail_log_pages = 5;
1226 	g_ctrlr2_A.num_avail_log_pages = 5;
1227 	g_ctrlr_B.num_avail_log_pages = 5;
1228 	g_ctrlr_C.num_avail_log_pages = 5;
1229 	ut_reservation_build_release_request(req, SPDK_NVME_RESERVE_RELEASE, 0,
1230 					     SPDK_NVME_RESERVE_WRITE_EXCLUSIVE, 0xb1);
1231 	nvmf_ns_reservation_release(&g_ns, &g_ctrlr_B, req);
1232 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
1233 	SPDK_CU_ASSERT_FATAL(g_ns.rtype == 0);
1234 	SPDK_CU_ASSERT_FATAL(5 == g_ctrlr1_A.num_avail_log_pages);
1235 	SPDK_CU_ASSERT_FATAL(5 == g_ctrlr2_A.num_avail_log_pages);
1236 	SPDK_CU_ASSERT_FATAL(5 == g_ctrlr_B.num_avail_log_pages);
1237 	SPDK_CU_ASSERT_FATAL(5 == g_ctrlr_C.num_avail_log_pages);
1238 
1239 	ut_reservation_free_req(req);
1240 	ut_reservation_deinit();
1241 }
1242 
1243 static void
1244 test_reservation_clear_notification(void)
1245 {
1246 	struct spdk_nvmf_request *req;
1247 	struct spdk_nvme_cpl *rsp;
1248 
1249 	ut_reservation_init();
1250 
1251 	req = ut_reservation_build_req(16);
1252 	SPDK_CU_ASSERT_FATAL(req != NULL);
1253 	rsp = &req->rsp->nvme_cpl;
1254 
1255 	ut_reservation_build_registrants();
1256 
1257 	/* ACQUIRE: Host B with g_ctrlr_B get reservation with
1258 	 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY
1259 	 */
1260 	rsp->status.sc = 0xff;
1261 	ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0,
1262 					     SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xb1, 0x0);
1263 	nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_B, req);
1264 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
1265 	SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY);
1266 
1267 	/* Test Case : g_ctrlr_B holds the reservation, g_ctrlr_B clear the reservation.
1268 	 * Reservation Preempted notification sends to g_ctrlr1_A/g_ctrlr2_A/g_ctrlr_C.
1269 	 */
1270 	rsp->status.sc = 0xff;
1271 	g_ctrlr1_A.num_avail_log_pages = 0;
1272 	g_ctrlr2_A.num_avail_log_pages = 0;
1273 	g_ctrlr_B.num_avail_log_pages = 5;
1274 	g_ctrlr_C.num_avail_log_pages = 0;
1275 	ut_reservation_build_release_request(req, SPDK_NVME_RESERVE_CLEAR, 0,
1276 					     0, 0xb1);
1277 	nvmf_ns_reservation_release(&g_ns, &g_ctrlr_B, req);
1278 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
1279 	SPDK_CU_ASSERT_FATAL(g_ns.rtype == 0);
1280 	SPDK_CU_ASSERT_FATAL(1 == g_ctrlr1_A.num_avail_log_pages);
1281 	SPDK_CU_ASSERT_FATAL(1 == g_ctrlr2_A.num_avail_log_pages);
1282 	SPDK_CU_ASSERT_FATAL(5 == g_ctrlr_B.num_avail_log_pages);
1283 	SPDK_CU_ASSERT_FATAL(1 == g_ctrlr_C.num_avail_log_pages);
1284 
1285 	ut_reservation_free_req(req);
1286 	ut_reservation_deinit();
1287 }
1288 
1289 static void
1290 test_reservation_preempt_notification(void)
1291 {
1292 	struct spdk_nvmf_request *req;
1293 	struct spdk_nvme_cpl *rsp;
1294 
1295 	ut_reservation_init();
1296 
1297 	req = ut_reservation_build_req(16);
1298 	SPDK_CU_ASSERT_FATAL(req != NULL);
1299 	rsp = &req->rsp->nvme_cpl;
1300 
1301 	ut_reservation_build_registrants();
1302 
1303 	/* ACQUIRE: Host B with g_ctrlr_B get reservation with
1304 	 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY
1305 	 */
1306 	rsp->status.sc = 0xff;
1307 	ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0,
1308 					     SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xb1, 0x0);
1309 	nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_B, req);
1310 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
1311 	SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY);
1312 
1313 	/* Test Case : g_ctrlr_B holds the reservation, g_ctrlr_C preempt g_ctrlr_B,
1314 	 * g_ctrlr_B registrant is unregistered, and reservation is preempted.
1315 	 * Registration Preempted notification sends to g_ctrlr_B.
1316 	 * Reservation Preempted notification sends to g_ctrlr1_A/g_ctrlr2_A.
1317 	 */
1318 	rsp->status.sc = 0xff;
1319 	g_ctrlr1_A.num_avail_log_pages = 0;
1320 	g_ctrlr2_A.num_avail_log_pages = 0;
1321 	g_ctrlr_B.num_avail_log_pages = 0;
1322 	g_ctrlr_C.num_avail_log_pages = 5;
1323 	ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_PREEMPT, 0,
1324 					     SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS, 0xc1, 0xb1);
1325 	nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_C, req);
1326 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
1327 	SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS);
1328 	SPDK_CU_ASSERT_FATAL(1 == g_ctrlr1_A.num_avail_log_pages);
1329 	SPDK_CU_ASSERT_FATAL(1 == g_ctrlr2_A.num_avail_log_pages);
1330 	SPDK_CU_ASSERT_FATAL(1 == g_ctrlr_B.num_avail_log_pages);
1331 	SPDK_CU_ASSERT_FATAL(5 == g_ctrlr_C.num_avail_log_pages);
1332 
1333 	ut_reservation_free_req(req);
1334 	ut_reservation_deinit();
1335 }
1336 
1337 static int
1338 nvmf_tgt_create_poll_group(void *io_device, void *ctx_buf)
1339 {
1340 	return 0;
1341 }
1342 
1343 static void
1344 nvmf_tgt_destroy_poll_group(void *io_device, void *ctx_buf)
1345 {
1346 }
1347 
1348 static void
1349 test_spdk_nvmf_ns_event(void)
1350 {
1351 	struct spdk_nvmf_tgt tgt = {};
1352 	struct spdk_nvmf_subsystem subsystem = {
1353 		.max_nsid = 1024,
1354 		.ns = NULL,
1355 		.tgt = &tgt,
1356 	};
1357 	struct spdk_nvmf_ctrlr ctrlr = {
1358 		.subsys = &subsystem
1359 	};
1360 	struct spdk_nvmf_ns_opts ns_opts;
1361 	uint32_t nsid;
1362 	struct spdk_bdev *bdev;
1363 
1364 	subsystem.ns = calloc(subsystem.max_nsid, sizeof(struct spdk_nvmf_subsystem_ns *));
1365 	SPDK_CU_ASSERT_FATAL(subsystem.ns != NULL);
1366 	subsystem.ana_group = calloc(subsystem.max_nsid, sizeof(uint32_t));
1367 	SPDK_CU_ASSERT_FATAL(subsystem.ana_group != NULL);
1368 
1369 	tgt.max_subsystems = 1024;
1370 	tgt.subsystems = calloc(tgt.max_subsystems, sizeof(struct spdk_nvmf_subsystem *));
1371 	SPDK_CU_ASSERT_FATAL(tgt.subsystems != NULL);
1372 
1373 	spdk_io_device_register(&tgt,
1374 				nvmf_tgt_create_poll_group,
1375 				nvmf_tgt_destroy_poll_group,
1376 				sizeof(struct spdk_nvmf_poll_group),
1377 				NULL);
1378 
1379 	/* Add one namespace */
1380 	spdk_nvmf_ns_opts_get_defaults(&ns_opts, sizeof(ns_opts));
1381 	nsid = spdk_nvmf_subsystem_add_ns_ext(&subsystem, "bdev1", &ns_opts, sizeof(ns_opts), NULL);
1382 	CU_ASSERT(nsid == 1);
1383 	CU_ASSERT(NULL != subsystem.ns[0]);
1384 	CU_ASSERT(subsystem.ns[nsid - 1]->bdev == &g_bdevs[nsid - 1]);
1385 
1386 	bdev = subsystem.ns[nsid - 1]->bdev;
1387 
1388 	/* Add one controller */
1389 	TAILQ_INIT(&subsystem.ctrlrs);
1390 	TAILQ_INSERT_TAIL(&subsystem.ctrlrs, &ctrlr, link);
1391 
1392 	/* Namespace resize event */
1393 	subsystem.state = SPDK_NVMF_SUBSYSTEM_ACTIVE;
1394 	g_ns_changed_nsid = 0xFFFFFFFF;
1395 	g_ns_changed_ctrlr = NULL;
1396 	nvmf_ns_event(SPDK_BDEV_EVENT_RESIZE, bdev, subsystem.ns[0]);
1397 	CU_ASSERT(SPDK_NVMF_SUBSYSTEM_PAUSING == subsystem.state);
1398 
1399 	poll_threads();
1400 	CU_ASSERT(1 == g_ns_changed_nsid);
1401 	CU_ASSERT(&ctrlr == g_ns_changed_ctrlr);
1402 	CU_ASSERT(SPDK_NVMF_SUBSYSTEM_ACTIVE == subsystem.state);
1403 
1404 	/* Namespace remove event */
1405 	subsystem.state = SPDK_NVMF_SUBSYSTEM_ACTIVE;
1406 	g_ns_changed_nsid = 0xFFFFFFFF;
1407 	g_ns_changed_ctrlr = NULL;
1408 	nvmf_ns_event(SPDK_BDEV_EVENT_REMOVE, bdev, subsystem.ns[0]);
1409 	CU_ASSERT(SPDK_NVMF_SUBSYSTEM_PAUSING == subsystem.state);
1410 	CU_ASSERT(0xFFFFFFFF == g_ns_changed_nsid);
1411 	CU_ASSERT(NULL == g_ns_changed_ctrlr);
1412 
1413 	poll_threads();
1414 	CU_ASSERT(1 == g_ns_changed_nsid);
1415 	CU_ASSERT(&ctrlr == g_ns_changed_ctrlr);
1416 	CU_ASSERT(NULL == subsystem.ns[0]);
1417 	CU_ASSERT(SPDK_NVMF_SUBSYSTEM_ACTIVE == subsystem.state);
1418 
1419 	spdk_io_device_unregister(&tgt, NULL);
1420 
1421 	poll_threads();
1422 
1423 	free(subsystem.ns);
1424 	free(subsystem.ana_group);
1425 	free(tgt.subsystems);
1426 }
1427 
1428 static void
1429 test_nvmf_ns_reservation_add_remove_registrant(void)
1430 {
1431 	struct spdk_nvmf_ns ns = {};
1432 	struct spdk_nvmf_ctrlr ctrlr = {};
1433 	struct spdk_nvmf_registrant *reg = NULL;
1434 	int rc;
1435 
1436 	TAILQ_INIT(&ns.registrants);
1437 	spdk_uuid_generate(&ctrlr.hostid);
1438 
1439 	rc = nvmf_ns_reservation_add_registrant(&ns, &ctrlr, 0xa11);
1440 	CU_ASSERT(rc == 0);
1441 	reg = TAILQ_FIRST(&ns.registrants);
1442 	SPDK_CU_ASSERT_FATAL(reg != NULL);
1443 	CU_ASSERT(ns.gen == 1);
1444 	CU_ASSERT(reg->rkey == 0xa11);
1445 	CU_ASSERT(!strncmp((uint8_t *)&reg->hostid, (uint8_t *)&ctrlr.hostid, sizeof(ctrlr.hostid)));
1446 
1447 	nvmf_ns_reservation_remove_registrant(&ns, reg);
1448 	CU_ASSERT(TAILQ_EMPTY(&ns.registrants));
1449 	CU_ASSERT(ns.gen == 2);
1450 }
1451 
1452 static void
1453 test_nvmf_subsystem_destroy_cb(void *cb_arg)
1454 {
1455 }
1456 
1457 static void
1458 test_nvmf_subsystem_add_ctrlr(void)
1459 {
1460 	int rc;
1461 	struct spdk_nvmf_ctrlr ctrlr = {};
1462 	struct spdk_nvmf_tgt tgt = {};
1463 	char nqn[256] = "nqn.2016-06.io.spdk:subsystem1";
1464 	struct spdk_nvmf_subsystem *subsystem = NULL;
1465 
1466 	tgt.max_subsystems = 1024;
1467 	tgt.subsystems = calloc(tgt.max_subsystems, sizeof(struct spdk_nvmf_subsystem *));
1468 	SPDK_CU_ASSERT_FATAL(tgt.subsystems != NULL);
1469 
1470 	subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0);
1471 	SPDK_CU_ASSERT_FATAL(subsystem != NULL);
1472 	ctrlr.subsys = subsystem;
1473 
1474 	ctrlr.dynamic_ctrlr = true;
1475 	rc = nvmf_subsystem_add_ctrlr(subsystem, &ctrlr);
1476 	CU_ASSERT(rc == 0);
1477 	CU_ASSERT(!TAILQ_EMPTY(&subsystem->ctrlrs));
1478 	CU_ASSERT(ctrlr.cntlid == 1);
1479 	CU_ASSERT(nvmf_subsystem_get_ctrlr(subsystem, 1) == &ctrlr);
1480 
1481 	nvmf_subsystem_remove_ctrlr(subsystem, &ctrlr);
1482 	CU_ASSERT(TAILQ_EMPTY(&subsystem->ctrlrs));
1483 	rc = spdk_nvmf_subsystem_destroy(subsystem, test_nvmf_subsystem_destroy_cb, NULL);
1484 	CU_ASSERT(rc == 0);
1485 	free(tgt.subsystems);
1486 }
1487 
1488 static void
1489 test_spdk_nvmf_subsystem_add_host(void)
1490 {
1491 	struct spdk_nvmf_tgt tgt = {};
1492 	struct spdk_nvmf_subsystem *subsystem = NULL;
1493 	int rc;
1494 	const char hostnqn[] = "nqn.2016-06.io.spdk:host1";
1495 	const char subsystemnqn[] = "nqn.2016-06.io.spdk:subsystem1";
1496 
1497 	tgt.max_subsystems = 1024;
1498 	tgt.subsystems = calloc(tgt.max_subsystems, sizeof(struct spdk_nvmf_subsystem *));
1499 	SPDK_CU_ASSERT_FATAL(tgt.subsystems != NULL);
1500 
1501 	subsystem = spdk_nvmf_subsystem_create(&tgt, subsystemnqn, SPDK_NVMF_SUBTYPE_NVME, 0);
1502 	SPDK_CU_ASSERT_FATAL(subsystem != NULL);
1503 	CU_ASSERT_STRING_EQUAL(subsystem->subnqn, subsystemnqn);
1504 
1505 	rc = spdk_nvmf_subsystem_add_host(subsystem, hostnqn);
1506 	CU_ASSERT(rc == 0);
1507 	CU_ASSERT(!TAILQ_EMPTY(&subsystem->hosts));
1508 
1509 	/* Add existing nqn, this function is allowed to be called if the nqn was previously added. */
1510 	rc = spdk_nvmf_subsystem_add_host(subsystem, hostnqn);
1511 	CU_ASSERT(rc == 0);
1512 
1513 	rc = spdk_nvmf_subsystem_remove_host(subsystem, hostnqn);
1514 	CU_ASSERT(rc == 0);
1515 	CU_ASSERT(TAILQ_EMPTY(&subsystem->hosts));
1516 
1517 	/* No available nqn */
1518 	rc = spdk_nvmf_subsystem_remove_host(subsystem, hostnqn);
1519 	CU_ASSERT(rc == -ENOENT);
1520 
1521 	spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL);
1522 	free(tgt.subsystems);
1523 }
1524 
1525 static void
1526 test_nvmf_ns_reservation_report(void)
1527 {
1528 	struct spdk_nvmf_ns ns = {};
1529 	struct spdk_nvmf_ctrlr ctrlr = {};
1530 	struct spdk_nvmf_request req = {};
1531 	union nvmf_h2c_msg cmd = {};
1532 	union nvmf_c2h_msg rsp = {};
1533 	struct spdk_nvme_registered_ctrlr_extended_data *ctrlr_data;
1534 	struct spdk_nvme_reservation_status_extended_data *status_data;
1535 	struct spdk_nvmf_registrant *reg;
1536 
1537 	req.data = calloc(1, sizeof(*status_data) + sizeof(*ctrlr_data) * 2);
1538 	reg = calloc(2, sizeof(struct spdk_nvmf_registrant));
1539 	SPDK_CU_ASSERT_FATAL(req.data != NULL && reg != NULL);
1540 
1541 	req.cmd = &cmd;
1542 	req.rsp = &rsp;
1543 	ns.gen = 1;
1544 	ns.rtype = SPDK_NVME_RESERVE_WRITE_EXCLUSIVE;
1545 	ns.ptpl_activated = true;
1546 	cmd.nvme_cmd.cdw11_bits.resv_report.eds = true;
1547 	cmd.nvme_cmd.cdw10 = 100;
1548 	reg[0].rkey = 0xa;
1549 	reg[1].rkey = 0xb;
1550 	spdk_uuid_generate(&reg[0].hostid);
1551 	spdk_uuid_generate(&reg[1].hostid);
1552 	TAILQ_INIT(&ns.registrants);
1553 	TAILQ_INSERT_TAIL(&ns.registrants, &reg[0], link);
1554 	TAILQ_INSERT_TAIL(&ns.registrants, &reg[1], link);
1555 
1556 	nvmf_ns_reservation_report(&ns, &ctrlr, &req);
1557 	CU_ASSERT(req.rsp->nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC);
1558 	CU_ASSERT(req.rsp->nvme_cpl.status.sc == SPDK_NVME_SC_SUCCESS);
1559 	/* Get ctrlr data and status data pointers */
1560 	ctrlr_data = (void *)((uint64_t)req.data + sizeof(*status_data));
1561 	status_data = (void *)req.data;
1562 	SPDK_CU_ASSERT_FATAL(status_data != NULL && ctrlr_data != NULL);
1563 	CU_ASSERT(status_data->data.gen == 1);
1564 	CU_ASSERT(status_data->data.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE);
1565 	CU_ASSERT(status_data->data.ptpls == true);
1566 	CU_ASSERT(status_data->data.regctl == 2);
1567 	CU_ASSERT(ctrlr_data->cntlid == 0xffff);
1568 	CU_ASSERT(ctrlr_data->rcsts.status == false);
1569 	CU_ASSERT(ctrlr_data->rkey ==  0xa);
1570 	CU_ASSERT(!spdk_uuid_compare((struct spdk_uuid *)ctrlr_data->hostid, &reg[0].hostid));
1571 	/* Check second ctrlr data */
1572 	ctrlr_data++;
1573 	CU_ASSERT(ctrlr_data->cntlid == 0xffff);
1574 	CU_ASSERT(ctrlr_data->rcsts.status == false);
1575 	CU_ASSERT(ctrlr_data->rkey ==  0xb);
1576 	CU_ASSERT(!spdk_uuid_compare((struct spdk_uuid *)ctrlr_data->hostid, &reg[1].hostid));
1577 
1578 	/* extended controller data structure */
1579 	memset(req.data, 0, sizeof(*status_data) + sizeof(*ctrlr_data) * 2);
1580 	memset(req.rsp, 0, sizeof(*req.rsp));
1581 	cmd.nvme_cmd.cdw11_bits.resv_report.eds = false;
1582 
1583 	nvmf_ns_reservation_report(&ns, &ctrlr, &req);
1584 	CU_ASSERT(req.rsp->nvme_cpl.status.sc == SPDK_NVME_SC_HOSTID_INCONSISTENT_FORMAT);
1585 	CU_ASSERT(req.rsp->nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC);
1586 
1587 	/* Transfer length invalid */
1588 	memset(req.data, 0, sizeof(*status_data) + sizeof(*ctrlr_data) * 2);
1589 	memset(req.rsp, 0, sizeof(*req.rsp));
1590 	cmd.nvme_cmd.cdw11_bits.resv_report.eds = true;
1591 	cmd.nvme_cmd.cdw10 = 0;
1592 
1593 	nvmf_ns_reservation_report(&ns, &ctrlr, &req);
1594 	CU_ASSERT(req.rsp->nvme_cpl.status.sc == SPDK_NVME_SC_INTERNAL_DEVICE_ERROR);
1595 	CU_ASSERT(req.rsp->nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC);
1596 
1597 	free(req.data);
1598 	free(reg);
1599 }
1600 
1601 static void
1602 test_nvmf_valid_nqn(void)
1603 {
1604 	bool rc;
1605 	char uuid[SPDK_NVMF_UUID_STRING_LEN + 1] = {};
1606 	char nqn[SPDK_NVMF_NQN_MAX_LEN + 1] = {};
1607 	struct spdk_uuid s_uuid = {};
1608 
1609 	spdk_uuid_generate(&s_uuid);
1610 	uuid_unparse((void *)&s_uuid, uuid);
1611 
1612 	/* discovery nqn */
1613 	snprintf(nqn, sizeof(nqn), "%s", SPDK_NVMF_DISCOVERY_NQN);
1614 
1615 	rc = nvmf_valid_nqn(nqn);
1616 	CU_ASSERT(rc == true);
1617 
1618 	/* nqn with uuid */
1619 	memset(nqn, 0xff, sizeof(nqn));
1620 	snprintf(nqn, sizeof(nqn), "%s%s", SPDK_NVMF_NQN_UUID_PRE, uuid);
1621 
1622 	rc = nvmf_valid_nqn(nqn);
1623 	CU_ASSERT(rc == true);
1624 
1625 	/* Check nqn valid reverse domain */
1626 	memset(nqn, 0xff, sizeof(nqn));
1627 	snprintf(nqn, sizeof(nqn), "%s", "nqn.2016-06.io.spdk:cnode1");
1628 
1629 	rc = nvmf_valid_nqn(nqn);
1630 	CU_ASSERT(rc == true);
1631 
1632 	/* Invalid nqn length */
1633 	memset(nqn, 0xff, sizeof(nqn));
1634 	snprintf(nqn, sizeof(nqn), "%s", "nqn.");
1635 
1636 	rc = nvmf_valid_nqn(nqn);
1637 	CU_ASSERT(rc == false);
1638 
1639 	/* Copy uuid to the nqn string, but omit the last character to make it invalid */
1640 	memset(nqn, 0, SPDK_NVMF_NQN_MAX_LEN + 1);
1641 	snprintf(nqn, sizeof(nqn), "%s", SPDK_NVMF_NQN_UUID_PRE);
1642 	memcpy(&nqn[SPDK_NVMF_NQN_UUID_PRE_LEN], uuid, SPDK_NVMF_UUID_STRING_LEN - 1);
1643 
1644 	rc = nvmf_valid_nqn(nqn);
1645 	CU_ASSERT(rc == false);
1646 
1647 	/* Invalid domain */
1648 	memset(nqn, 0xff, SPDK_NVMF_NQN_MAX_LEN + 1);
1649 	snprintf(nqn, sizeof(nqn), "%s", "nqn.2016-06.io...spdk:cnode1");
1650 
1651 	rc = nvmf_valid_nqn(nqn);
1652 	CU_ASSERT(rc == false);
1653 }
1654 
1655 static void
1656 test_nvmf_ns_reservation_restore(void)
1657 {
1658 	struct spdk_nvmf_ns ns = {};
1659 	struct spdk_nvmf_reservation_info info = {};
1660 	struct spdk_bdev bdev = {};
1661 	struct spdk_uuid s_uuid = {};
1662 	struct spdk_nvmf_registrant *reg0, *reg1;
1663 	char uuid[SPDK_UUID_STRING_LEN] = {};
1664 	int rc;
1665 
1666 	ns.bdev = &bdev;
1667 	TAILQ_INIT(&ns.registrants);
1668 	info.ptpl_activated = true;
1669 	info.num_regs = 2;
1670 	info.rtype = SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS;
1671 	info.registrants[0].rkey = 0xb;
1672 	info.registrants[1].rkey = 0xc;
1673 
1674 	/* Generate and prepare uuids, make sure bdev and info uuid are the same */
1675 	spdk_uuid_generate(&s_uuid);
1676 	uuid_unparse((void *)&s_uuid, uuid);
1677 	snprintf(info.holder_uuid, SPDK_UUID_STRING_LEN, "%s", uuid);
1678 	snprintf(info.bdev_uuid, SPDK_UUID_STRING_LEN, "%s", uuid);
1679 	snprintf(info.registrants[0].host_uuid, SPDK_UUID_STRING_LEN, "%s", uuid);
1680 	spdk_uuid_copy(&bdev.uuid, &s_uuid);
1681 	spdk_uuid_generate(&s_uuid);
1682 	uuid_unparse((void *)&s_uuid, uuid);
1683 	snprintf(info.registrants[1].host_uuid, SPDK_UUID_STRING_LEN, "%s", uuid);
1684 
1685 	/* info->rkey not exist in registrants */
1686 	info.crkey = 0xa;
1687 
1688 	rc = nvmf_ns_reservation_restore(&ns, &info);
1689 	CU_ASSERT(rc == -EINVAL);
1690 
1691 	/* info->rkey exists in registrants */
1692 	info.crkey = 0xb;
1693 
1694 	rc = nvmf_ns_reservation_restore(&ns, &info);
1695 	CU_ASSERT(rc == 0);
1696 	CU_ASSERT(ns.crkey == 0xb);
1697 	CU_ASSERT(ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS);
1698 	CU_ASSERT(ns.ptpl_activated == true);
1699 	/* Check two registrant`s rkey */
1700 	reg0 = TAILQ_FIRST(&ns.registrants);
1701 	reg1 = TAILQ_NEXT(reg0, link);
1702 	CU_ASSERT(ns.holder == reg0);
1703 	CU_ASSERT(reg0->rkey = 0xb);
1704 	CU_ASSERT(reg1->rkey = 0xc);
1705 
1706 	rc = nvmf_ns_reservation_clear_all_registrants(&ns);
1707 	CU_ASSERT(rc == 2);
1708 	CU_ASSERT(TAILQ_EMPTY(&ns.registrants));
1709 
1710 	/* Existing bdev UUID is different with configuration */
1711 	spdk_uuid_generate(&s_uuid);
1712 	uuid_unparse((void *)&s_uuid, uuid);
1713 	snprintf(info.bdev_uuid, SPDK_UUID_STRING_LEN, "%s", uuid);
1714 	spdk_uuid_generate(&s_uuid);
1715 	spdk_uuid_copy(&bdev.uuid, &s_uuid);
1716 
1717 	rc = nvmf_ns_reservation_restore(&ns, &info);
1718 	CU_ASSERT(rc == -EINVAL);
1719 }
1720 
1721 int main(int argc, char **argv)
1722 {
1723 	CU_pSuite	suite = NULL;
1724 	unsigned int	num_failures;
1725 
1726 	CU_set_error_action(CUEA_ABORT);
1727 	CU_initialize_registry();
1728 
1729 	suite = CU_add_suite("nvmf", NULL, NULL);
1730 
1731 	CU_ADD_TEST(suite, nvmf_test_create_subsystem);
1732 	CU_ADD_TEST(suite, test_spdk_nvmf_subsystem_add_ns);
1733 	CU_ADD_TEST(suite, test_spdk_nvmf_subsystem_set_sn);
1734 	CU_ADD_TEST(suite, test_reservation_register);
1735 	CU_ADD_TEST(suite, test_reservation_register_with_ptpl);
1736 	CU_ADD_TEST(suite, test_reservation_acquire_preempt_1);
1737 	CU_ADD_TEST(suite, test_reservation_acquire_release_with_ptpl);
1738 	CU_ADD_TEST(suite, test_reservation_release);
1739 	CU_ADD_TEST(suite, test_reservation_unregister_notification);
1740 	CU_ADD_TEST(suite, test_reservation_release_notification);
1741 	CU_ADD_TEST(suite, test_reservation_release_notification_write_exclusive);
1742 	CU_ADD_TEST(suite, test_reservation_clear_notification);
1743 	CU_ADD_TEST(suite, test_reservation_preempt_notification);
1744 	CU_ADD_TEST(suite, test_spdk_nvmf_ns_event);
1745 	CU_ADD_TEST(suite, test_nvmf_ns_reservation_add_remove_registrant);
1746 	CU_ADD_TEST(suite, test_nvmf_subsystem_add_ctrlr);
1747 	CU_ADD_TEST(suite, test_spdk_nvmf_subsystem_add_host);
1748 	CU_ADD_TEST(suite, test_nvmf_ns_reservation_report);
1749 	CU_ADD_TEST(suite, test_nvmf_valid_nqn);
1750 	CU_ADD_TEST(suite, test_nvmf_ns_reservation_restore);
1751 
1752 	allocate_threads(1);
1753 	set_thread(0);
1754 
1755 	CU_basic_set_mode(CU_BRM_VERBOSE);
1756 	CU_basic_run_tests();
1757 	num_failures = CU_get_number_of_failures();
1758 	CU_cleanup_registry();
1759 
1760 	free_threads();
1761 
1762 	return num_failures;
1763 }
1764