lib/nvmf: Use qpair_get_listen_trid() to find a subsystem listener
There is a public API spdk_nvmf_qpair_get_listen_trid() and it can get trid of the specified qpair safely for any transport including pluggable transports. The API was overlooked when implementing the multipath feature for NVMe-oF target. trid pointer was added to struct spdk_nvmf_qpair and was used to find a subsystem listener. However, pluggable transports got seg. fault because trid of the qpair was not set. To avoid such segmentation fault for any transport, change nvmf_ctrlr_create() to use spdk_nvmf_qpair_get_listen_trid(). The struct spdk_nvmf_qpair is located in the public header file, and so leave the added trid for now. It will be deprecated eventually. Reported-by: Jacek Kalwas <jacek.kalwas@intel.com> Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Change-Id: I5e0bd24bd58b6ffdf1352332a179a82682f1589f Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/5323 Community-CI: Broadcom CI Community-CI: Mellanox Build Bot Reviewed-by: Changpeng Liu <changpeng.liu@intel.com> Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com> Reviewed-by: Jacek Kalwas <jacek.kalwas@intel.com> Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
parent
92e541b58b
commit
5c9a8a3c41
@ -317,6 +317,7 @@ nvmf_ctrlr_create(struct spdk_nvmf_subsystem *subsystem,
|
|||||||
{
|
{
|
||||||
struct spdk_nvmf_ctrlr *ctrlr;
|
struct spdk_nvmf_ctrlr *ctrlr;
|
||||||
struct spdk_nvmf_transport *transport;
|
struct spdk_nvmf_transport *transport;
|
||||||
|
struct spdk_nvme_transport_id listen_trid = {};
|
||||||
|
|
||||||
ctrlr = calloc(1, sizeof(*ctrlr));
|
ctrlr = calloc(1, sizeof(*ctrlr));
|
||||||
if (ctrlr == NULL) {
|
if (ctrlr == NULL) {
|
||||||
@ -425,8 +426,13 @@ nvmf_ctrlr_create(struct spdk_nvmf_subsystem *subsystem,
|
|||||||
ctrlr->dif_insert_or_strip = transport->opts.dif_insert_or_strip;
|
ctrlr->dif_insert_or_strip = transport->opts.dif_insert_or_strip;
|
||||||
|
|
||||||
if (ctrlr->subsys->subtype == SPDK_NVMF_SUBTYPE_NVME) {
|
if (ctrlr->subsys->subtype == SPDK_NVMF_SUBTYPE_NVME) {
|
||||||
ctrlr->listener = nvmf_subsystem_find_listener(ctrlr->subsys,
|
if (spdk_nvmf_qpair_get_listen_trid(req->qpair, &listen_trid) != 0) {
|
||||||
req->qpair->trid);
|
SPDK_ERRLOG("Could not get listener transport ID\n");
|
||||||
|
free(ctrlr);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctrlr->listener = nvmf_subsystem_find_listener(ctrlr->subsys, &listen_trid);
|
||||||
if (!ctrlr->listener) {
|
if (!ctrlr->listener) {
|
||||||
SPDK_ERRLOG("Listener was not found\n");
|
SPDK_ERRLOG("Listener was not found\n");
|
||||||
free(ctrlr);
|
free(ctrlr);
|
||||||
@ -527,6 +533,7 @@ _nvmf_ctrlr_add_io_qpair(void *ctx)
|
|||||||
struct spdk_nvmf_qpair *admin_qpair;
|
struct spdk_nvmf_qpair *admin_qpair;
|
||||||
struct spdk_nvmf_tgt *tgt = qpair->transport->tgt;
|
struct spdk_nvmf_tgt *tgt = qpair->transport->tgt;
|
||||||
struct spdk_nvmf_subsystem *subsystem;
|
struct spdk_nvmf_subsystem *subsystem;
|
||||||
|
struct spdk_nvme_transport_id listen_trid = {};
|
||||||
const struct spdk_nvmf_subsystem_listener *listener;
|
const struct spdk_nvmf_subsystem_listener *listener;
|
||||||
|
|
||||||
SPDK_DEBUGLOG(nvmf, "Connect I/O Queue for controller id 0x%x\n", data->cntlid);
|
SPDK_DEBUGLOG(nvmf, "Connect I/O Queue for controller id 0x%x\n", data->cntlid);
|
||||||
@ -553,7 +560,14 @@ _nvmf_ctrlr_add_io_qpair(void *ctx)
|
|||||||
|
|
||||||
/* If ANA reporting is enabled, check if I/O connect is on the same listener. */
|
/* If ANA reporting is enabled, check if I/O connect is on the same listener. */
|
||||||
if (subsystem->flags.ana_reporting) {
|
if (subsystem->flags.ana_reporting) {
|
||||||
listener = nvmf_subsystem_find_listener(subsystem, qpair->trid);
|
if (spdk_nvmf_qpair_get_listen_trid(req->qpair, &listen_trid) != 0) {
|
||||||
|
SPDK_ERRLOG("Could not get listener transport ID\n");
|
||||||
|
SPDK_NVMF_INVALID_CONNECT_CMD(rsp, qid);
|
||||||
|
spdk_nvmf_request_complete(req);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
listener = nvmf_subsystem_find_listener(subsystem, &listen_trid);
|
||||||
if (listener != ctrlr->listener) {
|
if (listener != ctrlr->listener) {
|
||||||
SPDK_ERRLOG("I/O connect is on a listener different from admin connect\n");
|
SPDK_ERRLOG("I/O connect is on a listener different from admin connect\n");
|
||||||
SPDK_NVMF_INVALID_CONNECT_CMD(rsp, qid);
|
SPDK_NVMF_INVALID_CONNECT_CMD(rsp, qid);
|
||||||
|
@ -2276,7 +2276,7 @@ nvmf_qpair_state_str(enum spdk_nvmf_qpair_state state)
|
|||||||
static void
|
static void
|
||||||
dump_nvmf_qpair(struct spdk_json_write_ctx *w, struct spdk_nvmf_qpair *qpair)
|
dump_nvmf_qpair(struct spdk_json_write_ctx *w, struct spdk_nvmf_qpair *qpair)
|
||||||
{
|
{
|
||||||
const struct spdk_nvme_transport_id *trid = qpair->trid;
|
struct spdk_nvme_transport_id listen_trid = {};
|
||||||
const char *adrfam;
|
const char *adrfam;
|
||||||
|
|
||||||
spdk_json_write_object_begin(w);
|
spdk_json_write_object_begin(w);
|
||||||
@ -2285,16 +2285,18 @@ dump_nvmf_qpair(struct spdk_json_write_ctx *w, struct spdk_nvmf_qpair *qpair)
|
|||||||
spdk_json_write_named_uint32(w, "qid", qpair->qid);
|
spdk_json_write_named_uint32(w, "qid", qpair->qid);
|
||||||
spdk_json_write_named_string(w, "state", nvmf_qpair_state_str(qpair->state));
|
spdk_json_write_named_string(w, "state", nvmf_qpair_state_str(qpair->state));
|
||||||
|
|
||||||
spdk_json_write_named_object_begin(w, "listen_address");
|
if (spdk_nvmf_qpair_get_listen_trid(qpair, &listen_trid) == 0) {
|
||||||
adrfam = spdk_nvme_transport_id_adrfam_str(trid->adrfam);
|
spdk_json_write_named_object_begin(w, "listen_address");
|
||||||
if (adrfam == NULL) {
|
adrfam = spdk_nvme_transport_id_adrfam_str(listen_trid.adrfam);
|
||||||
adrfam = "unknown";
|
if (adrfam == NULL) {
|
||||||
|
adrfam = "unknown";
|
||||||
|
}
|
||||||
|
spdk_json_write_named_string(w, "trtype", listen_trid.trstring);
|
||||||
|
spdk_json_write_named_string(w, "adrfam", adrfam);
|
||||||
|
spdk_json_write_named_string(w, "traddr", listen_trid.traddr);
|
||||||
|
spdk_json_write_named_string(w, "trsvcid", listen_trid.trsvcid);
|
||||||
|
spdk_json_write_object_end(w);
|
||||||
}
|
}
|
||||||
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);
|
|
||||||
spdk_json_write_object_end(w);
|
|
||||||
|
|
||||||
spdk_json_write_object_end(w);
|
spdk_json_write_object_end(w);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user