nvmf: Add a transport notification when listeners are associated with

subsystems

This is optional and most transports will not implement it.

Change-Id: I51e0f1289b0e61a8bdb9a719e0a2aae51ecb451c
Signed-off-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/629
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
Reviewed-by: Jacek Kalwas <jacek.kalwas@intel.com>
This commit is contained in:
Ben Walker 2020-02-05 14:45:09 -07:00 committed by Tomasz Zawadzki
parent 6fc8c8c2fc
commit 40529e5d11
4 changed files with 58 additions and 5 deletions

View File

@ -217,6 +217,24 @@ struct spdk_nvmf_transport_ops {
void (*stop_listen)(struct spdk_nvmf_transport *transport,
const struct spdk_nvme_transport_id *trid);
/**
* A listener has been associated with a subsystem with the given NQN.
* This is only a notification. Most transports will not need to take any
* action here, as the enforcement of the association is done in the generic
* code.
*
* The association is not considered complete until cb_fn is called. New
* connections on the listener targeting this subsystem will be rejected
* until that time.
*
* Pass a negated errno code to `cb_fn` to block the association. 0 to allow.
*/
void (*listen_associate)(struct spdk_nvmf_transport *transport,
const struct spdk_nvmf_subsystem *subsystem,
const struct spdk_nvme_transport_id *trid,
spdk_nvmf_tgt_subsystem_listen_done_fn cb_fn,
void *cb_arg);
/**
* Check for new connections on the transport.
*/

View File

@ -81,6 +81,9 @@ struct spdk_nvmf_host {
};
struct spdk_nvmf_subsystem_listener {
struct spdk_nvmf_subsystem *subsystem;
spdk_nvmf_tgt_subsystem_listen_done_fn cb_fn;
void *cb_arg;
struct spdk_nvme_transport_id *trid;
struct spdk_nvmf_transport *transport;
TAILQ_ENTRY(spdk_nvmf_subsystem_listener) link;

View File

@ -747,6 +747,28 @@ spdk_nvmf_subsystem_find_listener(struct spdk_nvmf_subsystem *subsystem,
return NULL;
}
/**
* Function to be called once the target is listening.
*
* \param ctx Context argument passed to this function.
* \param status 0 if it completed successfully, or negative errno if it failed.
*/
static void
_nvmf_subsystem_add_listener_done(void *ctx, int status)
{
struct spdk_nvmf_subsystem_listener *listener = ctx;
if (status) {
listener->cb_fn(listener->cb_arg, status);
free(listener);
return;
}
TAILQ_INSERT_HEAD(&listener->subsystem->listeners, listener, link);
listener->subsystem->tgt->discovery_genctr++;
listener->cb_fn(listener->cb_arg, status);
}
void
spdk_nvmf_subsystem_add_listener(struct spdk_nvmf_subsystem *subsystem,
struct spdk_nvme_transport_id *trid,
@ -793,11 +815,17 @@ spdk_nvmf_subsystem_add_listener(struct spdk_nvmf_subsystem *subsystem,
listener->trid = &tr_listener->trid;
listener->transport = transport;
listener->cb_fn = cb_fn;
listener->cb_arg = cb_arg;
listener->subsystem = subsystem;
TAILQ_INSERT_HEAD(&subsystem->listeners, listener, link);
subsystem->tgt->discovery_genctr++;
cb_fn(cb_arg, 0);
if (transport->ops->listen_associate != NULL) {
transport->ops->listen_associate(transport, subsystem, trid,
_nvmf_subsystem_add_listener_done,
listener);
} else {
_nvmf_subsystem_add_listener_done(listener, 0);
}
}
int

View File

@ -101,7 +101,11 @@ spdk_nvmf_transport_listener_discover(struct spdk_nvmf_transport *transport,
entry->trtype = 42;
}
static struct spdk_nvmf_transport g_transport = {};
struct spdk_nvmf_transport_ops g_transport_ops = {};
static struct spdk_nvmf_transport g_transport = {
.ops = &g_transport_ops
};
struct spdk_nvmf_transport *
spdk_nvmf_transport_create(const char *transport_name,