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 "spdk_cunit.h" 37 #include "spdk_internal/mock.h" 38 #include "spdk_internal/thread.h" 39 40 #include "common/lib/ut_multithread.c" 41 #include "nvmf/ctrlr.c" 42 43 SPDK_LOG_REGISTER_COMPONENT("nvmf", SPDK_LOG_NVMF) 44 45 struct spdk_bdev { 46 int ut_mock; 47 uint64_t blockcnt; 48 }; 49 50 const char subsystem_default_sn[SPDK_NVME_CTRLR_SN_LEN + 1] = "subsys_default_sn"; 51 const char subsystem_default_mn[SPDK_NVME_CTRLR_MN_LEN + 1] = "subsys_default_mn"; 52 53 DEFINE_STUB(spdk_nvmf_tgt_find_subsystem, 54 struct spdk_nvmf_subsystem *, 55 (struct spdk_nvmf_tgt *tgt, const char *subnqn), 56 NULL); 57 58 DEFINE_STUB(spdk_nvmf_poll_group_create, 59 struct spdk_nvmf_poll_group *, 60 (struct spdk_nvmf_tgt *tgt), 61 NULL); 62 63 DEFINE_STUB(spdk_nvmf_subsystem_get_sn, 64 const char *, 65 (const struct spdk_nvmf_subsystem *subsystem), 66 subsystem_default_sn); 67 68 DEFINE_STUB(spdk_nvmf_subsystem_get_mn, 69 const char *, 70 (const struct spdk_nvmf_subsystem *subsystem), 71 subsystem_default_mn); 72 73 DEFINE_STUB(spdk_nvmf_subsystem_get_first_ns, 74 struct spdk_nvmf_ns *, 75 (struct spdk_nvmf_subsystem *subsystem), 76 NULL); 77 78 DEFINE_STUB(spdk_nvmf_subsystem_get_next_ns, 79 struct spdk_nvmf_ns *, 80 (struct spdk_nvmf_subsystem *subsystem, struct spdk_nvmf_ns *prev_ns), 81 NULL); 82 83 DEFINE_STUB(spdk_nvmf_subsystem_host_allowed, 84 bool, 85 (struct spdk_nvmf_subsystem *subsystem, const char *hostnqn), 86 true); 87 88 DEFINE_STUB(nvmf_subsystem_add_ctrlr, 89 int, 90 (struct spdk_nvmf_subsystem *subsystem, struct spdk_nvmf_ctrlr *ctrlr), 91 0); 92 93 DEFINE_STUB(nvmf_subsystem_get_ctrlr, 94 struct spdk_nvmf_ctrlr *, 95 (struct spdk_nvmf_subsystem *subsystem, uint16_t cntlid), 96 NULL); 97 98 DEFINE_STUB(nvmf_ctrlr_dsm_supported, 99 bool, 100 (struct spdk_nvmf_ctrlr *ctrlr), 101 false); 102 103 DEFINE_STUB(nvmf_ctrlr_write_zeroes_supported, 104 bool, 105 (struct spdk_nvmf_ctrlr *ctrlr), 106 false); 107 108 DEFINE_STUB_V(nvmf_get_discovery_log_page, 109 (struct spdk_nvmf_tgt *tgt, const char *hostnqn, struct iovec *iov, 110 uint32_t iovcnt, uint64_t offset, uint32_t length)); 111 112 DEFINE_STUB(spdk_nvmf_qpair_get_listen_trid, 113 int, 114 (struct spdk_nvmf_qpair *qpair, struct spdk_nvme_transport_id *trid), 115 0); 116 117 DEFINE_STUB(spdk_nvmf_subsystem_listener_allowed, 118 bool, 119 (struct spdk_nvmf_subsystem *subsystem, const struct spdk_nvme_transport_id *trid), 120 true); 121 122 DEFINE_STUB(nvmf_bdev_ctrlr_read_cmd, 123 int, 124 (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 125 struct spdk_nvmf_request *req), 126 0); 127 128 DEFINE_STUB(nvmf_bdev_ctrlr_write_cmd, 129 int, 130 (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 131 struct spdk_nvmf_request *req), 132 0); 133 134 DEFINE_STUB(nvmf_bdev_ctrlr_compare_cmd, 135 int, 136 (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 137 struct spdk_nvmf_request *req), 138 0); 139 140 DEFINE_STUB(nvmf_bdev_ctrlr_compare_and_write_cmd, 141 int, 142 (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 143 struct spdk_nvmf_request *cmp_req, struct spdk_nvmf_request *write_req), 144 0); 145 146 DEFINE_STUB(nvmf_bdev_ctrlr_write_zeroes_cmd, 147 int, 148 (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 149 struct spdk_nvmf_request *req), 150 0); 151 152 DEFINE_STUB(nvmf_bdev_ctrlr_flush_cmd, 153 int, 154 (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 155 struct spdk_nvmf_request *req), 156 0); 157 158 DEFINE_STUB(nvmf_bdev_ctrlr_dsm_cmd, 159 int, 160 (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 161 struct spdk_nvmf_request *req), 162 0); 163 164 DEFINE_STUB(nvmf_bdev_ctrlr_nvme_passthru_io, 165 int, 166 (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 167 struct spdk_nvmf_request *req), 168 0); 169 170 DEFINE_STUB(nvmf_transport_req_complete, 171 int, 172 (struct spdk_nvmf_request *req), 173 0); 174 175 DEFINE_STUB_V(nvmf_ns_reservation_request, (void *ctx)); 176 177 DEFINE_STUB(nvmf_bdev_ctrlr_get_dif_ctx, bool, 178 (struct spdk_bdev *bdev, struct spdk_nvme_cmd *cmd, 179 struct spdk_dif_ctx *dif_ctx), 180 true); 181 182 DEFINE_STUB_V(nvmf_transport_qpair_abort_request, 183 (struct spdk_nvmf_qpair *qpair, struct spdk_nvmf_request *req)); 184 185 DEFINE_STUB_V(spdk_nvme_print_command, (uint16_t qid, struct spdk_nvme_cmd *cmd)); 186 DEFINE_STUB_V(spdk_nvme_print_completion, (uint16_t qid, struct spdk_nvme_cpl *cpl)); 187 188 int 189 spdk_nvmf_qpair_disconnect(struct spdk_nvmf_qpair *qpair, nvmf_qpair_disconnect_cb cb_fn, void *ctx) 190 { 191 return 0; 192 } 193 194 void 195 nvmf_bdev_ctrlr_identify_ns(struct spdk_nvmf_ns *ns, struct spdk_nvme_ns_data *nsdata, 196 bool dif_insert_or_strip) 197 { 198 uint64_t num_blocks; 199 200 SPDK_CU_ASSERT_FATAL(ns->bdev != NULL); 201 num_blocks = ns->bdev->blockcnt; 202 nsdata->nsze = num_blocks; 203 nsdata->ncap = num_blocks; 204 nsdata->nuse = num_blocks; 205 nsdata->nlbaf = 0; 206 nsdata->flbas.format = 0; 207 nsdata->lbaf[0].lbads = spdk_u32log2(512); 208 } 209 210 static void 211 test_get_log_page(void) 212 { 213 struct spdk_nvmf_subsystem subsystem = {}; 214 struct spdk_nvmf_request req = {}; 215 struct spdk_nvmf_qpair qpair = {}; 216 struct spdk_nvmf_ctrlr ctrlr = {}; 217 union nvmf_h2c_msg cmd = {}; 218 union nvmf_c2h_msg rsp = {}; 219 char data[4096]; 220 221 subsystem.subtype = SPDK_NVMF_SUBTYPE_NVME; 222 223 ctrlr.subsys = &subsystem; 224 225 qpair.ctrlr = &ctrlr; 226 227 req.qpair = &qpair; 228 req.cmd = &cmd; 229 req.rsp = &rsp; 230 req.data = &data; 231 req.length = sizeof(data); 232 233 /* Get Log Page - all valid */ 234 memset(&cmd, 0, sizeof(cmd)); 235 memset(&rsp, 0, sizeof(rsp)); 236 cmd.nvme_cmd.opc = SPDK_NVME_OPC_GET_LOG_PAGE; 237 cmd.nvme_cmd.cdw10_bits.get_log_page.lid = SPDK_NVME_LOG_ERROR; 238 cmd.nvme_cmd.cdw10_bits.get_log_page.numdl = (req.length / 4 - 1); 239 CU_ASSERT(nvmf_ctrlr_get_log_page(&req) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 240 CU_ASSERT(req.rsp->nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 241 CU_ASSERT(req.rsp->nvme_cpl.status.sc == SPDK_NVME_SC_SUCCESS); 242 243 /* Get Log Page with invalid log ID */ 244 memset(&cmd, 0, sizeof(cmd)); 245 memset(&rsp, 0, sizeof(rsp)); 246 cmd.nvme_cmd.opc = SPDK_NVME_OPC_GET_LOG_PAGE; 247 cmd.nvme_cmd.cdw10 = 0; 248 CU_ASSERT(nvmf_ctrlr_get_log_page(&req) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 249 CU_ASSERT(req.rsp->nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 250 CU_ASSERT(req.rsp->nvme_cpl.status.sc == SPDK_NVME_SC_INVALID_FIELD); 251 252 /* Get Log Page with invalid offset (not dword aligned) */ 253 memset(&cmd, 0, sizeof(cmd)); 254 memset(&rsp, 0, sizeof(rsp)); 255 cmd.nvme_cmd.opc = SPDK_NVME_OPC_GET_LOG_PAGE; 256 cmd.nvme_cmd.cdw10_bits.get_log_page.lid = SPDK_NVME_LOG_ERROR; 257 cmd.nvme_cmd.cdw10_bits.get_log_page.numdl = (req.length / 4 - 1); 258 cmd.nvme_cmd.cdw12 = 2; 259 CU_ASSERT(nvmf_ctrlr_get_log_page(&req) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 260 CU_ASSERT(req.rsp->nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 261 CU_ASSERT(req.rsp->nvme_cpl.status.sc == SPDK_NVME_SC_INVALID_FIELD); 262 263 /* Get Log Page without data buffer */ 264 memset(&cmd, 0, sizeof(cmd)); 265 memset(&rsp, 0, sizeof(rsp)); 266 req.data = NULL; 267 cmd.nvme_cmd.opc = SPDK_NVME_OPC_GET_LOG_PAGE; 268 cmd.nvme_cmd.cdw10_bits.get_log_page.lid = SPDK_NVME_LOG_ERROR; 269 cmd.nvme_cmd.cdw10_bits.get_log_page.numdl = (req.length / 4 - 1); 270 CU_ASSERT(nvmf_ctrlr_get_log_page(&req) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 271 CU_ASSERT(req.rsp->nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 272 CU_ASSERT(req.rsp->nvme_cpl.status.sc == SPDK_NVME_SC_INVALID_FIELD); 273 req.data = data; 274 } 275 276 static void 277 test_process_fabrics_cmd(void) 278 { 279 struct spdk_nvmf_request req = {}; 280 int ret; 281 struct spdk_nvmf_qpair req_qpair = {}; 282 union nvmf_h2c_msg req_cmd = {}; 283 union nvmf_c2h_msg req_rsp = {}; 284 285 req.qpair = &req_qpair; 286 req.cmd = &req_cmd; 287 req.rsp = &req_rsp; 288 req.qpair->ctrlr = NULL; 289 290 /* No ctrlr and invalid command check */ 291 req.cmd->nvmf_cmd.fctype = SPDK_NVMF_FABRIC_COMMAND_PROPERTY_GET; 292 ret = nvmf_ctrlr_process_fabrics_cmd(&req); 293 CU_ASSERT_EQUAL(req.rsp->nvme_cpl.status.sc, SPDK_NVME_SC_COMMAND_SEQUENCE_ERROR); 294 CU_ASSERT_EQUAL(ret, SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 295 } 296 297 static bool 298 nvme_status_success(const struct spdk_nvme_status *status) 299 { 300 return status->sct == SPDK_NVME_SCT_GENERIC && status->sc == SPDK_NVME_SC_SUCCESS; 301 } 302 303 static void 304 test_connect(void) 305 { 306 struct spdk_nvmf_fabric_connect_data connect_data; 307 struct spdk_nvmf_poll_group group; 308 struct spdk_nvmf_subsystem_poll_group *sgroups; 309 struct spdk_nvmf_transport transport; 310 struct spdk_nvmf_transport_ops tops = {}; 311 struct spdk_nvmf_subsystem subsystem; 312 struct spdk_nvmf_request req; 313 struct spdk_nvmf_qpair admin_qpair; 314 struct spdk_nvmf_qpair qpair; 315 struct spdk_nvmf_qpair qpair2; 316 struct spdk_nvmf_ctrlr ctrlr; 317 struct spdk_nvmf_tgt tgt; 318 union nvmf_h2c_msg cmd; 319 union nvmf_c2h_msg rsp; 320 const uint8_t hostid[16] = { 321 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 322 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F 323 }; 324 const char subnqn[] = "nqn.2016-06.io.spdk:subsystem1"; 325 const char hostnqn[] = "nqn.2016-06.io.spdk:host1"; 326 int rc; 327 328 memset(&group, 0, sizeof(group)); 329 group.thread = spdk_get_thread(); 330 331 memset(&ctrlr, 0, sizeof(ctrlr)); 332 ctrlr.subsys = &subsystem; 333 ctrlr.qpair_mask = spdk_bit_array_create(3); 334 SPDK_CU_ASSERT_FATAL(ctrlr.qpair_mask != NULL); 335 ctrlr.vcprop.cc.bits.en = 1; 336 ctrlr.vcprop.cc.bits.iosqes = 6; 337 ctrlr.vcprop.cc.bits.iocqes = 4; 338 339 memset(&admin_qpair, 0, sizeof(admin_qpair)); 340 admin_qpair.group = &group; 341 342 memset(&tgt, 0, sizeof(tgt)); 343 memset(&transport, 0, sizeof(transport)); 344 transport.ops = &tops; 345 transport.opts.max_aq_depth = 32; 346 transport.opts.max_queue_depth = 64; 347 transport.opts.max_qpairs_per_ctrlr = 3; 348 transport.tgt = &tgt; 349 350 memset(&qpair, 0, sizeof(qpair)); 351 qpair.transport = &transport; 352 qpair.group = &group; 353 qpair.state = SPDK_NVMF_QPAIR_ACTIVE; 354 TAILQ_INIT(&qpair.outstanding); 355 356 memset(&connect_data, 0, sizeof(connect_data)); 357 memcpy(connect_data.hostid, hostid, sizeof(hostid)); 358 connect_data.cntlid = 0xFFFF; 359 snprintf(connect_data.subnqn, sizeof(connect_data.subnqn), "%s", subnqn); 360 snprintf(connect_data.hostnqn, sizeof(connect_data.hostnqn), "%s", hostnqn); 361 362 memset(&subsystem, 0, sizeof(subsystem)); 363 subsystem.thread = spdk_get_thread(); 364 subsystem.id = 1; 365 TAILQ_INIT(&subsystem.ctrlrs); 366 subsystem.tgt = &tgt; 367 subsystem.subtype = SPDK_NVMF_SUBTYPE_NVME; 368 subsystem.state = SPDK_NVMF_SUBSYSTEM_ACTIVE; 369 snprintf(subsystem.subnqn, sizeof(subsystem.subnqn), "%s", subnqn); 370 371 sgroups = calloc(subsystem.id + 1, sizeof(struct spdk_nvmf_subsystem_poll_group)); 372 group.sgroups = sgroups; 373 374 memset(&cmd, 0, sizeof(cmd)); 375 cmd.connect_cmd.opcode = SPDK_NVME_OPC_FABRIC; 376 cmd.connect_cmd.cid = 1; 377 cmd.connect_cmd.fctype = SPDK_NVMF_FABRIC_COMMAND_CONNECT; 378 cmd.connect_cmd.recfmt = 0; 379 cmd.connect_cmd.qid = 0; 380 cmd.connect_cmd.sqsize = 31; 381 cmd.connect_cmd.cattr = 0; 382 cmd.connect_cmd.kato = 120000; 383 384 memset(&req, 0, sizeof(req)); 385 req.qpair = &qpair; 386 req.length = sizeof(connect_data); 387 req.xfer = SPDK_NVME_DATA_HOST_TO_CONTROLLER; 388 req.data = &connect_data; 389 req.cmd = &cmd; 390 req.rsp = &rsp; 391 392 MOCK_SET(spdk_nvmf_tgt_find_subsystem, &subsystem); 393 MOCK_SET(spdk_nvmf_poll_group_create, &group); 394 395 /* Valid admin connect command */ 396 memset(&rsp, 0, sizeof(rsp)); 397 sgroups[subsystem.id].io_outstanding++; 398 TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 399 rc = nvmf_ctrlr_cmd_connect(&req); 400 poll_threads(); 401 CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS); 402 CU_ASSERT(nvme_status_success(&rsp.nvme_cpl.status)); 403 CU_ASSERT(qpair.ctrlr != NULL); 404 CU_ASSERT(sgroups[subsystem.id].io_outstanding == 0); 405 nvmf_ctrlr_stop_keep_alive_timer(qpair.ctrlr); 406 spdk_bit_array_free(&qpair.ctrlr->qpair_mask); 407 free(qpair.ctrlr); 408 qpair.ctrlr = NULL; 409 410 /* Valid admin connect command with kato = 0 */ 411 cmd.connect_cmd.kato = 0; 412 memset(&rsp, 0, sizeof(rsp)); 413 sgroups[subsystem.id].io_outstanding++; 414 TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 415 rc = nvmf_ctrlr_cmd_connect(&req); 416 poll_threads(); 417 CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS); 418 CU_ASSERT(nvme_status_success(&rsp.nvme_cpl.status)); 419 CU_ASSERT(qpair.ctrlr != NULL && qpair.ctrlr->keep_alive_poller == NULL); 420 CU_ASSERT(sgroups[subsystem.id].io_outstanding == 0); 421 spdk_bit_array_free(&qpair.ctrlr->qpair_mask); 422 free(qpair.ctrlr); 423 qpair.ctrlr = NULL; 424 cmd.connect_cmd.kato = 120000; 425 426 /* Invalid data length */ 427 memset(&rsp, 0, sizeof(rsp)); 428 req.length = sizeof(connect_data) - 1; 429 TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 430 rc = nvmf_ctrlr_cmd_connect(&req); 431 poll_threads(); 432 CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 433 CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 434 CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_INVALID_FIELD); 435 CU_ASSERT(qpair.ctrlr == NULL); 436 req.length = sizeof(connect_data); 437 438 /* Invalid recfmt */ 439 memset(&rsp, 0, sizeof(rsp)); 440 cmd.connect_cmd.recfmt = 1234; 441 TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 442 rc = nvmf_ctrlr_cmd_connect(&req); 443 poll_threads(); 444 CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 445 CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC); 446 CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVMF_FABRIC_SC_INCOMPATIBLE_FORMAT); 447 CU_ASSERT(qpair.ctrlr == NULL); 448 cmd.connect_cmd.recfmt = 0; 449 450 /* Subsystem not found */ 451 memset(&rsp, 0, sizeof(rsp)); 452 MOCK_SET(spdk_nvmf_tgt_find_subsystem, NULL); 453 TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 454 rc = nvmf_ctrlr_cmd_connect(&req); 455 poll_threads(); 456 CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 457 CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC); 458 CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVMF_FABRIC_SC_INVALID_PARAM); 459 CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.iattr == 1); 460 CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.ipo == 256); 461 CU_ASSERT(qpair.ctrlr == NULL); 462 MOCK_SET(spdk_nvmf_tgt_find_subsystem, &subsystem); 463 464 /* Unterminated hostnqn */ 465 memset(&rsp, 0, sizeof(rsp)); 466 memset(connect_data.hostnqn, 'b', sizeof(connect_data.hostnqn)); 467 TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 468 rc = nvmf_ctrlr_cmd_connect(&req); 469 poll_threads(); 470 CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 471 CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC); 472 CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVMF_FABRIC_SC_INVALID_PARAM); 473 CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.iattr == 1); 474 CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.ipo == 512); 475 CU_ASSERT(qpair.ctrlr == NULL); 476 snprintf(connect_data.hostnqn, sizeof(connect_data.hostnqn), "%s", hostnqn); 477 478 /* Host not allowed */ 479 memset(&rsp, 0, sizeof(rsp)); 480 MOCK_SET(spdk_nvmf_subsystem_host_allowed, false); 481 TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 482 rc = nvmf_ctrlr_cmd_connect(&req); 483 poll_threads(); 484 CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 485 CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC); 486 CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVMF_FABRIC_SC_INVALID_HOST); 487 CU_ASSERT(qpair.ctrlr == NULL); 488 MOCK_SET(spdk_nvmf_subsystem_host_allowed, true); 489 490 /* Invalid sqsize == 0 */ 491 memset(&rsp, 0, sizeof(rsp)); 492 cmd.connect_cmd.sqsize = 0; 493 TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 494 rc = nvmf_ctrlr_cmd_connect(&req); 495 poll_threads(); 496 CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 497 CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC); 498 CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVMF_FABRIC_SC_INVALID_PARAM); 499 CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.iattr == 0); 500 CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.ipo == 44); 501 CU_ASSERT(qpair.ctrlr == NULL); 502 cmd.connect_cmd.sqsize = 31; 503 504 /* Invalid admin sqsize > max_aq_depth */ 505 memset(&rsp, 0, sizeof(rsp)); 506 cmd.connect_cmd.sqsize = 32; 507 TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 508 rc = nvmf_ctrlr_cmd_connect(&req); 509 poll_threads(); 510 CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 511 CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC); 512 CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVMF_FABRIC_SC_INVALID_PARAM); 513 CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.iattr == 0); 514 CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.ipo == 44); 515 CU_ASSERT(qpair.ctrlr == NULL); 516 cmd.connect_cmd.sqsize = 31; 517 518 /* Invalid I/O sqsize > max_queue_depth */ 519 memset(&rsp, 0, sizeof(rsp)); 520 cmd.connect_cmd.qid = 1; 521 cmd.connect_cmd.sqsize = 64; 522 TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 523 rc = nvmf_ctrlr_cmd_connect(&req); 524 poll_threads(); 525 CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 526 CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC); 527 CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVMF_FABRIC_SC_INVALID_PARAM); 528 CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.iattr == 0); 529 CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.ipo == 44); 530 CU_ASSERT(qpair.ctrlr == NULL); 531 cmd.connect_cmd.qid = 0; 532 cmd.connect_cmd.sqsize = 31; 533 534 /* Invalid cntlid for admin queue */ 535 memset(&rsp, 0, sizeof(rsp)); 536 connect_data.cntlid = 0x1234; 537 TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 538 rc = nvmf_ctrlr_cmd_connect(&req); 539 poll_threads(); 540 CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 541 CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC); 542 CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVMF_FABRIC_SC_INVALID_PARAM); 543 CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.iattr == 1); 544 CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.ipo == 16); 545 CU_ASSERT(qpair.ctrlr == NULL); 546 connect_data.cntlid = 0xFFFF; 547 548 ctrlr.admin_qpair = &admin_qpair; 549 ctrlr.subsys = &subsystem; 550 551 /* Valid I/O queue connect command */ 552 memset(&rsp, 0, sizeof(rsp)); 553 MOCK_SET(nvmf_subsystem_get_ctrlr, &ctrlr); 554 cmd.connect_cmd.qid = 1; 555 cmd.connect_cmd.sqsize = 63; 556 sgroups[subsystem.id].io_outstanding++; 557 TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 558 rc = nvmf_ctrlr_cmd_connect(&req); 559 poll_threads(); 560 CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS); 561 CU_ASSERT(nvme_status_success(&rsp.nvme_cpl.status)); 562 CU_ASSERT(qpair.ctrlr == &ctrlr); 563 CU_ASSERT(sgroups[subsystem.id].io_outstanding == 0); 564 qpair.ctrlr = NULL; 565 cmd.connect_cmd.sqsize = 31; 566 567 /* Non-existent controller */ 568 memset(&rsp, 0, sizeof(rsp)); 569 MOCK_SET(nvmf_subsystem_get_ctrlr, NULL); 570 sgroups[subsystem.id].io_outstanding++; 571 TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 572 rc = nvmf_ctrlr_cmd_connect(&req); 573 poll_threads(); 574 CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS); 575 CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC); 576 CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVMF_FABRIC_SC_INVALID_PARAM); 577 CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.iattr == 1); 578 CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.ipo == 16); 579 CU_ASSERT(qpair.ctrlr == NULL); 580 CU_ASSERT(sgroups[subsystem.id].io_outstanding == 0); 581 MOCK_SET(nvmf_subsystem_get_ctrlr, &ctrlr); 582 583 /* I/O connect to discovery controller */ 584 memset(&rsp, 0, sizeof(rsp)); 585 subsystem.subtype = SPDK_NVMF_SUBTYPE_DISCOVERY; 586 subsystem.state = SPDK_NVMF_SUBSYSTEM_ACTIVE; 587 sgroups[subsystem.id].io_outstanding++; 588 TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 589 rc = nvmf_ctrlr_cmd_connect(&req); 590 poll_threads(); 591 CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS); 592 CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC); 593 CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVMF_FABRIC_SC_INVALID_PARAM); 594 CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.iattr == 0); 595 CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.ipo == 42); 596 CU_ASSERT(qpair.ctrlr == NULL); 597 CU_ASSERT(sgroups[subsystem.id].io_outstanding == 0); 598 599 /* I/O connect to discovery controller with keep-alive-timeout != 0 */ 600 cmd.connect_cmd.qid = 0; 601 cmd.connect_cmd.kato = 120000; 602 memset(&rsp, 0, sizeof(rsp)); 603 subsystem.subtype = SPDK_NVMF_SUBTYPE_DISCOVERY; 604 subsystem.state = SPDK_NVMF_SUBSYSTEM_ACTIVE; 605 sgroups[subsystem.id].io_outstanding++; 606 TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 607 rc = nvmf_ctrlr_cmd_connect(&req); 608 poll_threads(); 609 CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS); 610 CU_ASSERT(nvme_status_success(&rsp.nvme_cpl.status)); 611 CU_ASSERT(qpair.ctrlr != NULL); 612 CU_ASSERT(qpair.ctrlr->keep_alive_poller != NULL); 613 CU_ASSERT(sgroups[subsystem.id].io_outstanding == 0); 614 nvmf_ctrlr_stop_keep_alive_timer(qpair.ctrlr); 615 spdk_bit_array_free(&qpair.ctrlr->qpair_mask); 616 free(qpair.ctrlr); 617 qpair.ctrlr = NULL; 618 619 /* I/O connect to discovery controller with keep-alive-timeout == 0. 620 * Then, a fixed timeout value is set to keep-alive-timeout. 621 */ 622 cmd.connect_cmd.kato = 0; 623 memset(&rsp, 0, sizeof(rsp)); 624 subsystem.subtype = SPDK_NVMF_SUBTYPE_DISCOVERY; 625 subsystem.state = SPDK_NVMF_SUBSYSTEM_ACTIVE; 626 sgroups[subsystem.id].io_outstanding++; 627 TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 628 rc = nvmf_ctrlr_cmd_connect(&req); 629 poll_threads(); 630 CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS); 631 CU_ASSERT(nvme_status_success(&rsp.nvme_cpl.status)); 632 CU_ASSERT(qpair.ctrlr != NULL); 633 CU_ASSERT(qpair.ctrlr->keep_alive_poller != NULL); 634 CU_ASSERT(sgroups[subsystem.id].io_outstanding == 0); 635 nvmf_ctrlr_stop_keep_alive_timer(qpair.ctrlr); 636 spdk_bit_array_free(&qpair.ctrlr->qpair_mask); 637 free(qpair.ctrlr); 638 qpair.ctrlr = NULL; 639 cmd.connect_cmd.qid = 1; 640 cmd.connect_cmd.kato = 120000; 641 subsystem.subtype = SPDK_NVMF_SUBTYPE_NVME; 642 643 /* I/O connect to disabled controller */ 644 memset(&rsp, 0, sizeof(rsp)); 645 ctrlr.vcprop.cc.bits.en = 0; 646 sgroups[subsystem.id].io_outstanding++; 647 TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 648 rc = nvmf_ctrlr_cmd_connect(&req); 649 poll_threads(); 650 CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS); 651 CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC); 652 CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVMF_FABRIC_SC_INVALID_PARAM); 653 CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.iattr == 0); 654 CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.ipo == 42); 655 CU_ASSERT(qpair.ctrlr == NULL); 656 CU_ASSERT(sgroups[subsystem.id].io_outstanding == 0); 657 ctrlr.vcprop.cc.bits.en = 1; 658 659 /* I/O connect with invalid IOSQES */ 660 memset(&rsp, 0, sizeof(rsp)); 661 ctrlr.vcprop.cc.bits.iosqes = 3; 662 sgroups[subsystem.id].io_outstanding++; 663 TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 664 rc = nvmf_ctrlr_cmd_connect(&req); 665 poll_threads(); 666 CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS); 667 CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC); 668 CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVMF_FABRIC_SC_INVALID_PARAM); 669 CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.iattr == 0); 670 CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.ipo == 42); 671 CU_ASSERT(qpair.ctrlr == NULL); 672 CU_ASSERT(sgroups[subsystem.id].io_outstanding == 0); 673 ctrlr.vcprop.cc.bits.iosqes = 6; 674 675 /* I/O connect with invalid IOCQES */ 676 memset(&rsp, 0, sizeof(rsp)); 677 ctrlr.vcprop.cc.bits.iocqes = 3; 678 sgroups[subsystem.id].io_outstanding++; 679 TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 680 rc = nvmf_ctrlr_cmd_connect(&req); 681 poll_threads(); 682 CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS); 683 CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC); 684 CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVMF_FABRIC_SC_INVALID_PARAM); 685 CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.iattr == 0); 686 CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.ipo == 42); 687 CU_ASSERT(qpair.ctrlr == NULL); 688 CU_ASSERT(sgroups[subsystem.id].io_outstanding == 0); 689 ctrlr.vcprop.cc.bits.iocqes = 4; 690 691 /* I/O connect with too many existing qpairs */ 692 memset(&rsp, 0, sizeof(rsp)); 693 spdk_bit_array_set(ctrlr.qpair_mask, 0); 694 spdk_bit_array_set(ctrlr.qpair_mask, 1); 695 spdk_bit_array_set(ctrlr.qpair_mask, 2); 696 sgroups[subsystem.id].io_outstanding++; 697 TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 698 rc = nvmf_ctrlr_cmd_connect(&req); 699 poll_threads(); 700 CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS); 701 CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC); 702 CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_INVALID_QUEUE_IDENTIFIER); 703 CU_ASSERT(qpair.ctrlr == NULL); 704 CU_ASSERT(sgroups[subsystem.id].io_outstanding == 0); 705 spdk_bit_array_clear(ctrlr.qpair_mask, 0); 706 spdk_bit_array_clear(ctrlr.qpair_mask, 1); 707 spdk_bit_array_clear(ctrlr.qpair_mask, 2); 708 709 /* I/O connect with duplicate queue ID */ 710 memset(&rsp, 0, sizeof(rsp)); 711 memset(&qpair2, 0, sizeof(qpair2)); 712 qpair2.group = &group; 713 qpair2.qid = 1; 714 spdk_bit_array_set(ctrlr.qpair_mask, 1); 715 cmd.connect_cmd.qid = 1; 716 sgroups[subsystem.id].io_outstanding++; 717 TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 718 rc = nvmf_ctrlr_cmd_connect(&req); 719 poll_threads(); 720 CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS); 721 CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC); 722 CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_INVALID_QUEUE_IDENTIFIER); 723 CU_ASSERT(qpair.ctrlr == NULL); 724 CU_ASSERT(sgroups[subsystem.id].io_outstanding == 0); 725 726 /* Clean up globals */ 727 MOCK_CLEAR(spdk_nvmf_tgt_find_subsystem); 728 MOCK_CLEAR(spdk_nvmf_poll_group_create); 729 730 spdk_bit_array_free(&ctrlr.qpair_mask); 731 free(sgroups); 732 } 733 734 static void 735 test_get_ns_id_desc_list(void) 736 { 737 struct spdk_nvmf_subsystem subsystem; 738 struct spdk_nvmf_qpair qpair; 739 struct spdk_nvmf_ctrlr ctrlr; 740 struct spdk_nvmf_request req; 741 struct spdk_nvmf_ns *ns_ptrs[1]; 742 struct spdk_nvmf_ns ns; 743 union nvmf_h2c_msg cmd; 744 union nvmf_c2h_msg rsp; 745 struct spdk_bdev bdev; 746 uint8_t buf[4096]; 747 748 memset(&subsystem, 0, sizeof(subsystem)); 749 ns_ptrs[0] = &ns; 750 subsystem.ns = ns_ptrs; 751 subsystem.max_nsid = 1; 752 subsystem.subtype = SPDK_NVMF_SUBTYPE_NVME; 753 754 memset(&ns, 0, sizeof(ns)); 755 ns.opts.nsid = 1; 756 ns.bdev = &bdev; 757 758 memset(&qpair, 0, sizeof(qpair)); 759 qpair.ctrlr = &ctrlr; 760 761 memset(&ctrlr, 0, sizeof(ctrlr)); 762 ctrlr.subsys = &subsystem; 763 ctrlr.vcprop.cc.bits.en = 1; 764 765 memset(&req, 0, sizeof(req)); 766 req.qpair = &qpair; 767 req.cmd = &cmd; 768 req.rsp = &rsp; 769 req.xfer = SPDK_NVME_DATA_CONTROLLER_TO_HOST; 770 req.data = buf; 771 req.length = sizeof(buf); 772 773 memset(&cmd, 0, sizeof(cmd)); 774 cmd.nvme_cmd.opc = SPDK_NVME_OPC_IDENTIFY; 775 cmd.nvme_cmd.cdw10_bits.identify.cns = SPDK_NVME_IDENTIFY_NS_ID_DESCRIPTOR_LIST; 776 777 /* Invalid NSID */ 778 cmd.nvme_cmd.nsid = 0; 779 memset(&rsp, 0, sizeof(rsp)); 780 CU_ASSERT(nvmf_ctrlr_process_admin_cmd(&req) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 781 CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 782 CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_INVALID_NAMESPACE_OR_FORMAT); 783 784 /* Valid NSID, but ns has no IDs defined */ 785 cmd.nvme_cmd.nsid = 1; 786 memset(&rsp, 0, sizeof(rsp)); 787 CU_ASSERT(nvmf_ctrlr_process_admin_cmd(&req) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 788 CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 789 CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_SUCCESS); 790 CU_ASSERT(spdk_mem_all_zero(buf, sizeof(buf))); 791 792 /* Valid NSID, only EUI64 defined */ 793 ns.opts.eui64[0] = 0x11; 794 ns.opts.eui64[7] = 0xFF; 795 memset(&rsp, 0, sizeof(rsp)); 796 CU_ASSERT(nvmf_ctrlr_process_admin_cmd(&req) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 797 CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 798 CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_SUCCESS); 799 CU_ASSERT(buf[0] == SPDK_NVME_NIDT_EUI64); 800 CU_ASSERT(buf[1] == 8); 801 CU_ASSERT(buf[4] == 0x11); 802 CU_ASSERT(buf[11] == 0xFF); 803 CU_ASSERT(buf[13] == 0); 804 805 /* Valid NSID, only NGUID defined */ 806 memset(ns.opts.eui64, 0, sizeof(ns.opts.eui64)); 807 ns.opts.nguid[0] = 0x22; 808 ns.opts.nguid[15] = 0xEE; 809 memset(&rsp, 0, sizeof(rsp)); 810 CU_ASSERT(nvmf_ctrlr_process_admin_cmd(&req) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 811 CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 812 CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_SUCCESS); 813 CU_ASSERT(buf[0] == SPDK_NVME_NIDT_NGUID); 814 CU_ASSERT(buf[1] == 16); 815 CU_ASSERT(buf[4] == 0x22); 816 CU_ASSERT(buf[19] == 0xEE); 817 CU_ASSERT(buf[21] == 0); 818 819 /* Valid NSID, both EUI64 and NGUID defined */ 820 ns.opts.eui64[0] = 0x11; 821 ns.opts.eui64[7] = 0xFF; 822 ns.opts.nguid[0] = 0x22; 823 ns.opts.nguid[15] = 0xEE; 824 memset(&rsp, 0, sizeof(rsp)); 825 CU_ASSERT(nvmf_ctrlr_process_admin_cmd(&req) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 826 CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 827 CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_SUCCESS); 828 CU_ASSERT(buf[0] == SPDK_NVME_NIDT_EUI64); 829 CU_ASSERT(buf[1] == 8); 830 CU_ASSERT(buf[4] == 0x11); 831 CU_ASSERT(buf[11] == 0xFF); 832 CU_ASSERT(buf[12] == SPDK_NVME_NIDT_NGUID); 833 CU_ASSERT(buf[13] == 16); 834 CU_ASSERT(buf[16] == 0x22); 835 CU_ASSERT(buf[31] == 0xEE); 836 CU_ASSERT(buf[33] == 0); 837 838 /* Valid NSID, EUI64, NGUID, and UUID defined */ 839 ns.opts.eui64[0] = 0x11; 840 ns.opts.eui64[7] = 0xFF; 841 ns.opts.nguid[0] = 0x22; 842 ns.opts.nguid[15] = 0xEE; 843 ns.opts.uuid.u.raw[0] = 0x33; 844 ns.opts.uuid.u.raw[15] = 0xDD; 845 memset(&rsp, 0, sizeof(rsp)); 846 CU_ASSERT(nvmf_ctrlr_process_admin_cmd(&req) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 847 CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 848 CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_SUCCESS); 849 CU_ASSERT(buf[0] == SPDK_NVME_NIDT_EUI64); 850 CU_ASSERT(buf[1] == 8); 851 CU_ASSERT(buf[4] == 0x11); 852 CU_ASSERT(buf[11] == 0xFF); 853 CU_ASSERT(buf[12] == SPDK_NVME_NIDT_NGUID); 854 CU_ASSERT(buf[13] == 16); 855 CU_ASSERT(buf[16] == 0x22); 856 CU_ASSERT(buf[31] == 0xEE); 857 CU_ASSERT(buf[32] == SPDK_NVME_NIDT_UUID); 858 CU_ASSERT(buf[33] == 16); 859 CU_ASSERT(buf[36] == 0x33); 860 CU_ASSERT(buf[51] == 0xDD); 861 CU_ASSERT(buf[53] == 0); 862 } 863 864 static void 865 test_identify_ns(void) 866 { 867 struct spdk_nvmf_subsystem subsystem = {}; 868 struct spdk_nvmf_transport transport = {}; 869 struct spdk_nvmf_qpair admin_qpair = { .transport = &transport}; 870 struct spdk_nvmf_ctrlr ctrlr = { .subsys = &subsystem, .admin_qpair = &admin_qpair }; 871 struct spdk_nvme_cmd cmd = {}; 872 struct spdk_nvme_cpl rsp = {}; 873 struct spdk_nvme_ns_data nsdata = {}; 874 struct spdk_bdev bdev[3] = {{.blockcnt = 1234}, {.blockcnt = 0}, {.blockcnt = 5678}}; 875 struct spdk_nvmf_ns ns[3] = {{.bdev = &bdev[0]}, {.bdev = NULL}, {.bdev = &bdev[2]}}; 876 struct spdk_nvmf_ns *ns_arr[3] = {&ns[0], NULL, &ns[2]}; 877 878 subsystem.ns = ns_arr; 879 subsystem.max_nsid = SPDK_COUNTOF(ns_arr); 880 881 /* Invalid NSID 0 */ 882 cmd.nsid = 0; 883 memset(&nsdata, 0, sizeof(nsdata)); 884 memset(&rsp, 0, sizeof(rsp)); 885 CU_ASSERT(spdk_nvmf_ctrlr_identify_ns(&ctrlr, &cmd, &rsp, 886 &nsdata) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 887 CU_ASSERT(rsp.status.sct == SPDK_NVME_SCT_GENERIC); 888 CU_ASSERT(rsp.status.sc == SPDK_NVME_SC_INVALID_NAMESPACE_OR_FORMAT); 889 CU_ASSERT(spdk_mem_all_zero(&nsdata, sizeof(nsdata))); 890 891 /* Valid NSID 1 */ 892 cmd.nsid = 1; 893 memset(&nsdata, 0, sizeof(nsdata)); 894 memset(&rsp, 0, sizeof(rsp)); 895 CU_ASSERT(spdk_nvmf_ctrlr_identify_ns(&ctrlr, &cmd, &rsp, 896 &nsdata) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 897 CU_ASSERT(rsp.status.sct == SPDK_NVME_SCT_GENERIC); 898 CU_ASSERT(rsp.status.sc == SPDK_NVME_SC_SUCCESS); 899 CU_ASSERT(nsdata.nsze == 1234); 900 901 /* Valid but inactive NSID 2 */ 902 cmd.nsid = 2; 903 memset(&nsdata, 0, sizeof(nsdata)); 904 memset(&rsp, 0, sizeof(rsp)); 905 CU_ASSERT(spdk_nvmf_ctrlr_identify_ns(&ctrlr, &cmd, &rsp, 906 &nsdata) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 907 CU_ASSERT(rsp.status.sct == SPDK_NVME_SCT_GENERIC); 908 CU_ASSERT(rsp.status.sc == SPDK_NVME_SC_SUCCESS); 909 CU_ASSERT(spdk_mem_all_zero(&nsdata, sizeof(nsdata))); 910 911 /* Valid NSID 3 */ 912 cmd.nsid = 3; 913 memset(&nsdata, 0, sizeof(nsdata)); 914 memset(&rsp, 0, sizeof(rsp)); 915 CU_ASSERT(spdk_nvmf_ctrlr_identify_ns(&ctrlr, &cmd, &rsp, 916 &nsdata) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 917 CU_ASSERT(rsp.status.sct == SPDK_NVME_SCT_GENERIC); 918 CU_ASSERT(rsp.status.sc == SPDK_NVME_SC_SUCCESS); 919 CU_ASSERT(nsdata.nsze == 5678); 920 921 /* Invalid NSID 4 */ 922 cmd.nsid = 4; 923 memset(&nsdata, 0, sizeof(nsdata)); 924 memset(&rsp, 0, sizeof(rsp)); 925 CU_ASSERT(spdk_nvmf_ctrlr_identify_ns(&ctrlr, &cmd, &rsp, 926 &nsdata) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 927 CU_ASSERT(rsp.status.sct == SPDK_NVME_SCT_GENERIC); 928 CU_ASSERT(rsp.status.sc == SPDK_NVME_SC_INVALID_NAMESPACE_OR_FORMAT); 929 CU_ASSERT(spdk_mem_all_zero(&nsdata, sizeof(nsdata))); 930 931 /* Invalid NSID 0xFFFFFFFF (NS management not supported) */ 932 cmd.nsid = 0xFFFFFFFF; 933 memset(&nsdata, 0, sizeof(nsdata)); 934 memset(&rsp, 0, sizeof(rsp)); 935 CU_ASSERT(spdk_nvmf_ctrlr_identify_ns(&ctrlr, &cmd, &rsp, 936 &nsdata) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 937 CU_ASSERT(rsp.status.sct == SPDK_NVME_SCT_GENERIC); 938 CU_ASSERT(rsp.status.sc == SPDK_NVME_SC_INVALID_NAMESPACE_OR_FORMAT); 939 CU_ASSERT(spdk_mem_all_zero(&nsdata, sizeof(nsdata))); 940 } 941 942 static void 943 test_set_get_features(void) 944 { 945 struct spdk_nvmf_subsystem subsystem = {}; 946 struct spdk_nvmf_qpair admin_qpair = {}; 947 struct spdk_nvmf_ctrlr ctrlr = { .subsys = &subsystem, .admin_qpair = &admin_qpair }; 948 union nvmf_h2c_msg cmd = {}; 949 union nvmf_c2h_msg rsp = {}; 950 struct spdk_nvmf_ns ns[3]; 951 struct spdk_nvmf_ns *ns_arr[3] = {&ns[0], NULL, &ns[2]};; 952 struct spdk_nvmf_request req; 953 int rc; 954 955 subsystem.ns = ns_arr; 956 subsystem.max_nsid = SPDK_COUNTOF(ns_arr); 957 admin_qpair.ctrlr = &ctrlr; 958 req.qpair = &admin_qpair; 959 cmd.nvme_cmd.nsid = 1; 960 req.cmd = &cmd; 961 req.rsp = &rsp; 962 963 /* Set SPDK_NVME_FEAT_HOST_RESERVE_PERSIST feature */ 964 cmd.nvme_cmd.opc = SPDK_NVME_OPC_SET_FEATURES; 965 cmd.nvme_cmd.cdw11_bits.feat_rsv_persistence.bits.ptpl = 1; 966 ns[0].ptpl_file = "testcfg"; 967 rc = nvmf_ctrlr_set_features_reservation_persistence(&req); 968 CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 969 CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC); 970 CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_FEATURE_ID_NOT_SAVEABLE); 971 CU_ASSERT(ns[0].ptpl_activated == true); 972 973 /* Get SPDK_NVME_FEAT_HOST_RESERVE_PERSIST feature */ 974 cmd.nvme_cmd.opc = SPDK_NVME_OPC_GET_FEATURES; 975 cmd.nvme_cmd.cdw10_bits.get_features.fid = SPDK_NVME_FEAT_HOST_RESERVE_PERSIST; 976 rc = nvmf_ctrlr_get_features_reservation_persistence(&req); 977 CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 978 CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 979 CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_SUCCESS); 980 CU_ASSERT(rsp.nvme_cpl.cdw0 == 1); 981 982 983 /* Get SPDK_NVME_FEAT_TEMPERATURE_THRESHOLD - valid TMPSEL */ 984 cmd.nvme_cmd.opc = SPDK_NVME_OPC_GET_FEATURES; 985 cmd.nvme_cmd.cdw11 = 0x42; 986 cmd.nvme_cmd.cdw10_bits.get_features.fid = SPDK_NVME_FEAT_TEMPERATURE_THRESHOLD; 987 988 rc = nvmf_ctrlr_get_features(&req); 989 CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 990 991 /* Get SPDK_NVME_FEAT_TEMPERATURE_THRESHOLD - invalid TMPSEL */ 992 cmd.nvme_cmd.opc = SPDK_NVME_OPC_GET_FEATURES; 993 cmd.nvme_cmd.cdw11 = 0x42 | 1 << 16 | 1 << 19; /* Set reserved value */ 994 cmd.nvme_cmd.cdw10_bits.get_features.fid = SPDK_NVME_FEAT_TEMPERATURE_THRESHOLD; 995 996 rc = nvmf_ctrlr_get_features(&req); 997 CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 998 CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 999 CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_INVALID_FIELD); 1000 1001 /* Set SPDK_NVME_FEAT_TEMPERATURE_THRESHOLD - valid TMPSEL */ 1002 cmd.nvme_cmd.opc = SPDK_NVME_OPC_SET_FEATURES; 1003 cmd.nvme_cmd.cdw11 = 0x42; 1004 cmd.nvme_cmd.cdw10_bits.set_features.fid = SPDK_NVME_FEAT_TEMPERATURE_THRESHOLD; 1005 1006 rc = nvmf_ctrlr_set_features(&req); 1007 CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 1008 1009 /* Set SPDK_NVME_FEAT_TEMPERATURE_THRESHOLD - invalid TMPSEL */ 1010 cmd.nvme_cmd.opc = SPDK_NVME_OPC_SET_FEATURES; 1011 cmd.nvme_cmd.cdw11 = 0x42 | 1 << 16 | 1 << 19; /* Set reserved value */ 1012 cmd.nvme_cmd.cdw10_bits.set_features.fid = SPDK_NVME_FEAT_TEMPERATURE_THRESHOLD; 1013 1014 rc = nvmf_ctrlr_set_features(&req); 1015 CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 1016 CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 1017 CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_INVALID_FIELD); 1018 1019 /* Set SPDK_NVME_FEAT_TEMPERATURE_THRESHOLD - invalid THSEL */ 1020 cmd.nvme_cmd.opc = SPDK_NVME_OPC_SET_FEATURES; 1021 cmd.nvme_cmd.cdw11 = 0x42; 1022 cmd.nvme_cmd.cdw11_bits.feat_temp_threshold.bits.thsel = 0x3; /* Set reserved value */ 1023 cmd.nvme_cmd.cdw10_bits.set_features.fid = SPDK_NVME_FEAT_TEMPERATURE_THRESHOLD; 1024 1025 rc = nvmf_ctrlr_set_features(&req); 1026 CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 1027 CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 1028 CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_INVALID_FIELD); 1029 1030 1031 /* get SPDK_NVME_FEAT_ERROR_RECOVERY - generic */ 1032 cmd.nvme_cmd.opc = SPDK_NVME_OPC_SET_FEATURES; 1033 cmd.nvme_cmd.cdw10_bits.get_features.fid = SPDK_NVME_FEAT_ERROR_RECOVERY; 1034 1035 rc = nvmf_ctrlr_get_features(&req); 1036 CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 1037 1038 /* Set SPDK_NVME_FEAT_ERROR_RECOVERY - DULBE set */ 1039 cmd.nvme_cmd.opc = SPDK_NVME_OPC_SET_FEATURES; 1040 cmd.nvme_cmd.cdw11 = 0x42; 1041 cmd.nvme_cmd.cdw11_bits.feat_error_recovery.bits.dulbe = 0x1; 1042 cmd.nvme_cmd.cdw10_bits.set_features.fid = SPDK_NVME_FEAT_ERROR_RECOVERY; 1043 1044 rc = nvmf_ctrlr_set_features(&req); 1045 CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 1046 CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 1047 CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_INVALID_FIELD); 1048 1049 /* Set SPDK_NVME_FEAT_ERROR_RECOVERY - DULBE cleared */ 1050 cmd.nvme_cmd.opc = SPDK_NVME_OPC_SET_FEATURES; 1051 cmd.nvme_cmd.cdw11 = 0x42; 1052 cmd.nvme_cmd.cdw11_bits.feat_error_recovery.bits.dulbe = 0x0; 1053 cmd.nvme_cmd.cdw10_bits.set_features.fid = SPDK_NVME_FEAT_ERROR_RECOVERY; 1054 1055 rc = nvmf_ctrlr_set_features(&req); 1056 CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 1057 } 1058 1059 /* 1060 * Reservation Unit Test Configuration 1061 * -------- -------- -------- 1062 * | Host A | | Host B | | Host C | 1063 * -------- -------- -------- 1064 * / \ | | 1065 * -------- -------- ------- ------- 1066 * |Ctrlr1_A| |Ctrlr2_A| |Ctrlr_B| |Ctrlr_C| 1067 * -------- -------- ------- ------- 1068 * \ \ / / 1069 * \ \ / / 1070 * \ \ / / 1071 * -------------------------------------- 1072 * | NAMESPACE 1 | 1073 * -------------------------------------- 1074 */ 1075 1076 static struct spdk_nvmf_ctrlr g_ctrlr1_A, g_ctrlr2_A, g_ctrlr_B, g_ctrlr_C; 1077 struct spdk_nvmf_subsystem_pg_ns_info g_ns_info; 1078 1079 static void 1080 ut_reservation_init(enum spdk_nvme_reservation_type rtype) 1081 { 1082 /* Host A has two controllers */ 1083 spdk_uuid_generate(&g_ctrlr1_A.hostid); 1084 spdk_uuid_copy(&g_ctrlr2_A.hostid, &g_ctrlr1_A.hostid); 1085 1086 /* Host B has 1 controller */ 1087 spdk_uuid_generate(&g_ctrlr_B.hostid); 1088 1089 /* Host C has 1 controller */ 1090 spdk_uuid_generate(&g_ctrlr_C.hostid); 1091 1092 memset(&g_ns_info, 0, sizeof(g_ns_info)); 1093 g_ns_info.rtype = rtype; 1094 g_ns_info.reg_hostid[0] = g_ctrlr1_A.hostid; 1095 g_ns_info.reg_hostid[1] = g_ctrlr_B.hostid; 1096 g_ns_info.reg_hostid[2] = g_ctrlr_C.hostid; 1097 } 1098 1099 static void 1100 test_reservation_write_exclusive(void) 1101 { 1102 struct spdk_nvmf_request req = {}; 1103 union nvmf_h2c_msg cmd = {}; 1104 union nvmf_c2h_msg rsp = {}; 1105 int rc; 1106 1107 req.cmd = &cmd; 1108 req.rsp = &rsp; 1109 1110 /* Host A holds reservation with type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE */ 1111 ut_reservation_init(SPDK_NVME_RESERVE_WRITE_EXCLUSIVE); 1112 g_ns_info.holder_id = g_ctrlr1_A.hostid; 1113 1114 /* Test Case: Issue a Read command from Host A and Host B */ 1115 cmd.nvme_cmd.opc = SPDK_NVME_OPC_READ; 1116 rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr1_A, &req); 1117 SPDK_CU_ASSERT_FATAL(rc == 0); 1118 rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_B, &req); 1119 SPDK_CU_ASSERT_FATAL(rc == 0); 1120 1121 /* Test Case: Issue a DSM Write command from Host A and Host B */ 1122 cmd.nvme_cmd.opc = SPDK_NVME_OPC_DATASET_MANAGEMENT; 1123 rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr1_A, &req); 1124 SPDK_CU_ASSERT_FATAL(rc == 0); 1125 rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_B, &req); 1126 SPDK_CU_ASSERT_FATAL(rc < 0); 1127 SPDK_CU_ASSERT_FATAL(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_RESERVATION_CONFLICT); 1128 1129 /* Test Case: Issue a Write command from Host C */ 1130 cmd.nvme_cmd.opc = SPDK_NVME_OPC_WRITE; 1131 rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_C, &req); 1132 SPDK_CU_ASSERT_FATAL(rc < 0); 1133 SPDK_CU_ASSERT_FATAL(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_RESERVATION_CONFLICT); 1134 1135 /* Test Case: Issue a Read command from Host B */ 1136 cmd.nvme_cmd.opc = SPDK_NVME_OPC_READ; 1137 rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_B, &req); 1138 SPDK_CU_ASSERT_FATAL(rc == 0); 1139 1140 /* Unregister Host C */ 1141 memset(&g_ns_info.reg_hostid[2], 0, sizeof(struct spdk_uuid)); 1142 1143 /* Test Case: Read and Write commands from non-registrant Host C */ 1144 cmd.nvme_cmd.opc = SPDK_NVME_OPC_WRITE; 1145 rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_C, &req); 1146 SPDK_CU_ASSERT_FATAL(rc < 0); 1147 SPDK_CU_ASSERT_FATAL(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_RESERVATION_CONFLICT); 1148 cmd.nvme_cmd.opc = SPDK_NVME_OPC_READ; 1149 rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_C, &req); 1150 SPDK_CU_ASSERT_FATAL(rc == 0); 1151 } 1152 1153 static void 1154 test_reservation_exclusive_access(void) 1155 { 1156 struct spdk_nvmf_request req = {}; 1157 union nvmf_h2c_msg cmd = {}; 1158 union nvmf_c2h_msg rsp = {}; 1159 int rc; 1160 1161 req.cmd = &cmd; 1162 req.rsp = &rsp; 1163 1164 /* Host A holds reservation with type SPDK_NVME_RESERVE_EXCLUSIVE_ACCESS */ 1165 ut_reservation_init(SPDK_NVME_RESERVE_EXCLUSIVE_ACCESS); 1166 g_ns_info.holder_id = g_ctrlr1_A.hostid; 1167 1168 /* Test Case: Issue a Read command from Host B */ 1169 cmd.nvme_cmd.opc = SPDK_NVME_OPC_READ; 1170 rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_B, &req); 1171 SPDK_CU_ASSERT_FATAL(rc < 0); 1172 SPDK_CU_ASSERT_FATAL(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_RESERVATION_CONFLICT); 1173 1174 /* Test Case: Issue a Reservation Release command from a valid Registrant */ 1175 cmd.nvme_cmd.opc = SPDK_NVME_OPC_RESERVATION_RELEASE; 1176 rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_B, &req); 1177 SPDK_CU_ASSERT_FATAL(rc == 0); 1178 } 1179 1180 static void 1181 _test_reservation_write_exclusive_regs_only_and_all_regs(enum spdk_nvme_reservation_type rtype) 1182 { 1183 struct spdk_nvmf_request req = {}; 1184 union nvmf_h2c_msg cmd = {}; 1185 union nvmf_c2h_msg rsp = {}; 1186 int rc; 1187 1188 req.cmd = &cmd; 1189 req.rsp = &rsp; 1190 1191 /* SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY and SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS */ 1192 ut_reservation_init(rtype); 1193 g_ns_info.holder_id = g_ctrlr1_A.hostid; 1194 1195 /* Test Case: Issue a Read command from Host A and Host C */ 1196 cmd.nvme_cmd.opc = SPDK_NVME_OPC_READ; 1197 rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr1_A, &req); 1198 SPDK_CU_ASSERT_FATAL(rc == 0); 1199 rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_C, &req); 1200 SPDK_CU_ASSERT_FATAL(rc == 0); 1201 1202 /* Test Case: Issue a DSM Write command from Host A and Host C */ 1203 cmd.nvme_cmd.opc = SPDK_NVME_OPC_DATASET_MANAGEMENT; 1204 rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr1_A, &req); 1205 SPDK_CU_ASSERT_FATAL(rc == 0); 1206 rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_C, &req); 1207 SPDK_CU_ASSERT_FATAL(rc == 0); 1208 1209 /* Unregister Host C */ 1210 memset(&g_ns_info.reg_hostid[2], 0, sizeof(struct spdk_uuid)); 1211 1212 /* Test Case: Read and Write commands from non-registrant Host C */ 1213 cmd.nvme_cmd.opc = SPDK_NVME_OPC_READ; 1214 rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_C, &req); 1215 SPDK_CU_ASSERT_FATAL(rc == 0); 1216 cmd.nvme_cmd.opc = SPDK_NVME_OPC_WRITE; 1217 rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_C, &req); 1218 SPDK_CU_ASSERT_FATAL(rc < 0); 1219 SPDK_CU_ASSERT_FATAL(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_RESERVATION_CONFLICT); 1220 } 1221 1222 static void 1223 test_reservation_write_exclusive_regs_only_and_all_regs(void) 1224 { 1225 _test_reservation_write_exclusive_regs_only_and_all_regs( 1226 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY); 1227 _test_reservation_write_exclusive_regs_only_and_all_regs( 1228 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS); 1229 } 1230 1231 static void 1232 _test_reservation_exclusive_access_regs_only_and_all_regs(enum spdk_nvme_reservation_type rtype) 1233 { 1234 struct spdk_nvmf_request req = {}; 1235 union nvmf_h2c_msg cmd = {}; 1236 union nvmf_c2h_msg rsp = {}; 1237 int rc; 1238 1239 req.cmd = &cmd; 1240 req.rsp = &rsp; 1241 1242 /* SPDK_NVME_RESERVE_EXCLUSIVE_ACCESS_REG_ONLY and SPDK_NVME_RESERVE_EXCLUSIVE_ACCESS_ALL_REGS */ 1243 ut_reservation_init(rtype); 1244 g_ns_info.holder_id = g_ctrlr1_A.hostid; 1245 1246 /* Test Case: Issue a Write command from Host B */ 1247 cmd.nvme_cmd.opc = SPDK_NVME_OPC_WRITE; 1248 rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_B, &req); 1249 SPDK_CU_ASSERT_FATAL(rc == 0); 1250 1251 /* Unregister Host B */ 1252 memset(&g_ns_info.reg_hostid[1], 0, sizeof(struct spdk_uuid)); 1253 1254 /* Test Case: Issue a Read command from Host B */ 1255 cmd.nvme_cmd.opc = SPDK_NVME_OPC_READ; 1256 rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_B, &req); 1257 SPDK_CU_ASSERT_FATAL(rc < 0); 1258 SPDK_CU_ASSERT_FATAL(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_RESERVATION_CONFLICT); 1259 cmd.nvme_cmd.opc = SPDK_NVME_OPC_WRITE; 1260 rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_B, &req); 1261 SPDK_CU_ASSERT_FATAL(rc < 0); 1262 SPDK_CU_ASSERT_FATAL(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_RESERVATION_CONFLICT); 1263 } 1264 1265 static void 1266 test_reservation_exclusive_access_regs_only_and_all_regs(void) 1267 { 1268 _test_reservation_exclusive_access_regs_only_and_all_regs( 1269 SPDK_NVME_RESERVE_EXCLUSIVE_ACCESS_REG_ONLY); 1270 _test_reservation_exclusive_access_regs_only_and_all_regs( 1271 SPDK_NVME_RESERVE_EXCLUSIVE_ACCESS_ALL_REGS); 1272 } 1273 1274 static void 1275 test_reservation_notification_log_page(void) 1276 { 1277 struct spdk_nvmf_ctrlr ctrlr; 1278 struct spdk_nvmf_qpair qpair; 1279 struct spdk_nvmf_ns ns; 1280 struct spdk_nvmf_request req; 1281 union nvmf_h2c_msg cmd = {}; 1282 union nvmf_c2h_msg rsp = {}; 1283 union spdk_nvme_async_event_completion event = {}; 1284 struct spdk_nvme_reservation_notification_log logs[3]; 1285 1286 memset(&ctrlr, 0, sizeof(ctrlr)); 1287 ctrlr.thread = spdk_get_thread(); 1288 TAILQ_INIT(&ctrlr.log_head); 1289 ns.nsid = 1; 1290 1291 /* Test Case: Mask all the reservation notifications */ 1292 ns.mask = SPDK_NVME_REGISTRATION_PREEMPTED_MASK | 1293 SPDK_NVME_RESERVATION_RELEASED_MASK | 1294 SPDK_NVME_RESERVATION_PREEMPTED_MASK; 1295 nvmf_ctrlr_reservation_notice_log(&ctrlr, &ns, 1296 SPDK_NVME_REGISTRATION_PREEMPTED); 1297 nvmf_ctrlr_reservation_notice_log(&ctrlr, &ns, 1298 SPDK_NVME_RESERVATION_RELEASED); 1299 nvmf_ctrlr_reservation_notice_log(&ctrlr, &ns, 1300 SPDK_NVME_RESERVATION_PREEMPTED); 1301 poll_threads(); 1302 SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&ctrlr.log_head)); 1303 1304 /* Test Case: Unmask all the reservation notifications, 1305 * 3 log pages are generated, and AER was triggered. 1306 */ 1307 ns.mask = 0; 1308 ctrlr.num_avail_log_pages = 0; 1309 req.cmd = &cmd; 1310 req.rsp = &rsp; 1311 ctrlr.aer_req[0] = &req; 1312 ctrlr.nr_aer_reqs = 1; 1313 req.qpair = &qpair; 1314 TAILQ_INIT(&qpair.outstanding); 1315 qpair.ctrlr = NULL; 1316 qpair.state = SPDK_NVMF_QPAIR_ACTIVE; 1317 TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 1318 1319 nvmf_ctrlr_reservation_notice_log(&ctrlr, &ns, 1320 SPDK_NVME_REGISTRATION_PREEMPTED); 1321 nvmf_ctrlr_reservation_notice_log(&ctrlr, &ns, 1322 SPDK_NVME_RESERVATION_RELEASED); 1323 nvmf_ctrlr_reservation_notice_log(&ctrlr, &ns, 1324 SPDK_NVME_RESERVATION_PREEMPTED); 1325 poll_threads(); 1326 event.raw = rsp.nvme_cpl.cdw0; 1327 SPDK_CU_ASSERT_FATAL(event.bits.async_event_type == SPDK_NVME_ASYNC_EVENT_TYPE_IO); 1328 SPDK_CU_ASSERT_FATAL(event.bits.async_event_info == SPDK_NVME_ASYNC_EVENT_RESERVATION_LOG_AVAIL); 1329 SPDK_CU_ASSERT_FATAL(event.bits.log_page_identifier == SPDK_NVME_LOG_RESERVATION_NOTIFICATION); 1330 SPDK_CU_ASSERT_FATAL(ctrlr.num_avail_log_pages == 3); 1331 1332 /* Test Case: Get Log Page to clear the log pages */ 1333 nvmf_get_reservation_notification_log_page(&ctrlr, (void *)logs, 0, sizeof(logs)); 1334 SPDK_CU_ASSERT_FATAL(ctrlr.num_avail_log_pages == 0); 1335 } 1336 1337 static void 1338 test_get_dif_ctx(void) 1339 { 1340 struct spdk_nvmf_subsystem subsystem = {}; 1341 struct spdk_nvmf_request req = {}; 1342 struct spdk_nvmf_qpair qpair = {}; 1343 struct spdk_nvmf_ctrlr ctrlr = {}; 1344 struct spdk_nvmf_ns ns = {}; 1345 struct spdk_nvmf_ns *_ns = NULL; 1346 struct spdk_bdev bdev = {}; 1347 union nvmf_h2c_msg cmd = {}; 1348 struct spdk_dif_ctx dif_ctx = {}; 1349 bool ret; 1350 1351 ctrlr.subsys = &subsystem; 1352 1353 qpair.ctrlr = &ctrlr; 1354 1355 req.qpair = &qpair; 1356 req.cmd = &cmd; 1357 1358 ns.bdev = &bdev; 1359 1360 ctrlr.dif_insert_or_strip = false; 1361 1362 ret = spdk_nvmf_request_get_dif_ctx(&req, &dif_ctx); 1363 CU_ASSERT(ret == false); 1364 1365 ctrlr.dif_insert_or_strip = true; 1366 qpair.state = SPDK_NVMF_QPAIR_UNINITIALIZED; 1367 1368 ret = spdk_nvmf_request_get_dif_ctx(&req, &dif_ctx); 1369 CU_ASSERT(ret == false); 1370 1371 qpair.state = SPDK_NVMF_QPAIR_ACTIVE; 1372 cmd.nvmf_cmd.opcode = SPDK_NVME_OPC_FABRIC; 1373 1374 ret = spdk_nvmf_request_get_dif_ctx(&req, &dif_ctx); 1375 CU_ASSERT(ret == false); 1376 1377 cmd.nvmf_cmd.opcode = SPDK_NVME_OPC_FLUSH; 1378 1379 ret = spdk_nvmf_request_get_dif_ctx(&req, &dif_ctx); 1380 CU_ASSERT(ret == false); 1381 1382 qpair.qid = 1; 1383 1384 ret = spdk_nvmf_request_get_dif_ctx(&req, &dif_ctx); 1385 CU_ASSERT(ret == false); 1386 1387 cmd.nvme_cmd.nsid = 1; 1388 1389 ret = spdk_nvmf_request_get_dif_ctx(&req, &dif_ctx); 1390 CU_ASSERT(ret == false); 1391 1392 subsystem.max_nsid = 1; 1393 subsystem.ns = &_ns; 1394 subsystem.ns[0] = &ns; 1395 1396 ret = spdk_nvmf_request_get_dif_ctx(&req, &dif_ctx); 1397 CU_ASSERT(ret == false); 1398 1399 cmd.nvmf_cmd.opcode = SPDK_NVME_OPC_WRITE; 1400 1401 ret = spdk_nvmf_request_get_dif_ctx(&req, &dif_ctx); 1402 CU_ASSERT(ret == true); 1403 } 1404 1405 static void 1406 test_identify_ctrlr(void) 1407 { 1408 struct spdk_nvmf_subsystem subsystem = { 1409 .subtype = SPDK_NVMF_SUBTYPE_NVME 1410 }; 1411 struct spdk_nvmf_transport_ops tops = {}; 1412 struct spdk_nvmf_transport transport = { 1413 .ops = &tops, 1414 .opts = { 1415 .in_capsule_data_size = 4096, 1416 }, 1417 }; 1418 struct spdk_nvmf_qpair admin_qpair = { .transport = &transport}; 1419 struct spdk_nvmf_ctrlr ctrlr = { .subsys = &subsystem, .admin_qpair = &admin_qpair }; 1420 struct spdk_nvme_ctrlr_data cdata = {}; 1421 uint32_t expected_ioccsz; 1422 1423 nvmf_ctrlr_cdata_init(&transport, &subsystem, &ctrlr.cdata); 1424 1425 /* Check ioccsz, TCP transport */ 1426 tops.type = SPDK_NVME_TRANSPORT_TCP; 1427 expected_ioccsz = sizeof(struct spdk_nvme_cmd) / 16 + transport.opts.in_capsule_data_size / 16; 1428 CU_ASSERT(spdk_nvmf_ctrlr_identify_ctrlr(&ctrlr, &cdata) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 1429 CU_ASSERT(cdata.nvmf_specific.ioccsz == expected_ioccsz); 1430 1431 /* Check ioccsz, RDMA transport */ 1432 tops.type = SPDK_NVME_TRANSPORT_RDMA; 1433 expected_ioccsz = sizeof(struct spdk_nvme_cmd) / 16 + transport.opts.in_capsule_data_size / 16; 1434 CU_ASSERT(spdk_nvmf_ctrlr_identify_ctrlr(&ctrlr, &cdata) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 1435 CU_ASSERT(cdata.nvmf_specific.ioccsz == expected_ioccsz); 1436 1437 /* Check ioccsz, TCP transport with dif_insert_or_strip */ 1438 tops.type = SPDK_NVME_TRANSPORT_TCP; 1439 ctrlr.dif_insert_or_strip = true; 1440 expected_ioccsz = sizeof(struct spdk_nvme_cmd) / 16 + transport.opts.in_capsule_data_size / 16; 1441 CU_ASSERT(spdk_nvmf_ctrlr_identify_ctrlr(&ctrlr, &cdata) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 1442 CU_ASSERT(cdata.nvmf_specific.ioccsz == expected_ioccsz); 1443 } 1444 1445 static int 1446 custom_admin_cmd_hdlr(struct spdk_nvmf_request *req) 1447 { 1448 req->rsp->nvme_cpl.status.sc = SPDK_NVME_SC_SUCCESS; 1449 1450 return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; 1451 }; 1452 1453 static void 1454 test_custom_admin_cmd(void) 1455 { 1456 struct spdk_nvmf_subsystem subsystem; 1457 struct spdk_nvmf_qpair qpair; 1458 struct spdk_nvmf_ctrlr ctrlr; 1459 struct spdk_nvmf_request req; 1460 struct spdk_nvmf_ns *ns_ptrs[1]; 1461 struct spdk_nvmf_ns ns; 1462 union nvmf_h2c_msg cmd; 1463 union nvmf_c2h_msg rsp; 1464 struct spdk_bdev bdev; 1465 uint8_t buf[4096]; 1466 int rc; 1467 1468 memset(&subsystem, 0, sizeof(subsystem)); 1469 ns_ptrs[0] = &ns; 1470 subsystem.ns = ns_ptrs; 1471 subsystem.max_nsid = 1; 1472 subsystem.subtype = SPDK_NVMF_SUBTYPE_NVME; 1473 1474 memset(&ns, 0, sizeof(ns)); 1475 ns.opts.nsid = 1; 1476 ns.bdev = &bdev; 1477 1478 memset(&qpair, 0, sizeof(qpair)); 1479 qpair.ctrlr = &ctrlr; 1480 1481 memset(&ctrlr, 0, sizeof(ctrlr)); 1482 ctrlr.subsys = &subsystem; 1483 ctrlr.vcprop.cc.bits.en = 1; 1484 1485 memset(&req, 0, sizeof(req)); 1486 req.qpair = &qpair; 1487 req.cmd = &cmd; 1488 req.rsp = &rsp; 1489 req.xfer = SPDK_NVME_DATA_CONTROLLER_TO_HOST; 1490 req.data = buf; 1491 req.length = sizeof(buf); 1492 1493 memset(&cmd, 0, sizeof(cmd)); 1494 cmd.nvme_cmd.opc = 0xc1; 1495 cmd.nvme_cmd.nsid = 0; 1496 memset(&rsp, 0, sizeof(rsp)); 1497 1498 spdk_nvmf_set_custom_admin_cmd_hdlr(cmd.nvme_cmd.opc, custom_admin_cmd_hdlr); 1499 1500 /* Ensure that our hdlr is being called */ 1501 rc = nvmf_ctrlr_process_admin_cmd(&req); 1502 CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 1503 CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 1504 CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_SUCCESS); 1505 } 1506 1507 static void 1508 test_fused_compare_and_write(void) 1509 { 1510 struct spdk_nvmf_request req = {}; 1511 struct spdk_nvmf_qpair qpair = {}; 1512 struct spdk_nvme_cmd cmd = {}; 1513 union nvmf_c2h_msg rsp = {}; 1514 struct spdk_nvmf_ctrlr ctrlr = {}; 1515 struct spdk_nvmf_subsystem subsystem = {}; 1516 struct spdk_nvmf_ns ns = {}; 1517 struct spdk_nvmf_ns *subsys_ns[1] = {}; 1518 struct spdk_bdev bdev = {}; 1519 1520 struct spdk_nvmf_poll_group group = {}; 1521 struct spdk_nvmf_subsystem_poll_group sgroups = {}; 1522 struct spdk_nvmf_subsystem_pg_ns_info ns_info = {}; 1523 1524 ns.bdev = &bdev; 1525 1526 subsystem.id = 0; 1527 subsystem.max_nsid = 1; 1528 subsys_ns[0] = &ns; 1529 subsystem.ns = (struct spdk_nvmf_ns **)&subsys_ns; 1530 1531 /* Enable controller */ 1532 ctrlr.vcprop.cc.bits.en = 1; 1533 ctrlr.subsys = (struct spdk_nvmf_subsystem *)&subsystem; 1534 1535 group.num_sgroups = 1; 1536 sgroups.state = SPDK_NVMF_SUBSYSTEM_ACTIVE; 1537 sgroups.num_ns = 1; 1538 sgroups.ns_info = &ns_info; 1539 TAILQ_INIT(&sgroups.queued); 1540 group.sgroups = &sgroups; 1541 TAILQ_INIT(&qpair.outstanding); 1542 1543 qpair.ctrlr = &ctrlr; 1544 qpair.group = &group; 1545 qpair.qid = 1; 1546 qpair.state = SPDK_NVMF_QPAIR_ACTIVE; 1547 1548 cmd.nsid = 1; 1549 1550 req.qpair = &qpair; 1551 req.cmd = (union nvmf_h2c_msg *)&cmd; 1552 req.rsp = &rsp; 1553 1554 /* SUCCESS/SUCCESS */ 1555 cmd.fuse = SPDK_NVME_CMD_FUSE_FIRST; 1556 cmd.opc = SPDK_NVME_OPC_COMPARE; 1557 1558 spdk_nvmf_request_exec(&req); 1559 CU_ASSERT(qpair.first_fused_req != NULL); 1560 CU_ASSERT(nvme_status_success(&rsp.nvme_cpl.status)); 1561 1562 cmd.fuse = SPDK_NVME_CMD_FUSE_SECOND; 1563 cmd.opc = SPDK_NVME_OPC_WRITE; 1564 1565 spdk_nvmf_request_exec(&req); 1566 CU_ASSERT(qpair.first_fused_req == NULL); 1567 CU_ASSERT(nvme_status_success(&rsp.nvme_cpl.status)); 1568 1569 /* Wrong sequence */ 1570 cmd.fuse = SPDK_NVME_CMD_FUSE_SECOND; 1571 cmd.opc = SPDK_NVME_OPC_WRITE; 1572 1573 spdk_nvmf_request_exec(&req); 1574 CU_ASSERT(!nvme_status_success(&rsp.nvme_cpl.status)); 1575 CU_ASSERT(qpair.first_fused_req == NULL); 1576 1577 /* Write as FUSE_FIRST (Wrong op code) */ 1578 cmd.fuse = SPDK_NVME_CMD_FUSE_FIRST; 1579 cmd.opc = SPDK_NVME_OPC_WRITE; 1580 1581 spdk_nvmf_request_exec(&req); 1582 CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_INVALID_OPCODE); 1583 CU_ASSERT(qpair.first_fused_req == NULL); 1584 1585 /* Compare as FUSE_SECOND (Wrong op code) */ 1586 cmd.fuse = SPDK_NVME_CMD_FUSE_FIRST; 1587 cmd.opc = SPDK_NVME_OPC_COMPARE; 1588 1589 spdk_nvmf_request_exec(&req); 1590 CU_ASSERT(qpair.first_fused_req != NULL); 1591 CU_ASSERT(nvme_status_success(&rsp.nvme_cpl.status)); 1592 1593 cmd.fuse = SPDK_NVME_CMD_FUSE_SECOND; 1594 cmd.opc = SPDK_NVME_OPC_COMPARE; 1595 1596 spdk_nvmf_request_exec(&req); 1597 CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_INVALID_OPCODE); 1598 CU_ASSERT(qpair.first_fused_req == NULL); 1599 } 1600 1601 static void 1602 test_multi_async_event_reqs(void) 1603 { 1604 struct spdk_nvmf_subsystem subsystem = {}; 1605 struct spdk_nvmf_qpair qpair = {}; 1606 struct spdk_nvmf_ctrlr ctrlr = {}; 1607 struct spdk_nvmf_request req[5] = {}; 1608 struct spdk_nvmf_ns *ns_ptrs[1] = {}; 1609 struct spdk_nvmf_ns ns = {}; 1610 union nvmf_h2c_msg cmd[5] = {}; 1611 union nvmf_c2h_msg rsp[5] = {}; 1612 1613 struct spdk_nvmf_poll_group group = {}; 1614 struct spdk_nvmf_subsystem_poll_group sgroups = {}; 1615 1616 int i; 1617 1618 ns_ptrs[0] = &ns; 1619 subsystem.ns = ns_ptrs; 1620 subsystem.max_nsid = 1; 1621 subsystem.subtype = SPDK_NVMF_SUBTYPE_NVME; 1622 1623 ns.opts.nsid = 1; 1624 group.sgroups = &sgroups; 1625 1626 qpair.ctrlr = &ctrlr; 1627 qpair.group = &group; 1628 TAILQ_INIT(&qpair.outstanding); 1629 1630 ctrlr.subsys = &subsystem; 1631 ctrlr.vcprop.cc.bits.en = 1; 1632 1633 for (i = 0; i < 5; i++) { 1634 cmd[i].nvme_cmd.opc = SPDK_NVME_OPC_ASYNC_EVENT_REQUEST; 1635 cmd[i].nvme_cmd.nsid = 1; 1636 cmd[i].nvme_cmd.cid = i; 1637 1638 req[i].qpair = &qpair; 1639 req[i].cmd = &cmd[i]; 1640 req[i].rsp = &rsp[i]; 1641 TAILQ_INSERT_TAIL(&qpair.outstanding, &req[i], link); 1642 } 1643 1644 /* Target can store NVMF_MAX_ASYNC_EVENTS reqs */ 1645 sgroups.io_outstanding = NVMF_MAX_ASYNC_EVENTS; 1646 for (i = 0; i < NVMF_MAX_ASYNC_EVENTS; i++) { 1647 CU_ASSERT(nvmf_ctrlr_process_admin_cmd(&req[i]) == SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS); 1648 CU_ASSERT(ctrlr.nr_aer_reqs == i + 1); 1649 } 1650 CU_ASSERT(sgroups.io_outstanding == 0); 1651 1652 /* Exceeding the NVMF_MAX_ASYNC_EVENTS reports error */ 1653 CU_ASSERT(nvmf_ctrlr_process_admin_cmd(&req[4]) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 1654 CU_ASSERT(ctrlr.nr_aer_reqs == NVMF_MAX_ASYNC_EVENTS); 1655 CU_ASSERT(rsp[4].nvme_cpl.status.sct = SPDK_NVME_SCT_COMMAND_SPECIFIC); 1656 CU_ASSERT(rsp[4].nvme_cpl.status.sc = SPDK_NVME_SC_ASYNC_EVENT_REQUEST_LIMIT_EXCEEDED); 1657 1658 /* Test if the aer_reqs keep continuous when abort a req in the middle */ 1659 CU_ASSERT(nvmf_qpair_abort_aer(&qpair, 2) == true); 1660 CU_ASSERT(ctrlr.aer_req[0] == &req[0]); 1661 CU_ASSERT(ctrlr.aer_req[1] == &req[1]); 1662 CU_ASSERT(ctrlr.aer_req[2] == &req[3]); 1663 1664 CU_ASSERT(nvmf_qpair_abort_aer(&qpair, 3) == true); 1665 CU_ASSERT(ctrlr.aer_req[0] == &req[0]); 1666 CU_ASSERT(ctrlr.aer_req[1] == &req[1]); 1667 CU_ASSERT(ctrlr.aer_req[2] == NULL); 1668 CU_ASSERT(ctrlr.nr_aer_reqs == 2); 1669 1670 TAILQ_REMOVE(&qpair.outstanding, &req[0], link); 1671 TAILQ_REMOVE(&qpair.outstanding, &req[1], link); 1672 } 1673 1674 int main(int argc, char **argv) 1675 { 1676 CU_pSuite suite = NULL; 1677 unsigned int num_failures; 1678 1679 CU_set_error_action(CUEA_ABORT); 1680 CU_initialize_registry(); 1681 1682 suite = CU_add_suite("nvmf", NULL, NULL); 1683 CU_ADD_TEST(suite, test_get_log_page); 1684 CU_ADD_TEST(suite, test_process_fabrics_cmd); 1685 CU_ADD_TEST(suite, test_connect); 1686 CU_ADD_TEST(suite, test_get_ns_id_desc_list); 1687 CU_ADD_TEST(suite, test_identify_ns); 1688 CU_ADD_TEST(suite, test_reservation_write_exclusive); 1689 CU_ADD_TEST(suite, test_reservation_exclusive_access); 1690 CU_ADD_TEST(suite, test_reservation_write_exclusive_regs_only_and_all_regs); 1691 CU_ADD_TEST(suite, test_reservation_exclusive_access_regs_only_and_all_regs); 1692 CU_ADD_TEST(suite, test_reservation_notification_log_page); 1693 CU_ADD_TEST(suite, test_get_dif_ctx); 1694 CU_ADD_TEST(suite, test_set_get_features); 1695 CU_ADD_TEST(suite, test_identify_ctrlr); 1696 CU_ADD_TEST(suite, test_custom_admin_cmd); 1697 CU_ADD_TEST(suite, test_fused_compare_and_write); 1698 CU_ADD_TEST(suite, test_multi_async_event_reqs); 1699 1700 allocate_threads(1); 1701 set_thread(0); 1702 1703 CU_basic_set_mode(CU_BRM_VERBOSE); 1704 CU_basic_run_tests(); 1705 num_failures = CU_get_number_of_failures(); 1706 CU_cleanup_registry(); 1707 1708 free_threads(); 1709 1710 return num_failures; 1711 } 1712