lib/nvme: update trid struct with trstring.

The trtype should be stored as both an enum and string. This is intended to
help pave the way for pluggable NVMe-oF transports.

Signed-off-by: Seth Howell <seth.howell@intel.com>
Change-Id: I6af658d7a17c405e191ff401b80ab704c65497e7
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/478744
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Alexey Marchuk <alexeymar@mellanox.com>
This commit is contained in:
Seth Howell 2019-12-23 12:58:27 -07:00 committed by Tomasz Zawadzki
parent 6c2747491d
commit 7ed0904b9b
18 changed files with 243 additions and 25 deletions

View File

@ -48,6 +48,11 @@ extern "C" {
#include "spdk/nvme_spec.h"
#include "spdk/nvmf_spec.h"
#define SPDK_NVME_TRANSPORT_NAME_FC "FC"
#define SPDK_NVME_TRANSPORT_NAME_PCIE "PCIE"
#define SPDK_NVME_TRANSPORT_NAME_RDMA "RDMA"
#define SPDK_NVME_TRANSPORT_NAME_TCP "TCP"
/**
* Opaque handle to a controller. Returned by spdk_nvme_probe()'s attach_cb.
*/
@ -293,6 +298,11 @@ typedef enum spdk_nvme_transport_type spdk_nvme_transport_type_t;
* spdk_nvme_transport_id_parse().
*/
struct spdk_nvme_transport_id {
/**
* NVMe transport string.
*/
char trstring[SPDK_NVMF_TRSTRING_MAX_LEN + 1];
/**
* NVMe transport type.
*/
@ -394,6 +404,17 @@ enum spdk_nvme_ctrlr_flags {
*/
int spdk_nvme_transport_id_parse(struct spdk_nvme_transport_id *trid, const char *str);
/**
* Fill in the trtype and trstring fields of this trid based on a known transport type.
*
* \param trid The trid to fill out.
* \param trtype The transport type to use for filling the trid fields. Only valid for
* transport types referenced in the NVMe-oF spec.
*/
void spdk_nvme_trid_populate_transport(struct spdk_nvme_transport_id *trid,
enum spdk_nvme_transport_type trtype);
/**
* Parse the string representation of a host ID.
*
@ -419,6 +440,18 @@ int spdk_nvme_transport_id_parse(struct spdk_nvme_transport_id *trid, const char
*/
int spdk_nvme_host_id_parse(struct spdk_nvme_host_id *hostid, const char *str);
/**
* Parse the string representation of a transport ID tranport type into the trid struct.
*
* \param trid The trid to write to
* \param trstring Input string representation of transport type (e.g. "PCIe", "RDMA").
*
* \return 0 if parsing was successful and trtype is filled out, or negated errno
* values if the provided string was an invalid transport string.
*/
int spdk_nvme_transport_id_populate_trstring(struct spdk_nvme_transport_id *trid,
const char *trstring);
/**
* Parse the string representation of a transport ID tranport type.
*

View File

@ -334,6 +334,7 @@ SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_fabric_prop_set_cmd) == 64, "Incorrec
#define SPDK_DOMAIN_LABEL_MAX_LEN 63 /* RFC 1034 max domain label length */
#define SPDK_NVMF_TRSTRING_MAX_LEN 32
#define SPDK_NVMF_TRADDR_MAX_LEN 256
#define SPDK_NVMF_TRSVCID_MAX_LEN 32

View File

@ -637,7 +637,7 @@ spdk_nvme_probe(const struct spdk_nvme_transport_id *trid, void *cb_ctx,
if (trid == NULL) {
memset(&trid_pcie, 0, sizeof(trid_pcie));
trid_pcie.trtype = SPDK_NVME_TRANSPORT_PCIE;
spdk_nvme_trid_populate_transport(&trid_pcie, SPDK_NVME_TRANSPORT_PCIE);
trid = &trid_pcie;
}
@ -701,6 +701,59 @@ spdk_nvme_connect(const struct spdk_nvme_transport_id *trid,
return ctrlr;
}
void
spdk_nvme_trid_populate_transport(struct spdk_nvme_transport_id *trid,
enum spdk_nvme_transport_type trtype)
{
const char *trstring;
trid->trtype = trtype;
switch (trtype) {
case SPDK_NVME_TRANSPORT_FC:
trstring = SPDK_NVME_TRANSPORT_NAME_FC;
break;
case SPDK_NVME_TRANSPORT_PCIE:
trstring = SPDK_NVME_TRANSPORT_NAME_PCIE;
break;
case SPDK_NVME_TRANSPORT_RDMA:
trstring = SPDK_NVME_TRANSPORT_NAME_RDMA;
break;
case SPDK_NVME_TRANSPORT_TCP:
trstring = SPDK_NVME_TRANSPORT_NAME_TCP;
break;
default:
SPDK_ERRLOG("don't use this for custom transports\n");
break;
}
snprintf(trid->trstring, SPDK_NVMF_TRSTRING_MAX_LEN, "%s", trstring);
}
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;
}
int
spdk_nvme_transport_id_parse_trtype(enum spdk_nvme_transport_type *trtype, const char *str)
{
@ -853,6 +906,10 @@ spdk_nvme_transport_id_parse(struct spdk_nvme_transport_id *trid, const char *st
}
if (strcasecmp(key, "trtype") == 0) {
if (spdk_nvme_transport_id_populate_trstring(trid, val) != 0) {
SPDK_ERRLOG("invalid transport '%s'\n", val);
return -EINVAL;
}
if (spdk_nvme_transport_id_parse_trtype(&trid->trtype, val) != 0) {
SPDK_ERRLOG("Unknown trtype '%s'\n", val);
return -EINVAL;

View File

@ -160,6 +160,7 @@ nvme_fabric_discover_probe(struct spdk_nvmf_discovery_log_page_entry *entry,
}
trid.trtype = entry->trtype;
spdk_nvme_transport_id_populate_trstring(&trid, spdk_nvme_transport_id_trtype_str(entry->trtype));
if (!spdk_nvme_transport_available(trid.trtype)) {
SPDK_WARNLOG("NVMe transport type %u not available; skipping probe\n",
trid.trtype);

View File

@ -286,7 +286,7 @@ _nvme_pcie_hotplug_monitor(struct spdk_nvme_probe_ctx *probe_ctx)
struct spdk_nvme_transport_id trid;
memset(&trid, 0, sizeof(trid));
trid.trtype = SPDK_NVME_TRANSPORT_PCIE;
spdk_nvme_trid_populate_transport(&trid, SPDK_NVME_TRANSPORT_PCIE);
snprintf(trid.traddr, sizeof(trid.traddr), "%s", event.traddr);
ctrlr = spdk_nvme_get_ctrlr_by_trid_unsafe(&trid);
@ -729,7 +729,7 @@ pcie_nvme_enum_cb(void *ctx, struct spdk_pci_device *pci_dev)
pci_addr = spdk_pci_device_get_addr(pci_dev);
trid.trtype = SPDK_NVME_TRANSPORT_PCIE;
spdk_nvme_trid_populate_transport(&trid, SPDK_NVME_TRANSPORT_PCIE);
spdk_pci_addr_fmt(trid.traddr, sizeof(trid.traddr), &pci_addr);
ctrlr = spdk_nvme_get_ctrlr_by_trid_unsafe(&trid);
@ -828,7 +828,7 @@ struct spdk_nvme_ctrlr *nvme_pcie_ctrlr_construct(const struct spdk_nvme_transpo
pctrlr->is_remapped = false;
pctrlr->ctrlr.is_removed = false;
pctrlr->ctrlr.trid.trtype = SPDK_NVME_TRANSPORT_PCIE;
spdk_nvme_trid_populate_transport(&pctrlr->ctrlr.trid, SPDK_NVME_TRANSPORT_PCIE);
pctrlr->devhandle = devhandle;
pctrlr->ctrlr.opts = *opts;
memcpy(&pctrlr->ctrlr.trid, trid, sizeof(pctrlr->ctrlr.trid));

View File

@ -1714,7 +1714,7 @@ struct spdk_nvme_ctrlr *nvme_rdma_ctrlr_construct(const struct spdk_nvme_transpo
return NULL;
}
rctrlr->ctrlr.trid.trtype = SPDK_NVME_TRANSPORT_RDMA;
spdk_nvme_trid_populate_transport(&rctrlr->ctrlr.trid, SPDK_NVME_TRANSPORT_RDMA);
rctrlr->ctrlr.opts = *opts;
memcpy(&rctrlr->ctrlr.trid, trid, sizeof(rctrlr->ctrlr.trid));

View File

@ -1717,9 +1717,9 @@ struct spdk_nvme_ctrlr *nvme_tcp_ctrlr_construct(const struct spdk_nvme_transpor
return NULL;
}
tctrlr->ctrlr.trid.trtype = SPDK_NVME_TRANSPORT_TCP;
tctrlr->ctrlr.opts = *opts;
tctrlr->ctrlr.trid = *trid;
spdk_nvme_trid_populate_transport(&tctrlr->ctrlr.trid, SPDK_NVME_TRANSPORT_TCP);
rc = nvme_ctrlr_construct(&tctrlr->ctrlr);
if (rc != 0) {

View File

@ -371,7 +371,6 @@ spdk_nvmf_write_subsystem_config_json(struct spdk_json_write_ctx *w,
struct spdk_nvmf_ns_opts ns_opts;
uint32_t max_namespaces;
char uuid_str[SPDK_UUID_STRING_LEN];
const char *trtype;
const char *adrfam;
if (spdk_nvmf_subsystem_get_type(subsystem) != SPDK_NVMF_SUBTYPE_NVME) {
@ -404,7 +403,6 @@ spdk_nvmf_write_subsystem_config_json(struct spdk_json_write_ctx *w,
listener = spdk_nvmf_subsystem_get_next_listener(subsystem, listener)) {
trid = spdk_nvmf_listener_get_trid(listener);
trtype = spdk_nvme_transport_id_trtype_str(trid->trtype);
adrfam = spdk_nvme_transport_id_adrfam_str(trid->adrfam);
spdk_json_write_object_begin(w);
@ -418,7 +416,7 @@ spdk_nvmf_write_subsystem_config_json(struct spdk_json_write_ctx *w,
/* "listen_address" : { */
spdk_json_write_named_object_begin(w, "listen_address");
spdk_json_write_named_string(w, "trtype", trtype);
spdk_json_write_named_string(w, "trtype", trid->trstring);
if (adrfam) {
spdk_json_write_named_string(w, "adrfam", adrfam);
}

View File

@ -848,7 +848,7 @@ spdk_nvmf_fc_req_in_xfer(struct spdk_nvmf_fc_request *fc_req)
static inline void
spdk_nvmf_fc_create_trid(struct spdk_nvme_transport_id *trid, uint64_t n_wwn, uint64_t p_wwn)
{
trid->trtype = (enum spdk_nvme_transport_type) SPDK_NVMF_TRTYPE_FC;
spdk_nvme_trid_populate_transport(trid, SPDK_NVME_TRANSPORT_FC);
trid->adrfam = SPDK_NVMF_ADRFAM_FC;
snprintf(trid->trsvcid, sizeof(trid->trsvcid), "none");
snprintf(trid->traddr, sizeof(trid->traddr), "nn-0x%lx:pn-0x%lx", n_wwn, p_wwn);

View File

@ -211,23 +211,18 @@ dump_nvmf_subsystem(struct spdk_json_write_ctx *w, struct spdk_nvmf_subsystem *s
for (listener = spdk_nvmf_subsystem_get_first_listener(subsystem); listener != NULL;
listener = spdk_nvmf_subsystem_get_next_listener(subsystem, listener)) {
const struct spdk_nvme_transport_id *trid;
const char *trtype;
const char *adrfam;
trid = spdk_nvmf_listener_get_trid(listener);
spdk_json_write_object_begin(w);
trtype = spdk_nvme_transport_id_trtype_str(trid->trtype);
if (trtype == NULL) {
trtype = "unknown";
}
adrfam = spdk_nvme_transport_id_adrfam_str(trid->adrfam);
if (adrfam == NULL) {
adrfam = "unknown";
}
/* NOTE: "transport" is kept for compatibility; new code should use "trtype" */
spdk_json_write_named_string(w, "transport", trtype);
spdk_json_write_named_string(w, "trtype", trtype);
spdk_json_write_named_string(w, "transport", trid->trstring);
spdk_json_write_named_string(w, "trtype", trid->trstring);
spdk_json_write_named_string(w, "adrfam", adrfam);
spdk_json_write_named_string(w, "traddr", trid->traddr);
spdk_json_write_named_string(w, "trsvcid", trid->trsvcid);
@ -689,6 +684,11 @@ rpc_listen_address_to_trid(const struct rpc_listen_address *address,
memset(trid, 0, sizeof(*trid));
if (spdk_nvme_transport_id_populate_trstring(trid, address->transport)) {
SPDK_ERRLOG("Invalid transport string: %s\n", address->transport);
return -EINVAL;
}
if (spdk_nvme_transport_id_parse_trtype(&trid->trtype, address->transport)) {
SPDK_ERRLOG("Invalid transport type: %s\n", address->transport);
return -EINVAL;

View File

@ -2642,7 +2642,7 @@ spdk_nvmf_rdma_listen(struct spdk_nvmf_transport *transport,
/* Selectively copy the trid. Things like NQN don't matter here - that
* mapping is enforced elsewhere.
*/
port->trid.trtype = SPDK_NVME_TRANSPORT_RDMA;
spdk_nvme_trid_populate_transport(&port->trid, SPDK_NVME_TRANSPORT_RDMA);
port->trid.adrfam = trid->adrfam;
snprintf(port->trid.traddr, sizeof(port->trid.traddr), "%s", trid->traddr);
snprintf(port->trid.trsvcid, sizeof(port->trid.trsvcid), "%s", trid->trsvcid);
@ -2762,7 +2762,7 @@ spdk_nvmf_rdma_stop_listen(struct spdk_nvmf_transport *transport,
/* Selectively copy the trid. Things like NQN don't matter here - that
* mapping is enforced elsewhere.
*/
trid.trtype = SPDK_NVME_TRANSPORT_RDMA;
spdk_nvme_trid_populate_transport(&trid, SPDK_NVME_TRANSPORT_RDMA);
trid.adrfam = _trid->adrfam;
snprintf(trid.traddr, sizeof(port->trid.traddr), "%s", _trid->traddr);
snprintf(trid.trsvcid, sizeof(port->trid.trsvcid), "%s", _trid->trsvcid);
@ -3928,7 +3928,7 @@ spdk_nvmf_rdma_trid_from_cm_id(struct rdma_cm_id *id,
struct sockaddr *saddr;
uint16_t port;
trid->trtype = SPDK_NVME_TRANSPORT_RDMA;
spdk_nvme_trid_populate_transport(trid, SPDK_NVME_TRANSPORT_RDMA);
if (peer) {
saddr = rdma_get_peer_addr(id);

View File

@ -610,7 +610,7 @@ _spdk_nvmf_tcp_canon_listen_trid(struct spdk_nvme_transport_id *canon_trid,
}
memset(canon_trid, 0, sizeof(*canon_trid));
canon_trid->trtype = SPDK_NVME_TRANSPORT_TCP;
spdk_nvme_trid_populate_transport(canon_trid, SPDK_NVME_TRANSPORT_TCP);
canon_trid->adrfam = trid->adrfam;
snprintf(canon_trid->traddr, sizeof(canon_trid->traddr), "%s", trid->traddr);
snprintf(canon_trid->trsvcid, sizeof(canon_trid->trsvcid), "%d", trsvcid_int);
@ -2651,7 +2651,7 @@ spdk_nvmf_tcp_qpair_get_trid(struct spdk_nvmf_qpair *qpair,
uint16_t port;
tqpair = SPDK_CONTAINEROF(qpair, struct spdk_nvmf_tcp_qpair, qpair);
trid->trtype = SPDK_NVME_TRANSPORT_TCP;
spdk_nvme_trid_populate_transport(trid, SPDK_NVME_TRANSPORT_TCP);
if (peer) {
snprintf(trid->traddr, sizeof(trid->traddr), "%s", tqpair->initiator_addr);

View File

@ -270,6 +270,15 @@ spdk_rpc_bdev_nvme_attach_controller(struct spdk_jsonrpc_request *request,
goto cleanup;
}
/* Parse trstring */
rc = spdk_nvme_transport_id_populate_trstring(&trid, ctx->req.trtype);
if (rc < 0) {
SPDK_ERRLOG("Failed to parse trtype: %s\n", ctx->req.trtype);
spdk_jsonrpc_send_error_response_fmt(request, -EINVAL, "Failed to parse trtype: %s",
ctx->req.trtype);
goto cleanup;
}
/* Parse trtype */
rc = spdk_nvme_transport_id_parse_trtype(&trid.trtype, ctx->req.trtype);
if (rc < 0) {

View File

@ -435,7 +435,7 @@ spdk_nvmf_parse_subsystem(struct spdk_conf_section *sp)
/* Parse Listen sections */
for (i = 0; ; i++) {
struct spdk_nvme_transport_id trid = {0};
struct spdk_nvme_transport_id trid = {{0}};
const char *transport;
const char *address;
char *address_dup;
@ -445,6 +445,11 @@ spdk_nvmf_parse_subsystem(struct spdk_conf_section *sp)
break;
}
if (spdk_nvme_transport_id_populate_trstring(&trid, transport)) {
SPDK_ERRLOG("Invalid listen address transport type '%s'\n", transport);
continue;
}
if (spdk_nvme_transport_id_parse_trtype(&trid.trtype, transport)) {
SPDK_ERRLOG("Invalid listen address transport type '%s'\n", transport);
continue;

View File

@ -1894,7 +1894,7 @@ static void
test_spdk_nvme_ctrlr_set_trid(void)
{
struct spdk_nvme_ctrlr ctrlr = {0};
struct spdk_nvme_transport_id new_trid = {0};
struct spdk_nvme_transport_id new_trid = {{0}};
ctrlr.is_failed = false;
ctrlr.trid.trtype = SPDK_NVME_TRANSPORT_RDMA;

View File

@ -40,6 +40,42 @@
#include "nvme/nvme_pcie.c"
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";
default:
return NULL;
}
}
int
spdk_nvme_transport_id_populate_trstring(struct spdk_nvme_transport_id *trid, const char *trstring)
{
int len, i;
if (trstring == NULL) {
return -EINVAL;
}
len = strnlen(trstring, SPDK_NVMF_TRSTRING_MAX_LEN);
if (len == SPDK_NVMF_TRSTRING_MAX_LEN) {
return -EINVAL;
}
/* cast official trstring to uppercase version of input. */
for (i = 0; i < len; i++) {
trid->trstring[i] = toupper(trstring[i]);
}
return 0;
}
struct spdk_log_flag SPDK_LOG_NVME = {
.name = "nvme",
.enabled = false,
@ -125,6 +161,8 @@ DEFINE_STUB_V(spdk_nvme_qpair_print_command, (struct spdk_nvme_qpair *qpair,
struct spdk_nvme_cmd *cmd));
DEFINE_STUB_V(spdk_nvme_qpair_print_completion, (struct spdk_nvme_qpair *qpair,
struct spdk_nvme_cpl *cpl));
DEFINE_STUB_V(spdk_nvme_trid_populate_transport, (struct spdk_nvme_transport_id *trid,
enum spdk_nvme_transport_type trtype));
static void
prp_list_prep(struct nvme_tracker *tr, struct nvme_request *req, uint32_t *prp_index)

View File

@ -82,6 +82,44 @@ DEFINE_STUB(spdk_nvme_transport_id_compare, int, (const struct spdk_nvme_transpo
DEFINE_STUB_V(spdk_nvmf_ctrlr_abort_aer, (struct spdk_nvmf_ctrlr *ctrlr));
DEFINE_STUB(spdk_nvmf_request_get_dif_ctx, bool, (struct spdk_nvmf_request *req,
struct spdk_dif_ctx *dif_ctx), false);
DEFINE_STUB_V(spdk_nvme_trid_populate_transport, (struct spdk_nvme_transport_id *trid,
enum spdk_nvme_transport_type trtype));
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";
default:
return NULL;
}
}
int
spdk_nvme_transport_id_populate_trstring(struct spdk_nvme_transport_id *trid, const char *trstring)
{
int len, i;
if (trstring == NULL) {
return -EINVAL;
}
len = strnlen(trstring, SPDK_NVMF_TRSTRING_MAX_LEN);
if (len == SPDK_NVMF_TRSTRING_MAX_LEN) {
return -EINVAL;
}
/* cast official trstring to uppercase version of input. */
for (i = 0; i < len; i++) {
trid->trstring[i] = toupper(trstring[i]);
}
return 0;
}
uint64_t
spdk_mem_map_translate(const struct spdk_mem_map *map, uint64_t vaddr, uint64_t *size)

View File

@ -188,6 +188,9 @@ DEFINE_STUB(spdk_sock_set_priority,
DEFINE_STUB_V(spdk_nvmf_ns_reservation_request, (void *ctx));
DEFINE_STUB_V(spdk_nvme_trid_populate_transport, (struct spdk_nvme_transport_id *trid,
enum spdk_nvme_transport_type trtype));
struct spdk_trace_histories *g_trace_histories;
struct spdk_bdev {
@ -221,13 +224,48 @@ _spdk_trace_record(uint64_t tsc, uint16_t tpoint_id, uint16_t poller_id,
{
}
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";
default:
return NULL;
}
}
int
spdk_nvme_transport_id_populate_trstring(struct spdk_nvme_transport_id *trid, const char *trstring)
{
int len, i;
if (trstring == NULL) {
return -EINVAL;
}
len = strnlen(trstring, SPDK_NVMF_TRSTRING_MAX_LEN);
if (len == SPDK_NVMF_TRSTRING_MAX_LEN) {
return -EINVAL;
}
/* cast official trstring to uppercase version of input. */
for (i = 0; i < len; i++) {
trid->trstring[i] = toupper(trstring[i]);
}
return 0;
}
int
spdk_nvmf_qpair_disconnect(struct spdk_nvmf_qpair *qpair, nvmf_qpair_disconnect_cb cb_fn, void *ctx)
{
return 0;
}
int
spdk_nvmf_request_get_buffers(struct spdk_nvmf_request *req,
struct spdk_nvmf_transport_poll_group *group,