nvmf: introduce the global and per subsystem listen addresses
Change-Id: I276a71a3280c41b215a9cf4ca85247bd397a85e5 Signed-off-by: GangCao <gang.cao@intel.com>
This commit is contained in:
parent
b865439deb
commit
4cdd929b66
@ -451,6 +451,7 @@ spdk_nvmf_construct_subsystem(const char *name,
|
|||||||
{
|
{
|
||||||
struct spdk_nvmf_subsystem *subsystem;
|
struct spdk_nvmf_subsystem *subsystem;
|
||||||
struct nvmf_tgt_subsystem *app_subsys;
|
struct nvmf_tgt_subsystem *app_subsys;
|
||||||
|
struct spdk_nvmf_listen_addr *listen_addr;
|
||||||
enum spdk_nvmf_subsystem_mode mode;
|
enum spdk_nvmf_subsystem_mode mode;
|
||||||
int i;
|
int i;
|
||||||
uint64_t mask;
|
uint64_t mask;
|
||||||
@ -519,8 +520,10 @@ spdk_nvmf_construct_subsystem(const char *name,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
spdk_nvmf_subsystem_add_listener(subsystem, addresses[i].transport, addresses[i].traddr,
|
listen_addr = spdk_nvmf_tgt_listen(addresses[i].transport,
|
||||||
addresses[i].trsvcid);
|
addresses[i].traddr, addresses[i].trsvcid);
|
||||||
|
assert(listen_addr != NULL);
|
||||||
|
spdk_nvmf_subsystem_add_listener(subsystem, listen_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse Host sections */
|
/* Parse Host sections */
|
||||||
|
@ -50,6 +50,7 @@ dump_nvmf_subsystem(struct spdk_json_write_ctx *w, struct nvmf_tgt_subsystem *tg
|
|||||||
struct spdk_nvmf_listen_addr *listen_addr;
|
struct spdk_nvmf_listen_addr *listen_addr;
|
||||||
struct spdk_nvmf_host *host;
|
struct spdk_nvmf_host *host;
|
||||||
struct spdk_nvmf_subsystem *subsystem = tgt_subsystem->subsystem;
|
struct spdk_nvmf_subsystem *subsystem = tgt_subsystem->subsystem;
|
||||||
|
struct spdk_nvmf_subsystem_allowed_listener *allowed_listener;
|
||||||
|
|
||||||
spdk_json_write_object_begin(w);
|
spdk_json_write_object_begin(w);
|
||||||
|
|
||||||
@ -76,7 +77,8 @@ dump_nvmf_subsystem(struct spdk_json_write_ctx *w, struct nvmf_tgt_subsystem *tg
|
|||||||
spdk_json_write_name(w, "listen_addresses");
|
spdk_json_write_name(w, "listen_addresses");
|
||||||
spdk_json_write_array_begin(w);
|
spdk_json_write_array_begin(w);
|
||||||
|
|
||||||
TAILQ_FOREACH(listen_addr, &subsystem->listen_addrs, link) {
|
TAILQ_FOREACH(allowed_listener, &subsystem->allowed_listeners, link) {
|
||||||
|
listen_addr = allowed_listener->listen_addr;
|
||||||
spdk_json_write_object_begin(w);
|
spdk_json_write_object_begin(w);
|
||||||
spdk_json_write_name(w, "transport");
|
spdk_json_write_name(w, "transport");
|
||||||
spdk_json_write_string(w, listen_addr->trname);
|
spdk_json_write_string(w, listen_addr->trname);
|
||||||
|
@ -115,6 +115,11 @@ struct spdk_nvmf_ctrlr_ops {
|
|||||||
void (*detach)(struct spdk_nvmf_subsystem *subsystem);
|
void (*detach)(struct spdk_nvmf_subsystem *subsystem);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct spdk_nvmf_subsystem_allowed_listener {
|
||||||
|
struct spdk_nvmf_listen_addr *listen_addr;
|
||||||
|
TAILQ_ENTRY(spdk_nvmf_subsystem_allowed_listener) link;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The NVMf subsystem, as indicated in the specification, is a collection
|
* The NVMf subsystem, as indicated in the specification, is a collection
|
||||||
* of virtual controller sessions. Any individual controller session has
|
* of virtual controller sessions. Any individual controller session has
|
||||||
@ -149,12 +154,11 @@ struct spdk_nvmf_subsystem {
|
|||||||
|
|
||||||
TAILQ_HEAD(, spdk_nvmf_session) sessions;
|
TAILQ_HEAD(, spdk_nvmf_session) sessions;
|
||||||
|
|
||||||
TAILQ_HEAD(, spdk_nvmf_listen_addr) listen_addrs;
|
|
||||||
uint32_t num_listen_addrs;
|
|
||||||
|
|
||||||
TAILQ_HEAD(, spdk_nvmf_host) hosts;
|
TAILQ_HEAD(, spdk_nvmf_host) hosts;
|
||||||
uint32_t num_hosts;
|
uint32_t num_hosts;
|
||||||
|
|
||||||
|
TAILQ_HEAD(, spdk_nvmf_subsystem_allowed_listener) allowed_listeners;
|
||||||
|
|
||||||
TAILQ_ENTRY(spdk_nvmf_subsystem) entries;
|
TAILQ_ENTRY(spdk_nvmf_subsystem) entries;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -181,9 +185,16 @@ bool spdk_nvmf_subsystem_exists(const char *subnqn);
|
|||||||
|
|
||||||
bool spdk_nvmf_subsystem_host_allowed(struct spdk_nvmf_subsystem *subsystem, const char *hostnqn);
|
bool spdk_nvmf_subsystem_host_allowed(struct spdk_nvmf_subsystem *subsystem, const char *hostnqn);
|
||||||
|
|
||||||
|
struct spdk_nvmf_listen_addr *
|
||||||
|
spdk_nvmf_tgt_listen(const char *trname, const char *traddr, const char *trsvcid);
|
||||||
|
|
||||||
int
|
int
|
||||||
spdk_nvmf_subsystem_add_listener(struct spdk_nvmf_subsystem *subsystem,
|
spdk_nvmf_subsystem_add_listener(struct spdk_nvmf_subsystem *subsystem,
|
||||||
const char *trname, const char *traddr, const char *trsvcid);
|
struct spdk_nvmf_listen_addr *listen_addr);
|
||||||
|
|
||||||
|
bool
|
||||||
|
spdk_nvmf_subsystem_listener_allowed(struct spdk_nvmf_subsystem *subsystem,
|
||||||
|
struct spdk_nvmf_listen_addr *listen_addr);
|
||||||
|
|
||||||
int
|
int
|
||||||
spdk_nvmf_subsystem_add_host(struct spdk_nvmf_subsystem *subsystem,
|
spdk_nvmf_subsystem_add_host(struct spdk_nvmf_subsystem *subsystem,
|
||||||
|
@ -62,6 +62,7 @@ spdk_nvmf_tgt_init(uint16_t max_queue_depth, uint16_t max_queues_per_sess,
|
|||||||
g_nvmf_tgt.discovery_log_page = NULL;
|
g_nvmf_tgt.discovery_log_page = NULL;
|
||||||
g_nvmf_tgt.discovery_log_page_size = 0;
|
g_nvmf_tgt.discovery_log_page_size = 0;
|
||||||
TAILQ_INIT(&g_nvmf_tgt.subsystems);
|
TAILQ_INIT(&g_nvmf_tgt.subsystems);
|
||||||
|
TAILQ_INIT(&g_nvmf_tgt.listen_addrs);
|
||||||
|
|
||||||
SPDK_TRACELOG(SPDK_TRACE_NVMF, "Max Queues Per Session: %d\n", max_queues_per_sess);
|
SPDK_TRACELOG(SPDK_TRACE_NVMF, "Max Queues Per Session: %d\n", max_queues_per_sess);
|
||||||
SPDK_TRACELOG(SPDK_TRACE_NVMF, "Max Queue Depth: %d\n", max_queue_depth);
|
SPDK_TRACELOG(SPDK_TRACE_NVMF, "Max Queue Depth: %d\n", max_queue_depth);
|
||||||
@ -80,6 +81,15 @@ spdk_nvmf_tgt_init(uint16_t max_queue_depth, uint16_t max_queues_per_sess,
|
|||||||
int
|
int
|
||||||
spdk_nvmf_tgt_fini(void)
|
spdk_nvmf_tgt_fini(void)
|
||||||
{
|
{
|
||||||
|
struct spdk_nvmf_listen_addr *listen_addr, *listen_addr_tmp;
|
||||||
|
|
||||||
|
TAILQ_FOREACH_SAFE(listen_addr, &g_nvmf_tgt.listen_addrs, link, listen_addr_tmp) {
|
||||||
|
TAILQ_REMOVE(&g_nvmf_tgt.listen_addrs, listen_addr, link);
|
||||||
|
g_nvmf_tgt.discovery_genctr++;
|
||||||
|
|
||||||
|
spdk_nvmf_listen_addr_destroy(listen_addr);
|
||||||
|
}
|
||||||
|
|
||||||
spdk_nvmf_transport_fini();
|
spdk_nvmf_transport_fini();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -55,6 +55,7 @@ struct spdk_nvmf_tgt {
|
|||||||
TAILQ_HEAD(, spdk_nvmf_subsystem) subsystems;
|
TAILQ_HEAD(, spdk_nvmf_subsystem) subsystems;
|
||||||
struct spdk_nvmf_discovery_log_page *discovery_log_page;
|
struct spdk_nvmf_discovery_log_page *discovery_log_page;
|
||||||
size_t discovery_log_page_size;
|
size_t discovery_log_page_size;
|
||||||
|
TAILQ_HEAD(, spdk_nvmf_listen_addr) listen_addrs;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct spdk_nvmf_tgt g_nvmf_tgt;
|
extern struct spdk_nvmf_tgt g_nvmf_tgt;
|
||||||
|
@ -199,7 +199,7 @@ spdk_nvmf_create_subsystem(const char *nqn,
|
|||||||
subsystem->connect_cb = connect_cb;
|
subsystem->connect_cb = connect_cb;
|
||||||
subsystem->disconnect_cb = disconnect_cb;
|
subsystem->disconnect_cb = disconnect_cb;
|
||||||
snprintf(subsystem->subnqn, sizeof(subsystem->subnqn), "%s", nqn);
|
snprintf(subsystem->subnqn, sizeof(subsystem->subnqn), "%s", nqn);
|
||||||
TAILQ_INIT(&subsystem->listen_addrs);
|
TAILQ_INIT(&subsystem->allowed_listeners);
|
||||||
TAILQ_INIT(&subsystem->hosts);
|
TAILQ_INIT(&subsystem->hosts);
|
||||||
TAILQ_INIT(&subsystem->sessions);
|
TAILQ_INIT(&subsystem->sessions);
|
||||||
|
|
||||||
@ -218,7 +218,7 @@ spdk_nvmf_create_subsystem(const char *nqn,
|
|||||||
void
|
void
|
||||||
spdk_nvmf_delete_subsystem(struct spdk_nvmf_subsystem *subsystem)
|
spdk_nvmf_delete_subsystem(struct spdk_nvmf_subsystem *subsystem)
|
||||||
{
|
{
|
||||||
struct spdk_nvmf_listen_addr *listen_addr, *listen_addr_tmp;
|
struct spdk_nvmf_subsystem_allowed_listener *allowed_listener, *allowed_listener_tmp;
|
||||||
struct spdk_nvmf_host *host, *host_tmp;
|
struct spdk_nvmf_host *host, *host_tmp;
|
||||||
struct spdk_nvmf_session *session, *session_tmp;
|
struct spdk_nvmf_session *session, *session_tmp;
|
||||||
|
|
||||||
@ -228,10 +228,11 @@ spdk_nvmf_delete_subsystem(struct spdk_nvmf_subsystem *subsystem)
|
|||||||
|
|
||||||
SPDK_TRACELOG(SPDK_TRACE_NVMF, "subsystem is %p\n", subsystem);
|
SPDK_TRACELOG(SPDK_TRACE_NVMF, "subsystem is %p\n", subsystem);
|
||||||
|
|
||||||
TAILQ_FOREACH_SAFE(listen_addr, &subsystem->listen_addrs, link, listen_addr_tmp) {
|
TAILQ_FOREACH_SAFE(allowed_listener,
|
||||||
TAILQ_REMOVE(&subsystem->listen_addrs, listen_addr, link);
|
&subsystem->allowed_listeners, link, allowed_listener_tmp) {
|
||||||
spdk_nvmf_listen_addr_destroy(listen_addr);
|
TAILQ_REMOVE(&subsystem->allowed_listeners, allowed_listener, link);
|
||||||
subsystem->num_listen_addrs--;
|
|
||||||
|
free(allowed_listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
TAILQ_FOREACH_SAFE(host, &subsystem->hosts, link, host_tmp) {
|
TAILQ_FOREACH_SAFE(host, &subsystem->hosts, link, host_tmp) {
|
||||||
@ -255,38 +256,84 @@ spdk_nvmf_delete_subsystem(struct spdk_nvmf_subsystem *subsystem)
|
|||||||
free(subsystem);
|
free(subsystem);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
struct spdk_nvmf_listen_addr *
|
||||||
spdk_nvmf_subsystem_add_listener(struct spdk_nvmf_subsystem *subsystem,
|
spdk_nvmf_tgt_listen(const char *trname, const char *traddr, const char *trsvcid)
|
||||||
const char *trname, const char *traddr, const char *trsvcid)
|
|
||||||
{
|
{
|
||||||
struct spdk_nvmf_listen_addr *listen_addr;
|
struct spdk_nvmf_listen_addr *listen_addr;
|
||||||
const struct spdk_nvmf_transport *transport;
|
const struct spdk_nvmf_transport *transport;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
TAILQ_FOREACH(listen_addr, &g_nvmf_tgt.listen_addrs, link) {
|
||||||
|
if ((strcmp(listen_addr->trname, trname) == 0) &&
|
||||||
|
(strcmp(listen_addr->traddr, traddr) == 0) &&
|
||||||
|
(strcmp(listen_addr->trsvcid, trsvcid) == 0)) {
|
||||||
|
return listen_addr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
transport = spdk_nvmf_transport_get(trname);
|
transport = spdk_nvmf_transport_get(trname);
|
||||||
if (!transport) {
|
if (!transport) {
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
listen_addr = spdk_nvmf_listen_addr_create(trname, traddr, trsvcid);
|
listen_addr = spdk_nvmf_listen_addr_create(trname, traddr, trsvcid);
|
||||||
if (!listen_addr) {
|
if (!listen_addr) {
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = transport->listen_addr_add(listen_addr);
|
rc = transport->listen_addr_add(listen_addr);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
spdk_nvmf_listen_addr_cleanup(listen_addr);
|
spdk_nvmf_listen_addr_cleanup(listen_addr);
|
||||||
SPDK_ERRLOG("Unable to listen on address '%s'\n", traddr);
|
SPDK_ERRLOG("Unable to listen on address '%s'\n", traddr);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
TAILQ_INSERT_HEAD(&g_nvmf_tgt.listen_addrs, listen_addr, link);
|
||||||
|
g_nvmf_tgt.discovery_genctr++;
|
||||||
|
|
||||||
|
return listen_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
spdk_nvmf_subsystem_add_listener(struct spdk_nvmf_subsystem *subsystem,
|
||||||
|
struct spdk_nvmf_listen_addr *listen_addr)
|
||||||
|
{
|
||||||
|
struct spdk_nvmf_subsystem_allowed_listener *allowed_listener;
|
||||||
|
|
||||||
|
allowed_listener = calloc(1, sizeof(*allowed_listener));
|
||||||
|
if (!allowed_listener) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
TAILQ_INSERT_HEAD(&subsystem->listen_addrs, listen_addr, link);
|
allowed_listener->listen_addr = listen_addr;
|
||||||
subsystem->num_listen_addrs++;
|
|
||||||
g_nvmf_tgt.discovery_genctr++;
|
TAILQ_INSERT_HEAD(&subsystem->allowed_listeners, allowed_listener, link);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: this is the whitelist and will be called during connection setup
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
spdk_nvmf_subsystem_listener_allowed(struct spdk_nvmf_subsystem *subsystem,
|
||||||
|
struct spdk_nvmf_listen_addr *listen_addr)
|
||||||
|
{
|
||||||
|
struct spdk_nvmf_subsystem_allowed_listener *allowed_listener;
|
||||||
|
|
||||||
|
if (TAILQ_EMPTY(&subsystem->allowed_listeners)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
TAILQ_FOREACH(allowed_listener, &subsystem->allowed_listeners, link) {
|
||||||
|
if (allowed_listener->listen_addr == listen_addr) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
spdk_nvmf_subsystem_add_host(struct spdk_nvmf_subsystem *subsystem, const char *host_nqn)
|
spdk_nvmf_subsystem_add_host(struct spdk_nvmf_subsystem *subsystem, const char *host_nqn)
|
||||||
{
|
{
|
||||||
@ -324,6 +371,7 @@ nvmf_update_discovery_log(void)
|
|||||||
{
|
{
|
||||||
uint64_t numrec = 0;
|
uint64_t numrec = 0;
|
||||||
struct spdk_nvmf_subsystem *subsystem;
|
struct spdk_nvmf_subsystem *subsystem;
|
||||||
|
struct spdk_nvmf_subsystem_allowed_listener *allowed_listener;
|
||||||
struct spdk_nvmf_listen_addr *listen_addr;
|
struct spdk_nvmf_listen_addr *listen_addr;
|
||||||
struct spdk_nvmf_discovery_log_page_entry *entry;
|
struct spdk_nvmf_discovery_log_page_entry *entry;
|
||||||
const struct spdk_nvmf_transport *transport;
|
const struct spdk_nvmf_transport *transport;
|
||||||
@ -345,7 +393,7 @@ nvmf_update_discovery_log(void)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
TAILQ_FOREACH(listen_addr, &subsystem->listen_addrs, link) {
|
TAILQ_FOREACH(allowed_listener, &subsystem->allowed_listeners, link) {
|
||||||
size_t new_size = cur_size + sizeof(*entry);
|
size_t new_size = cur_size + sizeof(*entry);
|
||||||
void *new_log_page = realloc(disc_log, new_size);
|
void *new_log_page = realloc(disc_log, new_size);
|
||||||
|
|
||||||
@ -354,6 +402,8 @@ nvmf_update_discovery_log(void)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
listen_addr = allowed_listener->listen_addr;
|
||||||
|
|
||||||
disc_log = new_log_page;
|
disc_log = new_log_page;
|
||||||
cur_size = new_size;
|
cur_size = new_size;
|
||||||
|
|
||||||
|
@ -225,6 +225,7 @@ test_discovery_log(void)
|
|||||||
uint8_t buffer[8192];
|
uint8_t buffer[8192];
|
||||||
struct spdk_nvmf_discovery_log_page *disc_log;
|
struct spdk_nvmf_discovery_log_page *disc_log;
|
||||||
struct spdk_nvmf_discovery_log_page_entry *entry;
|
struct spdk_nvmf_discovery_log_page_entry *entry;
|
||||||
|
struct spdk_nvmf_listen_addr *listen_addr;
|
||||||
|
|
||||||
/* Reset discovery-related globals */
|
/* Reset discovery-related globals */
|
||||||
g_nvmf_tgt.discovery_genctr = 0;
|
g_nvmf_tgt.discovery_genctr = 0;
|
||||||
@ -237,8 +238,10 @@ test_discovery_log(void)
|
|||||||
NVMF_SUBSYSTEM_MODE_DIRECT, NULL, NULL, NULL);
|
NVMF_SUBSYSTEM_MODE_DIRECT, NULL, NULL, NULL);
|
||||||
SPDK_CU_ASSERT_FATAL(subsystem != NULL);
|
SPDK_CU_ASSERT_FATAL(subsystem != NULL);
|
||||||
|
|
||||||
SPDK_CU_ASSERT_FATAL(spdk_nvmf_subsystem_add_listener(subsystem, "test_transport1",
|
listen_addr = spdk_nvmf_tgt_listen("test_transport1", "1234", "5678");
|
||||||
"1234", "5678") == 0);
|
SPDK_CU_ASSERT_FATAL(listen_addr != NULL);
|
||||||
|
|
||||||
|
SPDK_CU_ASSERT_FATAL(spdk_nvmf_subsystem_add_listener(subsystem, listen_addr) == 0);
|
||||||
|
|
||||||
/* Get only genctr (first field in the header) */
|
/* Get only genctr (first field in the header) */
|
||||||
memset(buffer, 0xCC, sizeof(buffer));
|
memset(buffer, 0xCC, sizeof(buffer));
|
||||||
|
Loading…
Reference in New Issue
Block a user