Commit 890c91a2 authored by Joel Cunningham's avatar Joel Cunningham Committed by Tomasz Zawadzki
Browse files

test/unit/nvmf: add preempt with no holder test



Add unit test for preempt command with no reservation holder.

This tests registers all hosts with the same rkey and then preempt will
unregister all of them.

For preempt-and-abort we make sure the hostid that issues the preempt
doesn't abort itself (i.e. is not in the preempted hostids list).

Change-Id: I3d7425154a900c75793d872b083ddaa151d167ea
Signed-off-by: default avatarJoel Cunningham <joel.cunningham@oracle.com>
Reviewed-on: https://review.spdk.io/c/spdk/spdk/+/26674


Tested-by: default avatarSPDK Automated Test System <spdkbot@gmail.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarJim Harris <jim.harris@nvidia.com>
Reviewed-by: default avatarChangpeng Liu <changpeliu@tencent.com>
parent 6bb6da3b
Loading
Loading
Loading
Loading
+77 −0
Original line number Diff line number Diff line
@@ -1270,6 +1270,81 @@ test_reservation_acquire_preempt_basic(enum spdk_nvme_reservation_acquire_action
	ut_reservation_deinit();
}

static bool
hostid_list_contains_id(const struct spdk_uuid *hostid_list, uint32_t num_hostid,
			const struct spdk_uuid *id)
{
	for (size_t i = 0; i < num_hostid; i++) {
		if (!spdk_uuid_compare(&hostid_list[i], id)) {
			return true;
		}
	}
	return false;
}

static void
test_reservation_acquire_preempt_no_holder(enum spdk_nvme_reservation_acquire_action preempt_type)
{
	struct spdk_nvmf_request *req;
	struct spdk_nvme_cpl *rsp;
	struct spdk_nvmf_registrant *reg;
	uint32_t gen;
	bool is_abort = (preempt_type == SPDK_NVME_RESERVE_PREEMPT_ABORT);
	uint64_t rkey = 0xDEADCAFE;
	int status;

	printf("Executing test: %s with acquire type: %d\n", __func__, preempt_type);

	ut_reservation_init();

	req = ut_reservation_build_req(16);
	rsp = &req->rsp->nvme_cpl;
	rsp->status.sc = SPDK_NVME_SC_INVALID_FIELD;
	SPDK_CU_ASSERT_FATAL(req != NULL);

	gen = g_ns.gen;
	/* Add registrants for each controller with the same rkey */
	status = nvmf_ns_reservation_add_registrant(g_ns_ptr, &g_ctrlr1_A, rkey);
	SPDK_CU_ASSERT_FATAL(status == 0);
	status = nvmf_ns_reservation_add_registrant(g_ns_ptr, &g_ctrlr_B, rkey);
	SPDK_CU_ASSERT_FATAL(status == 0);
	status = nvmf_ns_reservation_add_registrant(g_ns_ptr, &g_ctrlr_C, rkey);
	SPDK_CU_ASSERT_FATAL(status == 0);
	SPDK_CU_ASSERT_FATAL(g_ns.gen - gen == 3);

	/* Premept while no reservation holder with prkey == rkey */
	ut_reservation_build_acquire_request(req, preempt_type, 0,
					     SPDK_NVME_RESERVE_WRITE_EXCLUSIVE, rkey, rkey);
	gen = g_ns.gen;
	nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr1_A, req);
	SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS);
	/* All registrants were released */
	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid);
	SPDK_CU_ASSERT_FATAL(reg == NULL);
	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_B.hostid);
	SPDK_CU_ASSERT_FATAL(reg == NULL);
	reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_C.hostid);
	SPDK_CU_ASSERT_FATAL(reg == NULL);
	SPDK_CU_ASSERT_FATAL(g_ns.holder == NULL); /* no reservation happens */
	SPDK_CU_ASSERT_FATAL(g_ns.rtype == 0);
	SPDK_CU_ASSERT_FATAL(g_ns.gen > gen);
	if (is_abort) {
		/* ctrlr1_A issued the preempt-and-abort but we don't abort ourselves */
		SPDK_CU_ASSERT_FATAL(g_ns.preempt_abort);
		SPDK_CU_ASSERT_FATAL(g_ns.preempt_abort->hostids_cnt == 2);
		SPDK_CU_ASSERT_FATAL(hostid_list_contains_id(g_ns.preempt_abort->hostids,
				     g_ns.preempt_abort->hostids_cnt, &g_ctrlr_B.hostid));
		SPDK_CU_ASSERT_FATAL(hostid_list_contains_id(g_ns.preempt_abort->hostids,
				     g_ns.preempt_abort->hostids_cnt, &g_ctrlr_C.hostid));
		SPDK_CU_ASSERT_FATAL(g_ns.preempt_abort->hostids_gen == 1);
	} else {
		SPDK_CU_ASSERT_FATAL(g_ns.preempt_abort == NULL);
	}

	ut_reservation_free_req(req);
	ut_reservation_deinit();
}

static void
test_reservation_acquire_preempt(void)
{
@@ -1278,6 +1353,8 @@ test_reservation_acquire_preempt(void)
	 */
	test_reservation_acquire_preempt_basic(SPDK_NVME_RESERVE_PREEMPT);
	test_reservation_acquire_preempt_basic(SPDK_NVME_RESERVE_PREEMPT_ABORT);
	test_reservation_acquire_preempt_no_holder(SPDK_NVME_RESERVE_PREEMPT);
	test_reservation_acquire_preempt_no_holder(SPDK_NVME_RESERVE_PREEMPT_ABORT);
}

static void