summaryrefslogtreecommitdiffstats
path: root/src/nvme/fabrics.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvme/fabrics.c')
-rw-r--r--src/nvme/fabrics.c146
1 files changed, 94 insertions, 52 deletions
diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c
index b68b7b9..a501f79 100644
--- a/src/nvme/fabrics.c
+++ b/src/nvme/fabrics.c
@@ -39,7 +39,6 @@
#include "private.h"
#define NVMF_HOSTID_SIZE 37
-#define UUID_SIZE 37 /* 1b4e28ba-2fa1-11d2-883f-0016d3cca427 + \0 */
#define NVMF_HOSTNQN_FILE SYSCONFDIR "/nvme/hostnqn"
#define NVMF_HOSTID_FILE SYSCONFDIR "/nvme/hostid"
@@ -192,13 +191,15 @@ void nvmf_default_config(struct nvme_fabrics_config *cfg)
#define MERGE_CFG_OPTION(c, n, o, d) \
if ((c)->o == d) (c)->o = (n)->o
+#define MERGE_CFG_OPTION_STR(c, n, o, d) \
+ if ((c)->o == d && (n)->o) (c)->o = strdup((n)->o)
static struct nvme_fabrics_config *merge_config(nvme_ctrl_t c,
const struct nvme_fabrics_config *cfg)
{
struct nvme_fabrics_config *ctrl_cfg = nvme_ctrl_get_config(c);
- MERGE_CFG_OPTION(ctrl_cfg, cfg, host_traddr, NULL);
- MERGE_CFG_OPTION(ctrl_cfg, cfg, host_iface, NULL);
+ MERGE_CFG_OPTION_STR(ctrl_cfg, cfg, host_traddr, NULL);
+ MERGE_CFG_OPTION_STR(ctrl_cfg, cfg, host_iface, NULL);
MERGE_CFG_OPTION(ctrl_cfg, cfg, nr_io_queues, 0);
MERGE_CFG_OPTION(ctrl_cfg, cfg, nr_write_queues, 0);
MERGE_CFG_OPTION(ctrl_cfg, cfg, nr_poll_queues, 0);
@@ -295,7 +296,7 @@ static int add_argument(char **argstr, const char *tok, const char *arg)
{
char *nstr;
- if (!(arg && strcmp(arg, "none")))
+ if (!arg || arg[0] == '\0' || !strcmp(arg, "none"))
return 0;
if (asprintf(&nstr, "%s,%s=%s", *argstr, tok, arg) < 0) {
errno = ENOMEM;
@@ -465,6 +466,8 @@ static int build_options(nvme_host_t h, nvme_ctrl_t c, char **argstr)
hostnqn = nvme_host_get_hostnqn(h);
hostid = nvme_host_get_hostid(h);
hostkey = nvme_host_get_dhchap_key(h);
+ if (!hostkey)
+ hostkey = nvme_ctrl_get_dhchap_host_key(c);
ctrlkey = nvme_ctrl_get_dhchap_key(c);
if (add_argument(argstr, "transport", transport) ||
add_argument(argstr, "traddr",
@@ -613,14 +616,20 @@ int nvmf_add_ctrl(nvme_host_t h, nvme_ctrl_t c,
nvme_ctrl_get_trsvcid(c),
NULL);
if (fc) {
+ const char *key;
+
cfg = merge_config(c, nvme_ctrl_get_config(fc));
/*
* An authentication key might already been set
* in @cfg, so ensure to update @c with the correct
* controller key.
*/
- if (fc->dhchap_key)
- nvme_ctrl_set_dhchap_key(c, fc->dhchap_key);
+ key = nvme_ctrl_get_dhchap_host_key(fc);
+ if (key)
+ nvme_ctrl_set_dhchap_host_key(c, key);
+ key = nvme_ctrl_get_dhchap_key(fc);
+ if (key)
+ nvme_ctrl_set_dhchap_key(c, key);
}
}
@@ -734,7 +743,7 @@ nvme_ctrl_t nvmf_connect_disc_entry(nvme_host_t h,
default:
nvme_msg(h->r, LOG_ERR, "unsupported subtype %d\n",
e->subtype);
- /* fallthrough */
+ fallthrough;
case NVME_NQN_NVME:
nvme_ctrl_set_discovery_ctrl(c, false);
break;
@@ -772,30 +781,9 @@ nvme_ctrl_t nvmf_connect_disc_entry(nvme_host_t h,
return NULL;
}
-static int nvme_discovery_log(int fd, __u32 len, struct nvmf_discovery_log *log, bool rae)
-{
- struct nvme_get_log_args args = {
- .args_size = sizeof(args),
- .fd = fd,
- .nsid = NVME_NSID_NONE,
- .lsp = NVME_LOG_LSP_NONE,
- .lsi = NVME_LOG_LSI_NONE,
- .uuidx = NVME_UUID_NONE,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
- .result = NULL,
- .lid = NVME_LOG_LID_DISCOVER,
- .log = log,
- .len = len,
- .csi = NVME_CSI_NVM,
- .rae = rae,
- .ot = false,
- };
-
- return nvme_get_log_page(fd, 4096, &args);
-}
-
-int nvmf_get_discovery_log(nvme_ctrl_t c, struct nvmf_discovery_log **logp,
- int max_retries)
+static struct nvmf_discovery_log *nvme_discovery_log(nvme_ctrl_t c,
+ struct nvme_get_log_args *args,
+ int max_retries)
{
nvme_root_t r = c->s && c->s->h ? c->s->h->r : NULL;
struct nvmf_discovery_log *log = NULL;
@@ -803,6 +791,9 @@ int nvmf_get_discovery_log(nvme_ctrl_t c, struct nvmf_discovery_log **logp,
const char *name = nvme_ctrl_get_name(c);
uint64_t genctr, numrec;
unsigned int size;
+ int fd = nvme_ctrl_get_fd(c);
+
+ args->fd = fd;
do {
size = sizeof(struct nvmf_discovery_log);
@@ -813,12 +804,15 @@ int nvmf_get_discovery_log(nvme_ctrl_t c, struct nvmf_discovery_log **logp,
nvme_msg(r, LOG_ERR,
"could not allocate memory for discovery log header\n");
errno = ENOMEM;
- return -1;
+ return NULL;
}
nvme_msg(r, LOG_DEBUG, "%s: get header (try %d/%d)\n",
name, retries, max_retries);
- ret = nvme_discovery_log(nvme_ctrl_get_fd(c), size, log, true);
+ args->rae = true;
+ args->len = size;
+ args->log = log;
+ ret = nvme_get_log_page(fd, 4096, args);
if (ret) {
nvme_msg(r, LOG_INFO,
"%s: discover try %d/%d failed, error %d\n",
@@ -841,14 +835,19 @@ int nvmf_get_discovery_log(nvme_ctrl_t c, struct nvmf_discovery_log **logp,
nvme_msg(r, LOG_ERR,
"could not alloc memory for discovery log page\n");
errno = ENOMEM;
- return -1;
+ return NULL;
}
nvme_msg(r, LOG_DEBUG,
"%s: get header and %" PRIu64
" records (length %d genctr %" PRIu64 ")\n",
name, numrec, size, genctr);
- ret = nvme_discovery_log(nvme_ctrl_get_fd(c), size, log, false);
+
+ args->rae = false;
+ args->len = size;
+ args->log = log;
+ ret = nvme_get_log_page(fd, 4096, args);
+
if (ret) {
nvme_msg(r, LOG_INFO,
"%s: discover try %d/%d failed, error %d\n",
@@ -861,21 +860,63 @@ int nvmf_get_discovery_log(nvme_ctrl_t c, struct nvmf_discovery_log **logp,
if (genctr != le64_to_cpu(log->genctr)) {
nvme_msg(r, LOG_INFO, "%s: discover genctr mismatch\n", name);
errno = EAGAIN;
- ret = -1;
} else if (numrec != le64_to_cpu(log->numrec)) {
nvme_msg(r, LOG_INFO,
"%s: could only fetch %" PRIu64 " of %" PRIu64 " records\n",
name, numrec, le64_to_cpu(log->numrec));
errno = EBADSLT;
- ret = -1;
} else {
- *logp = log;
- return 0;
+ return log;
}
out_free_log:
free(log);
- return ret;
+ return NULL;
+}
+
+int nvmf_get_discovery_log(nvme_ctrl_t c, struct nvmf_discovery_log **logp,
+ int max_retries)
+{
+ struct nvme_get_log_args args = {
+ .args_size = sizeof(args),
+ .fd = nvme_ctrl_get_fd(c),
+ .nsid = NVME_NSID_NONE,
+ .lsp = NVMF_LOG_DISC_LSP_NONE,
+ .lsi = NVME_LOG_LSI_NONE,
+ .uuidx = NVME_UUID_NONE,
+ .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .result = NULL,
+ .lid = NVME_LOG_LID_DISCOVER,
+ .log = NULL,
+ .len = 0,
+ .csi = NVME_CSI_NVM,
+ .rae = false,
+ .ot = false,
+ };
+ *logp = nvme_discovery_log(c, &args, max_retries);
+ return logp ? 0 : -1;
+}
+
+struct nvmf_discovery_log *nvmf_get_discovery_wargs(struct nvme_get_discovery_args *args)
+{
+ struct nvme_get_log_args _args = {
+ .args_size = sizeof(_args),
+ .fd = nvme_ctrl_get_fd(args->c),
+ .nsid = NVME_NSID_NONE,
+ .lsp = args->lsp,
+ .lsi = NVME_LOG_LSI_NONE,
+ .uuidx = NVME_UUID_NONE,
+ .timeout = args->timeout,
+ .result = args->result,
+ .lid = NVME_LOG_LID_DISCOVER,
+ .log = NULL,
+ .len = 0,
+ .csi = NVME_CSI_NVM,
+ .rae = false,
+ .ot = false,
+ };
+
+ return nvme_discovery_log(args->c, &_args, args->max_retries);
}
#define PATH_UUID_IBM "/proc/device-tree/ibm,partition-uuid"
@@ -889,8 +930,8 @@ static int uuid_from_device_tree(char *system_uuid)
if (f < 0)
return -ENXIO;
- memset(system_uuid, 0, UUID_SIZE);
- len = read(f, system_uuid, UUID_SIZE - 1);
+ memset(system_uuid, 0, NVME_UUID_LEN_STRING);
+ len = read(f, system_uuid, NVME_UUID_LEN_STRING - 1);
close(f);
if (len < 0)
return -ENXIO;
@@ -978,7 +1019,7 @@ static int uuid_from_product_uuid(char *system_uuid)
system_uuid[0] = '\0';
nread = getline(&line, &len, stream);
- if (nread != UUID_SIZE) {
+ if (nread != NVME_UUID_LEN_STRING) {
ret = -ENXIO;
goto out;
}
@@ -986,8 +1027,8 @@ static int uuid_from_product_uuid(char *system_uuid)
/* The kernel is handling the byte swapping according DMTF
* SMBIOS 3.0 Section 7.2.1 System UUID */
- memcpy(system_uuid, line, UUID_SIZE - 1);
- system_uuid[UUID_SIZE - 1] = '\0';
+ memcpy(system_uuid, line, NVME_UUID_LEN_STRING - 1);
+ system_uuid[NVME_UUID_LEN_STRING - 1] = '\0';
ret = 0;
@@ -1023,16 +1064,17 @@ char *nvmf_hostnqn_generate()
{
char *hostnqn;
int ret;
- char uuid_str[UUID_SIZE];
- uuid_t uuid;
+ char uuid_str[NVME_UUID_LEN_STRING];
+ unsigned char uuid[NVME_UUID_LEN];
ret = uuid_from_dmi(uuid_str);
if (ret < 0) {
ret = uuid_from_device_tree(uuid_str);
}
if (ret < 0) {
- uuid_generate_random(uuid);
- uuid_unparse_lower(uuid, uuid_str);
+ if (nvme_uuid_random(uuid) < 0)
+ memset(uuid, 0, NVME_UUID_LEN);
+ nvme_uuid_to_string(uuid, uuid_str);
}
if (asprintf(&hostnqn, "nqn.2014-08.org.nvmexpress:uuid:%s", uuid_str) < 0)
@@ -1085,7 +1127,7 @@ static __u32 nvmf_get_tel(const char *hostsymname)
__u16 len;
/* Host ID is mandatory */
- tel += nvmf_exat_size(sizeof(uuid_t));
+ tel += nvmf_exat_size(NVME_UUID_LEN_STRING);
/* Symbolic name is optional */
len = hostsymname ? strlen(hostsymname) : 0;
@@ -1129,8 +1171,8 @@ static void nvmf_fill_die(struct nvmf_ext_die *die, struct nvme_host *h,
numexat++;
exat = die->exat;
exat->exattype = cpu_to_le16(NVMF_EXATTYPE_HOSTID);
- exat->exatlen = cpu_to_le16(nvmf_exat_len(sizeof(uuid_t)));
- uuid_parse(h->hostid, exat->exatval);
+ exat->exatlen = cpu_to_le16(nvmf_exat_len(NVME_UUID_LEN));
+ nvme_uuid_from_string(h->hostid, exat->exatval);
/* Extended Attribute for the Symbolic Name (optional) */
symname_len = h->hostsymname ? strlen(h->hostsymname) : 0;