2022-06-03 19:15:11 +00:00
|
|
|
/* SPDX-License-Identifier: BSD-3-Clause
|
2022-11-01 20:26:26 +00:00
|
|
|
* Copyright (C) 2021 Intel Corporation.
|
2021-02-26 06:43:46 +00:00
|
|
|
* All rights reserved.
|
2022-07-15 10:10:52 +00:00
|
|
|
* Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
2021-02-26 06:43:46 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "spdk/stdinc.h"
|
|
|
|
#include "spdk_cunit.h"
|
|
|
|
#include "nvme/nvme_fabric.c"
|
|
|
|
#include "common/lib/test_env.c"
|
|
|
|
|
|
|
|
SPDK_LOG_REGISTER_COMPONENT(nvme)
|
|
|
|
|
2021-06-01 07:10:10 +00:00
|
|
|
pid_t g_spdk_nvme_pid;
|
2021-02-26 06:43:46 +00:00
|
|
|
struct spdk_nvmf_fabric_prop_set_cmd g_ut_cmd = {};
|
|
|
|
struct spdk_nvmf_fabric_prop_get_rsp g_ut_response = {};
|
|
|
|
|
|
|
|
DEFINE_STUB_V(spdk_nvme_ctrlr_get_default_ctrlr_opts,
|
|
|
|
(struct spdk_nvme_ctrlr_opts *opts, size_t opts_size));
|
|
|
|
|
|
|
|
DEFINE_STUB(nvme_transport_ctrlr_set_reg_4, int,
|
|
|
|
(struct spdk_nvme_ctrlr *ctrlr,
|
|
|
|
uint32_t offset, uint32_t value), 0);
|
|
|
|
|
|
|
|
DEFINE_STUB_V(nvme_ctrlr_destruct, (struct spdk_nvme_ctrlr *ctrlr));
|
|
|
|
|
|
|
|
DEFINE_STUB(nvme_ctrlr_cmd_identify, int,
|
|
|
|
(struct spdk_nvme_ctrlr *ctrlr, uint8_t cns, uint16_t cntid,
|
|
|
|
uint32_t nsid, uint8_t csi, void *payload, size_t payload_size,
|
|
|
|
spdk_nvme_cmd_cb cb_fn, void *cb_arg), 0);
|
|
|
|
|
|
|
|
DEFINE_STUB_V(nvme_ctrlr_connected, (struct spdk_nvme_probe_ctx *probe_ctx,
|
|
|
|
struct spdk_nvme_ctrlr *ctrlr));
|
|
|
|
DEFINE_STUB(nvme_ctrlr_add_process, int,
|
|
|
|
(struct spdk_nvme_ctrlr *ctrlr, void *devhandle), 0);
|
|
|
|
|
|
|
|
DEFINE_STUB(spdk_nvme_ctrlr_cmd_get_log_page, int,
|
|
|
|
(struct spdk_nvme_ctrlr *ctrlr, uint8_t log_page,
|
|
|
|
uint32_t nsid, void *payload, uint32_t payload_size,
|
|
|
|
uint64_t offset, spdk_nvme_cmd_cb cb_fn, void *cb_arg), 0);
|
|
|
|
|
|
|
|
DEFINE_STUB(spdk_nvme_transport_available_by_name, bool,
|
|
|
|
(const char *transport_name), true);
|
|
|
|
|
|
|
|
DEFINE_STUB(nvme_transport_ctrlr_construct, struct spdk_nvme_ctrlr *,
|
|
|
|
(const struct spdk_nvme_transport_id *trid,
|
|
|
|
const struct spdk_nvme_ctrlr_opts *opts,
|
|
|
|
void *devhandle), NULL);
|
|
|
|
|
|
|
|
DEFINE_STUB(spdk_nvme_transport_id_adrfam_str, const char *,
|
|
|
|
(enum spdk_nvmf_adrfam adrfam), NULL);
|
|
|
|
|
2021-05-27 19:22:07 +00:00
|
|
|
DEFINE_STUB(nvme_ctrlr_process_init, int, (struct spdk_nvme_ctrlr *ctrlr), 0);
|
|
|
|
|
2021-06-01 07:10:10 +00:00
|
|
|
static struct spdk_nvmf_fabric_connect_data g_nvmf_data;
|
2021-06-08 19:08:19 +00:00
|
|
|
static struct nvme_request *g_request;
|
2021-06-01 07:10:10 +00:00
|
|
|
|
|
|
|
int
|
2022-02-09 20:50:32 +00:00
|
|
|
nvme_qpair_submit_request(struct spdk_nvme_qpair *qpair, struct nvme_request *req)
|
2021-06-01 07:10:10 +00:00
|
|
|
{
|
2022-02-09 20:50:32 +00:00
|
|
|
CU_ASSERT(nvme_payload_type(&req->payload) == NVME_PAYLOAD_TYPE_CONTIG);
|
2021-06-01 07:10:10 +00:00
|
|
|
|
2021-06-08 19:08:19 +00:00
|
|
|
g_request = req;
|
2022-02-09 20:50:32 +00:00
|
|
|
memcpy(&g_nvmf_data, req->payload.contig_or_cb_arg, sizeof(g_nvmf_data));
|
2021-06-01 07:10:10 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-06-08 19:08:19 +00:00
|
|
|
void
|
|
|
|
nvme_completion_poll_cb(void *arg, const struct spdk_nvme_cpl *cpl)
|
|
|
|
{
|
|
|
|
struct nvme_completion_poll_status *status = arg;
|
|
|
|
|
|
|
|
if (status->timed_out) {
|
|
|
|
spdk_free(status->dma_data);
|
|
|
|
free(status);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_request = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool g_nvme_wait_for_completion_timeout;
|
|
|
|
|
2021-06-01 07:10:10 +00:00
|
|
|
int
|
2021-06-08 19:08:19 +00:00
|
|
|
nvme_wait_for_completion_robust_lock_timeout_poll(struct spdk_nvme_qpair *qpair,
|
|
|
|
struct nvme_completion_poll_status *status,
|
|
|
|
pthread_mutex_t *robust_mutex)
|
2021-06-01 07:10:10 +00:00
|
|
|
{
|
|
|
|
struct spdk_nvmf_fabric_connect_rsp *rsp = (void *)&status->cpl;
|
|
|
|
|
|
|
|
if (nvme_qpair_is_admin_queue(qpair)) {
|
|
|
|
rsp->status_code_specific.success.cntlid = 1;
|
|
|
|
}
|
|
|
|
|
2021-06-08 19:08:19 +00:00
|
|
|
status->timed_out = g_nvme_wait_for_completion_timeout;
|
2021-06-01 07:10:10 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-04-29 10:12:56 +00:00
|
|
|
int
|
|
|
|
spdk_nvme_transport_id_populate_trstring(struct spdk_nvme_transport_id *trid, const char *trstring)
|
|
|
|
{
|
|
|
|
int len, i, rc;
|
|
|
|
|
|
|
|
if (trstring == NULL) {
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
len = strnlen(trstring, SPDK_NVMF_TRSTRING_MAX_LEN);
|
|
|
|
if (len == SPDK_NVMF_TRSTRING_MAX_LEN) {
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = snprintf(trid->trstring, SPDK_NVMF_TRSTRING_MAX_LEN, "%s", trstring);
|
|
|
|
if (rc < 0) {
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* cast official trstring to uppercase version of input. */
|
|
|
|
for (i = 0; i < len; i++) {
|
|
|
|
trid->trstring[i] = toupper(trid->trstring[i]);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-05-10 19:13:49 +00:00
|
|
|
static struct spdk_nvme_transport_id g_ut_trid;
|
|
|
|
static bool g_ut_ctrlr_is_probed;
|
2021-04-29 10:12:56 +00:00
|
|
|
|
|
|
|
int
|
|
|
|
nvme_ctrlr_probe(const struct spdk_nvme_transport_id *trid,
|
|
|
|
struct spdk_nvme_probe_ctx *probe_ctx, void *devhandle)
|
|
|
|
{
|
2021-05-10 19:13:49 +00:00
|
|
|
g_ut_trid = *trid;
|
|
|
|
g_ut_ctrlr_is_probed = true;
|
2021-04-29 10:12:56 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *
|
|
|
|
spdk_nvme_transport_id_trtype_str(enum spdk_nvme_transport_type trtype)
|
|
|
|
{
|
|
|
|
switch (trtype) {
|
|
|
|
case SPDK_NVME_TRANSPORT_PCIE:
|
|
|
|
return "PCIe";
|
|
|
|
case SPDK_NVME_TRANSPORT_RDMA:
|
|
|
|
return "RDMA";
|
|
|
|
case SPDK_NVME_TRANSPORT_FC:
|
|
|
|
return "FC";
|
|
|
|
case SPDK_NVME_TRANSPORT_TCP:
|
|
|
|
return "TCP";
|
|
|
|
case SPDK_NVME_TRANSPORT_VFIOUSER:
|
|
|
|
return "VFIOUSER";
|
|
|
|
case SPDK_NVME_TRANSPORT_CUSTOM:
|
|
|
|
return "CUSTOM";
|
|
|
|
default:
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFINE_RETURN_MOCK(nvme_wait_for_completion, int);
|
|
|
|
int
|
|
|
|
nvme_wait_for_completion(struct spdk_nvme_qpair *qpair,
|
|
|
|
struct nvme_completion_poll_status *status)
|
|
|
|
{
|
|
|
|
status->timed_out = false;
|
|
|
|
HANDLE_RETURN_MOCK(nvme_wait_for_completion);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2022-07-15 10:10:52 +00:00
|
|
|
DEFINE_RETURN_MOCK(nvme_wait_for_completion_robust_lock, int);
|
|
|
|
int
|
|
|
|
nvme_wait_for_completion_robust_lock(struct spdk_nvme_qpair *qpair,
|
|
|
|
struct nvme_completion_poll_status *status,
|
|
|
|
pthread_mutex_t *robust_mutex)
|
|
|
|
{
|
|
|
|
status->timed_out = false;
|
|
|
|
HANDLE_RETURN_MOCK(nvme_wait_for_completion_robust_lock);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-02-26 06:43:46 +00:00
|
|
|
DEFINE_RETURN_MOCK(spdk_nvme_ctrlr_cmd_admin_raw, int);
|
|
|
|
int
|
|
|
|
spdk_nvme_ctrlr_cmd_admin_raw(struct spdk_nvme_ctrlr *ctrlr,
|
|
|
|
struct spdk_nvme_cmd *cmd,
|
|
|
|
void *buf, uint32_t len,
|
|
|
|
spdk_nvme_cmd_cb cb_fn, void *cb_arg)
|
|
|
|
{
|
|
|
|
struct spdk_nvmf_fabric_prop_set_cmd *cmd_tmp = (void *)cmd;
|
|
|
|
struct nvme_completion_poll_status *status = cb_arg;
|
|
|
|
struct spdk_nvmf_fabric_prop_get_rsp *response = (void *)&status->cpl;
|
|
|
|
|
|
|
|
g_ut_cmd.opcode = cmd_tmp->opcode;
|
|
|
|
g_ut_cmd.fctype = cmd_tmp->fctype;
|
|
|
|
g_ut_cmd.ofst = cmd_tmp->ofst;
|
|
|
|
g_ut_cmd.attrib.size = cmd_tmp->attrib.size;
|
|
|
|
|
|
|
|
if (cmd_tmp->fctype == SPDK_NVMF_FABRIC_COMMAND_PROPERTY_SET) {
|
|
|
|
g_ut_cmd.value.u64 = cmd_tmp->value.u64;
|
|
|
|
} else if (cmd_tmp->fctype == SPDK_NVMF_FABRIC_COMMAND_PROPERTY_GET) {
|
|
|
|
memcpy(&g_ut_response, response, sizeof(g_ut_response));
|
|
|
|
}
|
|
|
|
|
|
|
|
HANDLE_RETURN_MOCK(spdk_nvme_ctrlr_cmd_admin_raw);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-06-08 19:08:19 +00:00
|
|
|
static void
|
|
|
|
abort_request(struct nvme_request *request)
|
|
|
|
{
|
|
|
|
struct spdk_nvme_cpl cpl = {
|
|
|
|
.status = {
|
|
|
|
.sct = SPDK_NVME_SCT_GENERIC,
|
|
|
|
.sc = SPDK_NVME_SC_ABORTED_SQ_DELETION,
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
request->cb_fn(request->cb_arg, &cpl);
|
|
|
|
}
|
|
|
|
|
2021-02-26 06:43:46 +00:00
|
|
|
static void
|
|
|
|
test_nvme_fabric_prop_set_cmd(void)
|
|
|
|
{
|
|
|
|
int rc;
|
|
|
|
struct spdk_nvme_ctrlr ctrlr = {};
|
|
|
|
|
|
|
|
memset(&g_ut_cmd, 0, sizeof(g_ut_cmd));
|
|
|
|
|
2021-06-22 11:50:56 +00:00
|
|
|
rc = nvme_fabric_prop_set_cmd_sync(&ctrlr, 1024, SPDK_NVMF_PROP_SIZE_8, 4096);
|
2021-02-26 06:43:46 +00:00
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
CU_ASSERT(g_ut_cmd.opcode == SPDK_NVME_OPC_FABRIC);
|
|
|
|
CU_ASSERT(g_ut_cmd.fctype == SPDK_NVMF_FABRIC_COMMAND_PROPERTY_SET);
|
|
|
|
CU_ASSERT(g_ut_cmd.ofst == 1024);
|
|
|
|
CU_ASSERT(g_ut_cmd.attrib.size == SPDK_NVMF_PROP_SIZE_8);
|
|
|
|
CU_ASSERT(g_ut_cmd.value.u64 == 4096);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_nvme_fabric_prop_get_cmd(void)
|
|
|
|
{
|
|
|
|
int rc;
|
|
|
|
uint64_t value;
|
|
|
|
struct spdk_nvme_ctrlr ctrlr = {};
|
|
|
|
|
|
|
|
memset(&g_ut_cmd, 0, sizeof(g_ut_cmd));
|
|
|
|
memset(&g_ut_response, 0, sizeof(g_ut_response));
|
|
|
|
value = 0xFFDEADBEEF;
|
|
|
|
|
|
|
|
/* Case 1: size is SPDK_NVMF_PROP_SIZE_4 */
|
2021-06-22 11:50:56 +00:00
|
|
|
rc = nvme_fabric_prop_get_cmd_sync(&ctrlr, 1024, SPDK_NVMF_PROP_SIZE_4, &value);
|
2021-02-26 06:43:46 +00:00
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
CU_ASSERT(g_ut_cmd.opcode == SPDK_NVME_OPC_FABRIC);
|
|
|
|
CU_ASSERT(g_ut_cmd.fctype == SPDK_NVMF_FABRIC_COMMAND_PROPERTY_GET);
|
|
|
|
CU_ASSERT(g_ut_cmd.ofst == 1024);
|
|
|
|
CU_ASSERT(g_ut_cmd.attrib.size == SPDK_NVMF_PROP_SIZE_4);
|
|
|
|
CU_ASSERT(g_ut_response.value.u32.low == (value & 0xFFFFFFFF));
|
|
|
|
|
|
|
|
/* Case 2: size is SPDK_NVMF_PROP_SIZE_8 */
|
|
|
|
memset(&g_ut_cmd, 0, sizeof(g_ut_cmd));
|
|
|
|
memset(&g_ut_response, 0, sizeof(g_ut_response));
|
|
|
|
|
2021-06-22 11:50:56 +00:00
|
|
|
rc = nvme_fabric_prop_get_cmd_sync(&ctrlr, 1024, SPDK_NVMF_PROP_SIZE_8, &value);
|
2021-02-26 06:43:46 +00:00
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
CU_ASSERT(g_ut_cmd.opcode == SPDK_NVME_OPC_FABRIC);
|
|
|
|
CU_ASSERT(g_ut_cmd.fctype == SPDK_NVMF_FABRIC_COMMAND_PROPERTY_GET);
|
|
|
|
CU_ASSERT(g_ut_cmd.ofst == 1024);
|
|
|
|
CU_ASSERT(g_ut_cmd.attrib.size == SPDK_NVMF_PROP_SIZE_8);
|
|
|
|
CU_ASSERT(g_ut_response.value.u64 == value);
|
|
|
|
}
|
|
|
|
|
2021-04-29 10:12:56 +00:00
|
|
|
static void
|
|
|
|
test_nvme_fabric_get_discovery_log_page(void)
|
|
|
|
{
|
|
|
|
struct spdk_nvme_ctrlr ctrlr = {};
|
|
|
|
char buffer[4096] = {};
|
|
|
|
uint64_t offset = 0;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
rc = nvme_fabric_get_discovery_log_page(&ctrlr, buffer, sizeof(buffer), offset);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
/* Get log page fail */
|
|
|
|
MOCK_SET(spdk_nvme_ctrlr_cmd_get_log_page, -EINVAL);
|
|
|
|
|
|
|
|
rc = nvme_fabric_get_discovery_log_page(&ctrlr, buffer, sizeof(buffer), offset);
|
|
|
|
CU_ASSERT(rc == -1);
|
|
|
|
MOCK_CLEAR(spdk_nvme_ctrlr_cmd_get_log_page);
|
|
|
|
|
|
|
|
/* Completion time out */
|
|
|
|
MOCK_SET(nvme_wait_for_completion, -1);
|
|
|
|
|
|
|
|
rc = nvme_fabric_get_discovery_log_page(&ctrlr, buffer, sizeof(buffer), offset);
|
|
|
|
CU_ASSERT(rc == -1);
|
|
|
|
MOCK_CLEAR(nvme_wait_for_completion);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_nvme_fabric_discover_probe(void)
|
|
|
|
{
|
|
|
|
struct spdk_nvmf_discovery_log_page_entry entry = {};
|
|
|
|
struct spdk_nvme_probe_ctx probe_ctx = {};
|
|
|
|
char hostnqn[256] = "nqn.2016-06.io.spdk:cnode1";
|
|
|
|
char traddr[SPDK_NVMF_TRADDR_MAX_LEN] = "192.168.100.8";
|
|
|
|
char trsvcid[SPDK_NVMF_TRSVCID_MAX_LEN] = "4420";
|
|
|
|
char trstring[SPDK_NVMF_TRSTRING_MAX_LEN + 1] = "RDMA";
|
|
|
|
|
|
|
|
entry.trtype = SPDK_NVME_TRANSPORT_RDMA;
|
|
|
|
entry.subtype = SPDK_NVMF_SUBTYPE_NVME;
|
|
|
|
entry.adrfam = SPDK_NVMF_ADRFAM_IPV4;
|
|
|
|
|
|
|
|
memcpy(entry.subnqn, hostnqn, 256);
|
|
|
|
memcpy(entry.traddr, traddr, SPDK_NVMF_TRADDR_MAX_LEN);
|
|
|
|
memcpy(entry.trsvcid, trsvcid, SPDK_NVMF_TRSVCID_MAX_LEN);
|
|
|
|
memcpy(probe_ctx.trid.trstring, trstring, sizeof(probe_ctx.trid.trstring));
|
|
|
|
|
|
|
|
nvme_fabric_discover_probe(&entry, &probe_ctx, 1);
|
2021-05-10 19:13:49 +00:00
|
|
|
CU_ASSERT(g_ut_ctrlr_is_probed == true);
|
|
|
|
CU_ASSERT(g_ut_trid.trtype == SPDK_NVME_TRANSPORT_RDMA);
|
|
|
|
CU_ASSERT(g_ut_trid.adrfam == SPDK_NVMF_ADRFAM_IPV4);
|
|
|
|
CU_ASSERT(!strncmp(g_ut_trid.trstring, trstring, sizeof(trstring)));
|
|
|
|
CU_ASSERT(!strncmp(g_ut_trid.subnqn, hostnqn, sizeof(hostnqn)));
|
|
|
|
CU_ASSERT(!strncmp(g_ut_trid.traddr, traddr, sizeof(traddr)));
|
|
|
|
CU_ASSERT(!strncmp(g_ut_trid.trsvcid, trsvcid, sizeof(trsvcid)));
|
|
|
|
|
|
|
|
g_ut_ctrlr_is_probed = false;
|
|
|
|
memset(&g_ut_trid, 0, sizeof(g_ut_trid));
|
2021-04-29 10:12:56 +00:00
|
|
|
|
|
|
|
/* Entry type unsupported */
|
|
|
|
entry.subtype = SPDK_NVMF_SUBTYPE_DISCOVERY;
|
|
|
|
|
|
|
|
nvme_fabric_discover_probe(&entry, &probe_ctx, 1);
|
2021-05-10 19:13:49 +00:00
|
|
|
CU_ASSERT(g_ut_ctrlr_is_probed == false);
|
2021-04-29 10:12:56 +00:00
|
|
|
|
|
|
|
/* Entry type invalid */
|
|
|
|
entry.subtype = 3;
|
|
|
|
|
|
|
|
nvme_fabric_discover_probe(&entry, &probe_ctx, 1);
|
2021-05-10 19:13:49 +00:00
|
|
|
CU_ASSERT(g_ut_ctrlr_is_probed == false);
|
2021-04-29 10:12:56 +00:00
|
|
|
}
|
|
|
|
|
2021-06-01 07:10:10 +00:00
|
|
|
static void
|
|
|
|
test_nvme_fabric_qpair_connect(void)
|
|
|
|
{
|
|
|
|
struct spdk_nvme_qpair qpair = {};
|
2022-02-09 20:50:32 +00:00
|
|
|
struct nvme_request reserved_req = {};
|
2021-06-01 07:10:10 +00:00
|
|
|
struct nvme_request req = {};
|
|
|
|
struct spdk_nvme_ctrlr ctrlr = {};
|
|
|
|
struct spdk_nvmf_fabric_connect_cmd *cmd = NULL;
|
|
|
|
int rc;
|
|
|
|
char hostnqn[SPDK_NVMF_NQN_MAX_LEN + 1] = "nqn.2016-06.io.spdk:host1";
|
|
|
|
char subnqn[SPDK_NVMF_NQN_MAX_LEN + 1] = "nqn.2016-06.io.spdk:subsystem1";
|
|
|
|
const uint8_t hostid[16] = {
|
|
|
|
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
|
|
|
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
|
|
|
|
};
|
|
|
|
|
2022-02-09 20:50:32 +00:00
|
|
|
cmd = (void *)&reserved_req.cmd;
|
2021-06-01 07:10:10 +00:00
|
|
|
qpair.ctrlr = &ctrlr;
|
|
|
|
req.qpair = &qpair;
|
2022-02-09 20:50:32 +00:00
|
|
|
reserved_req.qpair = &qpair;
|
2021-06-01 07:10:10 +00:00
|
|
|
STAILQ_INIT(&qpair.free_req);
|
|
|
|
STAILQ_INSERT_HEAD(&qpair.free_req, &req, stailq);
|
2022-02-09 20:50:32 +00:00
|
|
|
qpair.reserved_req = &reserved_req;
|
2021-06-01 07:10:10 +00:00
|
|
|
memset(&g_nvmf_data, 0, sizeof(g_nvmf_data));
|
|
|
|
|
|
|
|
qpair.id = 1;
|
|
|
|
ctrlr.opts.keep_alive_timeout_ms = 100;
|
|
|
|
ctrlr.cntlid = 2;
|
|
|
|
memcpy(ctrlr.opts.extended_host_id, hostid, sizeof(hostid));
|
|
|
|
memcpy(ctrlr.opts.hostnqn, hostnqn, sizeof(hostnqn));
|
|
|
|
memcpy(ctrlr.trid.subnqn, subnqn, sizeof(subnqn));
|
|
|
|
|
|
|
|
rc = nvme_fabric_qpair_connect(&qpair, 1);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
CU_ASSERT(cmd->opcode == SPDK_NVME_OPC_FABRIC);
|
|
|
|
CU_ASSERT(cmd->fctype == SPDK_NVMF_FABRIC_COMMAND_CONNECT);
|
|
|
|
CU_ASSERT(cmd->qid == 1);
|
|
|
|
CU_ASSERT(cmd->sqsize == 0);
|
|
|
|
CU_ASSERT(cmd->kato == 100);
|
|
|
|
CU_ASSERT(g_nvmf_data.cntlid == 2);
|
|
|
|
CU_ASSERT(!strncmp(g_nvmf_data.hostid, ctrlr.opts.extended_host_id, sizeof(g_nvmf_data.hostid)));
|
|
|
|
CU_ASSERT(!strncmp(g_nvmf_data.hostnqn, ctrlr.opts.hostnqn, sizeof(ctrlr.opts.hostnqn)));
|
|
|
|
CU_ASSERT(!strncmp(g_nvmf_data.subnqn, ctrlr.trid.subnqn, sizeof(ctrlr.trid.subnqn)));
|
2022-02-09 20:50:32 +00:00
|
|
|
/* Make sure we used the qpair's reserved_req, and not one from the STAILQ */
|
|
|
|
CU_ASSERT(g_request == qpair.reserved_req);
|
|
|
|
CU_ASSERT(!STAILQ_EMPTY(&qpair.free_req));
|
2021-06-01 07:10:10 +00:00
|
|
|
|
|
|
|
/* qid is adminq */
|
|
|
|
memset(&g_nvmf_data, 0, sizeof(g_nvmf_data));
|
2022-02-09 20:50:32 +00:00
|
|
|
memset(&reserved_req, 0, sizeof(reserved_req));
|
2021-06-01 07:10:10 +00:00
|
|
|
qpair.id = 0;
|
|
|
|
ctrlr.cntlid = 0;
|
|
|
|
|
|
|
|
rc = nvme_fabric_qpair_connect(&qpair, 1);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
CU_ASSERT(cmd->opcode == SPDK_NVME_OPC_FABRIC);
|
|
|
|
CU_ASSERT(cmd->fctype == SPDK_NVMF_FABRIC_COMMAND_CONNECT);
|
|
|
|
CU_ASSERT(cmd->qid == 0);
|
|
|
|
CU_ASSERT(cmd->sqsize == 0);
|
|
|
|
CU_ASSERT(cmd->kato == 100);
|
|
|
|
CU_ASSERT(ctrlr.cntlid == 1);
|
|
|
|
CU_ASSERT(g_nvmf_data.cntlid == 0xffff);
|
|
|
|
CU_ASSERT(!strncmp(g_nvmf_data.hostid, ctrlr.opts.extended_host_id, sizeof(g_nvmf_data.hostid)));
|
|
|
|
CU_ASSERT(!strncmp(g_nvmf_data.hostnqn, ctrlr.opts.hostnqn, sizeof(ctrlr.opts.hostnqn)));
|
|
|
|
CU_ASSERT(!strncmp(g_nvmf_data.subnqn, ctrlr.trid.subnqn, sizeof(ctrlr.trid.subnqn)));
|
2022-02-09 20:50:32 +00:00
|
|
|
/* Make sure we used the qpair's reserved_req, and not one from the STAILQ */
|
|
|
|
CU_ASSERT(g_request == qpair.reserved_req);
|
|
|
|
CU_ASSERT(!STAILQ_EMPTY(&qpair.free_req));
|
2021-06-01 07:10:10 +00:00
|
|
|
|
|
|
|
/* Wait_for completion timeout */
|
2021-06-08 19:08:19 +00:00
|
|
|
g_nvme_wait_for_completion_timeout = true;
|
2021-06-01 07:10:10 +00:00
|
|
|
|
|
|
|
rc = nvme_fabric_qpair_connect(&qpair, 1);
|
2021-06-08 19:25:37 +00:00
|
|
|
CU_ASSERT(rc == -ECANCELED);
|
2021-06-08 19:08:19 +00:00
|
|
|
g_nvme_wait_for_completion_timeout = false;
|
|
|
|
abort_request(g_request);
|
2021-06-01 07:10:10 +00:00
|
|
|
|
|
|
|
/* Input parameters invalid */
|
|
|
|
rc = nvme_fabric_qpair_connect(&qpair, 0);
|
|
|
|
CU_ASSERT(rc == -EINVAL);
|
|
|
|
}
|
|
|
|
|
2022-06-22 21:35:04 +00:00
|
|
|
int
|
|
|
|
main(int argc, char **argv)
|
2021-02-26 06:43:46 +00:00
|
|
|
{
|
|
|
|
CU_pSuite suite = NULL;
|
|
|
|
unsigned int num_failures;
|
|
|
|
|
|
|
|
CU_set_error_action(CUEA_ABORT);
|
|
|
|
CU_initialize_registry();
|
|
|
|
|
|
|
|
suite = CU_add_suite("nvme_fabric", NULL, NULL);
|
|
|
|
CU_ADD_TEST(suite, test_nvme_fabric_prop_set_cmd);
|
|
|
|
CU_ADD_TEST(suite, test_nvme_fabric_prop_get_cmd);
|
2021-04-29 10:12:56 +00:00
|
|
|
CU_ADD_TEST(suite, test_nvme_fabric_get_discovery_log_page);
|
|
|
|
CU_ADD_TEST(suite, test_nvme_fabric_discover_probe);
|
2021-06-01 07:10:10 +00:00
|
|
|
CU_ADD_TEST(suite, test_nvme_fabric_qpair_connect);
|
2021-02-26 06:43:46 +00:00
|
|
|
|
|
|
|
CU_basic_set_mode(CU_BRM_VERBOSE);
|
|
|
|
CU_basic_run_tests();
|
|
|
|
num_failures = CU_get_number_of_failures();
|
|
|
|
CU_cleanup_registry();
|
|
|
|
return num_failures;
|
|
|
|
}
|