diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2022-11-05 18:17:21 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2022-11-05 18:17:32 +0000 |
commit | b0dc2feab3271dbcb42df6e6d8a37138a90c44a1 (patch) | |
tree | ae02f159c125f183b2adae47fdf0e64357bf76a8 /src/nvme/fabrics.c | |
parent | Releasing debian version 1.1-2. (diff) | |
download | libnvme-b0dc2feab3271dbcb42df6e6d8a37138a90c44a1.tar.xz libnvme-b0dc2feab3271dbcb42df6e6d8a37138a90c44a1.zip |
Merging upstream version 1.2.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/nvme/fabrics.c')
-rw-r--r-- | src/nvme/fabrics.c | 146 |
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; |