Commit be6a2fef authored by Ben Walker's avatar Ben Walker Committed by Tomasz Zawadzki
Browse files

bdev/nvme: bdev_nvme_delete now takes a path_id



Specifying only a transport id is not enough. We need to be able to
describe the host parameters too.

Signed-off-by: default avatarBen Walker <benjamin.walker@intel.com>
Change-Id: Iadbea553aee4b38e7cacab0b486e7e5746d0d1ab
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/9825


Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Community-CI: Mellanox Build Bot
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-by: default avatarAleksey Marchuk <alexeymar@mellanox.com>
parent 128a921e
Loading
Loading
Loading
Loading
+19 −19
Original line number Diff line number Diff line
@@ -3129,14 +3129,14 @@ bdev_nvme_delete_secondary_trid(struct nvme_ctrlr *nvme_ctrlr,
}

int
bdev_nvme_delete(const char *name, const struct spdk_nvme_transport_id *trid)
bdev_nvme_delete(const char *name, const struct nvme_path_id *path_id)
{
	struct nvme_bdev_ctrlr	*nbdev_ctrlr;
	struct nvme_ctrlr	*nvme_ctrlr, *tmp_nvme_ctrlr;
	struct nvme_path_id	*path_id, *tmp_path;
	struct nvme_path_id	*p, *t;
	int			rc = -ENXIO;

	if (name == NULL || trid == NULL) {
	if (name == NULL || path_id == NULL) {
		return -EINVAL;
	}

@@ -3151,48 +3151,48 @@ bdev_nvme_delete(const char *name, const struct spdk_nvme_transport_id *trid)
	 */

	TAILQ_FOREACH_SAFE(nvme_ctrlr, &nbdev_ctrlr->ctrlrs, tailq, tmp_nvme_ctrlr) {
		TAILQ_FOREACH_REVERSE_SAFE(path_id, &nvme_ctrlr->trids, nvme_paths, link, tmp_path) {
			if (trid->trtype != 0) {
				if (trid->trtype == SPDK_NVME_TRANSPORT_CUSTOM) {
					if (strcasecmp(trid->trstring, path_id->trid.trstring) != 0) {
		TAILQ_FOREACH_REVERSE_SAFE(p, &nvme_ctrlr->trids, nvme_paths, link, t) {
			if (path_id->trid.trtype != 0) {
				if (path_id->trid.trtype == SPDK_NVME_TRANSPORT_CUSTOM) {
					if (strcasecmp(path_id->trid.trstring, p->trid.trstring) != 0) {
						continue;
					}
				} else {
					if (trid->trtype != path_id->trid.trtype) {
					if (path_id->trid.trtype != p->trid.trtype) {
						continue;
					}
				}
			}

			if (!spdk_mem_all_zero(trid->traddr, sizeof(trid->traddr))) {
				if (strcasecmp(trid->traddr, path_id->trid.traddr) != 0) {
			if (!spdk_mem_all_zero(path_id->trid.traddr, sizeof(path_id->trid.traddr))) {
				if (strcasecmp(path_id->trid.traddr, p->trid.traddr) != 0) {
					continue;
				}
			}

			if (trid->adrfam != 0) {
				if (trid->adrfam != path_id->trid.adrfam) {
			if (path_id->trid.adrfam != 0) {
				if (path_id->trid.adrfam != p->trid.adrfam) {
					continue;
				}
			}

			if (!spdk_mem_all_zero(trid->trsvcid, sizeof(trid->trsvcid))) {
				if (strcasecmp(trid->trsvcid, path_id->trid.trsvcid) != 0) {
			if (!spdk_mem_all_zero(path_id->trid.trsvcid, sizeof(path_id->trid.trsvcid))) {
				if (strcasecmp(path_id->trid.trsvcid, p->trid.trsvcid) != 0) {
					continue;
				}
			}

			if (!spdk_mem_all_zero(trid->subnqn, sizeof(trid->subnqn))) {
				if (strcmp(trid->subnqn, path_id->trid.subnqn) != 0) {
			if (!spdk_mem_all_zero(path_id->trid.subnqn, sizeof(path_id->trid.subnqn))) {
				if (strcmp(path_id->trid.subnqn, p->trid.subnqn) != 0) {
					continue;
				}
			}

			/* If we made it here, then this path is a match! Now we need to remove it. */
			if (path_id == nvme_ctrlr->active_path_id) {
			if (p == nvme_ctrlr->active_path_id) {
				/* This is the active path in use right now. The active path is always the first in the list. */

				if (!TAILQ_NEXT(path_id, link)) {
				if (!TAILQ_NEXT(p, link)) {
					/* The current path is the only path. */
					rc = _bdev_nvme_delete(nvme_ctrlr, false);
				} else {
@@ -3201,7 +3201,7 @@ bdev_nvme_delete(const char *name, const struct spdk_nvme_transport_id *trid)
				}
			} else {
				/* We are not using the specified path. */
				rc = bdev_nvme_delete_secondary_trid(nvme_ctrlr, &path_id->trid);
				rc = bdev_nvme_delete_secondary_trid(nvme_ctrlr, &p->trid);
			}

			if (rc < 0 && rc != -ENXIO) {
+2 −2
Original line number Diff line number Diff line
@@ -231,10 +231,10 @@ struct spdk_nvme_ctrlr *bdev_nvme_get_ctrlr(struct spdk_bdev *bdev);
 * if there is any alternative path. Requires to pass name of NVMe controller.
 *
 * \param name NVMe controller name
 * \param trid The specified transport ID to remove (optional)
 * \param path_id The specified path to remove (optional)
 * \return zero on success, -EINVAL on wrong parameters or -ENODEV if controller is not found
 */
int bdev_nvme_delete(const char *name, const struct spdk_nvme_transport_id *trid);
int bdev_nvme_delete(const char *name, const struct nvme_path_id *path_id);

/**
 * Reset NVMe controller.
+1 −1
Original line number Diff line number Diff line
@@ -690,7 +690,7 @@ rpc_bdev_nvme_detach_controller(struct spdk_jsonrpc_request *request,
		memcpy(path.trid.subnqn, req.subnqn, len + 1);
	}

	rc = bdev_nvme_delete(req.name, &path.trid);
	rc = bdev_nvme_delete(req.name, &path);

	if (rc != 0) {
		spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
+75 −75
Original line number Diff line number Diff line
@@ -301,7 +301,7 @@ static int g_ut_attach_ctrlr_status;
static size_t g_ut_attach_bdev_count;
static int g_ut_register_bdev_status;
static uint16_t g_ut_cntlid;
static struct spdk_nvme_transport_id g_any_trid = {};
static struct nvme_path_id g_any_path = {};

static void
ut_init_trid(struct spdk_nvme_transport_id *trid)
@@ -1196,7 +1196,7 @@ test_create_ctrlr(void)

	CU_ASSERT(nvme_ctrlr_get_by_name("nvme0") != NULL);

	rc = bdev_nvme_delete("nvme0", &g_any_trid);
	rc = bdev_nvme_delete("nvme0", &g_any_path);
	CU_ASSERT(rc == 0);

	CU_ASSERT(nvme_ctrlr_get_by_name("nvme0") != NULL);
@@ -1308,7 +1308,7 @@ test_reset_ctrlr(void)

	poll_threads();

	rc = bdev_nvme_delete("nvme0", &g_any_trid);
	rc = bdev_nvme_delete("nvme0", &g_any_path);
	CU_ASSERT(rc == 0);

	poll_threads();
@@ -1356,7 +1356,7 @@ test_race_between_reset_and_destruct_ctrlr(void)
	/* Try destructing ctrlr while ctrlr is being reset, but it will be deferred. */
	set_thread(0);

	rc = bdev_nvme_delete("nvme0", &g_any_trid);
	rc = bdev_nvme_delete("nvme0", &g_any_path);
	CU_ASSERT(rc == 0);
	CU_ASSERT(nvme_ctrlr_get_by_name("nvme0") == nvme_ctrlr);
	CU_ASSERT(nvme_ctrlr->destruct == true);
@@ -1526,7 +1526,7 @@ test_failover_ctrlr(void)

	poll_threads();

	rc = bdev_nvme_delete("nvme0", &g_any_trid);
	rc = bdev_nvme_delete("nvme0", &g_any_path);
	CU_ASSERT(rc == 0);

	poll_threads();
@@ -1657,7 +1657,7 @@ test_pending_reset(void)

	set_thread(0);

	rc = bdev_nvme_delete("nvme0", &g_any_trid);
	rc = bdev_nvme_delete("nvme0", &g_any_path);
	CU_ASSERT(rc == 0);

	poll_threads();
@@ -1723,7 +1723,7 @@ test_attach_ctrlr(void)
	CU_ASSERT(nvme_ctrlr->ctrlr == ctrlr);
	CU_ASSERT(nvme_ctrlr->num_ns == 0);

	rc = bdev_nvme_delete("nvme0", &g_any_trid);
	rc = bdev_nvme_delete("nvme0", &g_any_path);
	CU_ASSERT(rc == 0);

	poll_threads();
@@ -1759,7 +1759,7 @@ test_attach_ctrlr(void)
	SPDK_CU_ASSERT_FATAL(nbdev != NULL);
	CU_ASSERT(bdev_nvme_get_ctrlr(&nbdev->disk) == ctrlr);

	rc = bdev_nvme_delete("nvme0", &g_any_trid);
	rc = bdev_nvme_delete("nvme0", &g_any_path);
	CU_ASSERT(rc == 0);

	poll_threads();
@@ -1791,7 +1791,7 @@ test_attach_ctrlr(void)

	CU_ASSERT(attached_names[0] == NULL);

	rc = bdev_nvme_delete("nvme0", &g_any_trid);
	rc = bdev_nvme_delete("nvme0", &g_any_path);
	CU_ASSERT(rc == 0);

	poll_threads();
@@ -1892,7 +1892,7 @@ test_aer_cb(void)
	CU_ASSERT(nvme_ctrlr_get_ns(nvme_ctrlr, 2)->ana_state == SPDK_NVME_ANA_INACCESSIBLE_STATE);
	CU_ASSERT(nvme_ctrlr_get_ns(nvme_ctrlr, 4)->ana_state == SPDK_NVME_ANA_CHANGE_STATE);

	rc = bdev_nvme_delete("nvme0", &g_any_trid);
	rc = bdev_nvme_delete("nvme0", &g_any_path);
	CU_ASSERT(rc == 0);

	poll_threads();
@@ -2088,7 +2088,7 @@ test_submit_nvme_cmd(void)

	set_thread(1);

	rc = bdev_nvme_delete("nvme0", &g_any_trid);
	rc = bdev_nvme_delete("nvme0", &g_any_path);
	CU_ASSERT(rc == 0);

	poll_threads();
@@ -2101,7 +2101,7 @@ test_submit_nvme_cmd(void)
static void
test_add_remove_trid(void)
{
	struct spdk_nvme_transport_id trid1 = {}, trid2 = {}, trid3 = {};
	struct nvme_path_id path1 = {}, path2 = {}, path3 = {};
	struct spdk_nvme_ctrlr *ctrlr1, *ctrlr2, *ctrlr3;
	struct nvme_ctrlr *nvme_ctrlr = NULL;
	const int STRING_SIZE = 32;
@@ -2110,19 +2110,19 @@ test_add_remove_trid(void)
	int rc;

	memset(attached_names, 0, sizeof(char *) * STRING_SIZE);
	ut_init_trid(&trid1);
	ut_init_trid2(&trid2);
	ut_init_trid3(&trid3);
	ut_init_trid(&path1.trid);
	ut_init_trid2(&path2.trid);
	ut_init_trid3(&path3.trid);

	set_thread(0);

	g_ut_attach_ctrlr_status = 0;
	g_ut_attach_bdev_count = 0;

	ctrlr1 = ut_attach_ctrlr(&trid1, 0, false, false);
	ctrlr1 = ut_attach_ctrlr(&path1.trid, 0, false, false);
	SPDK_CU_ASSERT_FATAL(ctrlr1 != NULL);

	rc = bdev_nvme_create(&trid1, "nvme0", attached_names, STRING_SIZE, 0,
	rc = bdev_nvme_create(&path1.trid, "nvme0", attached_names, STRING_SIZE, 0,
			      attach_ctrlr_done, NULL, NULL, false);
	CU_ASSERT(rc == 0);

@@ -2132,76 +2132,76 @@ test_add_remove_trid(void)
	nvme_ctrlr = nvme_ctrlr_get_by_name("nvme0");
	SPDK_CU_ASSERT_FATAL(nvme_ctrlr != NULL);

	CU_ASSERT(spdk_nvme_transport_id_compare(&nvme_ctrlr->active_path_id->trid, &trid1) == 0);
	CU_ASSERT(spdk_nvme_transport_id_compare(&nvme_ctrlr->active_path_id->trid, &path1.trid) == 0);

	ctrlr2 = ut_attach_ctrlr(&trid2, 0, false, false);
	ctrlr2 = ut_attach_ctrlr(&path2.trid, 0, false, false);
	SPDK_CU_ASSERT_FATAL(ctrlr2 != NULL);

	rc = bdev_nvme_create(&trid2, "nvme0", attached_names, STRING_SIZE, 0,
	rc = bdev_nvme_create(&path2.trid, "nvme0", attached_names, STRING_SIZE, 0,
			      attach_ctrlr_done, NULL, NULL, false);
	CU_ASSERT(rc == 0);

	spdk_delay_us(1000);
	poll_threads();

	CU_ASSERT(spdk_nvme_transport_id_compare(&nvme_ctrlr->active_path_id->trid, &trid1) == 0);
	CU_ASSERT(spdk_nvme_transport_id_compare(&nvme_ctrlr->active_path_id->trid, &path1.trid) == 0);
	TAILQ_FOREACH(ctrid, &nvme_ctrlr->trids, link) {
		if (spdk_nvme_transport_id_compare(&ctrid->trid, &trid2) == 0) {
		if (spdk_nvme_transport_id_compare(&ctrid->trid, &path2.trid) == 0) {
			break;
		}
	}
	CU_ASSERT(ctrid != NULL);

	/* trid3 is not in the registered list. */
	rc = bdev_nvme_delete("nvme0", &trid3);
	rc = bdev_nvme_delete("nvme0", &path3);
	CU_ASSERT(rc == -ENXIO);

	/* trid2 is not used, and simply removed. */
	rc = bdev_nvme_delete("nvme0", &trid2);
	rc = bdev_nvme_delete("nvme0", &path2);
	CU_ASSERT(rc == 0);
	CU_ASSERT(nvme_ctrlr_get_by_name("nvme0") == nvme_ctrlr);
	TAILQ_FOREACH(ctrid, &nvme_ctrlr->trids, link) {
		CU_ASSERT(spdk_nvme_transport_id_compare(&ctrid->trid, &trid2) != 0);
		CU_ASSERT(spdk_nvme_transport_id_compare(&ctrid->trid, &path2.trid) != 0);
	}

	ctrlr3 = ut_attach_ctrlr(&trid3, 0, false, false);
	ctrlr3 = ut_attach_ctrlr(&path3.trid, 0, false, false);
	SPDK_CU_ASSERT_FATAL(ctrlr3 != NULL);

	rc = bdev_nvme_create(&trid3, "nvme0", attached_names, STRING_SIZE, 0,
	rc = bdev_nvme_create(&path3.trid, "nvme0", attached_names, STRING_SIZE, 0,
			      attach_ctrlr_done, NULL, NULL, false);
	CU_ASSERT(rc == 0);

	spdk_delay_us(1000);
	poll_threads();

	CU_ASSERT(spdk_nvme_transport_id_compare(&nvme_ctrlr->active_path_id->trid, &trid1) == 0);
	CU_ASSERT(spdk_nvme_transport_id_compare(&nvme_ctrlr->active_path_id->trid, &path1.trid) == 0);
	TAILQ_FOREACH(ctrid, &nvme_ctrlr->trids, link) {
		if (spdk_nvme_transport_id_compare(&ctrid->trid, &trid3) == 0) {
		if (spdk_nvme_transport_id_compare(&ctrid->trid, &path3.trid) == 0) {
			break;
		}
	}
	CU_ASSERT(ctrid != NULL);

	/* trid1 is currently used and trid3 is an alternative path.
	 * If we remove trid1, path is changed to trid3.
	/* path1 is currently used and path3 is an alternative path.
	 * If we remove path1, path is changed to path3.
	 */
	rc = bdev_nvme_delete("nvme0", &trid1);
	rc = bdev_nvme_delete("nvme0", &path1);
	CU_ASSERT(rc == 0);
	CU_ASSERT(nvme_ctrlr_get_by_name("nvme0") == nvme_ctrlr);
	CU_ASSERT(nvme_ctrlr->resetting == true);
	TAILQ_FOREACH(ctrid, &nvme_ctrlr->trids, link) {
		CU_ASSERT(spdk_nvme_transport_id_compare(&ctrid->trid, &trid1) != 0);
		CU_ASSERT(spdk_nvme_transport_id_compare(&ctrid->trid, &path1.trid) != 0);
	}
	CU_ASSERT(spdk_nvme_transport_id_compare(&nvme_ctrlr->active_path_id->trid, &trid3) == 0);
	CU_ASSERT(spdk_nvme_transport_id_compare(&nvme_ctrlr->active_path_id->trid, &path3.trid) == 0);

	poll_threads();

	CU_ASSERT(nvme_ctrlr->resetting == false);

	/* trid3 is the current and only path. If we remove trid3, the corresponding
	/* path3 is the current and only path. If we remove path3, the corresponding
	 * nvme_ctrlr is removed.
	 */
	rc = bdev_nvme_delete("nvme0", &trid3);
	rc = bdev_nvme_delete("nvme0", &path3);
	CU_ASSERT(rc == 0);
	CU_ASSERT(nvme_ctrlr_get_by_name("nvme0") == nvme_ctrlr);

@@ -2211,10 +2211,10 @@ test_add_remove_trid(void)

	CU_ASSERT(nvme_ctrlr_get_by_name("nvme0") == NULL);

	ctrlr1 = ut_attach_ctrlr(&trid1, 0, false, false);
	ctrlr1 = ut_attach_ctrlr(&path1.trid, 0, false, false);
	SPDK_CU_ASSERT_FATAL(ctrlr1 != NULL);

	rc = bdev_nvme_create(&trid1, "nvme0", attached_names, STRING_SIZE, 0,
	rc = bdev_nvme_create(&path1.trid, "nvme0", attached_names, STRING_SIZE, 0,
			      attach_ctrlr_done, NULL, NULL, false);
	CU_ASSERT(rc == 0);

@@ -2224,28 +2224,28 @@ test_add_remove_trid(void)
	nvme_ctrlr = nvme_ctrlr_get_by_name("nvme0");
	SPDK_CU_ASSERT_FATAL(nvme_ctrlr != NULL);

	CU_ASSERT(spdk_nvme_transport_id_compare(&nvme_ctrlr->active_path_id->trid, &trid1) == 0);
	CU_ASSERT(spdk_nvme_transport_id_compare(&nvme_ctrlr->active_path_id->trid, &path1.trid) == 0);

	ctrlr2 = ut_attach_ctrlr(&trid2, 0, false, false);
	ctrlr2 = ut_attach_ctrlr(&path2.trid, 0, false, false);
	SPDK_CU_ASSERT_FATAL(ctrlr2 != NULL);

	rc = bdev_nvme_create(&trid2, "nvme0", attached_names, STRING_SIZE, 0,
	rc = bdev_nvme_create(&path2.trid, "nvme0", attached_names, STRING_SIZE, 0,
			      attach_ctrlr_done, NULL, NULL, false);
	CU_ASSERT(rc == 0);

	spdk_delay_us(1000);
	poll_threads();

	CU_ASSERT(spdk_nvme_transport_id_compare(&nvme_ctrlr->active_path_id->trid, &trid1) == 0);
	CU_ASSERT(spdk_nvme_transport_id_compare(&nvme_ctrlr->active_path_id->trid, &path1.trid) == 0);
	TAILQ_FOREACH(ctrid, &nvme_ctrlr->trids, link) {
		if (spdk_nvme_transport_id_compare(&ctrid->trid, &trid2) == 0) {
		if (spdk_nvme_transport_id_compare(&ctrid->trid, &path2.trid) == 0) {
			break;
		}
	}
	CU_ASSERT(ctrid != NULL);

	/* If trid is not specified, nvme_ctrlr itself is removed. */
	rc = bdev_nvme_delete("nvme0", &g_any_trid);
	rc = bdev_nvme_delete("nvme0", &g_any_path);
	CU_ASSERT(rc == 0);
	CU_ASSERT(nvme_ctrlr_get_by_name("nvme0") == nvme_ctrlr);

@@ -2424,7 +2424,7 @@ test_abort(void)

	set_thread(1);

	rc = bdev_nvme_delete("nvme0", &g_any_trid);
	rc = bdev_nvme_delete("nvme0", &g_any_path);
	CU_ASSERT(rc == 0);

	poll_threads();
@@ -2466,7 +2466,7 @@ test_get_io_qpair(void)

	spdk_put_io_channel(ch);

	rc = bdev_nvme_delete("nvme0", &g_any_trid);
	rc = bdev_nvme_delete("nvme0", &g_any_path);
	CU_ASSERT(rc == 0);

	poll_threads();
@@ -2648,7 +2648,7 @@ test_init_ana_log_page(void)
	CU_ASSERT(nvme_ctrlr_get_ns(nvme_ctrlr, 4)->bdev != NULL);
	CU_ASSERT(nvme_ctrlr_get_ns(nvme_ctrlr, 5)->bdev != NULL);

	rc = bdev_nvme_delete("nvme0", &g_any_trid);
	rc = bdev_nvme_delete("nvme0", &g_any_path);
	CU_ASSERT(rc == 0);

	poll_threads();
@@ -2811,7 +2811,7 @@ test_reconnect_qpair(void)

	poll_threads();

	rc = bdev_nvme_delete("nvme0", &g_any_trid);
	rc = bdev_nvme_delete("nvme0", &g_any_path);
	CU_ASSERT(rc == 0);

	poll_threads();
@@ -2824,7 +2824,7 @@ test_reconnect_qpair(void)
static void
test_create_bdev_ctrlr(void)
{
	struct spdk_nvme_transport_id trid1 = {}, trid2 = {};
	struct nvme_path_id path1 = {}, path2 = {};
	struct spdk_nvme_ctrlr *ctrlr1, *ctrlr2;
	struct nvme_bdev_ctrlr *nbdev_ctrlr;
	const int STRING_SIZE = 32;
@@ -2832,16 +2832,16 @@ test_create_bdev_ctrlr(void)
	int rc;

	memset(attached_names, 0, sizeof(char *) * STRING_SIZE);
	ut_init_trid(&trid1);
	ut_init_trid2(&trid2);
	ut_init_trid(&path1.trid);
	ut_init_trid2(&path2.trid);

	ctrlr1 = ut_attach_ctrlr(&trid1, 0, true, true);
	ctrlr1 = ut_attach_ctrlr(&path1.trid, 0, true, true);
	SPDK_CU_ASSERT_FATAL(ctrlr1 != NULL);

	g_ut_attach_ctrlr_status = 0;
	g_ut_attach_bdev_count = 0;

	rc = bdev_nvme_create(&trid1, "nvme0", attached_names, STRING_SIZE, 0,
	rc = bdev_nvme_create(&path1.trid, "nvme0", attached_names, STRING_SIZE, 0,
			      attach_ctrlr_done, NULL, NULL, true);

	spdk_delay_us(1000);
@@ -2852,17 +2852,17 @@ test_create_bdev_ctrlr(void)

	nbdev_ctrlr = nvme_bdev_ctrlr_get("nvme0");
	SPDK_CU_ASSERT_FATAL(nbdev_ctrlr != NULL);
	CU_ASSERT(nvme_bdev_ctrlr_get_ctrlr(nbdev_ctrlr, &trid1) != NULL);
	CU_ASSERT(nvme_bdev_ctrlr_get_ctrlr(nbdev_ctrlr, &path1.trid) != NULL);

	/* cntlid is duplicated, and adding the second ctrlr should fail. */
	g_ut_attach_ctrlr_status = -EINVAL;

	ctrlr2 = ut_attach_ctrlr(&trid2, 0, true, true);
	ctrlr2 = ut_attach_ctrlr(&path2.trid, 0, true, true);
	SPDK_CU_ASSERT_FATAL(ctrlr2 != NULL);

	ctrlr2->cdata.cntlid = ctrlr1->cdata.cntlid;

	rc = bdev_nvme_create(&trid2, "nvme0", attached_names, STRING_SIZE, 0,
	rc = bdev_nvme_create(&path2.trid, "nvme0", attached_names, STRING_SIZE, 0,
			      attach_ctrlr_done, NULL, NULL, true);
	CU_ASSERT(rc == 0);

@@ -2872,15 +2872,15 @@ test_create_bdev_ctrlr(void)
	spdk_delay_us(g_opts.nvme_adminq_poll_period_us);
	poll_threads();

	CU_ASSERT(nvme_bdev_ctrlr_get_ctrlr(nbdev_ctrlr, &trid2) == NULL);
	CU_ASSERT(nvme_bdev_ctrlr_get_ctrlr(nbdev_ctrlr, &path2.trid) == NULL);

	/* cntlid is not duplicated, and adding the third ctrlr should succeed. */
	g_ut_attach_ctrlr_status = 0;

	ctrlr2 = ut_attach_ctrlr(&trid2, 0, true, true);
	ctrlr2 = ut_attach_ctrlr(&path2.trid, 0, true, true);
	SPDK_CU_ASSERT_FATAL(ctrlr2 != NULL);

	rc = bdev_nvme_create(&trid2, "nvme0", attached_names, STRING_SIZE, 0,
	rc = bdev_nvme_create(&path2.trid, "nvme0", attached_names, STRING_SIZE, 0,
			      attach_ctrlr_done, NULL, NULL, true);
	CU_ASSERT(rc == 0);

@@ -2890,15 +2890,15 @@ test_create_bdev_ctrlr(void)
	spdk_delay_us(g_opts.nvme_adminq_poll_period_us);
	poll_threads();

	CU_ASSERT(nvme_bdev_ctrlr_get_ctrlr(nbdev_ctrlr, &trid2) != NULL);
	CU_ASSERT(nvme_bdev_ctrlr_get_ctrlr(nbdev_ctrlr, &path2.trid) != NULL);

	/* Delete two ctrlrs at once. */
	rc = bdev_nvme_delete("nvme0", &g_any_trid);
	rc = bdev_nvme_delete("nvme0", &g_any_path);
	CU_ASSERT(rc == 0);

	CU_ASSERT(nvme_bdev_ctrlr_get("nvme0") == nbdev_ctrlr);
	CU_ASSERT(nvme_bdev_ctrlr_get_ctrlr(nbdev_ctrlr, &trid1) != NULL);
	CU_ASSERT(nvme_bdev_ctrlr_get_ctrlr(nbdev_ctrlr, &trid2) != NULL);
	CU_ASSERT(nvme_bdev_ctrlr_get_ctrlr(nbdev_ctrlr, &path1.trid) != NULL);
	CU_ASSERT(nvme_bdev_ctrlr_get_ctrlr(nbdev_ctrlr, &path2.trid) != NULL);

	poll_threads();
	spdk_delay_us(1000);
@@ -2907,13 +2907,13 @@ test_create_bdev_ctrlr(void)
	CU_ASSERT(nvme_bdev_ctrlr_get("nvme0") == NULL);

	/* Add two ctrlrs and delete one by one. */
	ctrlr1 = ut_attach_ctrlr(&trid1, 0, true, true);
	ctrlr1 = ut_attach_ctrlr(&path1.trid, 0, true, true);
	SPDK_CU_ASSERT_FATAL(ctrlr1 != NULL);

	ctrlr2 = ut_attach_ctrlr(&trid2, 0, true, true);
	ctrlr2 = ut_attach_ctrlr(&path2.trid, 0, true, true);
	SPDK_CU_ASSERT_FATAL(ctrlr2 != NULL);

	rc = bdev_nvme_create(&trid1, "nvme0", attached_names, STRING_SIZE, 0,
	rc = bdev_nvme_create(&path1.trid, "nvme0", attached_names, STRING_SIZE, 0,
			      attach_ctrlr_done, NULL, NULL, true);
	CU_ASSERT(rc == 0);

@@ -2923,7 +2923,7 @@ test_create_bdev_ctrlr(void)
	spdk_delay_us(g_opts.nvme_adminq_poll_period_us);
	poll_threads();

	rc = bdev_nvme_create(&trid2, "nvme0", attached_names, STRING_SIZE, 0,
	rc = bdev_nvme_create(&path2.trid, "nvme0", attached_names, STRING_SIZE, 0,
			      attach_ctrlr_done, NULL, NULL, true);
	CU_ASSERT(rc == 0);

@@ -2936,27 +2936,27 @@ test_create_bdev_ctrlr(void)
	nbdev_ctrlr = nvme_bdev_ctrlr_get("nvme0");
	SPDK_CU_ASSERT_FATAL(nbdev_ctrlr != NULL);

	rc = bdev_nvme_delete("nvme0", &trid1);
	rc = bdev_nvme_delete("nvme0", &path1);
	CU_ASSERT(rc == 0);

	CU_ASSERT(nvme_bdev_ctrlr_get("nvme0") == nbdev_ctrlr);
	CU_ASSERT(nvme_bdev_ctrlr_get_ctrlr(nbdev_ctrlr, &trid1) != NULL);
	CU_ASSERT(nvme_bdev_ctrlr_get_ctrlr(nbdev_ctrlr, &trid2) != NULL);
	CU_ASSERT(nvme_bdev_ctrlr_get_ctrlr(nbdev_ctrlr, &path1.trid) != NULL);
	CU_ASSERT(nvme_bdev_ctrlr_get_ctrlr(nbdev_ctrlr, &path2.trid) != NULL);

	poll_threads();
	spdk_delay_us(1000);
	poll_threads();

	CU_ASSERT(nvme_bdev_ctrlr_get("nvme0") == nbdev_ctrlr);
	CU_ASSERT(nvme_bdev_ctrlr_get_ctrlr(nbdev_ctrlr, &trid1) == NULL);
	CU_ASSERT(nvme_bdev_ctrlr_get_ctrlr(nbdev_ctrlr, &trid2) != NULL);
	CU_ASSERT(nvme_bdev_ctrlr_get_ctrlr(nbdev_ctrlr, &path1.trid) == NULL);
	CU_ASSERT(nvme_bdev_ctrlr_get_ctrlr(nbdev_ctrlr, &path2.trid) != NULL);

	rc = bdev_nvme_delete("nvme0", &trid2);
	rc = bdev_nvme_delete("nvme0", &path2);
	CU_ASSERT(rc == 0);

	CU_ASSERT(nvme_bdev_ctrlr_get("nvme0") == nbdev_ctrlr);
	CU_ASSERT(nvme_bdev_ctrlr_get_ctrlr(nbdev_ctrlr, &trid1) == NULL);
	CU_ASSERT(nvme_bdev_ctrlr_get_ctrlr(nbdev_ctrlr, &trid2) != NULL);
	CU_ASSERT(nvme_bdev_ctrlr_get_ctrlr(nbdev_ctrlr, &path1.trid) == NULL);
	CU_ASSERT(nvme_bdev_ctrlr_get_ctrlr(nbdev_ctrlr, &path2.trid) != NULL);

	poll_threads();
	spdk_delay_us(1000);