nvmf: add listen addresses after creating subsystem

Remove the array of listen addresses from the parameters of
spdk_nvmf_construct_subsystem() and add the listen addresses
individually now that we have the capability to add them after subsystem
creation.

Change-Id: If9b9e5f5ce2e6af2bddbda7c3926170f2296abdd
Signed-off-by: Daniel Verkamp <daniel.verkamp@intel.com>
Reviewed-on: https://review.gerrithub.io/403376
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
This commit is contained in:
Daniel Verkamp 2018-03-09 16:52:40 -07:00
parent d4ef1338b0
commit 333e9299b1
3 changed files with 78 additions and 87 deletions

View File

@ -41,7 +41,6 @@
#include "spdk/string.h" #include "spdk/string.h"
#include "spdk/util.h" #include "spdk/util.h"
#define MAX_LISTEN_ADDRESSES 255
#define MAX_HOSTS 255 #define MAX_HOSTS 255
#define MAX_NAMESPACES 255 #define MAX_NAMESPACES 255
@ -147,9 +146,6 @@ spdk_nvmf_parse_subsystem(struct spdk_conf_section *sp)
size_t i; size_t i;
int ret; int ret;
int lcore; int lcore;
int num_listen_addrs;
struct rpc_listen_address listen_addrs[MAX_LISTEN_ADDRESSES] = {};
char *listen_addrs_str[MAX_LISTEN_ADDRESSES] = {};
int num_hosts; int num_hosts;
char *hosts[MAX_HOSTS]; char *hosts[MAX_HOSTS];
bool allow_any_host; bool allow_any_host;
@ -184,40 +180,6 @@ spdk_nvmf_parse_subsystem(struct spdk_conf_section *sp)
SPDK_NOTICELOG("Please remove Core from your configuration file. Ignoring it and continuing.\n"); SPDK_NOTICELOG("Please remove Core from your configuration file. Ignoring it and continuing.\n");
} }
/* Parse Listen sections */
num_listen_addrs = 0;
for (i = 0; i < MAX_LISTEN_ADDRESSES; i++) {
listen_addrs[num_listen_addrs].transport =
spdk_conf_section_get_nmval(sp, "Listen", i, 0);
if (!listen_addrs[num_listen_addrs].transport) {
break;
}
listen_addrs_str[i] = spdk_conf_section_get_nmval(sp, "Listen", i, 1);
if (!listen_addrs_str[i]) {
break;
}
listen_addrs_str[i] = strdup(listen_addrs_str[i]);
ret = spdk_parse_ip_addr(listen_addrs_str[i], &listen_addrs[num_listen_addrs].traddr,
&listen_addrs[num_listen_addrs].trsvcid);
if (ret < 0) {
SPDK_ERRLOG("Unable to parse listen address '%s'\n", listen_addrs_str[i]);
free(listen_addrs_str[i]);
listen_addrs_str[i] = NULL;
continue;
}
if (strchr(listen_addrs[num_listen_addrs].traddr, ':')) {
listen_addrs[num_listen_addrs].adrfam = "IPv6";
} else {
listen_addrs[num_listen_addrs].adrfam = "IPv4";
}
num_listen_addrs++;
}
/* Parse Host sections */ /* Parse Host sections */
for (i = 0; i < MAX_HOSTS; i++) { for (i = 0; i < MAX_HOSTS; i++) {
hosts[i] = spdk_conf_section_get_nval(sp, "Host", i); hosts[i] = spdk_conf_section_get_nval(sp, "Host", i);
@ -232,7 +194,6 @@ spdk_nvmf_parse_subsystem(struct spdk_conf_section *sp)
sn = spdk_conf_section_get_val(sp, "SN"); sn = spdk_conf_section_get_val(sp, "SN");
subsystem = spdk_nvmf_construct_subsystem(nqn, subsystem = spdk_nvmf_construct_subsystem(nqn,
num_listen_addrs, listen_addrs,
num_hosts, hosts, allow_any_host, num_hosts, hosts, allow_any_host,
sn); sn);
@ -287,11 +248,63 @@ spdk_nvmf_parse_subsystem(struct spdk_conf_section *sp)
spdk_bdev_get_name(bdev), spdk_nvmf_subsystem_get_nqn(subsystem)); spdk_bdev_get_name(bdev), spdk_nvmf_subsystem_get_nqn(subsystem));
} }
done: /* Parse Listen sections */
for (i = 0; i < MAX_LISTEN_ADDRESSES; i++) { for (i = 0; ; i++) {
free(listen_addrs_str[i]); struct spdk_nvme_transport_id trid = {0};
const char *transport;
const char *address;
char *address_dup;
char *host;
char *port;
transport = spdk_conf_section_get_nmval(sp, "Listen", i, 0);
if (!transport) {
break;
}
if (spdk_nvme_transport_id_parse_trtype(&trid.trtype, transport)) {
SPDK_ERRLOG("Invalid listen address transport type '%s'\n", transport);
continue;
}
address = spdk_conf_section_get_nmval(sp, "Listen", i, 1);
if (!address) {
break;
}
address_dup = strdup(address);
if (!address_dup) {
break;
}
ret = spdk_parse_ip_addr(address_dup, &host, &port);
if (ret < 0) {
SPDK_ERRLOG("Unable to parse listen address '%s'\n", address);
free(address_dup);
continue;
}
if (strchr(host, ':')) {
trid.adrfam = SPDK_NVMF_ADRFAM_IPV6;
} else {
trid.adrfam = SPDK_NVMF_ADRFAM_IPV4;
}
snprintf(trid.traddr, sizeof(trid.traddr), "%s", host);
snprintf(trid.trsvcid, sizeof(trid.trsvcid), "%s", port);
free(address_dup);
ret = spdk_nvmf_tgt_listen(g_tgt.tgt, &trid);
if (ret) {
SPDK_ERRLOG("Failed to listen on transport %s address %s\n",
transport, address);
continue;
}
spdk_nvmf_subsystem_add_listener(subsystem, &trid);
} }
done:
return (subsystem != NULL); return (subsystem != NULL);
} }
@ -336,23 +349,17 @@ spdk_nvmf_parse_conf(void)
struct spdk_nvmf_subsystem * struct spdk_nvmf_subsystem *
spdk_nvmf_construct_subsystem(const char *name, spdk_nvmf_construct_subsystem(const char *name,
int num_listen_addresses, struct rpc_listen_address *addresses,
int num_hosts, char *hosts[], bool allow_any_host, int num_hosts, char *hosts[], bool allow_any_host,
const char *sn) const char *sn)
{ {
struct spdk_nvmf_subsystem *subsystem; struct spdk_nvmf_subsystem *subsystem;
int i, rc; int i;
if (name == NULL) { if (name == NULL) {
SPDK_ERRLOG("No NQN specified for subsystem\n"); SPDK_ERRLOG("No NQN specified for subsystem\n");
return NULL; return NULL;
} }
if (num_listen_addresses > MAX_LISTEN_ADDRESSES) {
SPDK_ERRLOG("invalid listen adresses number\n");
return NULL;
}
if (num_hosts > MAX_HOSTS) { if (num_hosts > MAX_HOSTS) {
SPDK_ERRLOG("invalid hosts number\n"); SPDK_ERRLOG("invalid hosts number\n");
return NULL; return NULL;
@ -364,34 +371,6 @@ struct spdk_nvmf_subsystem *
return NULL; return NULL;
} }
/* Parse Listen sections */
for (i = 0; i < num_listen_addresses; i++) {
struct spdk_nvme_transport_id trid = {};
if (spdk_nvme_transport_id_parse_trtype(&trid.trtype, addresses[i].transport)) {
SPDK_ERRLOG("Missing listen address transport type\n");
goto error;
}
if (spdk_nvme_transport_id_parse_adrfam(&trid.adrfam, addresses[i].adrfam)) {
trid.adrfam = SPDK_NVMF_ADRFAM_IPV4;
}
snprintf(trid.traddr, sizeof(trid.traddr), "%s", addresses[i].traddr);
snprintf(trid.trsvcid, sizeof(trid.trsvcid), "%s", addresses[i].trsvcid);
rc = spdk_nvmf_tgt_listen(g_tgt.tgt, &trid);
if (rc) {
SPDK_ERRLOG("Failed to listen on transport %s, adrfam %s, traddr %s, trsvcid %s\n",
addresses[i].transport,
addresses[i].adrfam,
addresses[i].traddr,
addresses[i].trsvcid);
goto error;
}
spdk_nvmf_subsystem_add_listener(subsystem, &trid);
}
/* Parse Host sections */ /* Parse Host sections */
for (i = 0; i < num_hosts; i++) { for (i = 0; i < num_hosts; i++) {
spdk_nvmf_subsystem_add_host(subsystem, hosts[i]); spdk_nvmf_subsystem_add_host(subsystem, hosts[i]);

View File

@ -41,13 +41,6 @@
#include "spdk_internal/event.h" #include "spdk_internal/event.h"
struct rpc_listen_address {
char *transport;
char *adrfam;
char *traddr;
char *trsvcid;
};
struct spdk_nvmf_tgt_conf { struct spdk_nvmf_tgt_conf {
uint32_t acceptor_poll_rate; uint32_t acceptor_poll_rate;
}; };
@ -85,7 +78,6 @@ struct spdk_nvmf_subsystem *nvmf_tgt_create_subsystem(const char *name,
enum spdk_nvmf_subtype subtype, uint32_t num_ns); enum spdk_nvmf_subtype subtype, uint32_t num_ns);
struct spdk_nvmf_subsystem *spdk_nvmf_construct_subsystem(const char *name, struct spdk_nvmf_subsystem *spdk_nvmf_construct_subsystem(const char *name,
int num_listen_addresses, struct rpc_listen_address *addresses,
int num_hosts, char *hosts[], bool allow_any_host, int num_hosts, char *hosts[], bool allow_any_host,
const char *sn); const char *sn);

View File

@ -299,6 +299,13 @@ spdk_rpc_get_nvmf_subsystems(struct spdk_jsonrpc_request *request,
} }
SPDK_RPC_REGISTER("get_nvmf_subsystems", spdk_rpc_get_nvmf_subsystems) SPDK_RPC_REGISTER("get_nvmf_subsystems", spdk_rpc_get_nvmf_subsystems)
struct rpc_listen_address {
char *transport;
char *adrfam;
char *traddr;
char *trsvcid;
};
#define RPC_MAX_LISTEN_ADDRESSES 255 #define RPC_MAX_LISTEN_ADDRESSES 255
#define RPC_MAX_HOSTS 255 #define RPC_MAX_HOSTS 255
#define RPC_MAX_NAMESPACES 255 #define RPC_MAX_NAMESPACES 255
@ -599,14 +606,27 @@ spdk_rpc_construct_nvmf_subsystem(struct spdk_jsonrpc_request *request,
} }
subsystem = spdk_nvmf_construct_subsystem(req.nqn, subsystem = spdk_nvmf_construct_subsystem(req.nqn,
req.listen_addresses.num_listen_address,
req.listen_addresses.addresses,
req.hosts.num_hosts, req.hosts.hosts, req.allow_any_host, req.hosts.num_hosts, req.hosts.hosts, req.allow_any_host,
req.serial_number); req.serial_number);
if (!subsystem) { if (!subsystem) {
goto invalid; goto invalid;
} }
for (i = 0; i < req.listen_addresses.num_listen_address; i++) {
struct rpc_listen_address *addr = &req.listen_addresses.addresses[i];
struct spdk_nvme_transport_id trid = {0};
if (rpc_listen_address_to_trid(addr, &trid)) {
goto invalid;
}
if (spdk_nvmf_tgt_listen(g_tgt.tgt, &trid)) {
goto invalid;
}
spdk_nvmf_subsystem_add_listener(subsystem, &trid);
}
for (i = 0; i < req.namespaces.num_ns; i++) { for (i = 0; i < req.namespaces.num_ns; i++) {
struct spdk_nvmf_ns_params *ns_params = &req.namespaces.ns_params[i]; struct spdk_nvmf_ns_params *ns_params = &req.namespaces.ns_params[i];
struct spdk_bdev *bdev; struct spdk_bdev *bdev;