xref: /spdk/test/unit/lib/nvmf/subsystem.c/subsystem_ut.c (revision 7025ceb9c119a6da0b6ee2013b6ae94b51fac2df)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (C) 2016 Intel Corporation. All rights reserved.
3  *   Copyright (c) 2019 Mellanox Technologies LTD. All rights reserved.
4  */
5 
6 #include "spdk/stdinc.h"
7 
8 #include "common/lib/ut_multithread.c"
9 #include "spdk_internal/cunit.h"
10 #include "spdk/nvmf.h"
11 #include "spdk_internal/mock.h"
12 
13 #include "spdk/bdev_module.h"
14 #include "nvmf/subsystem.c"
15 #include "nvmf/transport.c"
16 
17 SPDK_LOG_REGISTER_COMPONENT(nvmf)
18 
19 DEFINE_STUB(spdk_bdev_module_claim_bdev,
20 	    int,
21 	    (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc,
22 	     struct spdk_bdev_module *module), 0);
23 
24 DEFINE_STUB_V(spdk_bdev_module_release_bdev,
25 	      (struct spdk_bdev *bdev));
26 
27 DEFINE_STUB(spdk_bdev_get_block_size, uint32_t,
28 	    (const struct spdk_bdev *bdev), 512);
29 
30 DEFINE_STUB(spdk_bdev_get_md_size, uint32_t,
31 	    (const struct spdk_bdev *bdev), 0);
32 
33 DEFINE_STUB(spdk_bdev_is_md_interleaved, bool,
34 	    (const struct spdk_bdev *bdev), false);
35 
36 DEFINE_STUB(spdk_bdev_io_type_supported, bool,
37 	    (struct spdk_bdev *bdev,
38 	     enum spdk_bdev_io_type io_type), false);
39 
40 DEFINE_STUB_V(nvmf_update_discovery_log,
41 	      (struct spdk_nvmf_tgt *tgt, const char *hostnqn));
42 
43 DEFINE_STUB(spdk_nvmf_qpair_disconnect,
44 	    int,
45 	    (struct spdk_nvmf_qpair *qpair,
46 	     nvmf_qpair_disconnect_cb cb_fn, void *ctx), 0);
47 
48 DEFINE_STUB(spdk_nvmf_request_complete,
49 	    int,
50 	    (struct spdk_nvmf_request *req), 0);
51 
52 DEFINE_STUB(nvmf_ctrlr_async_event_ana_change_notice,
53 	    int,
54 	    (struct spdk_nvmf_ctrlr *ctrlr), 0);
55 
56 DEFINE_STUB(spdk_nvme_transport_id_trtype_str,
57 	    const char *,
58 	    (enum spdk_nvme_transport_type trtype), NULL);
59 
60 DEFINE_STUB(spdk_bdev_is_zoned, bool,
61 	    (const struct spdk_bdev *bdev), false);
62 
63 DEFINE_STUB(spdk_bdev_get_max_zone_append_size, uint32_t,
64 	    (const struct spdk_bdev *bdev), 0);
65 
66 DEFINE_STUB(spdk_mempool_lookup, struct spdk_mempool *,
67 	    (const char *name), NULL);
68 
69 DEFINE_STUB(spdk_nvme_transport_id_adrfam_str, const char *,
70 	    (enum spdk_nvmf_adrfam adrfam), NULL);
71 
72 DEFINE_STUB(spdk_nvmf_qpair_get_listen_trid, int,
73 	    (struct spdk_nvmf_qpair *qpair,
74 	     struct spdk_nvme_transport_id *trid), 0);
75 
76 static struct spdk_nvmf_transport g_transport = {};
77 
78 struct spdk_nvmf_subsystem *
79 spdk_nvmf_tgt_find_subsystem(struct spdk_nvmf_tgt *tgt, const char *subnqn)
80 {
81 	return NULL;
82 }
83 
84 struct spdk_nvmf_transport *
85 spdk_nvmf_tgt_get_transport(struct spdk_nvmf_tgt *tgt, const char *transport_name)
86 {
87 	if (strncmp(transport_name, SPDK_NVME_TRANSPORT_NAME_RDMA, SPDK_NVMF_TRSTRING_MAX_LEN)) {
88 		return &g_transport;
89 	}
90 
91 	return NULL;
92 }
93 
94 int
95 nvmf_poll_group_update_subsystem(struct spdk_nvmf_poll_group *group,
96 				 struct spdk_nvmf_subsystem *subsystem)
97 {
98 	return 0;
99 }
100 
101 int
102 nvmf_poll_group_add_subsystem(struct spdk_nvmf_poll_group *group,
103 			      struct spdk_nvmf_subsystem *subsystem,
104 			      spdk_nvmf_poll_group_mod_done cb_fn, void *cb_arg)
105 {
106 	return 0;
107 }
108 
109 void
110 nvmf_poll_group_remove_subsystem(struct spdk_nvmf_poll_group *group,
111 				 struct spdk_nvmf_subsystem *subsystem,
112 				 spdk_nvmf_poll_group_mod_done cb_fn, void *cb_arg)
113 {
114 }
115 
116 void
117 nvmf_poll_group_pause_subsystem(struct spdk_nvmf_poll_group *group,
118 				struct spdk_nvmf_subsystem *subsystem,
119 				uint32_t nsid,
120 				spdk_nvmf_poll_group_mod_done cb_fn, void *cb_arg)
121 {
122 }
123 
124 void
125 nvmf_poll_group_resume_subsystem(struct spdk_nvmf_poll_group *group,
126 				 struct spdk_nvmf_subsystem *subsystem,
127 				 spdk_nvmf_poll_group_mod_done cb_fn, void *cb_arg)
128 {
129 }
130 
131 int
132 spdk_nvme_transport_id_parse_trtype(enum spdk_nvme_transport_type *trtype, const char *str)
133 {
134 	if (trtype == NULL || str == NULL) {
135 		return -EINVAL;
136 	}
137 
138 	if (strcasecmp(str, "PCIe") == 0) {
139 		*trtype = SPDK_NVME_TRANSPORT_PCIE;
140 	} else if (strcasecmp(str, "RDMA") == 0) {
141 		*trtype = SPDK_NVME_TRANSPORT_RDMA;
142 	} else {
143 		return -ENOENT;
144 	}
145 	return 0;
146 }
147 
148 int
149 spdk_nvme_transport_id_compare(const struct spdk_nvme_transport_id *trid1,
150 			       const struct spdk_nvme_transport_id *trid2)
151 {
152 	return 0;
153 }
154 
155 int32_t
156 spdk_nvme_ctrlr_process_admin_completions(struct spdk_nvme_ctrlr *ctrlr)
157 {
158 	return -1;
159 }
160 
161 int32_t
162 spdk_nvme_qpair_process_completions(struct spdk_nvme_qpair *qpair, uint32_t max_completions)
163 {
164 	return -1;
165 }
166 
167 int
168 spdk_nvme_detach(struct spdk_nvme_ctrlr *ctrlr)
169 {
170 	return -1;
171 }
172 
173 void
174 nvmf_ctrlr_destruct(struct spdk_nvmf_ctrlr *ctrlr)
175 {
176 }
177 
178 static struct spdk_nvmf_ctrlr *g_ns_changed_ctrlr = NULL;
179 static uint32_t g_ns_changed_nsid = 0;
180 void
181 nvmf_ctrlr_ns_changed(struct spdk_nvmf_ctrlr *ctrlr, uint32_t nsid)
182 {
183 	g_ns_changed_ctrlr = ctrlr;
184 	g_ns_changed_nsid = nsid;
185 }
186 
187 
188 static struct spdk_nvmf_ctrlr *g_async_event_ctrlr = NULL;
189 int
190 nvmf_ctrlr_async_event_ns_notice(struct spdk_nvmf_ctrlr *ctrlr)
191 {
192 	g_async_event_ctrlr = ctrlr;
193 	return 0;
194 }
195 
196 static struct spdk_bdev g_bdevs[] = {
197 	{ .name = "bdev1" },
198 	{ .name = "bdev2" },
199 };
200 
201 struct spdk_bdev_desc {
202 	struct spdk_bdev	*bdev;
203 };
204 
205 int
206 spdk_bdev_open_ext(const char *bdev_name, bool write, spdk_bdev_event_cb_t event_cb,
207 		   void *event_ctx, struct spdk_bdev_desc **_desc)
208 {
209 	struct spdk_bdev_desc *desc;
210 	size_t i;
211 
212 	for (i = 0; i < sizeof(g_bdevs); i++) {
213 		if (strcmp(bdev_name, g_bdevs[i].name) == 0) {
214 
215 			desc = calloc(1, sizeof(*desc));
216 			SPDK_CU_ASSERT_FATAL(desc != NULL);
217 
218 			desc->bdev = &g_bdevs[i];
219 			*_desc = desc;
220 			return 0;
221 		}
222 	}
223 
224 	return -EINVAL;
225 }
226 
227 void
228 spdk_bdev_close(struct spdk_bdev_desc *desc)
229 {
230 	free(desc);
231 }
232 
233 struct spdk_bdev *
234 spdk_bdev_desc_get_bdev(struct spdk_bdev_desc *desc)
235 {
236 	return desc->bdev;
237 }
238 
239 const char *
240 spdk_bdev_get_name(const struct spdk_bdev *bdev)
241 {
242 	return "test";
243 }
244 
245 const struct spdk_uuid *
246 spdk_bdev_get_uuid(const struct spdk_bdev *bdev)
247 {
248 	return &bdev->uuid;
249 }
250 
251 static void
252 test_spdk_nvmf_subsystem_add_ns(void)
253 {
254 	struct spdk_nvmf_tgt tgt = {};
255 	struct spdk_nvmf_subsystem subsystem = {
256 		.max_nsid = 1024,
257 		.ns = NULL,
258 		.tgt = &tgt,
259 	};
260 	struct spdk_nvmf_ns_opts ns_opts;
261 	uint32_t nsid;
262 	int rc;
263 
264 	subsystem.ns = calloc(subsystem.max_nsid, sizeof(struct spdk_nvmf_subsystem_ns *));
265 	SPDK_CU_ASSERT_FATAL(subsystem.ns != NULL);
266 	subsystem.ana_group = calloc(subsystem.max_nsid, sizeof(uint32_t));
267 	SPDK_CU_ASSERT_FATAL(subsystem.ana_group != NULL);
268 
269 	tgt.max_subsystems = 1024;
270 	RB_INIT(&tgt.subsystems);
271 
272 	/* Request a specific NSID */
273 	spdk_nvmf_ns_opts_get_defaults(&ns_opts, sizeof(ns_opts));
274 	ns_opts.nsid = 5;
275 	nsid = spdk_nvmf_subsystem_add_ns_ext(&subsystem, "bdev2", &ns_opts, sizeof(ns_opts), NULL);
276 	CU_ASSERT(nsid == 5);
277 	CU_ASSERT(subsystem.max_nsid == 1024);
278 	SPDK_CU_ASSERT_FATAL(subsystem.ns[nsid - 1] != NULL);
279 	CU_ASSERT(subsystem.ns[nsid - 1]->bdev == &g_bdevs[1]);
280 
281 	/* Request an NSID that is already in use */
282 	spdk_nvmf_ns_opts_get_defaults(&ns_opts, sizeof(ns_opts));
283 	ns_opts.nsid = 5;
284 	nsid = spdk_nvmf_subsystem_add_ns_ext(&subsystem, "bdev2", &ns_opts, sizeof(ns_opts), NULL);
285 	CU_ASSERT(nsid == 0);
286 	CU_ASSERT(subsystem.max_nsid == 1024);
287 
288 	/* Request 0xFFFFFFFF (invalid NSID, reserved for broadcast) */
289 	spdk_nvmf_ns_opts_get_defaults(&ns_opts, sizeof(ns_opts));
290 	ns_opts.nsid = 0xFFFFFFFF;
291 	nsid = spdk_nvmf_subsystem_add_ns_ext(&subsystem, "bdev2", &ns_opts, sizeof(ns_opts), NULL);
292 	CU_ASSERT(nsid == 0);
293 	CU_ASSERT(subsystem.max_nsid == 1024);
294 
295 	rc = spdk_nvmf_subsystem_remove_ns(&subsystem, 5);
296 	CU_ASSERT(rc == 0);
297 
298 	free(subsystem.ns);
299 	free(subsystem.ana_group);
300 }
301 
302 static void
303 nvmf_test_create_subsystem(void)
304 {
305 	struct spdk_nvmf_tgt tgt = {};
306 	char nqn[256];
307 	struct spdk_nvmf_subsystem *subsystem;
308 	int rc;
309 
310 	tgt.max_subsystems = 1024;
311 	tgt.subsystem_ids = spdk_bit_array_create(tgt.max_subsystems);
312 	RB_INIT(&tgt.subsystems);
313 
314 	snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk:subsystem1");
315 	subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0);
316 	SPDK_CU_ASSERT_FATAL(subsystem != NULL);
317 	CU_ASSERT_STRING_EQUAL(subsystem->subnqn, nqn);
318 	rc = spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL);
319 	CU_ASSERT(rc == 0);
320 
321 	/* valid name with complex reverse domain */
322 	snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk-full--rev-domain.name:subsystem1");
323 	subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0);
324 	SPDK_CU_ASSERT_FATAL(subsystem != NULL);
325 	CU_ASSERT_STRING_EQUAL(subsystem->subnqn, nqn);
326 	rc = spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL);
327 	CU_ASSERT(rc == 0);
328 
329 	/* Valid name discovery controller */
330 	snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk:subsystem1");
331 	subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0);
332 	SPDK_CU_ASSERT_FATAL(subsystem != NULL);
333 	CU_ASSERT_STRING_EQUAL(subsystem->subnqn, nqn);
334 	rc = spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL);
335 	CU_ASSERT(rc == 0);
336 
337 	/* Invalid name, no user supplied string */
338 	snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk:");
339 	subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0);
340 	SPDK_CU_ASSERT_FATAL(subsystem == NULL);
341 
342 	/* Valid name, only contains top-level domain name */
343 	snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk:subsystem1");
344 	subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0);
345 	SPDK_CU_ASSERT_FATAL(subsystem != NULL);
346 	CU_ASSERT_STRING_EQUAL(subsystem->subnqn, nqn);
347 	rc = spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL);
348 	CU_ASSERT(rc == 0);
349 
350 	/* Invalid name, domain label > 63 characters */
351 	snprintf(nqn, sizeof(nqn),
352 		 "nqn.2016-06.io.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz:sub");
353 	subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0);
354 	SPDK_CU_ASSERT_FATAL(subsystem == NULL);
355 
356 	/* Invalid name, domain label starts with digit */
357 	snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.3spdk:sub");
358 	subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0);
359 	SPDK_CU_ASSERT_FATAL(subsystem == NULL);
360 
361 	/* Invalid name, domain label starts with - */
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 
366 	/* Invalid name, domain label ends with - */
367 	snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk-:subsystem1");
368 	subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0);
369 	SPDK_CU_ASSERT_FATAL(subsystem == NULL);
370 
371 	/* Invalid name, domain label with multiple consecutive periods */
372 	snprintf(nqn, sizeof(nqn), "nqn.2016-06.io..spdk:subsystem1");
373 	subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0);
374 	SPDK_CU_ASSERT_FATAL(subsystem == NULL);
375 
376 	/* Longest valid name */
377 	snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk:");
378 	memset(nqn + strlen(nqn), 'a', 223 - strlen(nqn));
379 	nqn[223] = '\0';
380 	CU_ASSERT(strlen(nqn) == 223);
381 	subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0);
382 	SPDK_CU_ASSERT_FATAL(subsystem != NULL);
383 	CU_ASSERT_STRING_EQUAL(subsystem->subnqn, nqn);
384 	rc = spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL);
385 	CU_ASSERT(rc == 0);
386 
387 	/* Invalid name, too long */
388 	snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk:");
389 	memset(nqn + strlen(nqn), 'a', 224 - strlen(nqn));
390 	nqn[224] = '\0';
391 	CU_ASSERT(strlen(nqn) == 224);
392 	subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0);
393 	CU_ASSERT(subsystem == NULL);
394 
395 	/* Valid name using uuid format */
396 	snprintf(nqn, sizeof(nqn), "nqn.2014-08.org.nvmexpress:uuid:ff9b6406-0fc8-4779-80ca-4dca14bda0d2");
397 	subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0);
398 	SPDK_CU_ASSERT_FATAL(subsystem != NULL);
399 	CU_ASSERT_STRING_EQUAL(subsystem->subnqn, nqn);
400 	rc = spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL);
401 	CU_ASSERT(rc == 0);
402 
403 	/* Invalid name user string contains an invalid utf-8 character */
404 	snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk:\xFFsubsystem1");
405 	subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0);
406 	SPDK_CU_ASSERT_FATAL(subsystem == NULL);
407 
408 	/* Valid name with non-ascii but valid utf-8 characters */
409 	snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk:\xe1\x8a\x88subsystem1\xca\x80");
410 	subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0);
411 	SPDK_CU_ASSERT_FATAL(subsystem != NULL);
412 	CU_ASSERT_STRING_EQUAL(subsystem->subnqn, nqn);
413 	rc = spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL);
414 	CU_ASSERT(rc == 0);
415 
416 	/* Invalid uuid (too long) */
417 	snprintf(nqn, sizeof(nqn),
418 		 "nqn.2014-08.org.nvmexpress:uuid:ff9b6406-0fc8-4779-80ca-4dca14bda0d2aaaa");
419 	subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0);
420 	SPDK_CU_ASSERT_FATAL(subsystem == NULL);
421 
422 	/* Invalid uuid (dashes placed incorrectly) */
423 	snprintf(nqn, sizeof(nqn), "nqn.2014-08.org.nvmexpress:uuid:ff9b64-060fc8-4779-80ca-4dca14bda0d2");
424 	subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0);
425 	SPDK_CU_ASSERT_FATAL(subsystem == NULL);
426 
427 	/* Invalid uuid (invalid characters in uuid) */
428 	snprintf(nqn, sizeof(nqn), "nqn.2014-08.org.nvmexpress:uuid:ff9hg406-0fc8-4779-80ca-4dca14bda0d2");
429 	subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0);
430 	SPDK_CU_ASSERT_FATAL(subsystem == NULL);
431 
432 	spdk_bit_array_free(&tgt.subsystem_ids);
433 }
434 
435 static void
436 test_spdk_nvmf_subsystem_set_sn(void)
437 {
438 	struct spdk_nvmf_subsystem subsystem = {};
439 
440 	/* Basic valid serial number */
441 	CU_ASSERT(spdk_nvmf_subsystem_set_sn(&subsystem, "abcd xyz") == 0);
442 	CU_ASSERT(strcmp(subsystem.sn, "abcd xyz") == 0);
443 
444 	/* Exactly 20 characters (valid) */
445 	CU_ASSERT(spdk_nvmf_subsystem_set_sn(&subsystem, "12345678901234567890") == 0);
446 	CU_ASSERT(strcmp(subsystem.sn, "12345678901234567890") == 0);
447 
448 	/* 21 characters (too long, invalid) */
449 	CU_ASSERT(spdk_nvmf_subsystem_set_sn(&subsystem, "123456789012345678901") < 0);
450 
451 	/* Non-ASCII characters (invalid) */
452 	CU_ASSERT(spdk_nvmf_subsystem_set_sn(&subsystem, "abcd\txyz") < 0);
453 }
454 
455 static void
456 test_spdk_nvmf_ns_visible(void)
457 {
458 	struct spdk_nvmf_subsystem subsystem = {};
459 	struct spdk_nvmf_ns ns1 = {
460 		.nsid = 1,
461 		.anagrpid = 1,
462 		.always_visible = false
463 	};
464 	struct spdk_nvmf_ns ns2 = {
465 		.nsid = 2,
466 		.anagrpid = 2,
467 		.always_visible = false
468 	};
469 	struct spdk_nvmf_ns *ns3;
470 	struct spdk_nvmf_ctrlr ctrlrA = {
471 		.subsys = &subsystem
472 	};
473 	struct spdk_nvmf_ctrlr ctrlrB = {
474 		.subsys = &subsystem
475 	};
476 	struct spdk_thread *thread;
477 	struct spdk_nvmf_tgt tgt = {};
478 	uint32_t nsid;
479 	int rc;
480 
481 	thread = spdk_get_thread();
482 	SPDK_CU_ASSERT_FATAL(thread != NULL);
483 	ctrlrA.thread = thread;
484 	ctrlrB.thread = thread;
485 
486 	subsystem.max_nsid = 1024;
487 	subsystem.ns = calloc(subsystem.max_nsid, sizeof(subsystem.ns));
488 	SPDK_CU_ASSERT_FATAL(subsystem.ns != NULL);
489 	subsystem.ana_group = calloc(subsystem.max_nsid, sizeof(uint32_t));
490 	SPDK_CU_ASSERT_FATAL(subsystem.ana_group != NULL);
491 	TAILQ_INIT(&tgt.transports);
492 	subsystem.tgt = &tgt;
493 
494 	subsystem.ns[1] = &ns1;
495 	subsystem.ns[2] = &ns2;
496 	ns3 = calloc(1, sizeof(*ns3));
497 	SPDK_CU_ASSERT_FATAL(ns3 != NULL);
498 	ns3->nsid = 3;
499 	ns3->anagrpid = 3;
500 	subsystem.ana_group[ns3->anagrpid - 1] = 1;
501 	subsystem.ns[3] = ns3;
502 
503 	snprintf(ctrlrA.hostnqn, sizeof(ctrlrA.hostnqn), "nqn.2016-06.io.spdk:host1");
504 	ctrlrA.visible_ns = spdk_bit_array_create(subsystem.max_nsid);
505 	SPDK_CU_ASSERT_FATAL(ctrlrA.visible_ns != NULL);
506 	snprintf(ctrlrB.hostnqn, sizeof(ctrlrB.hostnqn), "nqn.2016-06.io.spdk:host2");
507 	ctrlrB.visible_ns = spdk_bit_array_create(subsystem.max_nsid);
508 	SPDK_CU_ASSERT_FATAL(ctrlrB.visible_ns != NULL);
509 
510 	/* Add two controllers ctrlrA and ctrlrB */
511 	TAILQ_INIT(&subsystem.ctrlrs);
512 	TAILQ_INSERT_TAIL(&subsystem.ctrlrs, &ctrlrA, link);
513 	TAILQ_INSERT_TAIL(&subsystem.ctrlrs, &ctrlrB, link);
514 
515 	/* Invalid host nqn */
516 	nsid = 1;
517 	rc = spdk_nvmf_ns_add_host(&subsystem, nsid, "", 0);
518 	CU_ASSERT(rc == -EINVAL);
519 	rc = spdk_nvmf_ns_add_host(&subsystem, nsid, NULL, 0);
520 	CU_ASSERT(rc == -EINVAL);
521 	rc = spdk_nvmf_ns_remove_host(&subsystem, nsid, NULL, 0);
522 	CU_ASSERT(rc == -EINVAL);
523 
524 	/* Invalid nsid */
525 	nsid = 0;
526 	rc = spdk_nvmf_ns_add_host(&subsystem, nsid, ctrlrA.hostnqn, 0);
527 	CU_ASSERT(rc == -EINVAL);
528 	rc = spdk_nvmf_ns_remove_host(&subsystem, nsid, ctrlrA.hostnqn, 0);
529 	CU_ASSERT(rc == -EINVAL);
530 
531 	/* Unallocated ns */
532 	nsid = 1;
533 	rc = spdk_nvmf_ns_add_host(&subsystem, nsid, ctrlrA.hostnqn, 0);
534 	CU_ASSERT(rc == -ENOENT);
535 	rc = spdk_nvmf_ns_remove_host(&subsystem, nsid, ctrlrA.hostnqn, 0);
536 	CU_ASSERT(rc == -ENOENT);
537 
538 	/* Attach any is active => do not allow individual host control */
539 	ns1.always_visible = true;
540 	nsid = 2;
541 	rc = spdk_nvmf_ns_add_host(&subsystem, nsid, ctrlrA.hostnqn, 0);
542 	CU_ASSERT(rc == -EPERM);
543 	rc = spdk_nvmf_ns_remove_host(&subsystem, nsid, ctrlrA.hostnqn, 0);
544 	CU_ASSERT(rc == -EPERM);
545 	ns1.always_visible = false;
546 
547 	/* Attach ctrlrA to namespace 2 hot + cold */
548 	nsid = 2;
549 	g_async_event_ctrlr = NULL;
550 	g_ns_changed_ctrlr = NULL;
551 	g_ns_changed_nsid = 0;
552 	rc = spdk_nvmf_ns_add_host(&subsystem, nsid, ctrlrA.hostnqn, 0);
553 	CU_ASSERT(rc == 0);
554 	CU_ASSERT(nvmf_ns_find_host(&ns1, ctrlrA.hostnqn) != NULL);
555 	CU_ASSERT(nvmf_ns_find_host(&ns1, ctrlrB.hostnqn) == NULL);
556 	CU_ASSERT(nvmf_ns_find_host(&ns2, ctrlrA.hostnqn) == NULL);
557 	CU_ASSERT(nvmf_ns_find_host(&ns2, ctrlrB.hostnqn) == NULL);
558 	CU_ASSERT(spdk_bit_array_get(ctrlrA.visible_ns, nsid - 1));
559 	CU_ASSERT(!spdk_bit_array_get(ctrlrB.visible_ns, nsid - 1));
560 	CU_ASSERT(!spdk_bit_array_get(ctrlrA.visible_ns, nsid));
561 	CU_ASSERT(!spdk_bit_array_get(ctrlrB.visible_ns, nsid));
562 	/* check last ns_changed */
563 	CU_ASSERT(g_ns_changed_ctrlr == &ctrlrA);
564 	CU_ASSERT(g_ns_changed_nsid == nsid);
565 	/* check async_event */
566 	poll_threads();
567 	CU_ASSERT(g_async_event_ctrlr == &ctrlrA);
568 
569 	/* Attach ctrlrA to namespace 2 again => should not create any ns change/async event */
570 	g_async_event_ctrlr = NULL;
571 	g_ns_changed_ctrlr = NULL;
572 	g_ns_changed_nsid = 0;
573 	rc = spdk_nvmf_ns_add_host(&subsystem, nsid, ctrlrA.hostnqn, 0);
574 	CU_ASSERT(rc == 0);
575 	CU_ASSERT(nvmf_ns_find_host(&ns1, ctrlrA.hostnqn) != NULL);
576 	CU_ASSERT(nvmf_ns_find_host(&ns1, ctrlrB.hostnqn) == NULL);
577 	CU_ASSERT(nvmf_ns_find_host(&ns2, ctrlrA.hostnqn) == NULL);
578 	CU_ASSERT(nvmf_ns_find_host(&ns2, ctrlrB.hostnqn) == NULL);
579 	CU_ASSERT(spdk_bit_array_get(ctrlrA.visible_ns, nsid - 1));
580 	CU_ASSERT(!spdk_bit_array_get(ctrlrB.visible_ns, nsid - 1));
581 	CU_ASSERT(!spdk_bit_array_get(ctrlrA.visible_ns, nsid));
582 	CU_ASSERT(!spdk_bit_array_get(ctrlrB.visible_ns, nsid));
583 	/* check last ns_changed */
584 	CU_ASSERT(g_ns_changed_ctrlr == NULL);
585 	CU_ASSERT(g_ns_changed_nsid == 0);
586 	/* check async_event */
587 	poll_threads();
588 	CU_ASSERT(g_async_event_ctrlr == NULL);
589 
590 	/* Detach ctrlrA from namespace 2 hot + cold */
591 	g_async_event_ctrlr = NULL;
592 	g_ns_changed_ctrlr = NULL;
593 	g_ns_changed_nsid = 0;
594 	rc = spdk_nvmf_ns_remove_host(&subsystem, nsid, ctrlrA.hostnqn, 0);
595 	CU_ASSERT(rc == 0);
596 	CU_ASSERT(nvmf_ns_find_host(&ns1, ctrlrA.hostnqn) == NULL);
597 	CU_ASSERT(nvmf_ns_find_host(&ns1, ctrlrB.hostnqn) == NULL);
598 	CU_ASSERT(nvmf_ns_find_host(&ns2, ctrlrA.hostnqn) == NULL);
599 	CU_ASSERT(nvmf_ns_find_host(&ns2, ctrlrB.hostnqn) == NULL);
600 	CU_ASSERT(!spdk_bit_array_get(ctrlrA.visible_ns, nsid - 1));
601 	CU_ASSERT(!spdk_bit_array_get(ctrlrB.visible_ns, nsid - 1));
602 	CU_ASSERT(!spdk_bit_array_get(ctrlrA.visible_ns, nsid));
603 	CU_ASSERT(!spdk_bit_array_get(ctrlrB.visible_ns, nsid));
604 	/* check last ns_changed */
605 	CU_ASSERT(g_ns_changed_ctrlr == &ctrlrA);
606 	CU_ASSERT(g_ns_changed_nsid == nsid);
607 	/* check async_event */
608 	poll_threads();
609 	CU_ASSERT(g_async_event_ctrlr == &ctrlrA);
610 
611 	/* Detach ctrlrA from namespace 2 again hot + cold */
612 	g_async_event_ctrlr = NULL;
613 	g_ns_changed_ctrlr = NULL;
614 	g_ns_changed_nsid = 0;
615 	rc = spdk_nvmf_ns_remove_host(&subsystem, nsid, ctrlrA.hostnqn, 0);
616 	CU_ASSERT(rc == 0);
617 	CU_ASSERT(nvmf_ns_find_host(&ns1, ctrlrA.hostnqn) == NULL);
618 	CU_ASSERT(nvmf_ns_find_host(&ns1, ctrlrB.hostnqn) == NULL);
619 	CU_ASSERT(nvmf_ns_find_host(&ns2, ctrlrA.hostnqn) == NULL);
620 	CU_ASSERT(nvmf_ns_find_host(&ns2, ctrlrB.hostnqn) == NULL);
621 	CU_ASSERT(!spdk_bit_array_get(ctrlrA.visible_ns, nsid - 1));
622 	CU_ASSERT(!spdk_bit_array_get(ctrlrB.visible_ns, nsid - 1));
623 	CU_ASSERT(!spdk_bit_array_get(ctrlrA.visible_ns, nsid));
624 	CU_ASSERT(!spdk_bit_array_get(ctrlrB.visible_ns, nsid));
625 	/* check last ns_changed */
626 	CU_ASSERT(g_ns_changed_ctrlr == NULL);
627 	CU_ASSERT(g_ns_changed_nsid == 0);
628 	/* check async_event */
629 	poll_threads();
630 	CU_ASSERT(g_async_event_ctrlr == NULL);
631 
632 	/* Attach ctrlrA to namespace 4 hot + cold => remove ns */
633 	nsid = 4;
634 	g_async_event_ctrlr = NULL;
635 	g_ns_changed_ctrlr = NULL;
636 	g_ns_changed_nsid = 0;
637 	rc = spdk_nvmf_ns_add_host(&subsystem, nsid, ctrlrA.hostnqn, 0);
638 	CU_ASSERT(rc == 0);
639 	CU_ASSERT(nvmf_ns_find_host(ns3, ctrlrA.hostnqn) != NULL);
640 	CU_ASSERT(nvmf_ns_find_host(ns3, ctrlrB.hostnqn) == NULL);
641 	CU_ASSERT(spdk_bit_array_get(ctrlrA.visible_ns, nsid - 1));
642 	CU_ASSERT(!spdk_bit_array_get(ctrlrB.visible_ns, nsid - 1));
643 	/* check last ns_changed */
644 	CU_ASSERT(g_ns_changed_ctrlr == &ctrlrA);
645 	CU_ASSERT(g_ns_changed_nsid == nsid);
646 	/* check async_event */
647 	poll_threads();
648 	CU_ASSERT(g_async_event_ctrlr == &ctrlrA);
649 
650 	g_async_event_ctrlr = NULL;
651 	g_ns_changed_ctrlr = NULL;
652 	g_ns_changed_nsid = 0;
653 	rc = spdk_nvmf_subsystem_remove_ns(&subsystem, nsid);
654 	CU_ASSERT(rc == 0);
655 	CU_ASSERT(!spdk_bit_array_get(ctrlrA.visible_ns, nsid - 1));
656 	CU_ASSERT(!spdk_bit_array_get(ctrlrB.visible_ns, nsid - 1));
657 	/* check last ns_changed */
658 	CU_ASSERT(g_ns_changed_ctrlr == &ctrlrA);
659 	CU_ASSERT(g_ns_changed_nsid == nsid);
660 
661 	free(ctrlrA.visible_ns);
662 	free(ctrlrB.visible_ns);
663 	free(subsystem.ana_group);
664 	free(subsystem.ns);
665 }
666 
667 /*
668  * Reservation Unit Test Configuration
669  *       --------             --------    --------
670  *      | Host A |           | Host B |  | Host C |
671  *       --------             --------    --------
672  *      /        \               |           |
673  *  --------   --------       -------     -------
674  * |Ctrlr1_A| |Ctrlr2_A|     |Ctrlr_B|   |Ctrlr_C|
675  *  --------   --------       -------     -------
676  *    \           \              /           /
677  *     \           \            /           /
678  *      \           \          /           /
679  *      --------------------------------------
680  *     |            NAMESPACE 1               |
681  *      --------------------------------------
682  */
683 static struct spdk_nvmf_subsystem g_subsystem;
684 static struct spdk_nvmf_ctrlr g_ctrlr1_A, g_ctrlr2_A, g_ctrlr_B, g_ctrlr_C;
685 static struct spdk_nvmf_ns g_ns;
686 struct spdk_nvmf_subsystem_pg_ns_info g_ns_info;
687 
688 void
689 nvmf_ctrlr_async_event_reservation_notification(struct spdk_nvmf_ctrlr *ctrlr)
690 {
691 }
692 
693 static void
694 ut_reservation_init(void)
695 {
696 
697 	TAILQ_INIT(&g_subsystem.ctrlrs);
698 
699 	memset(&g_ns, 0, sizeof(g_ns));
700 	TAILQ_INIT(&g_ns.registrants);
701 	g_ns.subsystem = &g_subsystem;
702 	g_ns.ptpl_file = NULL;
703 	g_ns.ptpl_activated = false;
704 	spdk_uuid_generate(&g_bdevs[0].uuid);
705 	g_ns.bdev = &g_bdevs[0];
706 
707 	/* Host A has two controllers */
708 	spdk_uuid_generate(&g_ctrlr1_A.hostid);
709 	TAILQ_INIT(&g_ctrlr1_A.log_head);
710 	g_ctrlr1_A.subsys = &g_subsystem;
711 	g_ctrlr1_A.num_avail_log_pages = 0;
712 	TAILQ_INSERT_TAIL(&g_subsystem.ctrlrs, &g_ctrlr1_A, link);
713 	spdk_uuid_copy(&g_ctrlr2_A.hostid, &g_ctrlr1_A.hostid);
714 	TAILQ_INIT(&g_ctrlr2_A.log_head);
715 	g_ctrlr2_A.subsys = &g_subsystem;
716 	g_ctrlr2_A.num_avail_log_pages = 0;
717 	TAILQ_INSERT_TAIL(&g_subsystem.ctrlrs, &g_ctrlr2_A, link);
718 
719 	/* Host B has 1 controller */
720 	spdk_uuid_generate(&g_ctrlr_B.hostid);
721 	TAILQ_INIT(&g_ctrlr_B.log_head);
722 	g_ctrlr_B.subsys = &g_subsystem;
723 	g_ctrlr_B.num_avail_log_pages = 0;
724 	TAILQ_INSERT_TAIL(&g_subsystem.ctrlrs, &g_ctrlr_B, link);
725 
726 	/* Host C has 1 controller */
727 	spdk_uuid_generate(&g_ctrlr_C.hostid);
728 	TAILQ_INIT(&g_ctrlr_C.log_head);
729 	g_ctrlr_C.subsys = &g_subsystem;
730 	g_ctrlr_C.num_avail_log_pages = 0;
731 	TAILQ_INSERT_TAIL(&g_subsystem.ctrlrs, &g_ctrlr_C, link);
732 }
733 
734 static void
735 ut_reservation_deinit(void)
736 {
737 	struct spdk_nvmf_registrant *reg, *tmp;
738 	struct spdk_nvmf_reservation_log *log, *log_tmp;
739 	struct spdk_nvmf_ctrlr *ctrlr, *ctrlr_tmp;
740 
741 	TAILQ_FOREACH_SAFE(reg, &g_ns.registrants, link, tmp) {
742 		TAILQ_REMOVE(&g_ns.registrants, reg, link);
743 		free(reg);
744 	}
745 	TAILQ_FOREACH_SAFE(log, &g_ctrlr1_A.log_head, link, log_tmp) {
746 		TAILQ_REMOVE(&g_ctrlr1_A.log_head, log, link);
747 		free(log);
748 	}
749 	g_ctrlr1_A.num_avail_log_pages = 0;
750 	TAILQ_FOREACH_SAFE(log, &g_ctrlr2_A.log_head, link, log_tmp) {
751 		TAILQ_REMOVE(&g_ctrlr2_A.log_head, log, link);
752 		free(log);
753 	}
754 	g_ctrlr2_A.num_avail_log_pages = 0;
755 	TAILQ_FOREACH_SAFE(log, &g_ctrlr_B.log_head, link, log_tmp) {
756 		TAILQ_REMOVE(&g_ctrlr_B.log_head, log, link);
757 		free(log);
758 	}
759 	g_ctrlr_B.num_avail_log_pages = 0;
760 	TAILQ_FOREACH_SAFE(log, &g_ctrlr_C.log_head, link, log_tmp) {
761 		TAILQ_REMOVE(&g_ctrlr_C.log_head, log, link);
762 		free(log);
763 	}
764 	g_ctrlr_C.num_avail_log_pages = 0;
765 
766 	TAILQ_FOREACH_SAFE(ctrlr, &g_subsystem.ctrlrs, link, ctrlr_tmp) {
767 		TAILQ_REMOVE(&g_subsystem.ctrlrs, ctrlr, link);
768 	}
769 }
770 
771 static struct spdk_nvmf_request *
772 ut_reservation_build_req(uint32_t length)
773 {
774 	struct spdk_nvmf_request *req;
775 
776 	req = calloc(1, sizeof(*req));
777 	assert(req != NULL);
778 
779 	SPDK_IOV_ONE(req->iov, &req->iovcnt, calloc(1, length), length);
780 	assert(req->iov[0].iov_base != NULL);
781 	req->length = length;
782 
783 	req->cmd = (union nvmf_h2c_msg *)calloc(1, sizeof(union nvmf_h2c_msg));
784 	assert(req->cmd != NULL);
785 
786 	req->rsp = (union nvmf_c2h_msg *)calloc(1, sizeof(union nvmf_c2h_msg));
787 	assert(req->rsp != NULL);
788 
789 	return req;
790 }
791 
792 static void
793 ut_reservation_free_req(struct spdk_nvmf_request *req)
794 {
795 	free(req->cmd);
796 	free(req->rsp);
797 	free(req->iov[0].iov_base);
798 	free(req);
799 }
800 
801 static void
802 ut_reservation_build_register_request(struct spdk_nvmf_request *req,
803 				      uint8_t rrega, uint8_t iekey,
804 				      uint8_t cptpl, uint64_t crkey,
805 				      uint64_t nrkey)
806 {
807 	struct spdk_nvme_reservation_register_data key;
808 	struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd;
809 
810 	key.crkey = crkey;
811 	key.nrkey = nrkey;
812 	cmd->cdw10 = 0;
813 	cmd->cdw10_bits.resv_register.rrega = rrega;
814 	cmd->cdw10_bits.resv_register.iekey = iekey;
815 	cmd->cdw10_bits.resv_register.cptpl = cptpl;
816 	memcpy(req->iov[0].iov_base, &key, sizeof(key));
817 }
818 
819 static void
820 ut_reservation_build_acquire_request(struct spdk_nvmf_request *req,
821 				     uint8_t racqa, uint8_t iekey,
822 				     uint8_t rtype, uint64_t crkey,
823 				     uint64_t prkey)
824 {
825 	struct spdk_nvme_reservation_acquire_data key;
826 	struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd;
827 
828 	key.crkey = crkey;
829 	key.prkey = prkey;
830 	cmd->cdw10 = 0;
831 	cmd->cdw10_bits.resv_acquire.racqa = racqa;
832 	cmd->cdw10_bits.resv_acquire.iekey = iekey;
833 	cmd->cdw10_bits.resv_acquire.rtype = rtype;
834 	memcpy(req->iov[0].iov_base, &key, sizeof(key));
835 }
836 
837 static void
838 ut_reservation_build_release_request(struct spdk_nvmf_request *req,
839 				     uint8_t rrela, uint8_t iekey,
840 				     uint8_t rtype, uint64_t crkey)
841 {
842 	struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd;
843 
844 	cmd->cdw10 = 0;
845 	cmd->cdw10_bits.resv_release.rrela = rrela;
846 	cmd->cdw10_bits.resv_release.iekey = iekey;
847 	cmd->cdw10_bits.resv_release.rtype = rtype;
848 	memcpy(req->iov[0].iov_base, &crkey, sizeof(crkey));
849 }
850 
851 /*
852  * Construct four registrants for other test cases.
853  *
854  * g_ctrlr1_A register with key 0xa1.
855  * g_ctrlr2_A register with key 0xa1.
856  * g_ctrlr_B register with key 0xb1.
857  * g_ctrlr_C register with key 0xc1.
858  * */
859 static void
860 ut_reservation_build_registrants(void)
861 {
862 	struct spdk_nvmf_request *req;
863 	struct spdk_nvme_cpl *rsp;
864 	struct spdk_nvmf_registrant *reg;
865 	uint32_t gen;
866 
867 	req = ut_reservation_build_req(16);
868 	rsp = &req->rsp->nvme_cpl;
869 	SPDK_CU_ASSERT_FATAL(req != NULL);
870 	gen = g_ns.gen;
871 
872 	/* TEST CASE: g_ctrlr1_A register with a new key */
873 	ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY,
874 					      0, 0, 0, 0xa1);
875 	nvmf_ns_reservation_register(&g_ns, &g_ctrlr1_A, req);
876 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
877 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid);
878 	SPDK_CU_ASSERT_FATAL(reg->rkey == 0xa1);
879 	SPDK_CU_ASSERT_FATAL(g_ns.gen == gen + 1);
880 
881 	/* TEST CASE: g_ctrlr2_A register with a new key, because it has same
882 	 * Host Identifier with g_ctrlr1_A, so the register key should same.
883 	 */
884 	ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY,
885 					      0, 0, 0, 0xa2);
886 	nvmf_ns_reservation_register(&g_ns, &g_ctrlr2_A, req);
887 	/* Reservation conflict for other key than 0xa1 */
888 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_RESERVATION_CONFLICT);
889 
890 	/* g_ctrlr_B register with a new key */
891 	ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY,
892 					      0, 0, 0, 0xb1);
893 	nvmf_ns_reservation_register(&g_ns, &g_ctrlr_B, req);
894 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
895 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_B.hostid);
896 	SPDK_CU_ASSERT_FATAL(reg->rkey == 0xb1);
897 	SPDK_CU_ASSERT_FATAL(g_ns.gen == gen + 2);
898 
899 	/* g_ctrlr_C register with a new key */
900 	ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY,
901 					      0, 0, 0, 0xc1);
902 	nvmf_ns_reservation_register(&g_ns, &g_ctrlr_C, req);
903 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
904 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_C.hostid);
905 	SPDK_CU_ASSERT_FATAL(reg->rkey == 0xc1);
906 	SPDK_CU_ASSERT_FATAL(g_ns.gen == gen + 3);
907 
908 	ut_reservation_free_req(req);
909 }
910 
911 static void
912 test_reservation_register(void)
913 {
914 	struct spdk_nvmf_request *req;
915 	struct spdk_nvme_cpl *rsp;
916 	struct spdk_nvmf_registrant *reg;
917 	uint32_t gen;
918 
919 	ut_reservation_init();
920 
921 	req = ut_reservation_build_req(16);
922 	rsp = &req->rsp->nvme_cpl;
923 	SPDK_CU_ASSERT_FATAL(req != NULL);
924 
925 	ut_reservation_build_registrants();
926 
927 	/* TEST CASE: Replace g_ctrlr1_A with a new key */
928 	ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REPLACE_KEY,
929 					      0, 0, 0xa1, 0xa11);
930 	nvmf_ns_reservation_register(&g_ns, &g_ctrlr1_A, req);
931 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
932 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid);
933 	SPDK_CU_ASSERT_FATAL(reg->rkey == 0xa11);
934 
935 	/* TEST CASE: Host A with g_ctrlr1_A get reservation with
936 	 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE
937 	 */
938 	ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0,
939 					     SPDK_NVME_RESERVE_WRITE_EXCLUSIVE, 0xa11, 0x0);
940 	gen = g_ns.gen;
941 	nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr1_A, req);
942 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
943 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid);
944 	SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE);
945 	SPDK_CU_ASSERT_FATAL(g_ns.crkey == 0xa11);
946 	SPDK_CU_ASSERT_FATAL(g_ns.holder == reg);
947 	SPDK_CU_ASSERT_FATAL(g_ns.gen == gen);
948 
949 	/* TEST CASE: g_ctrlr_C unregister with IEKEY enabled */
950 	ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_UNREGISTER_KEY,
951 					      1, 0, 0, 0);
952 	nvmf_ns_reservation_register(&g_ns, &g_ctrlr_C, req);
953 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
954 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_C.hostid);
955 	SPDK_CU_ASSERT_FATAL(reg == NULL);
956 
957 	/* TEST CASE: g_ctrlr_B unregister with correct key */
958 	ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_UNREGISTER_KEY,
959 					      0, 0, 0xb1, 0);
960 	nvmf_ns_reservation_register(&g_ns, &g_ctrlr_B, req);
961 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
962 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_B.hostid);
963 	SPDK_CU_ASSERT_FATAL(reg == NULL);
964 
965 	/* TEST CASE: No registrant now, g_ctrlr_B replace new key with IEKEY disabled */
966 	ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REPLACE_KEY,
967 					      0, 0, 0, 0xb1);
968 	nvmf_ns_reservation_register(&g_ns, &g_ctrlr_B, req);
969 	SPDK_CU_ASSERT_FATAL(rsp->status.sc != SPDK_NVME_SC_SUCCESS);
970 
971 	/* TEST CASE: No registrant now, g_ctrlr_B replace new key with IEKEY enabled */
972 	ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REPLACE_KEY,
973 					      1, 0, 0, 0xb1);
974 	nvmf_ns_reservation_register(&g_ns, &g_ctrlr_B, req);
975 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
976 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_B.hostid);
977 	SPDK_CU_ASSERT_FATAL(reg != NULL);
978 
979 	/* TEST CASE: g_ctrlr_B replace new key with IEKEY enabled and wrong crkey  */
980 	ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REPLACE_KEY,
981 					      1, 0, 0xff, 0xb2);
982 	nvmf_ns_reservation_register(&g_ns, &g_ctrlr_B, req);
983 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
984 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_B.hostid);
985 	SPDK_CU_ASSERT_FATAL(reg != NULL);
986 	SPDK_CU_ASSERT_FATAL(reg->rkey == 0xb2);
987 
988 	/* TEST CASE: g_ctrlr1_A unregister with correct key,
989 	 * reservation should be removed as well.
990 	 */
991 	ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_UNREGISTER_KEY,
992 					      0, 0, 0xa11, 0);
993 	nvmf_ns_reservation_register(&g_ns, &g_ctrlr1_A, req);
994 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
995 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid);
996 	SPDK_CU_ASSERT_FATAL(reg == NULL);
997 	SPDK_CU_ASSERT_FATAL(g_ns.rtype == 0);
998 	SPDK_CU_ASSERT_FATAL(g_ns.crkey == 0);
999 	SPDK_CU_ASSERT_FATAL(g_ns.holder == NULL);
1000 
1001 	ut_reservation_free_req(req);
1002 	ut_reservation_deinit();
1003 }
1004 
1005 static void
1006 test_reservation_register_with_ptpl(void)
1007 {
1008 	struct spdk_nvmf_request *req;
1009 	struct spdk_nvme_cpl *rsp;
1010 	struct spdk_nvmf_registrant *reg;
1011 	bool update_sgroup = false;
1012 	int rc;
1013 	struct spdk_nvmf_reservation_info info;
1014 
1015 	ut_reservation_init();
1016 
1017 	req = ut_reservation_build_req(16);
1018 	rsp = &req->rsp->nvme_cpl;
1019 	SPDK_CU_ASSERT_FATAL(req != NULL);
1020 
1021 	/* TEST CASE: No persistent file, register with PTPL enabled will fail */
1022 	g_ns.ptpl_file = NULL;
1023 	ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY, 0,
1024 					      SPDK_NVME_RESERVE_PTPL_PERSIST_POWER_LOSS, 0, 0xa1);
1025 	update_sgroup = nvmf_ns_reservation_register(&g_ns, &g_ctrlr1_A, req);
1026 	SPDK_CU_ASSERT_FATAL(update_sgroup == false);
1027 	SPDK_CU_ASSERT_FATAL(rsp->status.sc != SPDK_NVME_SC_SUCCESS);
1028 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid);
1029 	SPDK_CU_ASSERT_FATAL(reg == NULL);
1030 
1031 	/* TEST CASE: Enable PTPL */
1032 	g_ns.ptpl_file = "/tmp/Ns1PR.cfg";
1033 	ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY, 0,
1034 					      SPDK_NVME_RESERVE_PTPL_PERSIST_POWER_LOSS, 0, 0xa1);
1035 	update_sgroup = nvmf_ns_reservation_register(&g_ns, &g_ctrlr1_A, req);
1036 	SPDK_CU_ASSERT_FATAL(update_sgroup == true);
1037 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
1038 	SPDK_CU_ASSERT_FATAL(g_ns.ptpl_activated == true);
1039 	rc = nvmf_ns_update_reservation_info(&g_ns);
1040 	SPDK_CU_ASSERT_FATAL(rc == 0);
1041 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid);
1042 	SPDK_CU_ASSERT_FATAL(reg != NULL);
1043 	SPDK_CU_ASSERT_FATAL(!spdk_uuid_compare(&g_ctrlr1_A.hostid, &reg->hostid));
1044 	/* Load reservation information from configuration file */
1045 	memset(&info, 0, sizeof(info));
1046 	rc = nvmf_ns_reservation_load(&g_ns, &info);
1047 	SPDK_CU_ASSERT_FATAL(rc == 0);
1048 	SPDK_CU_ASSERT_FATAL(info.ptpl_activated == true);
1049 
1050 	/* TEST CASE: Disable PTPL */
1051 	rsp->status.sc = SPDK_NVME_SC_INVALID_FIELD;
1052 	ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY, 0,
1053 					      SPDK_NVME_RESERVE_PTPL_CLEAR_POWER_ON, 0, 0xa1);
1054 	update_sgroup = nvmf_ns_reservation_register(&g_ns, &g_ctrlr1_A, req);
1055 	SPDK_CU_ASSERT_FATAL(update_sgroup == true);
1056 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
1057 	SPDK_CU_ASSERT_FATAL(g_ns.ptpl_activated == false);
1058 	rc = nvmf_ns_update_reservation_info(&g_ns);
1059 	SPDK_CU_ASSERT_FATAL(rc == 0);
1060 	rc = nvmf_ns_reservation_load(&g_ns, &info);
1061 	SPDK_CU_ASSERT_FATAL(rc < 0);
1062 	unlink(g_ns.ptpl_file);
1063 
1064 	ut_reservation_free_req(req);
1065 	ut_reservation_deinit();
1066 }
1067 
1068 static void
1069 test_reservation_acquire_preempt_1(void)
1070 {
1071 	struct spdk_nvmf_request *req;
1072 	struct spdk_nvme_cpl *rsp;
1073 	struct spdk_nvmf_registrant *reg;
1074 	uint32_t gen;
1075 
1076 	ut_reservation_init();
1077 
1078 	req = ut_reservation_build_req(16);
1079 	rsp = &req->rsp->nvme_cpl;
1080 	SPDK_CU_ASSERT_FATAL(req != NULL);
1081 
1082 	ut_reservation_build_registrants();
1083 
1084 	gen = g_ns.gen;
1085 	/* ACQUIRE: Host A with g_ctrlr1_A acquire reservation with
1086 	 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE.
1087 	 */
1088 	ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0,
1089 					     SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xa1, 0x0);
1090 	nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr1_A, req);
1091 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
1092 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid);
1093 	SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY);
1094 	SPDK_CU_ASSERT_FATAL(g_ns.crkey == 0xa1);
1095 	SPDK_CU_ASSERT_FATAL(g_ns.holder == reg);
1096 	SPDK_CU_ASSERT_FATAL(g_ns.gen == gen);
1097 
1098 	/* TEST CASE: g_ctrlr1_A holds the reservation, g_ctrlr_B preempt g_ctrl1_A,
1099 	 * g_ctrl1_A registrant is unregistered.
1100 	 */
1101 	gen = g_ns.gen;
1102 	ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_PREEMPT, 0,
1103 					     SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS, 0xb1, 0xa1);
1104 	nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_B, req);
1105 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
1106 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid);
1107 	SPDK_CU_ASSERT_FATAL(reg == NULL);
1108 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_B.hostid);
1109 	SPDK_CU_ASSERT_FATAL(reg != NULL);
1110 	SPDK_CU_ASSERT_FATAL(g_ns.holder == reg);
1111 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_C.hostid);
1112 	SPDK_CU_ASSERT_FATAL(reg != NULL);
1113 	SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS);
1114 	SPDK_CU_ASSERT_FATAL(g_ns.gen > gen);
1115 
1116 	/* TEST CASE: g_ctrlr_B holds the reservation, g_ctrlr_C preempt g_ctrlr_B
1117 	 * with valid key and PRKEY set to 0, all registrants other the host that issued
1118 	 * the command are unregistered.
1119 	 */
1120 	gen = g_ns.gen;
1121 	ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_PREEMPT, 0,
1122 					     SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS, 0xc1, 0x0);
1123 	nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_C, req);
1124 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
1125 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr2_A.hostid);
1126 	SPDK_CU_ASSERT_FATAL(reg == NULL);
1127 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_B.hostid);
1128 	SPDK_CU_ASSERT_FATAL(reg == NULL);
1129 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_C.hostid);
1130 	SPDK_CU_ASSERT_FATAL(reg != NULL);
1131 	SPDK_CU_ASSERT_FATAL(g_ns.holder == reg);
1132 	SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS);
1133 	SPDK_CU_ASSERT_FATAL(g_ns.gen > gen);
1134 
1135 	ut_reservation_free_req(req);
1136 	ut_reservation_deinit();
1137 }
1138 
1139 static void
1140 test_reservation_acquire_release_with_ptpl(void)
1141 {
1142 	struct spdk_nvmf_request *req;
1143 	struct spdk_nvme_cpl *rsp;
1144 	struct spdk_nvmf_registrant *reg;
1145 	bool update_sgroup = false;
1146 	struct spdk_uuid holder_uuid;
1147 	int rc;
1148 	struct spdk_nvmf_reservation_info info;
1149 
1150 	ut_reservation_init();
1151 
1152 	req = ut_reservation_build_req(16);
1153 	rsp = &req->rsp->nvme_cpl;
1154 	SPDK_CU_ASSERT_FATAL(req != NULL);
1155 
1156 	/* TEST CASE: Enable PTPL */
1157 	g_ns.ptpl_file = "/tmp/Ns1PR.cfg";
1158 	ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY, 0,
1159 					      SPDK_NVME_RESERVE_PTPL_PERSIST_POWER_LOSS, 0, 0xa1);
1160 	update_sgroup = nvmf_ns_reservation_register(&g_ns, &g_ctrlr1_A, req);
1161 	SPDK_CU_ASSERT_FATAL(update_sgroup == true);
1162 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
1163 	SPDK_CU_ASSERT_FATAL(g_ns.ptpl_activated == true);
1164 	rc = nvmf_ns_update_reservation_info(&g_ns);
1165 	SPDK_CU_ASSERT_FATAL(rc == 0);
1166 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid);
1167 	SPDK_CU_ASSERT_FATAL(reg != NULL);
1168 	SPDK_CU_ASSERT_FATAL(!spdk_uuid_compare(&g_ctrlr1_A.hostid, &reg->hostid));
1169 	/* Load reservation information from configuration file */
1170 	memset(&info, 0, sizeof(info));
1171 	rc = nvmf_ns_reservation_load(&g_ns, &info);
1172 	SPDK_CU_ASSERT_FATAL(rc == 0);
1173 	SPDK_CU_ASSERT_FATAL(info.ptpl_activated == true);
1174 
1175 	/* TEST CASE: Acquire the reservation */
1176 	rsp->status.sc = SPDK_NVME_SC_INVALID_FIELD;
1177 	ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0,
1178 					     SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xa1, 0x0);
1179 	update_sgroup = nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr1_A, req);
1180 	SPDK_CU_ASSERT_FATAL(update_sgroup == true);
1181 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
1182 	rc = nvmf_ns_update_reservation_info(&g_ns);
1183 	SPDK_CU_ASSERT_FATAL(rc == 0);
1184 	memset(&info, 0, sizeof(info));
1185 	rc = nvmf_ns_reservation_load(&g_ns, &info);
1186 	SPDK_CU_ASSERT_FATAL(rc == 0);
1187 	SPDK_CU_ASSERT_FATAL(info.ptpl_activated == true);
1188 	SPDK_CU_ASSERT_FATAL(info.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY);
1189 	SPDK_CU_ASSERT_FATAL(info.crkey == 0xa1);
1190 	spdk_uuid_parse(&holder_uuid, info.holder_uuid);
1191 	SPDK_CU_ASSERT_FATAL(!spdk_uuid_compare(&g_ctrlr1_A.hostid, &holder_uuid));
1192 
1193 	/* TEST CASE: Release the reservation */
1194 	rsp->status.sc = SPDK_NVME_SC_INVALID_FIELD;
1195 	ut_reservation_build_release_request(req, SPDK_NVME_RESERVE_RELEASE, 0,
1196 					     SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xa1);
1197 	update_sgroup = nvmf_ns_reservation_release(&g_ns, &g_ctrlr1_A, req);
1198 	SPDK_CU_ASSERT_FATAL(update_sgroup == true);
1199 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
1200 	rc = nvmf_ns_update_reservation_info(&g_ns);
1201 	SPDK_CU_ASSERT_FATAL(rc == 0);
1202 	memset(&info, 0, sizeof(info));
1203 	rc = nvmf_ns_reservation_load(&g_ns, &info);
1204 	SPDK_CU_ASSERT_FATAL(rc == 0);
1205 	SPDK_CU_ASSERT_FATAL(info.rtype == 0);
1206 	SPDK_CU_ASSERT_FATAL(info.crkey == 0);
1207 	SPDK_CU_ASSERT_FATAL(info.ptpl_activated == true);
1208 	unlink(g_ns.ptpl_file);
1209 
1210 	ut_reservation_free_req(req);
1211 	ut_reservation_deinit();
1212 }
1213 
1214 static void
1215 test_reservation_release(void)
1216 {
1217 	struct spdk_nvmf_request *req;
1218 	struct spdk_nvme_cpl *rsp;
1219 	struct spdk_nvmf_registrant *reg;
1220 
1221 	ut_reservation_init();
1222 
1223 	req = ut_reservation_build_req(16);
1224 	rsp = &req->rsp->nvme_cpl;
1225 	SPDK_CU_ASSERT_FATAL(req != NULL);
1226 
1227 	ut_reservation_build_registrants();
1228 
1229 	/* ACQUIRE: Host A with g_ctrlr1_A get reservation with
1230 	 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS
1231 	 */
1232 	ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0,
1233 					     SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS, 0xa1, 0x0);
1234 	nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr1_A, req);
1235 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
1236 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid);
1237 	SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS);
1238 	SPDK_CU_ASSERT_FATAL(g_ns.holder == reg);
1239 
1240 	/* Test Case: Host B release the reservation */
1241 	ut_reservation_build_release_request(req, SPDK_NVME_RESERVE_RELEASE, 0,
1242 					     SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS, 0xb1);
1243 	nvmf_ns_reservation_release(&g_ns, &g_ctrlr_B, req);
1244 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
1245 	SPDK_CU_ASSERT_FATAL(g_ns.rtype == 0);
1246 	SPDK_CU_ASSERT_FATAL(g_ns.crkey == 0);
1247 	SPDK_CU_ASSERT_FATAL(g_ns.holder == NULL);
1248 
1249 	/* Test Case: Host C clear the registrants */
1250 	ut_reservation_build_release_request(req, SPDK_NVME_RESERVE_CLEAR, 0,
1251 					     0, 0xc1);
1252 	nvmf_ns_reservation_release(&g_ns, &g_ctrlr_C, req);
1253 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
1254 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid);
1255 	SPDK_CU_ASSERT_FATAL(reg == NULL);
1256 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr2_A.hostid);
1257 	SPDK_CU_ASSERT_FATAL(reg == NULL);
1258 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_B.hostid);
1259 	SPDK_CU_ASSERT_FATAL(reg == NULL);
1260 	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_C.hostid);
1261 	SPDK_CU_ASSERT_FATAL(reg == NULL);
1262 
1263 	ut_reservation_free_req(req);
1264 	ut_reservation_deinit();
1265 }
1266 
1267 void
1268 nvmf_ctrlr_reservation_notice_log(struct spdk_nvmf_ctrlr *ctrlr,
1269 				  struct spdk_nvmf_ns *ns,
1270 				  enum spdk_nvme_reservation_notification_log_page_type type)
1271 {
1272 	ctrlr->num_avail_log_pages++;
1273 }
1274 
1275 static void
1276 test_reservation_unregister_notification(void)
1277 {
1278 	struct spdk_nvmf_request *req;
1279 	struct spdk_nvme_cpl *rsp;
1280 
1281 	ut_reservation_init();
1282 
1283 	req = ut_reservation_build_req(16);
1284 	SPDK_CU_ASSERT_FATAL(req != NULL);
1285 	rsp = &req->rsp->nvme_cpl;
1286 
1287 	ut_reservation_build_registrants();
1288 
1289 	/* ACQUIRE: Host B with g_ctrlr_B get reservation with
1290 	 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY
1291 	 */
1292 	rsp->status.sc = 0xff;
1293 	ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0,
1294 					     SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xb1, 0x0);
1295 	nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_B, req);
1296 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
1297 	SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY);
1298 
1299 	/* Test Case : g_ctrlr_B holds the reservation, g_ctrlr_B unregister the registration.
1300 	 * Reservation release notification sends to g_ctrlr1_A/g_ctrlr2_A/g_ctrlr_C only for
1301 	 * SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY or SPDK_NVME_RESERVE_EXCLUSIVE_ACCESS_REG_ONLY
1302 	 * type.
1303 	 */
1304 	rsp->status.sc = 0xff;
1305 	g_ctrlr1_A.num_avail_log_pages = 0;
1306 	g_ctrlr2_A.num_avail_log_pages = 0;
1307 	g_ctrlr_B.num_avail_log_pages = 5;
1308 	g_ctrlr_C.num_avail_log_pages = 0;
1309 	ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_UNREGISTER_KEY,
1310 					      0, 0, 0xb1, 0);
1311 	nvmf_ns_reservation_register(&g_ns, &g_ctrlr_B, req);
1312 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
1313 	SPDK_CU_ASSERT_FATAL(g_ns.rtype == 0);
1314 	SPDK_CU_ASSERT_FATAL(1 == g_ctrlr1_A.num_avail_log_pages);
1315 	SPDK_CU_ASSERT_FATAL(1 == g_ctrlr2_A.num_avail_log_pages);
1316 	SPDK_CU_ASSERT_FATAL(5 == g_ctrlr_B.num_avail_log_pages);
1317 	SPDK_CU_ASSERT_FATAL(1 == g_ctrlr_C.num_avail_log_pages);
1318 
1319 	ut_reservation_free_req(req);
1320 	ut_reservation_deinit();
1321 }
1322 
1323 static void
1324 test_reservation_release_notification(void)
1325 {
1326 	struct spdk_nvmf_request *req;
1327 	struct spdk_nvme_cpl *rsp;
1328 
1329 	ut_reservation_init();
1330 
1331 	req = ut_reservation_build_req(16);
1332 	SPDK_CU_ASSERT_FATAL(req != NULL);
1333 	rsp = &req->rsp->nvme_cpl;
1334 
1335 	ut_reservation_build_registrants();
1336 
1337 	/* ACQUIRE: Host B with g_ctrlr_B get reservation with
1338 	 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY
1339 	 */
1340 	rsp->status.sc = 0xff;
1341 	ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0,
1342 					     SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xb1, 0x0);
1343 	nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_B, req);
1344 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
1345 	SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY);
1346 
1347 	/* Test Case : g_ctrlr_B holds the reservation, g_ctrlr_B release the reservation.
1348 	 * Reservation release notification sends to g_ctrlr1_A/g_ctrlr2_A/g_ctrlr_C.
1349 	 */
1350 	rsp->status.sc = 0xff;
1351 	g_ctrlr1_A.num_avail_log_pages = 0;
1352 	g_ctrlr2_A.num_avail_log_pages = 0;
1353 	g_ctrlr_B.num_avail_log_pages = 5;
1354 	g_ctrlr_C.num_avail_log_pages = 0;
1355 	ut_reservation_build_release_request(req, SPDK_NVME_RESERVE_RELEASE, 0,
1356 					     SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xb1);
1357 	nvmf_ns_reservation_release(&g_ns, &g_ctrlr_B, req);
1358 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
1359 	SPDK_CU_ASSERT_FATAL(g_ns.rtype == 0);
1360 	SPDK_CU_ASSERT_FATAL(1 == g_ctrlr1_A.num_avail_log_pages);
1361 	SPDK_CU_ASSERT_FATAL(1 == g_ctrlr2_A.num_avail_log_pages);
1362 	SPDK_CU_ASSERT_FATAL(5 == g_ctrlr_B.num_avail_log_pages);
1363 	SPDK_CU_ASSERT_FATAL(1 == g_ctrlr_C.num_avail_log_pages);
1364 
1365 	ut_reservation_free_req(req);
1366 	ut_reservation_deinit();
1367 }
1368 
1369 static void
1370 test_reservation_release_notification_write_exclusive(void)
1371 {
1372 	struct spdk_nvmf_request *req;
1373 	struct spdk_nvme_cpl *rsp;
1374 
1375 	ut_reservation_init();
1376 
1377 	req = ut_reservation_build_req(16);
1378 	SPDK_CU_ASSERT_FATAL(req != NULL);
1379 	rsp = &req->rsp->nvme_cpl;
1380 
1381 	ut_reservation_build_registrants();
1382 
1383 	/* ACQUIRE: Host B with g_ctrlr_B get reservation with
1384 	 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE
1385 	 */
1386 	rsp->status.sc = 0xff;
1387 	ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0,
1388 					     SPDK_NVME_RESERVE_WRITE_EXCLUSIVE, 0xb1, 0x0);
1389 	nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_B, req);
1390 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
1391 	SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE);
1392 
1393 	/* Test Case : g_ctrlr_B holds the reservation, g_ctrlr_B release the reservation.
1394 	 * Because the reservation type is SPDK_NVME_RESERVE_WRITE_EXCLUSIVE,
1395 	 * no reservation notification occurs.
1396 	 */
1397 	rsp->status.sc = 0xff;
1398 	g_ctrlr1_A.num_avail_log_pages = 5;
1399 	g_ctrlr2_A.num_avail_log_pages = 5;
1400 	g_ctrlr_B.num_avail_log_pages = 5;
1401 	g_ctrlr_C.num_avail_log_pages = 5;
1402 	ut_reservation_build_release_request(req, SPDK_NVME_RESERVE_RELEASE, 0,
1403 					     SPDK_NVME_RESERVE_WRITE_EXCLUSIVE, 0xb1);
1404 	nvmf_ns_reservation_release(&g_ns, &g_ctrlr_B, req);
1405 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
1406 	SPDK_CU_ASSERT_FATAL(g_ns.rtype == 0);
1407 	SPDK_CU_ASSERT_FATAL(5 == g_ctrlr1_A.num_avail_log_pages);
1408 	SPDK_CU_ASSERT_FATAL(5 == g_ctrlr2_A.num_avail_log_pages);
1409 	SPDK_CU_ASSERT_FATAL(5 == g_ctrlr_B.num_avail_log_pages);
1410 	SPDK_CU_ASSERT_FATAL(5 == g_ctrlr_C.num_avail_log_pages);
1411 
1412 	ut_reservation_free_req(req);
1413 	ut_reservation_deinit();
1414 }
1415 
1416 static void
1417 test_reservation_clear_notification(void)
1418 {
1419 	struct spdk_nvmf_request *req;
1420 	struct spdk_nvme_cpl *rsp;
1421 
1422 	ut_reservation_init();
1423 
1424 	req = ut_reservation_build_req(16);
1425 	SPDK_CU_ASSERT_FATAL(req != NULL);
1426 	rsp = &req->rsp->nvme_cpl;
1427 
1428 	ut_reservation_build_registrants();
1429 
1430 	/* ACQUIRE: Host B with g_ctrlr_B get reservation with
1431 	 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY
1432 	 */
1433 	rsp->status.sc = 0xff;
1434 	ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0,
1435 					     SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xb1, 0x0);
1436 	nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_B, req);
1437 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
1438 	SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY);
1439 
1440 	/* Test Case : g_ctrlr_B holds the reservation, g_ctrlr_B clear the reservation.
1441 	 * Reservation Preempted notification sends to g_ctrlr1_A/g_ctrlr2_A/g_ctrlr_C.
1442 	 */
1443 	rsp->status.sc = 0xff;
1444 	g_ctrlr1_A.num_avail_log_pages = 0;
1445 	g_ctrlr2_A.num_avail_log_pages = 0;
1446 	g_ctrlr_B.num_avail_log_pages = 5;
1447 	g_ctrlr_C.num_avail_log_pages = 0;
1448 	ut_reservation_build_release_request(req, SPDK_NVME_RESERVE_CLEAR, 0,
1449 					     0, 0xb1);
1450 	nvmf_ns_reservation_release(&g_ns, &g_ctrlr_B, req);
1451 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
1452 	SPDK_CU_ASSERT_FATAL(g_ns.rtype == 0);
1453 	SPDK_CU_ASSERT_FATAL(1 == g_ctrlr1_A.num_avail_log_pages);
1454 	SPDK_CU_ASSERT_FATAL(1 == g_ctrlr2_A.num_avail_log_pages);
1455 	SPDK_CU_ASSERT_FATAL(5 == g_ctrlr_B.num_avail_log_pages);
1456 	SPDK_CU_ASSERT_FATAL(1 == g_ctrlr_C.num_avail_log_pages);
1457 
1458 	ut_reservation_free_req(req);
1459 	ut_reservation_deinit();
1460 }
1461 
1462 static void
1463 test_reservation_preempt_notification(void)
1464 {
1465 	struct spdk_nvmf_request *req;
1466 	struct spdk_nvme_cpl *rsp;
1467 
1468 	ut_reservation_init();
1469 
1470 	req = ut_reservation_build_req(16);
1471 	SPDK_CU_ASSERT_FATAL(req != NULL);
1472 	rsp = &req->rsp->nvme_cpl;
1473 
1474 	ut_reservation_build_registrants();
1475 
1476 	/* ACQUIRE: Host B with g_ctrlr_B get reservation with
1477 	 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY
1478 	 */
1479 	rsp->status.sc = 0xff;
1480 	ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0,
1481 					     SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xb1, 0x0);
1482 	nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_B, req);
1483 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
1484 	SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY);
1485 
1486 	/* Test Case : g_ctrlr_B holds the reservation, g_ctrlr_C preempt g_ctrlr_B,
1487 	 * g_ctrlr_B registrant is unregistered, and reservation is preempted.
1488 	 * Registration Preempted notification sends to g_ctrlr_B.
1489 	 * Reservation Preempted notification sends to g_ctrlr1_A/g_ctrlr2_A.
1490 	 */
1491 	rsp->status.sc = 0xff;
1492 	g_ctrlr1_A.num_avail_log_pages = 0;
1493 	g_ctrlr2_A.num_avail_log_pages = 0;
1494 	g_ctrlr_B.num_avail_log_pages = 0;
1495 	g_ctrlr_C.num_avail_log_pages = 5;
1496 	ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_PREEMPT, 0,
1497 					     SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS, 0xc1, 0xb1);
1498 	nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_C, req);
1499 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
1500 	SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS);
1501 	SPDK_CU_ASSERT_FATAL(1 == g_ctrlr1_A.num_avail_log_pages);
1502 	SPDK_CU_ASSERT_FATAL(1 == g_ctrlr2_A.num_avail_log_pages);
1503 	SPDK_CU_ASSERT_FATAL(1 == g_ctrlr_B.num_avail_log_pages);
1504 	SPDK_CU_ASSERT_FATAL(5 == g_ctrlr_C.num_avail_log_pages);
1505 
1506 	ut_reservation_free_req(req);
1507 	ut_reservation_deinit();
1508 }
1509 
1510 static int
1511 nvmf_tgt_create_poll_group(void *io_device, void *ctx_buf)
1512 {
1513 	return 0;
1514 }
1515 
1516 static void
1517 nvmf_tgt_destroy_poll_group(void *io_device, void *ctx_buf)
1518 {
1519 }
1520 
1521 static void
1522 test_spdk_nvmf_ns_event(void)
1523 {
1524 	struct spdk_nvmf_tgt tgt = {};
1525 	struct spdk_nvmf_subsystem subsystem = {
1526 		.max_nsid = 1024,
1527 		.ns = NULL,
1528 		.tgt = &tgt,
1529 	};
1530 	struct spdk_nvmf_ctrlr ctrlr = {
1531 		.subsys = &subsystem
1532 	};
1533 	struct spdk_nvmf_ns_opts ns_opts;
1534 	uint32_t nsid;
1535 	struct spdk_bdev *bdev;
1536 	struct spdk_thread *thread;
1537 
1538 	ctrlr.visible_ns = spdk_bit_array_create(1);
1539 	spdk_bit_array_set(ctrlr.visible_ns, 0);
1540 
1541 	thread = spdk_get_thread();
1542 	SPDK_CU_ASSERT_FATAL(thread != NULL);
1543 
1544 	subsystem.ns = calloc(subsystem.max_nsid, sizeof(struct spdk_nvmf_subsystem_ns *));
1545 	SPDK_CU_ASSERT_FATAL(subsystem.ns != NULL);
1546 	subsystem.ana_group = calloc(subsystem.max_nsid, sizeof(uint32_t));
1547 	SPDK_CU_ASSERT_FATAL(subsystem.ana_group != NULL);
1548 
1549 	tgt.max_subsystems = 1024;
1550 	tgt.subsystem_ids = spdk_bit_array_create(tgt.max_subsystems);
1551 	RB_INIT(&tgt.subsystems);
1552 
1553 	spdk_io_device_register(&tgt,
1554 				nvmf_tgt_create_poll_group,
1555 				nvmf_tgt_destroy_poll_group,
1556 				sizeof(struct spdk_nvmf_poll_group),
1557 				NULL);
1558 
1559 	/* Add one namespace */
1560 	spdk_nvmf_ns_opts_get_defaults(&ns_opts, sizeof(ns_opts));
1561 	nsid = spdk_nvmf_subsystem_add_ns_ext(&subsystem, "bdev1", &ns_opts, sizeof(ns_opts), NULL);
1562 	CU_ASSERT(nsid == 1);
1563 	CU_ASSERT(NULL != subsystem.ns[0]);
1564 	CU_ASSERT(subsystem.ns[nsid - 1]->bdev == &g_bdevs[nsid - 1]);
1565 
1566 	bdev = subsystem.ns[nsid - 1]->bdev;
1567 
1568 	/* Add one controller */
1569 	TAILQ_INIT(&subsystem.ctrlrs);
1570 	TAILQ_INSERT_TAIL(&subsystem.ctrlrs, &ctrlr, link);
1571 
1572 	/* Namespace resize event */
1573 	subsystem.state = SPDK_NVMF_SUBSYSTEM_ACTIVE;
1574 	g_ns_changed_nsid = 0xFFFFFFFF;
1575 	g_ns_changed_ctrlr = NULL;
1576 	nvmf_ns_event(SPDK_BDEV_EVENT_RESIZE, bdev, subsystem.ns[0]);
1577 	CU_ASSERT(SPDK_NVMF_SUBSYSTEM_PAUSING == subsystem.state);
1578 
1579 	poll_threads();
1580 	CU_ASSERT(1 == g_ns_changed_nsid);
1581 	CU_ASSERT(&ctrlr == g_ns_changed_ctrlr);
1582 	CU_ASSERT(SPDK_NVMF_SUBSYSTEM_ACTIVE == subsystem.state);
1583 
1584 	/* Namespace remove event */
1585 	subsystem.state = SPDK_NVMF_SUBSYSTEM_ACTIVE;
1586 	g_ns_changed_nsid = 0xFFFFFFFF;
1587 	g_ns_changed_ctrlr = NULL;
1588 	nvmf_ns_event(SPDK_BDEV_EVENT_REMOVE, bdev, subsystem.ns[0]);
1589 	CU_ASSERT(SPDK_NVMF_SUBSYSTEM_PAUSING == subsystem.state);
1590 	CU_ASSERT(0xFFFFFFFF == g_ns_changed_nsid);
1591 	CU_ASSERT(NULL == g_ns_changed_ctrlr);
1592 
1593 	poll_threads();
1594 	CU_ASSERT(1 == g_ns_changed_nsid);
1595 	CU_ASSERT(&ctrlr == g_ns_changed_ctrlr);
1596 	CU_ASSERT(NULL == subsystem.ns[0]);
1597 	CU_ASSERT(SPDK_NVMF_SUBSYSTEM_ACTIVE == subsystem.state);
1598 
1599 	spdk_io_device_unregister(&tgt, NULL);
1600 
1601 	poll_threads();
1602 
1603 	free(subsystem.ns);
1604 	free(subsystem.ana_group);
1605 	spdk_bit_array_free(&ctrlr.visible_ns);
1606 	spdk_bit_array_free(&tgt.subsystem_ids);
1607 }
1608 
1609 static void
1610 test_nvmf_ns_reservation_add_remove_registrant(void)
1611 {
1612 	struct spdk_nvmf_ns ns = {};
1613 	struct spdk_nvmf_ctrlr ctrlr = {};
1614 	struct spdk_nvmf_registrant *reg = NULL;
1615 	int rc;
1616 
1617 	TAILQ_INIT(&ns.registrants);
1618 	spdk_uuid_generate(&ctrlr.hostid);
1619 
1620 	rc = nvmf_ns_reservation_add_registrant(&ns, &ctrlr, 0xa11);
1621 	CU_ASSERT(rc == 0);
1622 	reg = TAILQ_FIRST(&ns.registrants);
1623 	SPDK_CU_ASSERT_FATAL(reg != NULL);
1624 	CU_ASSERT(ns.gen == 1);
1625 	CU_ASSERT(reg->rkey == 0xa11);
1626 	CU_ASSERT(!strncmp((uint8_t *)&reg->hostid, (uint8_t *)&ctrlr.hostid, sizeof(ctrlr.hostid)));
1627 
1628 	nvmf_ns_reservation_remove_registrant(&ns, reg);
1629 	CU_ASSERT(TAILQ_EMPTY(&ns.registrants));
1630 	CU_ASSERT(ns.gen == 2);
1631 }
1632 
1633 static void
1634 test_nvmf_subsystem_destroy_cb(void *cb_arg)
1635 {
1636 }
1637 
1638 static void
1639 test_nvmf_subsystem_add_ctrlr(void)
1640 {
1641 	int rc;
1642 	struct spdk_nvmf_ctrlr ctrlr = {};
1643 	struct spdk_nvmf_tgt tgt = {};
1644 	char nqn[256] = "nqn.2016-06.io.spdk:subsystem1";
1645 	struct spdk_nvmf_subsystem *subsystem = NULL;
1646 
1647 	tgt.max_subsystems = 1024;
1648 	tgt.subsystem_ids = spdk_bit_array_create(tgt.max_subsystems);
1649 	RB_INIT(&tgt.subsystems);
1650 
1651 	subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0);
1652 	SPDK_CU_ASSERT_FATAL(subsystem != NULL);
1653 	ctrlr.subsys = subsystem;
1654 
1655 	ctrlr.dynamic_ctrlr = true;
1656 	rc = nvmf_subsystem_add_ctrlr(subsystem, &ctrlr);
1657 	CU_ASSERT(rc == 0);
1658 	CU_ASSERT(!TAILQ_EMPTY(&subsystem->ctrlrs));
1659 	CU_ASSERT(ctrlr.cntlid == 1);
1660 	CU_ASSERT(nvmf_subsystem_get_ctrlr(subsystem, 1) == &ctrlr);
1661 
1662 	nvmf_subsystem_remove_ctrlr(subsystem, &ctrlr);
1663 	CU_ASSERT(TAILQ_EMPTY(&subsystem->ctrlrs));
1664 	rc = spdk_nvmf_subsystem_destroy(subsystem, test_nvmf_subsystem_destroy_cb, NULL);
1665 	CU_ASSERT(rc == 0);
1666 	spdk_bit_array_free(&tgt.subsystem_ids);
1667 }
1668 
1669 static void
1670 _add_transport_cb(void *arg, int status)
1671 {
1672 	CU_ASSERT(status == 0);
1673 }
1674 
1675 static int
1676 transport_subsystem_add_host_err(struct spdk_nvmf_transport *transport,
1677 				 const struct spdk_nvmf_subsystem *subsystem,
1678 				 const char *hostnqn,
1679 				 const struct spdk_json_val *transport_specific)
1680 {
1681 	return -1;
1682 }
1683 
1684 void
1685 spdk_nvmf_tgt_add_transport(struct spdk_nvmf_tgt *tgt,
1686 			    struct spdk_nvmf_transport *transport,
1687 			    spdk_nvmf_tgt_add_transport_done_fn cb_fn,
1688 			    void *cb_arg)
1689 {
1690 	TAILQ_INSERT_TAIL(&tgt->transports, transport, link);
1691 }
1692 
1693 static struct spdk_nvmf_transport *
1694 transport_create(struct spdk_nvmf_transport_opts *opts)
1695 {
1696 	return &g_transport;
1697 }
1698 
1699 static void
1700 test_spdk_nvmf_subsystem_add_host(void)
1701 {
1702 	struct spdk_nvmf_tgt tgt = {};
1703 	struct spdk_nvmf_subsystem *subsystem = NULL;
1704 	int rc;
1705 	const char hostnqn[] = "nqn.2016-06.io.spdk:host1";
1706 	const char subsystemnqn[] = "nqn.2016-06.io.spdk:subsystem1";
1707 	struct spdk_nvmf_transport_opts opts = {
1708 		.opts_size = sizeof(struct spdk_nvmf_transport_opts),
1709 		.io_unit_size = 8192
1710 	};
1711 	const struct spdk_nvmf_transport_ops test_ops = {
1712 		.name = "transport_ut",
1713 		.create = transport_create,
1714 		.subsystem_add_host = transport_subsystem_add_host_err,
1715 	};
1716 	struct spdk_nvmf_transport *transport;
1717 
1718 	tgt.max_subsystems = 1024;
1719 	tgt.subsystem_ids = spdk_bit_array_create(tgt.max_subsystems);
1720 	RB_INIT(&tgt.subsystems);
1721 
1722 	subsystem = spdk_nvmf_subsystem_create(&tgt, subsystemnqn, SPDK_NVMF_SUBTYPE_NVME, 0);
1723 	SPDK_CU_ASSERT_FATAL(subsystem != NULL);
1724 	CU_ASSERT_STRING_EQUAL(subsystem->subnqn, subsystemnqn);
1725 
1726 	rc = spdk_nvmf_subsystem_add_host(subsystem, hostnqn, NULL);
1727 	CU_ASSERT(rc == 0);
1728 	CU_ASSERT(!TAILQ_EMPTY(&subsystem->hosts));
1729 
1730 	/* Add existing nqn, this function is allowed to be called if the nqn was previously added. */
1731 	rc = spdk_nvmf_subsystem_add_host(subsystem, hostnqn, NULL);
1732 	CU_ASSERT(rc == 0);
1733 
1734 	rc = spdk_nvmf_subsystem_remove_host(subsystem, hostnqn);
1735 	CU_ASSERT(rc == 0);
1736 	CU_ASSERT(TAILQ_EMPTY(&subsystem->hosts));
1737 
1738 	/* No available nqn */
1739 	rc = spdk_nvmf_subsystem_remove_host(subsystem, hostnqn);
1740 	CU_ASSERT(rc == -ENOENT);
1741 
1742 	/* Ensure hostnqn list remains empty after transport callback fails */
1743 	spdk_nvmf_transport_register(&test_ops);
1744 	transport = spdk_nvmf_transport_create("transport_ut", &opts);
1745 	SPDK_CU_ASSERT_FATAL(transport != NULL);
1746 
1747 	TAILQ_INIT(&tgt.transports);
1748 	spdk_nvmf_tgt_add_transport(&tgt, transport, _add_transport_cb, 0);
1749 
1750 	rc = spdk_nvmf_subsystem_add_host(subsystem, hostnqn, NULL);
1751 	CU_ASSERT(rc != 0);
1752 	CU_ASSERT(TAILQ_EMPTY(&subsystem->hosts));
1753 
1754 	spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL);
1755 	spdk_bit_array_free(&tgt.subsystem_ids);
1756 }
1757 
1758 static void
1759 test_nvmf_ns_reservation_report(void)
1760 {
1761 	struct spdk_nvmf_ns ns = {};
1762 	struct spdk_nvmf_ctrlr ctrlr = {};
1763 	struct spdk_nvmf_request req = {};
1764 	union nvmf_h2c_msg cmd = {};
1765 	union nvmf_c2h_msg rsp = {};
1766 	struct spdk_nvme_registered_ctrlr_extended_data *ctrlr_data;
1767 	struct spdk_nvme_reservation_status_extended_data *status_data;
1768 	struct spdk_nvmf_registrant *reg;
1769 	void *data;
1770 
1771 	data = calloc(1, sizeof(*status_data) + sizeof(*ctrlr_data) * 2);
1772 	reg = calloc(2, sizeof(struct spdk_nvmf_registrant));
1773 	SPDK_CU_ASSERT_FATAL(data != NULL && reg != NULL);
1774 
1775 	req.length = sizeof(*status_data) + sizeof(*ctrlr_data) * 2;
1776 	SPDK_IOV_ONE(req.iov, &req.iovcnt, data, req.length);
1777 
1778 	req.cmd = &cmd;
1779 	req.rsp = &rsp;
1780 	ns.gen = 1;
1781 	ns.rtype = SPDK_NVME_RESERVE_WRITE_EXCLUSIVE;
1782 	ns.ptpl_activated = true;
1783 	cmd.nvme_cmd.cdw11_bits.resv_report.eds = true;
1784 	cmd.nvme_cmd.cdw10 = 100;
1785 	reg[0].rkey = 0xa;
1786 	reg[1].rkey = 0xb;
1787 	spdk_uuid_generate(&reg[0].hostid);
1788 	spdk_uuid_generate(&reg[1].hostid);
1789 	TAILQ_INIT(&ns.registrants);
1790 	TAILQ_INSERT_TAIL(&ns.registrants, &reg[0], link);
1791 	TAILQ_INSERT_TAIL(&ns.registrants, &reg[1], link);
1792 
1793 	nvmf_ns_reservation_report(&ns, &ctrlr, &req);
1794 	CU_ASSERT(req.rsp->nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC);
1795 	CU_ASSERT(req.rsp->nvme_cpl.status.sc == SPDK_NVME_SC_SUCCESS);
1796 	/* Get ctrlr data and status data pointers */
1797 	ctrlr_data = (void *)((char *)req.iov[0].iov_base + sizeof(*status_data));
1798 	status_data = (void *)req.iov[0].iov_base;
1799 	SPDK_CU_ASSERT_FATAL(status_data != NULL && ctrlr_data != NULL);
1800 	CU_ASSERT(status_data->data.gen == 1);
1801 	CU_ASSERT(status_data->data.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE);
1802 	CU_ASSERT(status_data->data.ptpls == true);
1803 	CU_ASSERT(status_data->data.regctl == 2);
1804 	CU_ASSERT(ctrlr_data->cntlid == 0xffff);
1805 	CU_ASSERT(ctrlr_data->rcsts.status == false);
1806 	CU_ASSERT(ctrlr_data->rkey ==  0xa);
1807 	CU_ASSERT(!spdk_uuid_compare((struct spdk_uuid *)ctrlr_data->hostid, &reg[0].hostid));
1808 	/* Check second ctrlr data */
1809 	ctrlr_data++;
1810 	CU_ASSERT(ctrlr_data->cntlid == 0xffff);
1811 	CU_ASSERT(ctrlr_data->rcsts.status == false);
1812 	CU_ASSERT(ctrlr_data->rkey ==  0xb);
1813 	CU_ASSERT(!spdk_uuid_compare((struct spdk_uuid *)ctrlr_data->hostid, &reg[1].hostid));
1814 
1815 	/* extended controller data structure */
1816 	spdk_iov_memset(req.iov, req.iovcnt, 0);
1817 	memset(req.rsp, 0, sizeof(*req.rsp));
1818 	cmd.nvme_cmd.cdw11_bits.resv_report.eds = false;
1819 
1820 	nvmf_ns_reservation_report(&ns, &ctrlr, &req);
1821 	CU_ASSERT(req.rsp->nvme_cpl.status.sc == SPDK_NVME_SC_HOSTID_INCONSISTENT_FORMAT);
1822 	CU_ASSERT(req.rsp->nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC);
1823 
1824 	/* Transfer length invalid */
1825 	spdk_iov_memset(req.iov, req.iovcnt, 0);
1826 	memset(req.rsp, 0, sizeof(*req.rsp));
1827 	cmd.nvme_cmd.cdw11_bits.resv_report.eds = true;
1828 	cmd.nvme_cmd.cdw10 = 0;
1829 
1830 	nvmf_ns_reservation_report(&ns, &ctrlr, &req);
1831 	CU_ASSERT(req.rsp->nvme_cpl.status.sc == SPDK_NVME_SC_INTERNAL_DEVICE_ERROR);
1832 	CU_ASSERT(req.rsp->nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC);
1833 
1834 	free(req.iov[0].iov_base);
1835 	free(reg);
1836 }
1837 
1838 static void
1839 test_nvmf_nqn_is_valid(void)
1840 {
1841 	bool rc;
1842 	char uuid[SPDK_NVMF_UUID_STRING_LEN + 1] = {};
1843 	char nqn[SPDK_NVMF_NQN_MAX_LEN + 1] = {};
1844 	struct spdk_uuid s_uuid = {};
1845 
1846 	spdk_uuid_generate(&s_uuid);
1847 	spdk_uuid_fmt_lower(uuid, sizeof(uuid), &s_uuid);
1848 
1849 	/* discovery nqn */
1850 	snprintf(nqn, sizeof(nqn), "%s", SPDK_NVMF_DISCOVERY_NQN);
1851 
1852 	rc = nvmf_nqn_is_valid(nqn);
1853 	CU_ASSERT(rc == true);
1854 
1855 	/* nqn with uuid */
1856 	memset(nqn, 0xff, sizeof(nqn));
1857 	snprintf(nqn, sizeof(nqn), "%s%s", SPDK_NVMF_NQN_UUID_PRE, uuid);
1858 
1859 	rc = nvmf_nqn_is_valid(nqn);
1860 	CU_ASSERT(rc == true);
1861 
1862 	/* Check nqn valid reverse domain */
1863 	memset(nqn, 0xff, sizeof(nqn));
1864 	snprintf(nqn, sizeof(nqn), "%s", "nqn.2016-06.io.spdk:cnode1");
1865 
1866 	rc = nvmf_nqn_is_valid(nqn);
1867 	CU_ASSERT(rc == true);
1868 
1869 	/* Invalid nqn length */
1870 	memset(nqn, 0xff, sizeof(nqn));
1871 	snprintf(nqn, sizeof(nqn), "%s", "nqn.");
1872 
1873 	rc = nvmf_nqn_is_valid(nqn);
1874 	CU_ASSERT(rc == false);
1875 
1876 	/* Copy uuid to the nqn string, but omit the last character to make it invalid */
1877 	memset(nqn, 0, SPDK_NVMF_NQN_MAX_LEN + 1);
1878 	snprintf(nqn, sizeof(nqn), "%s", SPDK_NVMF_NQN_UUID_PRE);
1879 	memcpy(&nqn[SPDK_NVMF_NQN_UUID_PRE_LEN], uuid, SPDK_NVMF_UUID_STRING_LEN - 1);
1880 
1881 	rc = nvmf_nqn_is_valid(nqn);
1882 	CU_ASSERT(rc == false);
1883 
1884 	/* Invalid domain */
1885 	memset(nqn, 0xff, SPDK_NVMF_NQN_MAX_LEN + 1);
1886 	snprintf(nqn, sizeof(nqn), "%s", "nqn.2016-06.io...spdk:cnode1");
1887 
1888 	rc = nvmf_nqn_is_valid(nqn);
1889 	CU_ASSERT(rc == false);
1890 }
1891 
1892 static void
1893 test_nvmf_ns_reservation_restore(void)
1894 {
1895 	struct spdk_nvmf_ns ns = {};
1896 	struct spdk_nvmf_reservation_info info = {};
1897 	struct spdk_bdev bdev = {};
1898 	struct spdk_uuid s_uuid = {};
1899 	struct spdk_nvmf_registrant *reg0, *reg1;
1900 	char uuid[SPDK_UUID_STRING_LEN] = {};
1901 	int rc;
1902 
1903 	ns.bdev = &bdev;
1904 	TAILQ_INIT(&ns.registrants);
1905 	info.ptpl_activated = true;
1906 	info.num_regs = 2;
1907 	info.rtype = SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS;
1908 	info.registrants[0].rkey = 0xb;
1909 	info.registrants[1].rkey = 0xc;
1910 
1911 	/* Generate and prepare uuids, make sure bdev and info uuid are the same */
1912 	spdk_uuid_generate(&s_uuid);
1913 	spdk_uuid_fmt_lower(uuid, sizeof(uuid), &s_uuid);
1914 	snprintf(info.holder_uuid, SPDK_UUID_STRING_LEN, "%s", uuid);
1915 	snprintf(info.bdev_uuid, SPDK_UUID_STRING_LEN, "%s", uuid);
1916 	snprintf(info.registrants[0].host_uuid, SPDK_UUID_STRING_LEN, "%s", uuid);
1917 	spdk_uuid_copy(&bdev.uuid, &s_uuid);
1918 	spdk_uuid_generate(&s_uuid);
1919 	spdk_uuid_fmt_lower(uuid, sizeof(uuid), &s_uuid);
1920 	snprintf(info.registrants[1].host_uuid, SPDK_UUID_STRING_LEN, "%s", uuid);
1921 
1922 	/* info->rkey not exist in registrants */
1923 	info.crkey = 0xa;
1924 
1925 	rc = nvmf_ns_reservation_restore(&ns, &info);
1926 	CU_ASSERT(rc == -EINVAL);
1927 
1928 	/* info->rkey exists in registrants */
1929 	info.crkey = 0xb;
1930 
1931 	rc = nvmf_ns_reservation_restore(&ns, &info);
1932 	CU_ASSERT(rc == 0);
1933 	CU_ASSERT(ns.crkey == 0xb);
1934 	CU_ASSERT(ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS);
1935 	CU_ASSERT(ns.ptpl_activated == true);
1936 	/* Check two registrant`s rkey */
1937 	reg0 = TAILQ_FIRST(&ns.registrants);
1938 	reg1 = TAILQ_NEXT(reg0, link);
1939 	CU_ASSERT(ns.holder == reg0);
1940 	CU_ASSERT(reg0->rkey = 0xb);
1941 	CU_ASSERT(reg1->rkey = 0xc);
1942 
1943 	rc = nvmf_ns_reservation_clear_all_registrants(&ns);
1944 	CU_ASSERT(rc == 2);
1945 	CU_ASSERT(TAILQ_EMPTY(&ns.registrants));
1946 
1947 	/* Existing bdev UUID is different with configuration */
1948 	spdk_uuid_generate(&s_uuid);
1949 	spdk_uuid_fmt_lower(uuid, sizeof(uuid), &s_uuid);
1950 	snprintf(info.bdev_uuid, SPDK_UUID_STRING_LEN, "%s", uuid);
1951 	spdk_uuid_generate(&s_uuid);
1952 	spdk_uuid_copy(&bdev.uuid, &s_uuid);
1953 
1954 	rc = nvmf_ns_reservation_restore(&ns, &info);
1955 	CU_ASSERT(rc == -EINVAL);
1956 
1957 	/* Check restore without reservation */
1958 	spdk_uuid_fmt_lower(info.bdev_uuid, sizeof(info.bdev_uuid), &bdev.uuid);
1959 	info.rtype = 0;
1960 	info.crkey = 0;
1961 	memset(info.holder_uuid, 0, SPDK_UUID_STRING_LEN);
1962 
1963 	rc = nvmf_ns_reservation_restore(&ns, &info);
1964 	CU_ASSERT(rc == 0);
1965 	CU_ASSERT(ns.crkey == 0);
1966 	CU_ASSERT(ns.rtype == 0);
1967 	CU_ASSERT(ns.ptpl_activated == true);
1968 	CU_ASSERT(ns.holder == NULL);
1969 	reg0 = TAILQ_FIRST(&ns.registrants);
1970 	reg1 = TAILQ_NEXT(reg0, link);
1971 	CU_ASSERT(reg0->rkey = 0xb);
1972 	CU_ASSERT(reg1->rkey = 0xc);
1973 
1974 	rc = nvmf_ns_reservation_clear_all_registrants(&ns);
1975 	CU_ASSERT(rc == 2);
1976 	CU_ASSERT(TAILQ_EMPTY(&ns.registrants));
1977 }
1978 
1979 static void
1980 test_nvmf_subsystem_state_change(void)
1981 {
1982 	struct spdk_nvmf_tgt tgt = {};
1983 	struct spdk_nvmf_subsystem *subsystem, *discovery_subsystem;
1984 	int rc;
1985 
1986 	tgt.max_subsystems = 1024;
1987 	tgt.subsystem_ids = spdk_bit_array_create(tgt.max_subsystems);
1988 	RB_INIT(&tgt.subsystems);
1989 
1990 	discovery_subsystem = spdk_nvmf_subsystem_create(&tgt, SPDK_NVMF_DISCOVERY_NQN,
1991 			      SPDK_NVMF_SUBTYPE_DISCOVERY_CURRENT, 0);
1992 	SPDK_CU_ASSERT_FATAL(discovery_subsystem != NULL);
1993 	subsystem = spdk_nvmf_subsystem_create(&tgt, "nqn.2016-06.io.spdk:subsystem1",
1994 					       SPDK_NVMF_SUBTYPE_NVME, 0);
1995 	SPDK_CU_ASSERT_FATAL(subsystem != NULL);
1996 
1997 	spdk_io_device_register(&tgt,
1998 				nvmf_tgt_create_poll_group,
1999 				nvmf_tgt_destroy_poll_group,
2000 				sizeof(struct spdk_nvmf_poll_group),
2001 				NULL);
2002 
2003 	rc = spdk_nvmf_subsystem_start(discovery_subsystem, NULL, NULL);
2004 	CU_ASSERT(rc == 0);
2005 	poll_threads();
2006 	CU_ASSERT(discovery_subsystem->state == SPDK_NVMF_SUBSYSTEM_ACTIVE);
2007 	rc = spdk_nvmf_subsystem_start(subsystem, NULL, NULL);
2008 	CU_ASSERT(rc == 0);
2009 	poll_threads();
2010 	CU_ASSERT(subsystem->state == SPDK_NVMF_SUBSYSTEM_ACTIVE);
2011 
2012 	rc = spdk_nvmf_subsystem_pause(subsystem, SPDK_NVME_GLOBAL_NS_TAG, NULL, NULL);
2013 	CU_ASSERT(rc == 0);
2014 	rc = spdk_nvmf_subsystem_stop(subsystem, NULL, NULL);
2015 	CU_ASSERT(rc == -EBUSY);
2016 	poll_threads();
2017 	CU_ASSERT(subsystem->state == SPDK_NVMF_SUBSYSTEM_PAUSED);
2018 
2019 	rc = spdk_nvmf_subsystem_stop(discovery_subsystem, NULL, NULL);
2020 	CU_ASSERT(rc == 0);
2021 	poll_threads();
2022 	CU_ASSERT(discovery_subsystem->state == SPDK_NVMF_SUBSYSTEM_INACTIVE);
2023 	rc = spdk_nvmf_subsystem_stop(subsystem, NULL, NULL);
2024 	CU_ASSERT(rc == 0);
2025 	poll_threads();
2026 	CU_ASSERT(subsystem->state == SPDK_NVMF_SUBSYSTEM_INACTIVE);
2027 
2028 	rc = spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL);
2029 	CU_ASSERT(rc == 0);
2030 	rc = spdk_nvmf_subsystem_destroy(discovery_subsystem, NULL, NULL);
2031 	CU_ASSERT(rc == 0);
2032 
2033 	spdk_io_device_unregister(&tgt, NULL);
2034 	poll_threads();
2035 
2036 	spdk_bit_array_free(&tgt.subsystem_ids);
2037 }
2038 
2039 static bool
2040 ut_is_ptpl_capable(const struct spdk_nvmf_ns *ns)
2041 {
2042 	return true;
2043 }
2044 
2045 static struct spdk_nvmf_reservation_info g_resv_info;
2046 
2047 static int
2048 ut_update_reservation(const struct spdk_nvmf_ns *ns, const struct spdk_nvmf_reservation_info *info)
2049 {
2050 	g_resv_info = *info;
2051 
2052 	return 0;
2053 }
2054 
2055 static int
2056 ut_load_reservation(const struct spdk_nvmf_ns *ns, struct spdk_nvmf_reservation_info *info)
2057 {
2058 	*info = g_resv_info;
2059 
2060 	return 0;
2061 }
2062 
2063 static void
2064 test_nvmf_reservation_custom_ops(void)
2065 {
2066 	struct spdk_nvmf_ns_reservation_ops ops = {
2067 		.is_ptpl_capable = ut_is_ptpl_capable,
2068 		.update = ut_update_reservation,
2069 		.load = ut_load_reservation,
2070 	};
2071 	struct spdk_nvmf_request *req;
2072 	struct spdk_nvme_cpl *rsp;
2073 	struct spdk_nvmf_registrant *reg;
2074 	bool update_sgroup = false;
2075 	struct spdk_nvmf_tgt tgt = {};
2076 	struct spdk_nvmf_subsystem subsystem = {
2077 		.max_nsid = 4,
2078 		.tgt = &tgt,
2079 	};
2080 	uint32_t nsid;
2081 	struct spdk_nvmf_ns *ns;
2082 	int rc;
2083 
2084 	subsystem.ns = calloc(subsystem.max_nsid, sizeof(struct spdk_nvmf_subsystem_ns *));
2085 	SPDK_CU_ASSERT_FATAL(subsystem.ns != NULL);
2086 	subsystem.ana_group = calloc(subsystem.max_nsid, sizeof(uint32_t));
2087 	SPDK_CU_ASSERT_FATAL(subsystem.ana_group != NULL);
2088 
2089 	spdk_nvmf_set_custom_ns_reservation_ops(&ops);
2090 
2091 	ut_reservation_init();
2092 
2093 	req = ut_reservation_build_req(16);
2094 	rsp = &req->rsp->nvme_cpl;
2095 	SPDK_CU_ASSERT_FATAL(req != NULL);
2096 
2097 	/* Add a registrant and activate ptpl */
2098 	ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY, 0,
2099 					      SPDK_NVME_RESERVE_PTPL_PERSIST_POWER_LOSS, 0, 0xa1);
2100 	update_sgroup = nvmf_ns_reservation_register(&g_ns, &g_ctrlr1_A, req);
2101 	SPDK_CU_ASSERT_FATAL(update_sgroup == true);
2102 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
2103 	SPDK_CU_ASSERT_FATAL(g_ns.ptpl_activated == true);
2104 	rc = nvmf_ns_update_reservation_info(&g_ns);
2105 	SPDK_CU_ASSERT_FATAL(rc == 0);
2106 
2107 	/* Acquire a reservation */
2108 	rsp->status.sc = SPDK_NVME_SC_INVALID_FIELD;
2109 	ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0,
2110 					     SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xa1, 0x0);
2111 	update_sgroup = nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr1_A, req);
2112 	SPDK_CU_ASSERT_FATAL(update_sgroup == true);
2113 	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
2114 	rc = nvmf_ns_update_reservation_info(&g_ns);
2115 	SPDK_CU_ASSERT_FATAL(rc == 0);
2116 
2117 	/* Add the namespace using a different subsystem.
2118 	 * Reservation information should be restored. */
2119 	nsid = spdk_nvmf_subsystem_add_ns_ext(&subsystem, g_ns.bdev->name, NULL, 0, NULL);
2120 	CU_ASSERT(nsid == 1);
2121 
2122 	ns = _nvmf_subsystem_get_ns(&subsystem, nsid);
2123 	SPDK_CU_ASSERT_FATAL(ns != NULL);
2124 	CU_ASSERT(ns->crkey == 0xa1);
2125 	CU_ASSERT(ns->rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY);
2126 	CU_ASSERT(ns->ptpl_activated == true);
2127 
2128 	reg = nvmf_ns_reservation_get_registrant(ns, &g_ctrlr1_A.hostid);
2129 	SPDK_CU_ASSERT_FATAL(reg != NULL);
2130 	SPDK_CU_ASSERT_FATAL(!spdk_uuid_compare(&g_ctrlr1_A.hostid, &reg->hostid));
2131 	CU_ASSERT(reg == ns->holder);
2132 
2133 	rc = spdk_nvmf_subsystem_remove_ns(&subsystem, nsid);
2134 	CU_ASSERT(rc == 0);
2135 
2136 	free(subsystem.ns);
2137 	free(subsystem.ana_group);
2138 	ut_reservation_free_req(req);
2139 	ut_reservation_deinit();
2140 }
2141 
2142 int
2143 main(int argc, char **argv)
2144 {
2145 	CU_pSuite	suite = NULL;
2146 	unsigned int	num_failures;
2147 
2148 	CU_initialize_registry();
2149 
2150 	suite = CU_add_suite("nvmf", NULL, NULL);
2151 
2152 	CU_ADD_TEST(suite, nvmf_test_create_subsystem);
2153 	CU_ADD_TEST(suite, test_spdk_nvmf_subsystem_add_ns);
2154 	CU_ADD_TEST(suite, test_spdk_nvmf_subsystem_set_sn);
2155 	CU_ADD_TEST(suite, test_spdk_nvmf_ns_visible);
2156 	CU_ADD_TEST(suite, test_reservation_register);
2157 	CU_ADD_TEST(suite, test_reservation_register_with_ptpl);
2158 	CU_ADD_TEST(suite, test_reservation_acquire_preempt_1);
2159 	CU_ADD_TEST(suite, test_reservation_acquire_release_with_ptpl);
2160 	CU_ADD_TEST(suite, test_reservation_release);
2161 	CU_ADD_TEST(suite, test_reservation_unregister_notification);
2162 	CU_ADD_TEST(suite, test_reservation_release_notification);
2163 	CU_ADD_TEST(suite, test_reservation_release_notification_write_exclusive);
2164 	CU_ADD_TEST(suite, test_reservation_clear_notification);
2165 	CU_ADD_TEST(suite, test_reservation_preempt_notification);
2166 	CU_ADD_TEST(suite, test_spdk_nvmf_ns_event);
2167 	CU_ADD_TEST(suite, test_nvmf_ns_reservation_add_remove_registrant);
2168 	CU_ADD_TEST(suite, test_nvmf_subsystem_add_ctrlr);
2169 	CU_ADD_TEST(suite, test_spdk_nvmf_subsystem_add_host);
2170 	CU_ADD_TEST(suite, test_nvmf_ns_reservation_report);
2171 	CU_ADD_TEST(suite, test_nvmf_nqn_is_valid);
2172 	CU_ADD_TEST(suite, test_nvmf_ns_reservation_restore);
2173 	CU_ADD_TEST(suite, test_nvmf_subsystem_state_change);
2174 	CU_ADD_TEST(suite, test_nvmf_reservation_custom_ops);
2175 
2176 	allocate_threads(1);
2177 	set_thread(0);
2178 
2179 	num_failures = spdk_ut_run_tests(argc, argv, NULL);
2180 	CU_cleanup_registry();
2181 
2182 	free_threads();
2183 
2184 	return num_failures;
2185 }
2186