UT/nvmf: add reservation filter check Unit test

Change-Id: I16136f9a622c23dc232629981110a1ff07593035
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/448346
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
Changpeng Liu 2019-03-19 18:05:38 +08:00
parent ca76e519f8
commit 24e012c082

View File

@ -819,6 +819,221 @@ test_identify_ns(void)
CU_ASSERT(spdk_mem_all_zero(&nsdata, sizeof(nsdata)));
}
/*
* Reservation Unit Test Configuration
* -------- -------- --------
* | Host A | | Host B | | Host C |
* -------- -------- --------
* / \ | |
* -------- -------- ------- -------
* |Ctrlr1_A| |Ctrlr2_A| |Ctrlr_B| |Ctrlr_C|
* -------- -------- ------- -------
* \ \ / /
* \ \ / /
* \ \ / /
* --------------------------------------
* | NAMESPACE 1 |
* --------------------------------------
*/
static struct spdk_nvmf_ctrlr g_ctrlr1_A, g_ctrlr2_A, g_ctrlr_B, g_ctrlr_C;
struct spdk_nvmf_subsystem_pg_ns_info g_ns_info;
static void
ut_reservation_init(enum spdk_nvme_reservation_type rtype)
{
/* Host A has two controllers */
spdk_uuid_generate(&g_ctrlr1_A.hostid);
spdk_uuid_copy(&g_ctrlr2_A.hostid, &g_ctrlr1_A.hostid);
/* Host B has 1 controller */
spdk_uuid_generate(&g_ctrlr_B.hostid);
/* Host C has 1 controller */
spdk_uuid_generate(&g_ctrlr_C.hostid);
memset(&g_ns_info, 0, sizeof(g_ns_info));
g_ns_info.rtype = rtype;
g_ns_info.reg_hostid[0] = g_ctrlr1_A.hostid;
g_ns_info.reg_hostid[1] = g_ctrlr_B.hostid;
g_ns_info.reg_hostid[2] = g_ctrlr_C.hostid;
}
static void
test_reservation_write_exclusive(void)
{
struct spdk_nvmf_request req = {};
union nvmf_h2c_msg cmd = {};
union nvmf_c2h_msg rsp = {};
int rc;
req.cmd = &cmd;
req.rsp = &rsp;
/* Host A holds reservation with type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE */
ut_reservation_init(SPDK_NVME_RESERVE_WRITE_EXCLUSIVE);
g_ns_info.holder_id = g_ctrlr1_A.hostid;
/* Test Case: Issue a Read command from Host A and Host B */
cmd.nvme_cmd.opc = SPDK_NVME_OPC_READ;
rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr1_A, &req);
SPDK_CU_ASSERT_FATAL(rc == 0);
rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_B, &req);
SPDK_CU_ASSERT_FATAL(rc == 0);
/* Test Case: Issue a DSM Write command from Host A and Host B */
cmd.nvme_cmd.opc = SPDK_NVME_OPC_DATASET_MANAGEMENT;
rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr1_A, &req);
SPDK_CU_ASSERT_FATAL(rc == 0);
rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_B, &req);
SPDK_CU_ASSERT_FATAL(rc < 0);
SPDK_CU_ASSERT_FATAL(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_RESERVATION_CONFLICT);
/* Test Case: Issue a Write command from Host C */
cmd.nvme_cmd.opc = SPDK_NVME_OPC_WRITE;
rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_C, &req);
SPDK_CU_ASSERT_FATAL(rc < 0);
SPDK_CU_ASSERT_FATAL(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_RESERVATION_CONFLICT);
/* Test Case: Issue a Read command from Host B */
cmd.nvme_cmd.opc = SPDK_NVME_OPC_READ;
rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_B, &req);
SPDK_CU_ASSERT_FATAL(rc == 0);
/* Unregister Host C */
memset(&g_ns_info.reg_hostid[2], 0, sizeof(struct spdk_uuid));
/* Test Case: Read and Write commands from non-registrant Host C */
cmd.nvme_cmd.opc = SPDK_NVME_OPC_WRITE;
rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_C, &req);
SPDK_CU_ASSERT_FATAL(rc < 0);
SPDK_CU_ASSERT_FATAL(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_RESERVATION_CONFLICT);
cmd.nvme_cmd.opc = SPDK_NVME_OPC_READ;
rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_C, &req);
SPDK_CU_ASSERT_FATAL(rc == 0);
}
static void
test_reservation_exclusive_access(void)
{
struct spdk_nvmf_request req = {};
union nvmf_h2c_msg cmd = {};
union nvmf_c2h_msg rsp = {};
int rc;
req.cmd = &cmd;
req.rsp = &rsp;
/* Host A holds reservation with type SPDK_NVME_RESERVE_EXCLUSIVE_ACCESS */
ut_reservation_init(SPDK_NVME_RESERVE_EXCLUSIVE_ACCESS);
g_ns_info.holder_id = g_ctrlr1_A.hostid;
/* Test Case: Issue a Read command from Host B */
cmd.nvme_cmd.opc = SPDK_NVME_OPC_READ;
rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_B, &req);
SPDK_CU_ASSERT_FATAL(rc < 0);
SPDK_CU_ASSERT_FATAL(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_RESERVATION_CONFLICT);
/* Test Case: Issue a Reservation Release command from a valid Registrant */
cmd.nvme_cmd.opc = SPDK_NVME_OPC_RESERVATION_RELEASE;
rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_B, &req);
SPDK_CU_ASSERT_FATAL(rc == 0);
}
static void
_test_reservation_write_exclusive_regs_only_and_all_regs(enum spdk_nvme_reservation_type rtype)
{
struct spdk_nvmf_request req = {};
union nvmf_h2c_msg cmd = {};
union nvmf_c2h_msg rsp = {};
int rc;
req.cmd = &cmd;
req.rsp = &rsp;
/* SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY and SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS */
ut_reservation_init(rtype);
g_ns_info.holder_id = g_ctrlr1_A.hostid;
/* Test Case: Issue a Read command from Host A and Host C */
cmd.nvme_cmd.opc = SPDK_NVME_OPC_READ;
rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr1_A, &req);
SPDK_CU_ASSERT_FATAL(rc == 0);
rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_C, &req);
SPDK_CU_ASSERT_FATAL(rc == 0);
/* Test Case: Issue a DSM Write command from Host A and Host C */
cmd.nvme_cmd.opc = SPDK_NVME_OPC_DATASET_MANAGEMENT;
rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr1_A, &req);
SPDK_CU_ASSERT_FATAL(rc == 0);
rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_C, &req);
SPDK_CU_ASSERT_FATAL(rc == 0);
/* Unregister Host C */
memset(&g_ns_info.reg_hostid[2], 0, sizeof(struct spdk_uuid));
/* Test Case: Read and Write commands from non-registrant Host C */
cmd.nvme_cmd.opc = SPDK_NVME_OPC_READ;
rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_C, &req);
SPDK_CU_ASSERT_FATAL(rc == 0);
cmd.nvme_cmd.opc = SPDK_NVME_OPC_WRITE;
rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_C, &req);
SPDK_CU_ASSERT_FATAL(rc < 0);
SPDK_CU_ASSERT_FATAL(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_RESERVATION_CONFLICT);
}
static void
test_reservation_write_exclusive_regs_only_and_all_regs(void)
{
_test_reservation_write_exclusive_regs_only_and_all_regs(
SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY);
_test_reservation_write_exclusive_regs_only_and_all_regs(
SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS);
}
static void
_test_reservation_exclusive_access_regs_only_and_all_regs(enum spdk_nvme_reservation_type rtype)
{
struct spdk_nvmf_request req = {};
union nvmf_h2c_msg cmd = {};
union nvmf_c2h_msg rsp = {};
int rc;
req.cmd = &cmd;
req.rsp = &rsp;
/* SPDK_NVME_RESERVE_EXCLUSIVE_ACCESS_REG_ONLY and SPDK_NVME_RESERVE_EXCLUSIVE_ACCESS_ALL_REGS */
ut_reservation_init(rtype);
g_ns_info.holder_id = g_ctrlr1_A.hostid;
/* Test Case: Issue a Write command from Host B */
cmd.nvme_cmd.opc = SPDK_NVME_OPC_WRITE;
rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_B, &req);
SPDK_CU_ASSERT_FATAL(rc == 0);
/* Unregister Host B */
memset(&g_ns_info.reg_hostid[1], 0, sizeof(struct spdk_uuid));
/* Test Case: Issue a Read command from Host B */
cmd.nvme_cmd.opc = SPDK_NVME_OPC_READ;
rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_B, &req);
SPDK_CU_ASSERT_FATAL(rc < 0);
SPDK_CU_ASSERT_FATAL(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_RESERVATION_CONFLICT);
cmd.nvme_cmd.opc = SPDK_NVME_OPC_WRITE;
rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_B, &req);
SPDK_CU_ASSERT_FATAL(rc < 0);
SPDK_CU_ASSERT_FATAL(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_RESERVATION_CONFLICT);
}
static void
test_reservation_exclusive_access_regs_only_and_all_regs(void)
{
_test_reservation_exclusive_access_regs_only_and_all_regs(
SPDK_NVME_RESERVE_EXCLUSIVE_ACCESS_REG_ONLY);
_test_reservation_exclusive_access_regs_only_and_all_regs(
SPDK_NVME_RESERVE_EXCLUSIVE_ACCESS_ALL_REGS);
}
int main(int argc, char **argv)
{
CU_pSuite suite = NULL;
@ -839,7 +1054,13 @@ int main(int argc, char **argv)
CU_add_test(suite, "process_fabrics_cmd", test_process_fabrics_cmd) == NULL ||
CU_add_test(suite, "connect", test_connect) == NULL ||
CU_add_test(suite, "get_ns_id_desc_list", test_get_ns_id_desc_list) == NULL ||
CU_add_test(suite, "identify_ns", test_identify_ns) == NULL
CU_add_test(suite, "identify_ns", test_identify_ns) == NULL ||
CU_add_test(suite, "reservation_write_exclusive", test_reservation_write_exclusive) == NULL ||
CU_add_test(suite, "reservation_exclusive_access", test_reservation_exclusive_access) == NULL ||
CU_add_test(suite, "reservation_write_exclusive_regs_only_and_all_regs",
test_reservation_write_exclusive_regs_only_and_all_regs) == NULL ||
CU_add_test(suite, "reservation_exclusive_access_regs_only_and_all_regs",
test_reservation_exclusive_access_regs_only_and_all_regs) == NULL
) {
CU_cleanup_registry();
return CU_get_error();