nvme_bdev: add parsing for hostaddr and hostsvcid
This allows us to specify the host-side configuration for each controller to which we connect. Change-Id: Iac2aed3934d4a326f45546f2f541e374308e2589 Signed-off-by: Seth Howell <seth.howell@intel.com> Reviewed-on: https://review.gerrithub.io/436219 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Chandler-Test-Pool: SPDK Automated Test System <sys_sgsw@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
parent
b035e2b848
commit
675c5592e7
@ -25,6 +25,9 @@ same TCP/IP support.
|
||||
Added API, spdk_nvme_ctrlr_is_discovery(), to indicate whether the ctrlr
|
||||
arg refers to a Discovery Controller or not.
|
||||
|
||||
Added an API function `spdk_nvme_host_id_parse` and corresponding object `spdk_nvme_host_id`
|
||||
for parsing host address and host service ID arguments on a per connection basis.
|
||||
|
||||
### NVMe-oF Target
|
||||
|
||||
The `spdk_nvmf_tgt_opts` struct has been deprecated in favor of `spdk_nvmf_transport_opts`.
|
||||
|
@ -102,6 +102,7 @@
|
||||
TransportID "trtype:PCIe traddr:0000:01:00.0" Nvme1
|
||||
TransportID "trtype:PCIe traddr:0000:02:00.0" Nvme2
|
||||
TransportID "trtype:PCIe traddr:0000:03:00.0" Nvme3
|
||||
TransportID "trtypr:RDMA traddr:192.168.100.8 trsvcid:4420 hostaddr:192.168.100.9" Nvme4
|
||||
|
||||
# The number of attempts per I/O when an I/O fails. Do not include
|
||||
# this key to get the default behavior.
|
||||
|
@ -279,6 +279,35 @@ struct spdk_nvme_transport_id {
|
||||
char subnqn[SPDK_NVMF_NQN_MAX_LEN + 1];
|
||||
};
|
||||
|
||||
/**
|
||||
* NVMe host identifier
|
||||
*
|
||||
* Used for defining the host identity for an NVMe-oF connection.
|
||||
*
|
||||
* In terms of configuration, this object can be considered a subtype of TransportID
|
||||
* Please see etc/spdk/nvmf.conf.in for more details.
|
||||
*
|
||||
* A string representation of this type may be converted to this type using
|
||||
* spdk_nvme_host_id_parse().
|
||||
*/
|
||||
struct spdk_nvme_host_id {
|
||||
/**
|
||||
* Transport address to be used by the host when connecting to the NVMe-oF endpoint.
|
||||
* May be an IP address or a zero length string for transports which
|
||||
* use IP addressing (e.g. RDMA).
|
||||
* For PCIe and FC this is always a zero length string.
|
||||
*/
|
||||
char hostaddr[SPDK_NVMF_TRADDR_MAX_LEN + 1];
|
||||
|
||||
/**
|
||||
* Transport service ID used by the host when connecting to the NVMe.
|
||||
* May be a port number or a zero length string for transports which
|
||||
* use IP addressing (e.g. RDMA).
|
||||
* For PCIe and FC this is always a zero length string.
|
||||
*/
|
||||
char hostsvcid[SPDK_NVMF_TRSVCID_MAX_LEN + 1];
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse the string representation of a transport ID.
|
||||
*
|
||||
@ -304,6 +333,31 @@ struct spdk_nvme_transport_id {
|
||||
*/
|
||||
int spdk_nvme_transport_id_parse(struct spdk_nvme_transport_id *trid, const char *str);
|
||||
|
||||
/**
|
||||
* Parse the string representation of a host ID.
|
||||
*
|
||||
* \param hostid Output host ID structure (must be allocated and initialized by caller).
|
||||
* \param str Input string representation of a transport ID to parse (hostid is a sub-configuration).
|
||||
*
|
||||
* str must be a zero-terminated C string containing one or more key:value pairs
|
||||
* separated by whitespace.
|
||||
*
|
||||
* Key | Value
|
||||
* -------------- | -----
|
||||
* hostaddr | Transport address (e.g. 192.168.100.8 for RDMA)
|
||||
* hostsvcid | Transport service identifier (e.g. 4420)
|
||||
*
|
||||
* Unspecified fields of trid are left unmodified, so the caller must initialize
|
||||
* hostid (for example, memset() to 0) before calling this function.
|
||||
*
|
||||
* This function should not be used with Fiber Channel or PCIe as these transports
|
||||
* do not require host information for connections.
|
||||
*
|
||||
* \return 0 if parsing was successful and hostid is filled out, or negated errno
|
||||
* values on failure.
|
||||
*/
|
||||
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.
|
||||
*
|
||||
|
@ -90,6 +90,7 @@ enum data_direction {
|
||||
struct nvme_probe_ctx {
|
||||
size_t count;
|
||||
struct spdk_nvme_transport_id trids[NVME_MAX_CONTROLLERS];
|
||||
struct spdk_nvme_host_id hostids[NVME_MAX_CONTROLLERS];
|
||||
const char *names[NVME_MAX_CONTROLLERS];
|
||||
const char *hostnqn;
|
||||
};
|
||||
@ -1384,6 +1385,13 @@ bdev_nvme_library_init(void)
|
||||
goto end;
|
||||
}
|
||||
|
||||
rc = spdk_nvme_host_id_parse(&probe_ctx->hostids[i], val);
|
||||
if (rc < 0) {
|
||||
SPDK_ERRLOG("Unable to parse HostID: %s\n", val);
|
||||
rc = -1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
val = spdk_conf_section_get_nmval(sp, "TransportID", i, 1);
|
||||
if (val == NULL) {
|
||||
SPDK_ERRLOG("No name provided for TransportID\n");
|
||||
@ -1417,6 +1425,14 @@ bdev_nvme_library_init(void)
|
||||
snprintf(opts.hostnqn, sizeof(opts.hostnqn), "%s", probe_ctx->hostnqn);
|
||||
}
|
||||
|
||||
if (probe_ctx->hostids[i].hostaddr[0] != '\0') {
|
||||
snprintf(opts.src_addr, sizeof(opts.src_addr), "%s", probe_ctx->hostids[i].hostaddr);
|
||||
}
|
||||
|
||||
if (probe_ctx->hostids[i].hostsvcid[0] != '\0') {
|
||||
snprintf(opts.src_svcid, sizeof(opts.src_svcid), "%s", probe_ctx->hostids[i].hostsvcid);
|
||||
}
|
||||
|
||||
ctrlr = spdk_nvme_connect(&probe_ctx->trids[i], &opts, sizeof(opts));
|
||||
if (ctrlr == NULL) {
|
||||
SPDK_ERRLOG("Unable to connect to provided trid (traddr: %s)\n",
|
||||
|
@ -828,6 +828,10 @@ spdk_nvme_transport_id_parse(struct spdk_nvme_transport_id *trid, const char *st
|
||||
return -EINVAL;
|
||||
}
|
||||
memcpy(trid->subnqn, val, val_len + 1);
|
||||
} else if (strcasecmp(key, "hostaddr") == 0) {
|
||||
continue;
|
||||
} else if (strcasecmp(key, "hostsvcid") == 0) {
|
||||
continue;
|
||||
} else if (strcasecmp(key, "ns") == 0) {
|
||||
/*
|
||||
* Special case. The namespace id parameter may
|
||||
@ -848,6 +852,65 @@ spdk_nvme_transport_id_parse(struct spdk_nvme_transport_id *trid, const char *st
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
spdk_nvme_host_id_parse(struct spdk_nvme_host_id *hostid, const char *str)
|
||||
{
|
||||
|
||||
size_t key_size = 32;
|
||||
size_t val_size = 1024;
|
||||
size_t val_len;
|
||||
char key[key_size];
|
||||
char val[val_size];
|
||||
|
||||
if (hostid == NULL || str == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
while (*str != '\0') {
|
||||
|
||||
val_len = parse_next_key(&str, key, val, key_size, val_size);
|
||||
|
||||
if (val_len == 0) {
|
||||
SPDK_ERRLOG("Failed to parse host ID\n");
|
||||
return val_len;
|
||||
}
|
||||
|
||||
/* Ignore the rest of the options from the transport ID. */
|
||||
if (strcasecmp(key, "trtype") == 0) {
|
||||
continue;
|
||||
} else if (strcasecmp(key, "adrfam") == 0) {
|
||||
continue;
|
||||
} else if (strcasecmp(key, "traddr") == 0) {
|
||||
continue;
|
||||
} else if (strcasecmp(key, "trsvcid") == 0) {
|
||||
continue;
|
||||
} else if (strcasecmp(key, "subnqn") == 0) {
|
||||
continue;
|
||||
} else if (strcasecmp(key, "ns") == 0) {
|
||||
continue;
|
||||
} else if (strcasecmp(key, "hostaddr") == 0) {
|
||||
if (val_len > SPDK_NVMF_TRADDR_MAX_LEN) {
|
||||
SPDK_ERRLOG("hostaddr length %zu greater than maximum allowed %u\n",
|
||||
val_len, SPDK_NVMF_TRADDR_MAX_LEN);
|
||||
return -EINVAL;
|
||||
}
|
||||
memcpy(hostid->hostaddr, val, val_len + 1);
|
||||
|
||||
} else if (strcasecmp(key, "hostsvcid") == 0) {
|
||||
if (val_len > SPDK_NVMF_TRSVCID_MAX_LEN) {
|
||||
SPDK_ERRLOG("trsvcid length %zu greater than maximum allowed %u\n",
|
||||
val_len, SPDK_NVMF_TRSVCID_MAX_LEN);
|
||||
return -EINVAL;
|
||||
}
|
||||
memcpy(hostid->hostsvcid, val, val_len + 1);
|
||||
} else {
|
||||
SPDK_ERRLOG("Unknown transport ID key '%s'\n", key);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
cmp_int(int a, int b)
|
||||
{
|
||||
|
@ -56,7 +56,7 @@ do
|
||||
done
|
||||
$rpc_py nvmf_subsystem_add_listener nqn.2016-06.io.spdk:cnode$i -t rdma -a $NVMF_FIRST_TARGET_IP -s $NVMF_PORT
|
||||
|
||||
echo " TransportID \"trtype:RDMA adrfam:IPv4 subnqn:nqn.2016-06.io.spdk:cnode$i traddr:$NVMF_FIRST_TARGET_IP trsvcid:$NVMF_PORT\" Nvme$i" >> $testdir/bdevperf.conf
|
||||
echo " TransportID \"trtype:RDMA adrfam:IPv4 subnqn:nqn.2016-06.io.spdk:cnode$i traddr:$NVMF_FIRST_TARGET_IP trsvcid:$NVMF_PORT hostaddr:$NVMF_FIRST_TARGET_IP\" Nvme$i" >> $testdir/bdevperf.conf
|
||||
done
|
||||
|
||||
# Test 1: Kill the initiator unexpectedly with no I/O outstanding
|
||||
|
Loading…
Reference in New Issue
Block a user