summaryrefslogtreecommitdiffstats
path: root/fabrics.c
diff options
context:
space:
mode:
Diffstat (limited to 'fabrics.c')
-rw-r--r--fabrics.c169
1 files changed, 82 insertions, 87 deletions
diff --git a/fabrics.c b/fabrics.c
index ac240ca..2a0ad70 100644
--- a/fabrics.c
+++ b/fabrics.c
@@ -88,7 +88,7 @@ static const char *nvmf_config_file = "Use specified JSON configuration file or
static const char *nvmf_context = "execution context identification string";
#define NVMF_ARGS(n, c, ...) \
- struct argconfig_commandline_options opts[] = { \
+ struct argconfig_commandline_options n[] = { \
OPT_STRING("transport", 't', "STR", &transport, nvmf_tport), \
OPT_STRING("nqn", 'n', "STR", &subsysnqn, nvmf_nqn), \
OPT_STRING("traddr", 'a', "STR", &traddr, nvmf_traddr), \
@@ -117,30 +117,6 @@ static const char *nvmf_context = "execution context identification string";
OPT_END() \
}
-/*
- * Compare two C strings and handle NULL pointers gracefully.
- * If either of the two strings is NULL, return 0
- * to let caller ignore the compare.
- */
-static inline int strcmp0(const char *s1, const char *s2)
-{
- if (!s1 || !s2)
- return 0;
- return strcmp(s1, s2);
-}
-
-/*
- * Compare two C strings and handle NULL pointers gracefully.
- * If either of the two strings is NULL, return 0
- * to let caller ignore the compare.
- */
-static inline int strcasecmp0(const char *s1, const char *s2)
-{
- if (!s1 || !s2)
- return 0;
- return strcasecmp(s1, s2);
-}
-
static bool is_persistent_discovery_ctrl(nvme_host_t h, nvme_ctrl_t c)
{
if (nvme_host_is_pdc_enabled(h, DEFAULT_PDC_ENABLED))
@@ -149,62 +125,26 @@ static bool is_persistent_discovery_ctrl(nvme_host_t h, nvme_ctrl_t c)
return false;
}
-static bool disc_ctrl_config_match(nvme_ctrl_t c, struct tr_config *trcfg)
-{
- if (nvme_ctrl_is_discovery_ctrl(c) &&
- !strcmp0(nvme_ctrl_get_transport(c), trcfg->transport) &&
- !strcasecmp0(nvme_ctrl_get_traddr(c), trcfg->traddr) &&
- !strcmp0(nvme_ctrl_get_trsvcid(c), trcfg->trsvcid) &&
- !strcmp0(nvme_ctrl_get_host_traddr(c), trcfg->host_traddr) &&
- !strcmp0(nvme_ctrl_get_host_iface(c), trcfg->host_iface))
- return true;
-
- return false;
-}
-
-static bool ctrl_config_match(nvme_ctrl_t c, struct tr_config *trcfg)
-{
- if (!strcmp0(nvme_ctrl_get_subsysnqn(c), trcfg->subsysnqn) &&
- !strcmp0(nvme_ctrl_get_transport(c), trcfg->transport) &&
- !strcasecmp0(nvme_ctrl_get_traddr(c), trcfg->traddr) &&
- !strcmp0(nvme_ctrl_get_trsvcid(c), trcfg->trsvcid) &&
- !strcmp0(nvme_ctrl_get_host_traddr(c), trcfg->host_traddr) &&
- !strcmp0(nvme_ctrl_get_host_iface(c), trcfg->host_iface))
- return true;
-
- return false;
-}
-
-static nvme_ctrl_t __lookup_ctrl(nvme_root_t r, struct tr_config *trcfg,
- bool (*filter)(nvme_ctrl_t, struct tr_config *))
+nvme_ctrl_t lookup_ctrl(nvme_host_t h, struct tr_config *trcfg)
{
- nvme_host_t h;
nvme_subsystem_t s;
nvme_ctrl_t c;
- nvme_for_each_host(r, h) {
- nvme_for_each_subsystem(h, s) {
- nvme_subsystem_for_each_ctrl(s, c) {
- if (!(filter(c, trcfg)))
- continue;
- return c;
- }
- }
+ nvme_for_each_subsystem(h, s) {
+ c = nvme_ctrl_find(s,
+ trcfg->transport,
+ trcfg->traddr,
+ trcfg->trsvcid,
+ trcfg->subsysnqn,
+ trcfg->host_traddr,
+ trcfg->host_iface);
+ if (c)
+ return c;
}
return NULL;
}
-static nvme_ctrl_t lookup_discovery_ctrl(nvme_root_t r, struct tr_config *trcfg)
-{
- return __lookup_ctrl(r, trcfg, disc_ctrl_config_match);
-}
-
-nvme_ctrl_t lookup_ctrl(nvme_root_t r, struct tr_config *trcfg)
-{
- return __lookup_ctrl(r, trcfg, ctrl_config_match);
-}
-
static int set_discovery_kato(struct nvme_fabrics_config *cfg)
{
int tmo = cfg->keep_alive_tmo;
@@ -317,7 +257,6 @@ static int __discover(nvme_ctrl_t c, struct nvme_fabrics_config *defcfg,
struct nvmf_discovery_log *log = NULL;
nvme_subsystem_t s = nvme_ctrl_get_subsystem(c);
nvme_host_t h = nvme_subsystem_get_host(s);
- nvme_root_t r = nvme_host_get_root(h);
uint64_t numrec;
struct nvme_get_discovery_args args = {
@@ -362,7 +301,7 @@ static int __discover(nvme_ctrl_t c, struct nvme_fabrics_config *defcfg,
};
/* Already connected ? */
- cl = lookup_ctrl(r, &trcfg);
+ cl = lookup_ctrl(h, &trcfg);
if (cl && nvme_ctrl_get_name(cl))
continue;
@@ -475,9 +414,11 @@ static int discover_from_conf_file(nvme_root_t r, nvme_host_t h,
nvmf_default_config(&cfg);
- ret = flags = validate_output_format(format);
- if (ret < 0)
+ ret = validate_output_format(format, &flags);
+ if (ret < 0) {
+ nvme_show_error("Invalid output format");
return ret;
+ }
f = fopen(PATH_NVMF_DISC, "r");
if (f == NULL) {
@@ -527,7 +468,7 @@ static int discover_from_conf_file(nvme_root_t r, nvme_host_t h,
};
if (!force) {
- c = lookup_discovery_ctrl(r, &trcfg);
+ c = lookup_ctrl(h, &trcfg);
if (c) {
__discover(c, &cfg, raw, connect,
true, flags);
@@ -621,7 +562,7 @@ static int discover_from_json_config_file(nvme_root_t r, nvme_host_t h,
};
if (!force) {
- cn = lookup_discovery_ctrl(r, &trcfg);
+ cn = lookup_ctrl(h, &trcfg);
if (cn) {
__discover(cn, &cfg, raw, connect,
true, flags);
@@ -677,6 +618,43 @@ static int nvme_read_volatile_config(nvme_root_t r)
return ret;
}
+char *nvmf_hostid_from_hostnqn(const char *hostnqn)
+{
+ const char *uuid;
+
+ if (!hostnqn)
+ return NULL;
+
+ uuid = strstr(hostnqn, "uuid:");
+ if (!uuid)
+ return NULL;
+
+ return strdup(uuid + strlen("uuid:"));
+}
+
+void nvmf_check_hostid_and_hostnqn(const char *hostid, const char *hostnqn)
+{
+ char *hostid_from_file, *hostid_from_hostnqn;
+
+ if (!hostid)
+ return;
+
+ hostid_from_file = nvmf_hostid_from_file();
+ if (hostid_from_file && strcmp(hostid_from_file, hostid)) {
+ fprintf(stderr, "warning: use generated hostid instead of hostid file\n");
+ free(hostid_from_file);
+ }
+
+ if (!hostnqn)
+ return;
+
+ hostid_from_hostnqn = nvmf_hostid_from_hostnqn(hostnqn);
+ if (hostid_from_hostnqn && strcmp(hostid_from_hostnqn, hostid)) {
+ fprintf(stderr, "warning: use hostid which does not match uuid in hostnqn\n");
+ free(hostid_from_hostnqn);
+ }
+}
+
int nvmf_discover(const char *desc, int argc, char **argv, bool connect)
{
char *subsysnqn = NVME_DISC_SUBSYS_NAME;
@@ -721,9 +699,11 @@ int nvmf_discover(const char *desc, int argc, char **argv, bool connect)
if (ret)
return ret;
- ret = flags = validate_output_format(format);
- if (ret < 0)
+ ret = validate_output_format(format, &flags);
+ if (ret < 0) {
+ nvme_show_error("Invalid output format");
return ret;
+ }
if (!strcmp(config_file, "none"))
config_file = NULL;
@@ -753,10 +733,15 @@ int nvmf_discover(const char *desc, int argc, char **argv, bool connect)
hostid_arg = hostid;
if (!hostnqn)
hostnqn = hnqn = nvmf_hostnqn_from_file();
- if (!hostnqn)
+ if (!hostnqn) {
hostnqn = hnqn = nvmf_hostnqn_generate();
+ hostid = hid = nvmf_hostid_from_hostnqn(hostnqn);
+ }
if (!hostid)
hostid = hid = nvmf_hostid_from_file();
+ if (!hostid && hostnqn)
+ hostid = hid = nvmf_hostid_from_hostnqn(hostnqn);
+ nvmf_check_hostid_and_hostnqn(hostid, hostnqn);
h = nvme_lookup_host(r, hostnqn, hostid);
if (!h) {
ret = ENOMEM;
@@ -807,7 +792,8 @@ int nvmf_discover(const char *desc, int argc, char **argv, bool connect)
c = nvme_scan_ctrl(r, device);
if (c) {
/* Check if device matches command-line options */
- if (!ctrl_config_match(c, &trcfg)) {
+ if (!nvme_ctrl_config_match(c, transport, traddr, trsvcid, subsysnqn,
+ cfg.host_traddr, cfg.host_iface)) {
fprintf(stderr,
"ctrl device %s found, ignoring non matching command-line options\n",
device);
@@ -855,7 +841,7 @@ int nvmf_discover(const char *desc, int argc, char **argv, bool connect)
}
}
if (!c && !force) {
- c = lookup_discovery_ctrl(r, &trcfg);
+ c = lookup_ctrl(h, &trcfg);
if (c)
persistent = true;
}
@@ -903,7 +889,7 @@ int nvmf_connect(const char *desc, int argc, char **argv)
int ret;
enum nvme_print_flags flags;
struct nvme_fabrics_config cfg = { 0 };
- char *format = "";
+ char *format = "normal";
NVMF_ARGS(opts, cfg,
@@ -920,7 +906,11 @@ int nvmf_connect(const char *desc, int argc, char **argv)
if (ret)
return ret;
- flags = validate_output_format(format);
+ ret = validate_output_format(format, &flags);
+ if (ret < 0) {
+ nvme_show_error("Invalid output format");
+ return ret;
+ }
if (!subsysnqn) {
fprintf(stderr,
@@ -966,10 +956,15 @@ int nvmf_connect(const char *desc, int argc, char **argv)
if (!hostnqn)
hostnqn = hnqn = nvmf_hostnqn_from_file();
- if (!hostnqn)
+ if (!hostnqn) {
hostnqn = hnqn = nvmf_hostnqn_generate();
+ hostid = hid = nvmf_hostid_from_hostnqn(hostnqn);
+ }
if (!hostid)
hostid = hid = nvmf_hostid_from_file();
+ if (!hostid && hostnqn)
+ hostid = hid = nvmf_hostid_from_hostnqn(hostnqn);
+ nvmf_check_hostid_and_hostnqn(hostid, hostnqn);
h = nvme_lookup_host(r, hostnqn, hostid);
if (!h) {
errno = ENOMEM;
@@ -989,7 +984,7 @@ int nvmf_connect(const char *desc, int argc, char **argv)
.trsvcid = trsvcid,
};
- c = lookup_ctrl(r, &trcfg);
+ c = lookup_ctrl(h, &trcfg);
if (c && nvme_ctrl_get_name(c)) {
fprintf(stderr, "already connected\n");
errno = EALREADY;