Beispiel #1
0
static void
nvmf_test_create_subsystem(void)
{
	char nqn[256];
	struct spdk_nvmf_subsystem *subsystem;

	strncpy(nqn, "nqn.2016-06.io.spdk:subsystem1", sizeof(nqn));
	subsystem = spdk_nvmf_create_subsystem(nqn, SPDK_NVMF_SUBTYPE_NVME,
					       NVMF_SUBSYSTEM_MODE_DIRECT, NULL, NULL, NULL);
	SPDK_CU_ASSERT_FATAL(subsystem != NULL);
	CU_ASSERT_STRING_EQUAL(subsystem->subnqn, nqn);
	spdk_nvmf_delete_subsystem(subsystem);

	/* Longest valid name */
	strncpy(nqn, "nqn.2016-06.io.spdk:", sizeof(nqn));
	memset(nqn + strlen(nqn), 'a', 222 - strlen(nqn));
	nqn[222] = '\0';
	CU_ASSERT(strlen(nqn) == 222);
	subsystem = spdk_nvmf_create_subsystem(nqn, SPDK_NVMF_SUBTYPE_NVME,
					       NVMF_SUBSYSTEM_MODE_DIRECT, NULL, NULL, NULL);
	SPDK_CU_ASSERT_FATAL(subsystem != NULL);
	CU_ASSERT_STRING_EQUAL(subsystem->subnqn, nqn);
	spdk_nvmf_delete_subsystem(subsystem);

	/* Name that is one byte longer than allowed */
	strncpy(nqn, "nqn.2016-06.io.spdk:", sizeof(nqn));
	memset(nqn + strlen(nqn), 'a', 223 - strlen(nqn));
	nqn[223] = '\0';
	CU_ASSERT(strlen(nqn) == 223);
	subsystem = spdk_nvmf_create_subsystem(nqn, SPDK_NVMF_SUBTYPE_NVME,
					       NVMF_SUBSYSTEM_MODE_DIRECT, NULL, NULL, NULL);
	CU_ASSERT(subsystem == NULL);
}
Beispiel #2
0
static struct spdk_conf *
spdk_config_init_scsi_params(char *key, char *value)
{
	struct spdk_conf *spdk_config;
	FILE *f;
	int fd, rc;
	char filename[] = "/tmp/scsi_init_ut.XXXXXX";

	/* Create temporary file to hold config */
	fd = mkstemp(filename);
	SPDK_CU_ASSERT_FATAL(fd != -1);

	f = fdopen(fd, "wb+");
	SPDK_CU_ASSERT_FATAL(f != NULL);

	fprintf(f, "[Scsi]\n");
	fprintf(f, "%s %s\n", key, value);

	fclose(f);

	spdk_config = spdk_conf_allocate();
	SPDK_CU_ASSERT_FATAL(spdk_config != NULL);

	rc = spdk_conf_read(spdk_config, filename);
	SPDK_CU_ASSERT_FATAL(rc == 0);

	spdk_conf_set_as_default(spdk_config);

	remove(filename);

	return spdk_config;
}
Beispiel #3
0
static void
nvmf_test_init(void)
{
	int rc = 0;
	struct spdk_nvme_ctrlr *ctrlr;
	uint32_t i;

	request_mempool = NULL;
	/* test that NVMf library will trap if mempool not created */
	rc = nvmf_initialize();
	CU_ASSERT(rc < 0);
	request_mempool = malloc(sizeof(struct rte_mempool));
	rc = nvmf_initialize();
	CU_ASSERT(rc == 0);
	free(request_mempool);
	/* create faked controller */
	ctrlr = malloc(sizeof(struct spdk_nvme_ctrlr));
	SPDK_CU_ASSERT_FATAL(ctrlr != NULL);
	ctrlr->num_ns = NS_PER_CTRLR;
	for (i = 0; i < ctrlr->num_ns; i++) {
		ctrlr->ns[i].ctrlr = ctrlr;
		ctrlr->ns[i].id = i + 1;
	}
	ctrlr->attached = 1;
	spdk_nvmf_ctrlr_create("Nvme0", 0, 0, 1, 2, ctrlr);
}
Beispiel #4
0
	/*
	 * Only memset up to (but not including) the children
	 *  TAILQ_ENTRY.  children, and following members, are
	 *  only used as part of I/O splitting so we avoid
	 *  memsetting them until it is actually needed.
	 *  They will be initialized in nvme_request_add_child()
	 *  if the request is split.
	 */
	memset(req, 0, offsetof(struct nvme_request, children));
	req->cb_fn = cb_fn;
	req->cb_arg = cb_arg;
	req->payload = *payload;
	req->payload_size = payload_size;
	req->pid = getpid();

	return req;
}

struct nvme_request *
nvme_allocate_request_contig(void *buffer, uint32_t payload_size, spdk_nvme_cmd_cb cb_fn,
			     void *cb_arg)
{
	struct nvme_payload payload;

	payload.type = NVME_PAYLOAD_TYPE_CONTIG;
	payload.u.contig = buffer;

	return nvme_allocate_request(&payload, payload_size, cb_fn, cb_arg);
}

struct nvme_request *
nvme_allocate_request_null(spdk_nvme_cmd_cb cb_fn, void *cb_arg)
{
	return nvme_allocate_request_contig(NULL, 0, cb_fn, cb_arg);
}

void
nvme_free_request(struct nvme_request *req)
{
	spdk_mempool_put(_g_nvme_driver.request_mempool, req);
}

void
nvme_request_remove_child(struct nvme_request *parent,
			  struct nvme_request *child)
{
	parent->num_children--;
	TAILQ_REMOVE(&parent->children, child, child_tailq);
}

int
nvme_transport_qpair_enable(struct spdk_nvme_qpair *qpair)
{
	return 0;
}

int
nvme_transport_qpair_disable(struct spdk_nvme_qpair *qpair)
{
	return 0;
}

int
nvme_transport_qpair_fail(struct spdk_nvme_qpair *qpair)
{
	return 0;
}

int
nvme_transport_qpair_submit_request(struct spdk_nvme_qpair *qpair, struct nvme_request *req)
{
	// TODO
	return 0;
}

int32_t
nvme_transport_qpair_process_completions(struct spdk_nvme_qpair *qpair, uint32_t max_completions)
{
	// TODO
	return 0;
}

static void
prepare_submit_request_test(struct spdk_nvme_qpair *qpair,
			    struct spdk_nvme_ctrlr *ctrlr)
{
	memset(ctrlr, 0, sizeof(*ctrlr));
	ctrlr->free_io_qids = NULL;
	TAILQ_INIT(&ctrlr->active_io_qpairs);
	TAILQ_INIT(&ctrlr->active_procs);
	nvme_qpair_construct(qpair, 1, 128, ctrlr, 0);

	ut_fail_vtophys = false;
}

static void
cleanup_submit_request_test(struct spdk_nvme_qpair *qpair)
{
}

#if 0 /* TODO: move to PCIe-specific unit test */
static void
ut_insert_cq_entry(struct spdk_nvme_qpair *qpair, uint32_t slot)
{
	struct nvme_request	*req;
	struct nvme_tracker 	*tr;
	struct spdk_nvme_cpl	*cpl;

	req = spdk_mempool_get(_g_nvme_driver.request_mempool);
	SPDK_CU_ASSERT_FATAL(req != NULL);
	memset(req, 0, sizeof(*req));

	tr = TAILQ_FIRST(&qpair->free_tr);
	TAILQ_REMOVE(&qpair->free_tr, tr, tq_list); /* remove tr from free_tr */
	TAILQ_INSERT_HEAD(&qpair->outstanding_tr, tr, tq_list);
	req->cmd.cid = tr->cid;
	tr->req = req;
	qpair->tr[tr->cid].active = true;

	cpl = &qpair->cpl[slot];
	cpl->status.p = qpair->phase;
	cpl->cid = tr->cid;
}
#endif

static void
expected_success_callback(void *arg, const struct spdk_nvme_cpl *cpl)
{
	CU_ASSERT(!spdk_nvme_cpl_is_error(cpl));
}

static void
expected_failure_callback(void *arg, const struct spdk_nvme_cpl *cpl)
{
	CU_ASSERT(spdk_nvme_cpl_is_error(cpl));
}

static void
test3(void)
{
	struct spdk_nvme_qpair		qpair = {};
	struct nvme_request		*req;
	struct spdk_nvme_ctrlr		ctrlr = {};

	prepare_submit_request_test(&qpair, &ctrlr);

	req = nvme_allocate_request_null(expected_success_callback, NULL);
	SPDK_CU_ASSERT_FATAL(req != NULL);

	CU_ASSERT(nvme_qpair_submit_request(&qpair, req) == 0);

	nvme_free_request(req);

	cleanup_submit_request_test(&qpair);
}

#if 0 /* TODO: move to PCIe-specific unit test */
static void
test4(void)
{
	struct spdk_nvme_qpair		qpair = {};
	struct nvme_request		*req;
	struct spdk_nvme_ctrlr		ctrlr = {};
	char				payload[4096];

	prepare_submit_request_test(&qpair, &ctrlr);

	req = nvme_allocate_request_contig(payload, sizeof(payload), expected_failure_callback, NULL);
	SPDK_CU_ASSERT_FATAL(req != NULL);

	/* Force vtophys to return a failure.  This should
	 *  result in the nvme_qpair manually failing
	 *  the request with error status to signify
	 *  a bad payload buffer.
	 */
	ut_fail_vtophys = true;

	CU_ASSERT(qpair.sq_tail == 0);

	CU_ASSERT(nvme_qpair_submit_request(&qpair, req) != 0);

	CU_ASSERT(qpair.sq_tail == 0);

	cleanup_submit_request_test(&qpair);
}
Beispiel #5
0
static void
test4(void)
{
	struct nvme_qpair		qpair = {};
	struct nvme_request		*req;
	struct spdk_nvme_ctrlr		ctrlr = {};
	struct spdk_nvme_registers	regs = {};
	char				payload[4096];

	prepare_submit_request_test(&qpair, &ctrlr, &regs);

	req = nvme_allocate_request_contig(payload, sizeof(payload), expected_failure_callback, NULL);
	SPDK_CU_ASSERT_FATAL(req != NULL);

	/* Force vtophys to return a failure.  This should
	 *  result in the nvme_qpair manually failing
	 *  the request with error status to signify
	 *  a bad payload buffer.
	 */
	fail_vtophys = true;
	outbuf[0] = '\0';

	CU_ASSERT(qpair.sq_tail == 0);

	nvme_qpair_submit_request(&qpair, req);

	CU_ASSERT(qpair.sq_tail == 0);
	/* Assert that command/completion data was printed to log. */
	CU_ASSERT(strlen(outbuf) > 0);

	cleanup_submit_request_test(&qpair);
}
Beispiel #6
0
static void
test_1bit(void)
{
	struct spdk_bit_array *ba;

	ba = spdk_bit_array_create(1);
	SPDK_CU_ASSERT_FATAL(ba != NULL);
	CU_ASSERT(spdk_bit_array_capacity(ba) == 1);

	CU_ASSERT(spdk_bit_array_get(ba, 0) == false);
	CU_ASSERT(spdk_bit_array_find_first_set(ba, 0) == UINT32_MAX);

	/* Set bit 0 */
	CU_ASSERT(spdk_bit_array_set(ba, 0) == 0);
	CU_ASSERT(spdk_bit_array_get(ba, 0) == true);
	CU_ASSERT(spdk_bit_array_find_first_set(ba, 0) == 0);

	/* Clear bit 0 */
	spdk_bit_array_clear(ba, 0);
	CU_ASSERT(spdk_bit_array_get(ba, 0) == false);
	CU_ASSERT(spdk_bit_array_find_first_set(ba, 0) == UINT32_MAX);

	spdk_bit_array_free(&ba);
	CU_ASSERT(ba == NULL);
}
Beispiel #7
0
static void
nvmf_test_create_session(void)
{
	int fake_session_count = 5;
	int i;
	struct nvmf_session *session;
	struct spdk_nvmf_subsystem *subsystem;

	/* create session in non-exist subsystem */
	CU_ASSERT_PTR_NULL(nvmf_create_session("subsystem2"));
	/* create session and check init values */
	subsystem = nvmf_find_subsystem("subsystem1");
	session = nvmf_create_session("subsystem1");
	SPDK_CU_ASSERT_FATAL(session != NULL);
	CU_ASSERT_EQUAL(session->cntlid, SS_SC_CNTLID);
	CU_ASSERT_TRUE(session->is_valid);
	CU_ASSERT_EQUAL(session->num_connections, 0);
	CU_ASSERT_EQUAL(session->active_queues, 0);
	CU_ASSERT_EQUAL(subsystem->num_sessions, 1);
	/* add multi-sessions to one subsystem
	 * if multi-sessions is not suported in the future
	 * we need to change the check condition. */
	for (i = 0; i != fake_session_count; i++) {
		nvmf_create_session("subsystem1");
	}
	CU_ASSERT_EQUAL(session->subsys->num_sessions, fake_session_count + 1);

}
Beispiel #8
0
static void
test_ctrlr_failed(void)
{
	struct nvme_qpair		qpair = {};
	struct nvme_request		*req;
	struct spdk_nvme_ctrlr		ctrlr = {};
	struct spdk_nvme_registers	regs = {};
	char				payload[4096];

	prepare_submit_request_test(&qpair, &ctrlr, &regs);

	req = nvme_allocate_request_contig(payload, sizeof(payload), expected_failure_callback, NULL);
	SPDK_CU_ASSERT_FATAL(req != NULL);

	/* Disable the queue and set the controller to failed.
	 * Set the controller to resetting so that the qpair won't get re-enabled.
	 */
	qpair.is_enabled = false;
	ctrlr.is_failed = true;
	ctrlr.is_resetting = true;

	outbuf[0] = '\0';

	CU_ASSERT(qpair.sq_tail == 0);

	nvme_qpair_submit_request(&qpair, req);

	CU_ASSERT(qpair.sq_tail == 0);
	/* Assert that command/completion data was printed to log. */
	CU_ASSERT(strlen(outbuf) > 0);

	cleanup_submit_request_test(&qpair);
}
Beispiel #9
0
static void
test_find(void)
{
	struct spdk_bit_array *ba;
	uint32_t i;

	ba = spdk_bit_array_create(256);
	SPDK_CU_ASSERT_FATAL(ba != NULL);
	CU_ASSERT(spdk_bit_array_capacity(ba) == 256);

	/* Set all bits */
	for (i = 0; i < 256; i++) {
		CU_ASSERT(spdk_bit_array_set(ba, i) == 0);
	}

	/* Verify that find_first_set and find_first_clear work for each starting position */
	for (i = 0; i < 256; i++) {
		CU_ASSERT(spdk_bit_array_find_first_set(ba, i) == i);
		CU_ASSERT(spdk_bit_array_find_first_clear(ba, i) == 256);
	}
	CU_ASSERT(spdk_bit_array_find_first_set(ba, 256) == UINT32_MAX);
	CU_ASSERT(spdk_bit_array_find_first_clear(ba, 256) == 256);

	/* Clear bits 0 through 31 */
	for (i = 0; i < 32; i++) {
		spdk_bit_array_clear(ba, i);
	}

	for (i = 0; i < 32; i++) {
		CU_ASSERT(spdk_bit_array_find_first_set(ba, i) == 32);
		CU_ASSERT(spdk_bit_array_find_first_clear(ba, i) == i);
	}

	for (i = 32; i < 256; i++) {
		CU_ASSERT(spdk_bit_array_find_first_set(ba, i) == i);
		CU_ASSERT(spdk_bit_array_find_first_clear(ba, i) == 256);
	}

	/* Clear bit 255 */
	spdk_bit_array_clear(ba, 255);

	for (i = 0; i < 32; i++) {
		CU_ASSERT(spdk_bit_array_find_first_set(ba, i) == 32);
		CU_ASSERT(spdk_bit_array_find_first_clear(ba, i) == i);
	}

	for (i = 32; i < 255; i++)  {
		CU_ASSERT(spdk_bit_array_find_first_set(ba, i) == i);
		CU_ASSERT(spdk_bit_array_find_first_clear(ba, i) == 255);
	}

	CU_ASSERT(spdk_bit_array_find_first_clear(ba, 256) == 256);

	spdk_bit_array_free(&ba);
}
Beispiel #10
0
static void
nvmf_test_delete_subsystem(void)
{
	struct spdk_nvmf_subsystem *subsystem;
	struct nvmf_session *sess;

	sess = nvmf_create_session("subsystem1");
	SPDK_CU_ASSERT_FATAL(sess != NULL);
	subsystem = nvmf_find_subsystem("subsystem1");
	CU_ASSERT_EQUAL(nvmf_delete_subsystem(subsystem), 0);
}
Beispiel #11
0
static void
nvmf_test_process_io_cmd(void)
{
	struct spdk_nvme_cmd nvmf_cmd = {};
	struct nvmf_session *sess;
	struct nvmf_request nvmf_req = {};
	struct nvme_read_cdw12 *cdw12;
	struct spdk_nvmf_subsystem *tmp;
	int buf_len = 64;
	uint8_t *buf;
	nvmf_cmd.opc = SPDK_NVME_OPC_READ;
	nvmf_cmd.nsid = 2;
	nvmf_cmd.cid = 3;
	nvmf_req.rsp = malloc(sizeof(union nvmf_c2h_msg));
	nvmf_req.cb_fn = io_nvmf_cmd_complete;
	nvmf_req.cid = nvmf_cmd.cid;
	cdw12 = (struct nvme_read_cdw12 *)&nvmf_cmd.cdw12;
	cdw12->nlb = 16; //read 16 lb, check in nvme read
	buf = malloc(buf_len);
	SPDK_CU_ASSERT_FATAL(buf != NULL);
	sess = nvmf_find_session_by_id("subsystem1", SS_SC_CNTLID);
	sess->vcprop.csts.bits.rdy = 1;
	CU_ASSERT_EQUAL(nvmf_process_io_cmd(sess, &nvmf_cmd, buf, buf_len, &nvmf_req), 0);
	CU_ASSERT_STRING_EQUAL(buf, "hello");
	nvmf_cmd.cid = 4;
	nvmf_cmd.opc = SPDK_NVME_OPC_WRITE;
	CU_ASSERT_EQUAL(nvmf_process_io_cmd(sess, &nvmf_cmd, buf, buf_len, &nvmf_req), 0);
	nvmf_cmd.opc = 0xff;
	nvmf_cmd.cid = 5;
	CU_ASSERT_EQUAL(nvmf_process_io_cmd(sess, &nvmf_cmd, buf, buf_len, &nvmf_req), 0);
	sess->vcprop.csts.bits.rdy = 0;
	nvmf_cmd.cid = 6;
	CU_ASSERT_EQUAL(nvmf_process_io_cmd(sess, &nvmf_cmd, buf, buf_len, &nvmf_req), -1);
	CU_ASSERT_EQUAL(nvmf_req.rsp->nvme_cpl.status.sc, SPDK_NVME_SC_NAMESPACE_NOT_READY);
	sess->vcprop.csts.bits.rdy = 1;
	/* nsid = 0 */
	nvmf_cmd.nsid = 0;
	nvmf_cmd.cid = 7;
	CU_ASSERT_EQUAL(nvmf_process_io_cmd(sess, &nvmf_cmd, buf, buf_len, &nvmf_req), -1);
	CU_ASSERT_NOT_EQUAL(nvmf_req.rsp->nvme_cpl.status.sc, SPDK_NVME_SC_SUCCESS);
	/* set sess->subsys to NULL */
	tmp = sess->subsys;
	sess->subsys = NULL;
	nvmf_cmd.nsid = 1;
	nvmf_cmd.cid = 8;
	CU_ASSERT_EQUAL(nvmf_process_io_cmd(sess, &nvmf_cmd, buf, buf_len, &nvmf_req), -1);
	CU_ASSERT_NOT_EQUAL(nvmf_req.rsp->nvme_cpl.status.sc, SPDK_NVME_SC_SUCCESS);
	sess->subsys = tmp;
	free(buf);
	free(nvmf_req.rsp);
}
Beispiel #12
0
static void
test3(void)
{
	struct spdk_nvme_qpair		qpair = {};
	struct nvme_request		*req;
	struct nvme_tracker		*tr;
	struct spdk_nvme_ctrlr		ctrlr = {};
	struct spdk_nvme_registers	regs = {};
	uint16_t			cid;

	prepare_submit_request_test(&qpair, &ctrlr, &regs);

	req = nvme_allocate_request_null(expected_success_callback, NULL);
	SPDK_CU_ASSERT_FATAL(req != NULL);

	CU_ASSERT(qpair.sq_tail == 0);

	nvme_qpair_submit_request(&qpair, req);

	CU_ASSERT(qpair.sq_tail == 1);

	/*
	 * Since sq_tail was 0 when the command was submitted, it is in cmd[0].
	 * Extract its command ID to retrieve its tracker.
	 */
	cid = qpair.cmd[0].cid;
	tr = qpair.act_tr[cid];
	SPDK_CU_ASSERT_FATAL(tr != NULL);

	/*
	 * Complete the tracker so that it is returned to the free list.
	 * This also frees the request.
	 */
	nvme_qpair_manual_complete_tracker(&qpair, tr, SPDK_NVME_SCT_GENERIC, SPDK_NVME_SC_SUCCESS, 0,
					   false);

	cleanup_submit_request_test(&qpair);
}
Beispiel #13
0
static void
nvmf_test_create_subsystem(void)
{
	char correct_name[] = "subsystem1";
	char wrong_name[512];
	struct spdk_nvmf_subsystem *subsystem;
	struct spdk_nvmf_ctrlr *nvmf_ctrlr;
	subsystem = nvmf_create_subsystem(1, correct_name);
	SPDK_CU_ASSERT_FATAL(subsystem != NULL);
	CU_ASSERT_EQUAL(subsystem->num, 1);
	CU_ASSERT_STRING_EQUAL(subsystem->subnqn, correct_name);
	nvmf_ctrlr = spdk_nvmf_ctrlr_claim("Nvme0");
	SPDK_CU_ASSERT_FATAL(nvmf_ctrlr != NULL);
	nvmf_subsystem_add_ns(subsystem, nvmf_ctrlr->ctrlr);

	/* test long name */
	memset(wrong_name, 'a', 512);
	subsystem = nvmf_create_subsystem(2, wrong_name);
	SPDK_CU_ASSERT_FATAL(subsystem != NULL);
	CU_ASSERT_EQUAL(subsystem->num, 2);
	CU_ASSERT_STRING_NOT_EQUAL(subsystem->subnqn, wrong_name);
	CU_ASSERT_EQUAL(strlen(subsystem->subnqn) + 1, MAX_NQN_SIZE);
}
Beispiel #14
0
static void
test3(void)
{
	struct spdk_nvme_qpair		qpair = {};
	struct nvme_request		*req;
	struct spdk_nvme_ctrlr		ctrlr = {};

	prepare_submit_request_test(&qpair, &ctrlr);

	req = nvme_allocate_request_null(expected_success_callback, NULL);
	SPDK_CU_ASSERT_FATAL(req != NULL);

	CU_ASSERT(nvme_qpair_submit_request(&qpair, req) == 0);

	nvme_free_request(req);

	cleanup_submit_request_test(&qpair);
}
Beispiel #15
0
static void
nvmf_test_delete_session(void)
{
	int i;
	int fake_session_count = 5;
	struct nvmf_session *session;
	struct spdk_nvmf_subsystem *subsystem;

	subsystem = nvmf_find_subsystem("subsystem1");
	for (i = 0; i != fake_session_count + 1; i++) {
		session = nvmf_find_session_by_id("subsystem1",
						  (subsystem->num << NVMF_CNTLID_SUBS_SHIFT) + (i + 1));
		SPDK_CU_ASSERT_FATAL(session != NULL);
		nvmf_delete_session(session);
	}
	CU_ASSERT_EQUAL(subsystem->num_sessions, 0);
	CU_ASSERT_PTR_NULL(subsystem->sessions.tqh_first);
}
Beispiel #16
0
static void
scsi_init_sp_null(void)
{
	struct spdk_conf *config;
	int rc;

	config = spdk_conf_allocate();
	SPDK_CU_ASSERT_FATAL(config != NULL);

	spdk_conf_set_as_default(config);

	rc = spdk_scsi_subsystem_init();

	/* sp = null; set default scsi params */
	CU_ASSERT_EQUAL(rc, 0);

	spdk_conf_set_as_default(NULL);
	spdk_conf_free(config);
}
Beispiel #17
0
static void
test_64bit(void)
{
	struct spdk_bit_array *ba;

	ba = spdk_bit_array_create(64);
	SPDK_CU_ASSERT_FATAL(ba != NULL);
	CU_ASSERT(spdk_bit_array_capacity(ba) == 64);
	CU_ASSERT(spdk_bit_array_get(ba, 0) == false);
	CU_ASSERT(spdk_bit_array_get(ba, 63) == false);
	CU_ASSERT(spdk_bit_array_get(ba, 64) == false);
	CU_ASSERT(spdk_bit_array_get(ba, 1000) == false);
	CU_ASSERT(spdk_bit_array_find_first_set(ba, 0) == UINT32_MAX);

	/* Set bit 1 */
	CU_ASSERT(spdk_bit_array_set(ba, 1) == 0);
	CU_ASSERT(spdk_bit_array_get(ba, 0) == false);
	CU_ASSERT(spdk_bit_array_get(ba, 1) == true);
	CU_ASSERT(spdk_bit_array_find_first_set(ba, 0) == 1);

	/* Set bit 63 (1 still set) */
	CU_ASSERT(spdk_bit_array_set(ba, 63) == 0);
	CU_ASSERT(spdk_bit_array_get(ba, 0) == false);
	CU_ASSERT(spdk_bit_array_get(ba, 1) == true);
	CU_ASSERT(spdk_bit_array_get(ba, 63) == true);
	CU_ASSERT(spdk_bit_array_find_first_set(ba, 0) == 1);

	/* Clear bit 1 (63 still set) */
	spdk_bit_array_clear(ba, 1);
	CU_ASSERT(spdk_bit_array_get(ba, 1) == false);
	CU_ASSERT(spdk_bit_array_find_first_set(ba, 0) == 63);

	/* Clear bit 63 (no bits set) */
	spdk_bit_array_clear(ba, 63);
	CU_ASSERT(spdk_bit_array_get(ba, 63) == false);
	CU_ASSERT(spdk_bit_array_find_first_set(ba, 0) == UINT32_MAX);

	spdk_bit_array_free(&ba);
}
Beispiel #18
0
	/*
	 * Only memset up to (but not including) the children
	 *  TAILQ_ENTRY.  children, and following members, are
	 *  only used as part of I/O splitting so we avoid
	 *  memsetting them until it is actually needed.
	 *  They will be initialized in nvme_request_add_child()
	 *  if the request is split.
	 */
	memset(req, 0, offsetof(struct nvme_request, children));
	req->cb_fn = cb_fn;
	req->cb_arg = cb_arg;
	req->payload = *payload;
	req->payload_size = payload_size;
	req->pid = getpid();

	return req;
}

struct nvme_request *
nvme_allocate_request_contig(void *buffer, uint32_t payload_size, spdk_nvme_cmd_cb cb_fn,
			     void *cb_arg)
{
	struct nvme_payload payload;

	payload.type = NVME_PAYLOAD_TYPE_CONTIG;
	payload.u.contig = buffer;

	return nvme_allocate_request(&payload, payload_size, cb_fn, cb_arg);
}

struct nvme_request *
nvme_allocate_request_null(spdk_nvme_cmd_cb cb_fn, void *cb_arg)
{
	return nvme_allocate_request_contig(NULL, 0, cb_fn, cb_arg);
}

void
nvme_free_request(struct nvme_request *req)
{
	spdk_mempool_put(_g_nvme_driver.request_mempool, req);
}

void
nvme_request_remove_child(struct nvme_request *parent,
			  struct nvme_request *child)
{
	parent->num_children--;
	TAILQ_REMOVE(&parent->children, child, child_tailq);
}

int
nvme_transport_qpair_enable(struct spdk_nvme_qpair *qpair)
{
	return 0;
}

int
nvme_transport_qpair_disable(struct spdk_nvme_qpair *qpair)
{
	return 0;
}

int
nvme_transport_qpair_fail(struct spdk_nvme_qpair *qpair)
{
	return 0;
}

int
nvme_transport_qpair_submit_request(struct spdk_nvme_qpair *qpair, struct nvme_request *req)
{
	// TODO
	return 0;
}

int32_t
nvme_transport_qpair_process_completions(struct spdk_nvme_qpair *qpair, uint32_t max_completions)
{
	// TODO
	return 0;
}

static void
prepare_submit_request_test(struct spdk_nvme_qpair *qpair,
			    struct spdk_nvme_ctrlr *ctrlr)
{
	memset(ctrlr, 0, sizeof(*ctrlr));
	ctrlr->free_io_qids = NULL;
	TAILQ_INIT(&ctrlr->active_io_qpairs);
	TAILQ_INIT(&ctrlr->active_procs);
	nvme_qpair_construct(qpair, 1, 128, ctrlr, 0);

	ut_fail_vtophys = false;
}

static void
cleanup_submit_request_test(struct spdk_nvme_qpair *qpair)
{
}

#if 0 /* TODO: move to PCIe-specific unit test */
static void
ut_insert_cq_entry(struct spdk_nvme_qpair *qpair, uint32_t slot)
{
	struct nvme_request	*req;
	struct nvme_tracker 	*tr;
	struct spdk_nvme_cpl	*cpl;

	req = spdk_mempool_get(_g_nvme_driver.request_mempool);
	SPDK_CU_ASSERT_FATAL(req != NULL);
	memset(req, 0, sizeof(*req));

	tr = TAILQ_FIRST(&qpair->free_tr);
	TAILQ_REMOVE(&qpair->free_tr, tr, tq_list); /* remove tr from free_tr */
	TAILQ_INSERT_HEAD(&qpair->outstanding_tr, tr, tq_list);
	req->cmd.cid = tr->cid;
	tr->req = req;
	qpair->tr[tr->cid].active = true;

	cpl = &qpair->cpl[slot];
	cpl->status.p = qpair->phase;
	cpl->cid = tr->cid;
}
Beispiel #19
0
static void
ut_insert_cq_entry(struct nvme_qpair *qpair, uint32_t slot)
{
	struct nvme_request	*req;
	struct nvme_tracker 	*tr;
	struct spdk_nvme_cpl	*cpl;

	nvme_alloc_request(&req);
	SPDK_CU_ASSERT_FATAL(req != NULL);
	memset(req, 0, sizeof(*req));
	req->cmd.cid = slot;

	tr = LIST_FIRST(&qpair->free_tr);
	LIST_REMOVE(tr, list); /* remove tr from free_tr */
	LIST_INSERT_HEAD(&qpair->outstanding_tr, tr, list);
	tr->cid = slot;
	tr->req = req;
	qpair->act_tr[tr->cid] = tr;

	cpl = &qpair->cpl[slot];
	cpl->status.p = qpair->phase;
	cpl->cid = slot;
}
Beispiel #20
0
static void
test_ctrlr_failed(void)
{
	struct spdk_nvme_qpair		qpair = {};
	struct nvme_request		*req;
	struct spdk_nvme_ctrlr		ctrlr = {};
	char				payload[4096];

	prepare_submit_request_test(&qpair, &ctrlr);

	req = nvme_allocate_request_contig(payload, sizeof(payload), expected_failure_callback, NULL);
	SPDK_CU_ASSERT_FATAL(req != NULL);

	/* Set the controller to failed.
	 * Set the controller to resetting so that the qpair won't get re-enabled.
	 */
	ctrlr.is_failed = true;
	ctrlr.is_resetting = true;

	CU_ASSERT(nvme_qpair_submit_request(&qpair, req) != 0);

	cleanup_submit_request_test(&qpair);
}
Beispiel #21
0
static void
parse_valid_test(void)
{
	struct iscsi_param *params;
	int rc;

	params = NULL;
	char *data;
	int len;
	char *partial_parameter = NULL;

	/* simple test with a single key=value */
	PARSE("Abc=def\0", false, NULL);
	CU_ASSERT(rc == 0);
	EXPECT_VAL("Abc", "def");

	/* multiple key=value pairs */
	PARSE("Aaa=bbbbbb\0Xyz=test\0", false, NULL);
	CU_ASSERT(rc == 0);
	EXPECT_VAL("Aaa", "bbbbbb");
	EXPECT_VAL("Xyz", "test");

	/* value with embedded '=' */
	PARSE("A=b=c\0", false, NULL);
	CU_ASSERT(rc == 0);
	EXPECT_VAL("A", "b=c");

	/* CHAP_C=AAAA.... with value length 8192 */
	len = strlen("CHAP_C=") + ISCSI_TEXT_MAX_VAL_LEN + 1/* null terminators */;
	data = malloc(len);
	SPDK_CU_ASSERT_FATAL(data != NULL);
	memset(data, 'A', len);
	strcpy(data, "CHAP_C");
	data[6] = '=';
	data[len - 1] = '\0';
	rc = spdk_iscsi_parse_params(&params, data, len, false, NULL);
	CU_ASSERT(rc == 0);
	free(data);

	/* partial parameter: value is partial*/
	PARSE("C=AAA\0D=B", true, &partial_parameter);
	SPDK_CU_ASSERT_FATAL(partial_parameter != NULL);
	CU_ASSERT_STRING_EQUAL(partial_parameter, "D=B");
	CU_ASSERT(rc == 0);
	EXPECT_VAL("C", "AAA");
	EXPECT_NULL("D");
	PARSE("XXXX\0E=UUUU\0", false, &partial_parameter);
	CU_ASSERT(rc == 0);
	EXPECT_VAL("D", "BXXXX");
	EXPECT_VAL("E", "UUUU");
	CU_ASSERT_PTR_NULL(partial_parameter);

	/* partial parameter: key is partial*/
	PARSE("IAMAFAK", true, &partial_parameter);
	CU_ASSERT_STRING_EQUAL(partial_parameter, "IAMAFAK");
	CU_ASSERT(rc == 0);
	EXPECT_NULL("IAMAFAK");
	PARSE("EDKEY=TTTT\0F=IIII", false, &partial_parameter);
	CU_ASSERT(rc == 0);
	EXPECT_VAL("IAMAFAKEDKEY", "TTTT");
	EXPECT_VAL("F", "IIII");
	CU_ASSERT_PTR_NULL(partial_parameter);

	/* Second partial parameter is the only parameter */
	PARSE("OOOO", true, &partial_parameter);
	CU_ASSERT_STRING_EQUAL(partial_parameter, "OOOO");
	CU_ASSERT(rc == 0);
	EXPECT_NULL("OOOO");
	PARSE("LL=MMMM", false, &partial_parameter);
	CU_ASSERT(rc == 0);
	EXPECT_VAL("OOOOLL", "MMMM");
	CU_ASSERT_PTR_NULL(partial_parameter);

	spdk_iscsi_param_free(params);
}
Beispiel #22
0
static void
test_hw_sgl_req(void)
{
	struct spdk_nvme_qpair	qpair = {};
	struct nvme_request	*req;
	struct spdk_nvme_ctrlr	ctrlr = {};
	struct nvme_payload	payload = {};
	struct nvme_tracker 	*sgl_tr = NULL;
	uint64_t 		i;
	struct io_request	io_req = {};

	payload.type = NVME_PAYLOAD_TYPE_SGL;
	payload.u.sgl.reset_sgl_fn = nvme_request_reset_sgl;
	payload.u.sgl.next_sge_fn = nvme_request_next_sge;
	payload.u.sgl.cb_arg = &io_req;

	prepare_submit_request_test(&qpair, &ctrlr);
	req = nvme_allocate_request(&payload, PAGE_SIZE, NULL, &io_req);
	SPDK_CU_ASSERT_FATAL(req != NULL);
	req->cmd.opc = SPDK_NVME_OPC_WRITE;
	req->cmd.cdw10 = 10000;
	req->cmd.cdw12 = 7 | 0;
	req->payload_offset = 0;
	ctrlr.flags |= SPDK_NVME_CTRLR_SGL_SUPPORTED;

	nvme_qpair_submit_request(&qpair, req);

	sgl_tr = TAILQ_FIRST(&qpair.outstanding_tr);
	CU_ASSERT(sgl_tr != NULL);
	CU_ASSERT(sgl_tr->u.sgl[0].generic.type == SPDK_NVME_SGL_TYPE_DATA_BLOCK);
	CU_ASSERT(sgl_tr->u.sgl[0].generic.subtype == 0);
	CU_ASSERT(sgl_tr->u.sgl[0].unkeyed.length == 4096);
	CU_ASSERT(sgl_tr->u.sgl[0].address == 0);
	CU_ASSERT(req->cmd.dptr.sgl1.generic.type == SPDK_NVME_SGL_TYPE_DATA_BLOCK);
	TAILQ_REMOVE(&qpair.outstanding_tr, sgl_tr, tq_list);
	cleanup_submit_request_test(&qpair);
	nvme_free_request(req);

	prepare_submit_request_test(&qpair, &ctrlr);
	req = nvme_allocate_request(&payload, NVME_MAX_SGL_DESCRIPTORS * PAGE_SIZE, NULL, &io_req);
	SPDK_CU_ASSERT_FATAL(req != NULL);
	req->cmd.opc = SPDK_NVME_OPC_WRITE;
	req->cmd.cdw10 = 10000;
	req->cmd.cdw12 = 2023 | 0;
	req->payload_offset = 0;
	ctrlr.flags |= SPDK_NVME_CTRLR_SGL_SUPPORTED;

	nvme_qpair_submit_request(&qpair, req);

	sgl_tr = TAILQ_FIRST(&qpair.outstanding_tr);
	CU_ASSERT(sgl_tr != NULL);
	for (i = 0; i < NVME_MAX_SGL_DESCRIPTORS; i++) {
		CU_ASSERT(sgl_tr->u.sgl[i].generic.type == SPDK_NVME_SGL_TYPE_DATA_BLOCK);
		CU_ASSERT(sgl_tr->u.sgl[i].generic.subtype == 0);
		CU_ASSERT(sgl_tr->u.sgl[i].unkeyed.length == 4096);
		CU_ASSERT(sgl_tr->u.sgl[i].address == i * 4096);
	}
	CU_ASSERT(req->cmd.dptr.sgl1.generic.type == SPDK_NVME_SGL_TYPE_LAST_SEGMENT);
	TAILQ_REMOVE(&qpair.outstanding_tr, sgl_tr, tq_list);
	cleanup_submit_request_test(&qpair);
	nvme_free_request(req);
}
Beispiel #23
0
static void
test_sgl_req(void)
{
	struct spdk_nvme_qpair	qpair = {};
	struct nvme_request	*req;
	struct spdk_nvme_ctrlr	ctrlr = {};
	struct nvme_payload	payload = {};
	struct nvme_tracker 	*sgl_tr = NULL;
	uint64_t 		i;
	struct io_request	io_req = {};

	payload.type = NVME_PAYLOAD_TYPE_SGL;
	payload.u.sgl.reset_sgl_fn = nvme_request_reset_sgl;
	payload.u.sgl.next_sge_fn = nvme_request_next_sge;
	payload.u.sgl.cb_arg = &io_req;

	prepare_submit_request_test(&qpair, &ctrlr);
	req = nvme_allocate_request(&payload, PAGE_SIZE, NULL, &io_req);
	SPDK_CU_ASSERT_FATAL(req != NULL);
	req->cmd.opc = SPDK_NVME_OPC_WRITE;
	req->cmd.cdw10 = 10000;
	req->cmd.cdw12 = 7 | 0;
	req->payload_offset = 1;

	CU_ASSERT(nvme_qpair_submit_request(&qpair, req) != 0);
	CU_ASSERT(qpair.sq_tail == 0);
	cleanup_submit_request_test(&qpair);

	prepare_submit_request_test(&qpair, &ctrlr);
	req = nvme_allocate_request(&payload, PAGE_SIZE, NULL, &io_req);
	SPDK_CU_ASSERT_FATAL(req != NULL);
	req->cmd.opc = SPDK_NVME_OPC_WRITE;
	req->cmd.cdw10 = 10000;
	req->cmd.cdw12 = 7 | 0;
	spdk_nvme_retry_count = 1;
	fail_next_sge = true;

	CU_ASSERT(nvme_qpair_submit_request(&qpair, req) != 0);
	CU_ASSERT(qpair.sq_tail == 0);
	cleanup_submit_request_test(&qpair);

	fail_next_sge = false;

	prepare_submit_request_test(&qpair, &ctrlr);
	req = nvme_allocate_request(&payload, 2 * PAGE_SIZE, NULL, &io_req);
	SPDK_CU_ASSERT_FATAL(req != NULL);
	req->cmd.opc = SPDK_NVME_OPC_WRITE;
	req->cmd.cdw10 = 10000;
	req->cmd.cdw12 = 15 | 0;
	req->payload_offset = 2;

	CU_ASSERT(nvme_qpair_submit_request(&qpair, req) != 0);
	CU_ASSERT(qpair.sq_tail == 0);
	cleanup_submit_request_test(&qpair);

	prepare_submit_request_test(&qpair, &ctrlr);
	req = nvme_allocate_request(&payload, (NVME_MAX_PRP_LIST_ENTRIES + 1) * PAGE_SIZE, NULL, &io_req);
	SPDK_CU_ASSERT_FATAL(req != NULL);
	req->cmd.opc = SPDK_NVME_OPC_WRITE;
	req->cmd.cdw10 = 10000;
	req->cmd.cdw12 = 4095 | 0;

	CU_ASSERT(nvme_qpair_submit_request(&qpair, req) == 0);

	CU_ASSERT(req->cmd.dptr.prp.prp1 == 0);
	CU_ASSERT(qpair.sq_tail == 1);
	sgl_tr = TAILQ_FIRST(&qpair.outstanding_tr);
	if (sgl_tr != NULL) {
		for (i = 0; i < NVME_MAX_PRP_LIST_ENTRIES; i++) {
			CU_ASSERT(sgl_tr->u.prp[i] == (PAGE_SIZE * (i + 1)));
		}

		TAILQ_REMOVE(&qpair.outstanding_tr, sgl_tr, tq_list);
	}
	cleanup_submit_request_test(&qpair);
	nvme_free_request(req);
}
Beispiel #24
0
static void
test_resize(void)
{
	struct spdk_bit_array *ba;

	/* Start with a 0 bit array */
	ba = spdk_bit_array_create(0);
	SPDK_CU_ASSERT_FATAL(ba != NULL);
	CU_ASSERT(spdk_bit_array_capacity(ba) == 0);
	CU_ASSERT(spdk_bit_array_get(ba, 0) == false);
	CU_ASSERT(spdk_bit_array_set(ba, 0) == -EINVAL);
	spdk_bit_array_clear(ba, 0);

	/* Increase size to 1 bit */
	SPDK_CU_ASSERT_FATAL(spdk_bit_array_resize(&ba, 1) == 0);
	SPDK_CU_ASSERT_FATAL(ba != NULL);
	CU_ASSERT(spdk_bit_array_capacity(ba) == 1);
	CU_ASSERT(spdk_bit_array_get(ba, 0) == false);
	CU_ASSERT(spdk_bit_array_set(ba, 0) == 0);
	CU_ASSERT(spdk_bit_array_get(ba, 0) == true);

	/* Increase size to 2 bits */
	SPDK_CU_ASSERT_FATAL(spdk_bit_array_resize(&ba, 2) == 0);
	SPDK_CU_ASSERT_FATAL(ba != NULL);
	CU_ASSERT(spdk_bit_array_capacity(ba) == 2);
	CU_ASSERT(spdk_bit_array_get(ba, 1) == false);
	CU_ASSERT(spdk_bit_array_set(ba, 1) == 0);
	CU_ASSERT(spdk_bit_array_get(ba, 1) == true);

	/* Shrink size back to 1 bit */
	SPDK_CU_ASSERT_FATAL(spdk_bit_array_resize(&ba, 1) == 0);
	SPDK_CU_ASSERT_FATAL(ba != NULL);
	CU_ASSERT(spdk_bit_array_capacity(ba) == 1);
	CU_ASSERT(spdk_bit_array_get(ba, 0) == true);
	CU_ASSERT(spdk_bit_array_get(ba, 1) == false);

	/* Increase size to 65 bits */
	SPDK_CU_ASSERT_FATAL(spdk_bit_array_resize(&ba, 65) == 0);
	SPDK_CU_ASSERT_FATAL(ba != NULL);
	CU_ASSERT(spdk_bit_array_capacity(ba) == 65);
	CU_ASSERT(spdk_bit_array_get(ba, 0) == true);
	CU_ASSERT(spdk_bit_array_get(ba, 1) == false);
	CU_ASSERT(spdk_bit_array_set(ba, 64) == 0);
	CU_ASSERT(spdk_bit_array_get(ba, 64) == true);

	/* Shrink size back to 0 bits */
	SPDK_CU_ASSERT_FATAL(spdk_bit_array_resize(&ba, 0) == 0);
	SPDK_CU_ASSERT_FATAL(ba != NULL);
	CU_ASSERT(spdk_bit_array_capacity(ba) == 0);
	CU_ASSERT(spdk_bit_array_get(ba, 0) == false);
	CU_ASSERT(spdk_bit_array_get(ba, 1) == false);

	spdk_bit_array_free(&ba);
}
Beispiel #25
0
static void
test_sgl_req(void)
{
	struct spdk_nvme_qpair	qpair = {};
	struct nvme_request	*req;
	struct spdk_nvme_ctrlr	ctrlr = {};
	struct spdk_nvme_registers	regs = {};
	struct nvme_payload	payload = {};
	struct nvme_tracker 	*sgl_tr = NULL;
	uint64_t 		i;
	struct io_request	io_req = {};

	payload.type = NVME_PAYLOAD_TYPE_SGL;
	payload.u.sgl.reset_sgl_fn = nvme_request_reset_sgl;
	payload.u.sgl.next_sge_fn = nvme_request_next_sge;
	payload.u.sgl.cb_arg = &io_req;

	prepare_submit_request_test(&qpair, &ctrlr, &regs);
	req = nvme_allocate_request(&payload, PAGE_SIZE, NULL, &io_req);
	SPDK_CU_ASSERT_FATAL(req != NULL);
	req->cmd.opc = SPDK_NVME_OPC_WRITE;
	req->cmd.cdw10 = 10000;
	req->cmd.cdw12 = 255 | 0;
	req->payload_offset = 1;

	nvme_qpair_submit_request(&qpair, req);
	CU_ASSERT(req->cmd.psdt == SPDK_NVME_PSDT_PRP);
	CU_ASSERT(req->cmd.dptr.prp.prp1 == 7);
	CU_ASSERT(req->cmd.dptr.prp.prp2 == 4096);

	sgl_tr = LIST_FIRST(&qpair.outstanding_tr);
	LIST_REMOVE(sgl_tr, list);
	free(sgl_tr);
	cleanup_submit_request_test(&qpair);
	nvme_free_request(req);

	prepare_submit_request_test(&qpair, &ctrlr, &regs);
	req = nvme_allocate_request(&payload, PAGE_SIZE, NULL, &io_req);
	SPDK_CU_ASSERT_FATAL(req != NULL);
	req->cmd.opc = SPDK_NVME_OPC_WRITE;
	req->cmd.cdw10 = 10000;
	req->cmd.cdw12 = 255 | 0;
	spdk_nvme_retry_count = 1;
	fail_next_sge = true;

	nvme_qpair_submit_request(&qpair, req);
	CU_ASSERT(qpair.sq_tail == 0);
	cleanup_submit_request_test(&qpair);

	fail_next_sge = false;

	prepare_submit_request_test(&qpair, &ctrlr, &regs);
	req = nvme_allocate_request(&payload, 2 * PAGE_SIZE, NULL, &io_req);
	SPDK_CU_ASSERT_FATAL(req != NULL);
	req->cmd.opc = SPDK_NVME_OPC_WRITE;
	req->cmd.cdw10 = 10000;
	req->cmd.cdw12 = 255 | 0;
	req->payload_offset = 2;

	nvme_qpair_submit_request(&qpair, req);
	CU_ASSERT(qpair.sq_tail == 0);
	cleanup_submit_request_test(&qpair);

	prepare_submit_request_test(&qpair, &ctrlr, &regs);
	req = nvme_allocate_request(&payload, 33 * PAGE_SIZE, NULL, &io_req);
	SPDK_CU_ASSERT_FATAL(req != NULL);
	req->cmd.opc = SPDK_NVME_OPC_WRITE;
	req->cmd.cdw10 = 10000;
	req->cmd.cdw12 = 255 | 0;

	nvme_qpair_submit_request(&qpair, req);

	CU_ASSERT(req->cmd.dptr.prp.prp1 == 0);
	CU_ASSERT(qpair.sq_tail == 1);
	sgl_tr = LIST_FIRST(&qpair.outstanding_tr);
	if (sgl_tr != NULL) {
		for (i = 0; i < 32; i++) {
			CU_ASSERT(sgl_tr->u.prp[i] == (PAGE_SIZE * (i + 1)));
		}

		LIST_REMOVE(sgl_tr, list);
		free(sgl_tr);
	}
	cleanup_submit_request_test(&qpair);
	nvme_free_request(req);
}
Beispiel #26
0
static void
nvmf_test_connect(void)
{
	uint64_t fabric_conn = 0;
	uint64_t fabric_conn_admin = 1;
	uint64_t fabric_conn_IO = 2;
	struct nvmf_session *sess, *io_sess;
	struct spdk_nvmf_fabric_connect_cmd connect = {};
	struct spdk_nvmf_fabric_connect_data connect_data = {};
	struct spdk_nvmf_fabric_connect_rsp response = {};
	struct spdk_nvmf_fabric_connect_rsp expect_rsp = {};


	connect.opcode = 0x7f;
	connect.cid = 0x01;
	connect.fctype = 0x01;
	connect_data.cntlid = 0xffff;
	connect.qid = 0;
	connect.sqsize = 64;

	/* change cmd field to do failure test first */
	/* invalid subnqn and qid = 0*/
	strcpy((char *)connect_data.subnqn, "fake");
	CU_ASSERT_PTR_NULL(nvmf_connect((void *)fabric_conn, &connect, &connect_data, &response));
	CU_ASSERT_NOT_EQUAL(response.status.sc, 0);
	/* valid subnqn and qid = 0 and cntlid != 0xfffff */
	strcpy((char *)connect_data.subnqn, "subsystem1");
	connect_data.cntlid = 0x000f;
	CU_ASSERT_PTR_NULL(nvmf_connect((void *)fabric_conn, &connect, &connect_data, &response));
	CU_ASSERT_EQUAL(response.status.sc, SPDK_NVMF_FABRIC_SC_INVALID_PARAM);
	/* invalid subnqn and qid = 1 */
	strcpy((char *)connect_data.subnqn, "fake");
	connect.qid = 1;
	connect_data.cntlid = 0;
	CU_ASSERT_PTR_NULL(nvmf_connect((void *)fabric_conn, &connect, &connect_data, &response));
	CU_ASSERT_EQUAL(response.status.sc, SPDK_NVMF_FABRIC_SC_RESTART_DISCOVERY);
	/* valid subnqn but session is not created. */
	strcpy((char *)connect_data.subnqn, "subsystem1");
	connect_data.cntlid = 0;
	CU_ASSERT_PTR_NULL(nvmf_connect((void *)fabric_conn, &connect, &connect_data, &response));
	CU_ASSERT_EQUAL(response.status.sc, SPDK_NVMF_FABRIC_SC_RESTART_DISCOVERY);
	/* create admin connection */
	connect.qid = 0;
	connect_data.cntlid = 0xffff;
	sess = nvmf_connect((void *)fabric_conn_admin, &connect, &connect_data, &response);
	SPDK_CU_ASSERT_FATAL(sess != NULL);
	nvmf_init_session_properties(sess, 64);
	sess->max_connections_allowed = 2;
	CU_ASSERT_EQUAL(sess->num_connections, 1);
	CU_ASSERT_PTR_EQUAL(sess->connections.tqh_first->fabric_conn, fabric_conn_admin);
	expect_rsp.status_code_specific.success.cntlid = SS_SC_CNTLID;
	expect_rsp.status.sc = 0;
	help_response_check(&response, &expect_rsp);
	/* create IO connection */
	connect.cid = 0x02;
	connect.qid = 1;
	connect_data.cntlid = SS_SC_CNTLID;
	io_sess = nvmf_connect((void *)fabric_conn_IO, &connect, &connect_data, &response);
	SPDK_CU_ASSERT_FATAL(io_sess != NULL);
	CU_ASSERT_EQUAL(io_sess->num_connections, 2);
	/* check admin and io connection are in same session. */
	CU_ASSERT_PTR_EQUAL(io_sess, sess);
	expect_rsp.status_code_specific.success.cntlid = SS_SC_CNTLID;
	expect_rsp.status.sc = 0;
	help_response_check(&response, &expect_rsp);
	/* right subnqn, session is created, but wrong cntlid */
	connect_data.cntlid = 1;
	connect.qid = 2;
	CU_ASSERT_PTR_NULL(nvmf_connect((void *)&fabric_conn, &connect, &connect_data, &response));
	CU_ASSERT_EQUAL(response.status.sc, SPDK_NVMF_FABRIC_SC_RESTART_DISCOVERY);
}
Beispiel #27
0
static void
test_discovery_log(void)
{
	struct spdk_nvmf_subsystem *subsystem;
	uint8_t buffer[8192];
	struct spdk_nvmf_discovery_log_page *disc_log;
	struct spdk_nvmf_discovery_log_page_entry *entry;

	/* Reset discovery-related globals */
	g_discovery_genctr = 0;
	free(g_discovery_log_page);
	g_discovery_log_page = NULL;
	g_discovery_log_page_size = 0;

	/* Add one subsystem and verify that the discovery log contains it */
	subsystem = spdk_nvmf_create_subsystem("nqn.2016-06.io.spdk:subsystem1", SPDK_NVMF_SUBTYPE_NVME,
					       NVMF_SUBSYSTEM_MODE_DIRECT, NULL, NULL, NULL);
	SPDK_CU_ASSERT_FATAL(subsystem != NULL);

	SPDK_CU_ASSERT_FATAL(spdk_nvmf_subsystem_add_listener(subsystem, "test_transport1",
			     "1234", "5678") == 0);

	/* Get only genctr (first field in the header) */
	memset(buffer, 0xCC, sizeof(buffer));
	disc_log = (struct spdk_nvmf_discovery_log_page *)buffer;
	spdk_nvmf_get_discovery_log_page(buffer, 0, sizeof(disc_log->genctr));
	CU_ASSERT(disc_log->genctr == 2); /* one added subsystem + one added listen address */

	/* Get only the header, no entries */
	memset(buffer, 0xCC, sizeof(buffer));
	disc_log = (struct spdk_nvmf_discovery_log_page *)buffer;
	spdk_nvmf_get_discovery_log_page(buffer, 0, sizeof(*disc_log));
	CU_ASSERT(disc_log->genctr == 2);
	CU_ASSERT(disc_log->numrec == 1);

	/* Offset 0, exact size match */
	memset(buffer, 0xCC, sizeof(buffer));
	disc_log = (struct spdk_nvmf_discovery_log_page *)buffer;
	spdk_nvmf_get_discovery_log_page(buffer, 0, sizeof(*disc_log) + sizeof(disc_log->entries[0]));
	CU_ASSERT(disc_log->genctr != 0);
	CU_ASSERT(disc_log->numrec == 1);
	CU_ASSERT(disc_log->entries[0].trtype == 42);

	/* Offset 0, oversize buffer */
	memset(buffer, 0xCC, sizeof(buffer));
	disc_log = (struct spdk_nvmf_discovery_log_page *)buffer;
	spdk_nvmf_get_discovery_log_page(buffer, 0, sizeof(buffer));
	CU_ASSERT(disc_log->genctr != 0);
	CU_ASSERT(disc_log->numrec == 1);
	CU_ASSERT(disc_log->entries[0].trtype == 42);
	CU_ASSERT(all_zero(buffer + sizeof(*disc_log) + sizeof(disc_log->entries[0]),
			   sizeof(buffer) - (sizeof(*disc_log) + sizeof(disc_log->entries[0]))));

	/* Get just the first entry, no header */
	memset(buffer, 0xCC, sizeof(buffer));
	entry = (struct spdk_nvmf_discovery_log_page_entry *)buffer;
	spdk_nvmf_get_discovery_log_page(buffer,
					 offsetof(struct spdk_nvmf_discovery_log_page, entries[0]),
					 sizeof(*entry));
	CU_ASSERT(entry->trtype == 42);
}
Beispiel #28
0
static void
parse_invalid_test(void)
{
	struct iscsi_param *params;
	int rc;

	params = NULL;
	char *data;
	int len;

	/* key without '=' */
	PARSE("Abc\0", false, NULL);
	CU_ASSERT(rc != 0);
	EXPECT_NULL("Abc");

	/* multiple key=value pairs, one missing '=' */
	PARSE("Abc=def\0Xyz\0Www=test\0", false, NULL);
	CU_ASSERT(rc != 0);
	EXPECT_VAL("Abc", "def");
	EXPECT_NULL("Xyz");
	EXPECT_NULL("Www");

	/* empty key */
	PARSE("=abcdef", false, NULL);
	CU_ASSERT(rc != 0);
	EXPECT_NULL("");

	/* CHAP_C=AAAA.... with value length 8192 + 1 */
	len = strlen("CHAP_C=") + ISCSI_TEXT_MAX_VAL_LEN + 1 /* max value len + 1 */ +
	      1 /* null terminators */;
	data = malloc(len);
	SPDK_CU_ASSERT_FATAL(data != NULL);
	memset(data, 'A', len);
	strcpy(data, "CHAP_C");
	data[6] = '=';
	data[len - 1] = '\0';
	rc = spdk_iscsi_parse_params(&params, data, len, false, NULL);
	free(data);
	CU_ASSERT(rc != 0);
	EXPECT_NULL("CHAP_C");

	/* Test simple value, length of value bigger than 255*/
	len = strlen("A=") + ISCSI_TEXT_MAX_SIMPLE_VAL_LEN + 1 /* max simple value len + 1 */ +
	      1 /* null terminators */;
	data = malloc(len);
	SPDK_CU_ASSERT_FATAL(data != NULL);
	memset(data, 'A', len);
	data[1] = '=';
	data[len - 1] = '\0';
	rc = spdk_iscsi_parse_params(&params, data, len, false, NULL);
	free(data);
	CU_ASSERT(rc != 0);
	EXPECT_NULL("A");

	/* key length bigger than 63 */
	len = ISCSI_TEXT_MAX_KEY_LEN + 1 /*max key length + 1*/ + 1 /* = */ + 1 /* A */ +
	      1/* null terminators */;
	data = malloc(len);
	SPDK_CU_ASSERT_FATAL(data != NULL);
	memset(data, 'A', len);
	data[64] = '=';
	data[len - 1] = '\0';
	rc = spdk_iscsi_parse_params(&params, data, len, false, NULL);
	free(data);
	CU_ASSERT(rc != 0);
	EXPECT_NULL("A");

	/* duplicated key */
	PARSE("B=BB", false, NULL);
	CU_ASSERT(rc == 0);
	PARSE("B=BBBB", false, NULL);
	CU_ASSERT(rc != 0);
	EXPECT_VAL("B", "BB");

	spdk_iscsi_param_free(params);
}