Commit bedc405f authored by Daniel Verkamp's avatar Daniel Verkamp Committed by Jim Harris
Browse files

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: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
Reviewed-on: https://review.gerrithub.io/390662


Tested-by: default avatarSPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
parent fab9349f
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -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);
+14 −0
Original line number Diff line number Diff line
@@ -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);