Commit 5215fad6 authored by Seth Howell's avatar Seth Howell Committed by Jim Harris
Browse files

nvme: Add an API for updating a controller trid.



This can be useful when trying to perform multipath failover at the
application level. However, the controller must be in the failed state
before calling this function.

Change-Id: I5403c0036fed5dd3600ee20592925297494ba8aa
Signed-off-by: default avatarSeth Howell <seth.howell@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/470699


Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent 7d3771f9
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -693,6 +693,25 @@ int spdk_nvme_probe_poll_async(struct spdk_nvme_probe_ctx *probe_ctx);
 */
int spdk_nvme_detach(struct spdk_nvme_ctrlr *ctrlr);

/**
 * Update the transport ID for a given controller.
 *
 * This function allows the user to set a new trid for a controller only if the
 * controller is failed. The controller's failed state can be obtained from
 * spdk_nvme_ctrlr_is_failed(). The controller can also be forced to the failed
 * state using spdk_nvme_ctrlr_fail().
 *
 * This function also requires that the transport type and subnqn of the new trid
 * be the same as the old trid.
 *
 * \param ctrlr Opaque handle to an NVMe controller.
 * \param trid The new transport ID.
 *
 * \return 0 on success, -EINVAL if the trid is invalid,
 * -EPERM if the ctrlr is not failed.
 */
int spdk_nvme_ctrlr_set_trid(struct spdk_nvme_ctrlr *ctrlr, struct spdk_nvme_transport_id *trid);

/**
 * Perform a full hardware reset of the NVMe controller.
 *
+29 −0
Original line number Diff line number Diff line
@@ -1107,6 +1107,35 @@ out:
	return rc;
}

int
spdk_nvme_ctrlr_set_trid(struct spdk_nvme_ctrlr *ctrlr, struct spdk_nvme_transport_id *trid)
{
	int rc = 0;

	nvme_robust_mutex_lock(&ctrlr->ctrlr_lock);

	if (ctrlr->is_failed == false) {
		rc = -EPERM;
		goto out;
	}

	if (trid->trtype != ctrlr->trid.trtype) {
		rc = -EINVAL;
		goto out;
	}

	if (strncmp(trid->subnqn, ctrlr->trid.subnqn, SPDK_NVMF_NQN_MAX_LEN)) {
		rc = -EINVAL;
		goto out;
	}

	ctrlr->trid = *trid;

out:
	nvme_robust_mutex_unlock(&ctrlr->ctrlr_lock);
	return rc;
}

static void
nvme_ctrlr_identify_done(void *arg, const struct spdk_nvme_cpl *cpl)
{
+33 −0
Original line number Diff line number Diff line
@@ -1890,6 +1890,38 @@ test_nvme_ctrlr_init_delay(void)
	nvme_ctrlr_destruct(&ctrlr);
}

static void
test_spdk_nvme_ctrlr_set_trid(void)
{
	struct spdk_nvme_ctrlr	ctrlr = {0};
	struct spdk_nvme_transport_id	new_trid = {0};

	ctrlr.is_failed = false;
	ctrlr.trid.trtype = SPDK_NVME_TRANSPORT_RDMA;
	snprintf(ctrlr.trid.subnqn, SPDK_NVMF_NQN_MAX_LEN, "%s", "nqn.2016-06.io.spdk:cnode1");
	snprintf(ctrlr.trid.traddr, SPDK_NVMF_TRADDR_MAX_LEN, "%s", "192.168.100.8");
	snprintf(ctrlr.trid.trsvcid, SPDK_NVMF_TRSVCID_MAX_LEN, "%s", "4420");
	CU_ASSERT(spdk_nvme_ctrlr_set_trid(&ctrlr, &new_trid) == -EPERM);

	ctrlr.is_failed = true;
	new_trid.trtype = SPDK_NVME_TRANSPORT_TCP;
	CU_ASSERT(spdk_nvme_ctrlr_set_trid(&ctrlr, &new_trid) == -EINVAL);
	CU_ASSERT(ctrlr.trid.trtype = SPDK_NVME_TRANSPORT_RDMA);

	new_trid.trtype = SPDK_NVME_TRANSPORT_RDMA;
	snprintf(new_trid.subnqn, SPDK_NVMF_NQN_MAX_LEN, "%s", "nqn.2016-06.io.spdk:cnode2");
	CU_ASSERT(spdk_nvme_ctrlr_set_trid(&ctrlr, &new_trid) == -EINVAL);
	CU_ASSERT(strncmp(ctrlr.trid.subnqn, "nqn.2016-06.io.spdk:cnode1", SPDK_NVMF_NQN_MAX_LEN) == 0);


	snprintf(new_trid.subnqn, SPDK_NVMF_NQN_MAX_LEN, "%s", "nqn.2016-06.io.spdk:cnode1");
	snprintf(new_trid.traddr, SPDK_NVMF_TRADDR_MAX_LEN, "%s", "192.168.100.9");
	snprintf(new_trid.trsvcid, SPDK_NVMF_TRSVCID_MAX_LEN, "%s", "4421");
	CU_ASSERT(spdk_nvme_ctrlr_set_trid(&ctrlr, &new_trid) == 0);
	CU_ASSERT(strncmp(ctrlr.trid.traddr, "192.168.100.9", SPDK_NVMF_TRADDR_MAX_LEN) == 0);
	CU_ASSERT(strncmp(ctrlr.trid.trsvcid, "4421", SPDK_NVMF_TRSVCID_MAX_LEN) == 0);
}

int main(int argc, char **argv)
{
	CU_pSuite	suite = NULL;
@@ -1944,6 +1976,7 @@ int main(int argc, char **argv)
			       test_nvme_ctrlr_test_active_ns) == NULL
		|| CU_add_test(suite, "test_spdk_nvme_ctrlr_reconnect_io_qpair",
			       test_spdk_nvme_ctrlr_reconnect_io_qpair) == NULL
		|| CU_add_test(suite, "test_spdk_nvme_ctrlr_set_trid", test_spdk_nvme_ctrlr_set_trid) == NULL
	) {
		CU_cleanup_registry();
		return CU_get_error();