nvmf: add duplicate QID check in I/O Connect

Disallow multiple I/O queues for the same controller with the same queue
ID.  NVMe-oF 1.0 ECN 001 specifies that this condition should return a
status value of Command Sequence Error.

Change-Id: I41126ddec388a985c403025e099ab15da5d3987c
Signed-off-by: Daniel Verkamp <daniel.verkamp@intel.com>
Reviewed-on: https://review.gerrithub.io/390662
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
Daniel Verkamp 2017-12-06 11:19:50 -07:00 committed by Jim Harris
parent fab9349fdc
commit bedc405f35
2 changed files with 21 additions and 0 deletions

View File

@ -310,6 +310,13 @@ spdk_nvmf_ctrlr_connect(struct spdk_nvmf_request *req)
return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE;
}
if (spdk_nvmf_ctrlr_get_qpair(ctrlr, cmd->qid)) {
SPDK_ERRLOG("Got I/O connect with duplicate QID %u\n", cmd->qid);
rsp->status.sct = SPDK_NVME_SCT_GENERIC;
rsp->status.sc = SPDK_NVME_SC_COMMAND_SEQUENCE_ERROR;
return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE;
}
/* check if we would exceed ctrlr connection limit */
if (ctrlr->num_qpairs >= ctrlr->max_qpairs_allowed) {
SPDK_ERRLOG("qpair limit %d\n", ctrlr->num_qpairs);

View File

@ -232,6 +232,7 @@ test_connect(void)
struct spdk_nvmf_subsystem subsystem;
struct spdk_nvmf_request req;
struct spdk_nvmf_qpair qpair;
struct spdk_nvmf_qpair qpair2;
struct spdk_nvmf_ctrlr ctrlr;
struct spdk_nvmf_tgt tgt;
union nvmf_h2c_msg cmd;
@ -491,6 +492,19 @@ test_connect(void)
CU_ASSERT(qpair.ctrlr == NULL);
ctrlr.num_qpairs = 0;
/* I/O connect with duplicate queue ID */
memset(&rsp, 0, sizeof(rsp));
memset(&qpair2, 0, sizeof(qpair2));
qpair2.qid = 1;
TAILQ_INSERT_TAIL(&ctrlr.qpairs, &qpair, link);
cmd.connect_cmd.qid = 1;
rc = spdk_nvmf_ctrlr_connect(&req);
CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE);
CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC);
CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_COMMAND_SEQUENCE_ERROR);
CU_ASSERT(qpair.ctrlr == NULL);
TAILQ_INIT(&ctrlr.qpairs);
/* Clean up globals */
MOCK_SET(spdk_nvmf_tgt_find_subsystem, struct spdk_nvmf_subsystem *, NULL);
MOCK_SET(spdk_nvmf_poll_group_create, struct spdk_nvmf_poll_group *, NULL);