diff options
Diffstat (limited to 'fabrics.c')
-rw-r--r-- | fabrics.c | 447 |
1 files changed, 222 insertions, 225 deletions
@@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) 2016 Intel Corporation. All rights reserved. * Copyright (c) 2016 HGST, a Western Digital Company. @@ -40,12 +40,14 @@ #include "common.h" #include "nvme.h" +#include "nbft.h" #include "libnvme.h" #include "nvme-print.h" -#include "nvme-print-json.h" +#include "fabrics.h" #define PATH_NVMF_DISC SYSCONFDIR "/nvme/discovery.conf" #define PATH_NVMF_CONFIG SYSCONFDIR "/nvme/config.json" +#define PATH_NVMF_RUNDIR RUNDIR "/nvme" #define MAX_DISC_ARGS 32 #define MAX_DISC_RETRIES 10 @@ -83,41 +85,37 @@ static const char *nvmf_hdr_digest = "enable transport protocol header digest (T static const char *nvmf_data_digest = "enable transport protocol data digest (TCP transport)"; static const char *nvmf_tls = "enable TLS"; static const char *nvmf_config_file = "Use specified JSON configuration file or 'none' to disable"; - -#define NVMF_OPTS(c) \ - OPT_STRING("transport", 't', "STR", &transport, nvmf_tport), \ - OPT_STRING("nqn", 'n', "STR", &subsysnqn, nvmf_nqn), \ - OPT_STRING("traddr", 'a', "STR", &traddr, nvmf_traddr), \ - OPT_STRING("trsvcid", 's', "STR", &trsvcid, nvmf_trsvcid), \ - OPT_STRING("host-traddr", 'w', "STR", &c.host_traddr, nvmf_htraddr), \ - OPT_STRING("host-iface", 'f', "STR", &c.host_iface, nvmf_hiface), \ - OPT_STRING("hostnqn", 'q', "STR", &hostnqn, nvmf_hostnqn), \ - OPT_STRING("hostid", 'I', "STR", &hostid, nvmf_hostid), \ - OPT_STRING("dhchap-secret", 'S', "STR", &hostkey, nvmf_hostkey), \ - OPT_INT("nr-io-queues", 'i', &c.nr_io_queues, nvmf_nr_io_queues), \ - OPT_INT("nr-write-queues", 'W', &c.nr_write_queues, nvmf_nr_write_queues),\ - OPT_INT("nr-poll-queues", 'P', &c.nr_poll_queues, nvmf_nr_poll_queues), \ - OPT_INT("queue-size", 'Q', &c.queue_size, nvmf_queue_size), \ - OPT_INT("keep-alive-tmo", 'k', &c.keep_alive_tmo, nvmf_keep_alive_tmo), \ - OPT_INT("reconnect-delay", 'c', &c.reconnect_delay, nvmf_reconnect_delay),\ - OPT_INT("ctrl-loss-tmo", 'l', &c.ctrl_loss_tmo, nvmf_ctrl_loss_tmo), \ - OPT_INT("tos", 'T', &c.tos, nvmf_tos), \ - OPT_INT("keyring", 0, &c.keyring, nvmf_keyring), \ - OPT_INT("tls_key", 0, &c.tls_key, nvmf_tls_key), \ - OPT_FLAG("duplicate-connect", 'D', &c.duplicate_connect, nvmf_dup_connect), \ - OPT_FLAG("disable-sqflow", 'd', &c.disable_sqflow, nvmf_disable_sqflow), \ - OPT_FLAG("hdr-digest", 'g', &c.hdr_digest, nvmf_hdr_digest), \ - OPT_FLAG("data-digest", 'G', &c.data_digest, nvmf_data_digest), \ - OPT_FLAG("tls", 0, &c.tls, nvmf_tls) \ - -struct tr_config { - const char *subsysnqn; - const char *transport; - const char *traddr; - const char *host_traddr; - const char *host_iface; - const char *trsvcid; -}; +static const char *nvmf_context = "execution context identification string"; + +#define NVMF_ARGS(n, c, ...) \ + struct argconfig_commandline_options opts[] = { \ + OPT_STRING("transport", 't', "STR", &transport, nvmf_tport), \ + OPT_STRING("nqn", 'n', "STR", &subsysnqn, nvmf_nqn), \ + OPT_STRING("traddr", 'a', "STR", &traddr, nvmf_traddr), \ + OPT_STRING("trsvcid", 's', "STR", &trsvcid, nvmf_trsvcid), \ + OPT_STRING("host-traddr", 'w', "STR", &c.host_traddr, nvmf_htraddr), \ + OPT_STRING("host-iface", 'f', "STR", &c.host_iface, nvmf_hiface), \ + OPT_STRING("hostnqn", 'q', "STR", &hostnqn, nvmf_hostnqn), \ + OPT_STRING("hostid", 'I', "STR", &hostid, nvmf_hostid), \ + OPT_STRING("dhchap-secret", 'S', "STR", &hostkey, nvmf_hostkey), \ + OPT_INT("nr-io-queues", 'i', &c.nr_io_queues, nvmf_nr_io_queues), \ + OPT_INT("nr-write-queues", 'W', &c.nr_write_queues, nvmf_nr_write_queues), \ + OPT_INT("nr-poll-queues", 'P', &c.nr_poll_queues, nvmf_nr_poll_queues), \ + OPT_INT("queue-size", 'Q', &c.queue_size, nvmf_queue_size), \ + OPT_INT("keep-alive-tmo", 'k', &c.keep_alive_tmo, nvmf_keep_alive_tmo), \ + OPT_INT("reconnect-delay", 'c', &c.reconnect_delay, nvmf_reconnect_delay), \ + OPT_INT("ctrl-loss-tmo", 'l', &c.ctrl_loss_tmo, nvmf_ctrl_loss_tmo), \ + OPT_INT("tos", 'T', &c.tos, nvmf_tos), \ + OPT_INT("keyring", 0, &c.keyring, nvmf_keyring), \ + OPT_INT("tls_key", 0, &c.tls_key, nvmf_tls_key), \ + OPT_FLAG("duplicate-connect", 'D', &c.duplicate_connect, nvmf_dup_connect), \ + OPT_FLAG("disable-sqflow", 'd', &c.disable_sqflow, nvmf_disable_sqflow), \ + OPT_FLAG("hdr-digest", 'g', &c.hdr_digest, nvmf_hdr_digest), \ + OPT_FLAG("data-digest", 'G', &c.data_digest, nvmf_data_digest), \ + OPT_FLAG("tls", 0, &c.tls, nvmf_tls), \ + __VA_ARGS__, \ + OPT_END() \ + } /* * Compare two C strings and handle NULL pointers gracefully. @@ -202,7 +200,7 @@ static nvme_ctrl_t lookup_discovery_ctrl(nvme_root_t r, struct tr_config *trcfg) return __lookup_ctrl(r, trcfg, disc_ctrl_config_match); } -static nvme_ctrl_t lookup_ctrl(nvme_root_t r, struct tr_config *trcfg) +nvme_ctrl_t lookup_ctrl(nvme_root_t r, struct tr_config *trcfg) { return __lookup_ctrl(r, trcfg, ctrl_config_match); } @@ -266,6 +264,7 @@ static nvme_ctrl_t create_discover_ctrl(nvme_root_t r, nvme_host_t h, /* Find out the name of discovery controller */ struct nvme_id_ctrl id = { 0 }; + if (nvme_ctrl_identify(c, &id)) { fprintf(stderr, "failed to identify controller, error %s\n", nvme_strerror(errno)); @@ -288,64 +287,19 @@ static nvme_ctrl_t create_discover_ctrl(nvme_root_t r, nvme_host_t h, return __create_discover_ctrl(r, h, cfg, trcfg); } -static void print_discovery_log(struct nvmf_discovery_log *log, int numrec) -{ - int i; - - printf("\nDiscovery Log Number of Records %d, " - "Generation counter %"PRIu64"\n", - numrec, le64_to_cpu(log->genctr)); - - for (i = 0; i < numrec; i++) { - struct nvmf_disc_log_entry *e = &log->entries[i]; - - printf("=====Discovery Log Entry %d======\n", i); - printf("trtype: %s\n", nvmf_trtype_str(e->trtype)); - printf("adrfam: %s\n", - strlen(e->traddr) ? - nvmf_adrfam_str(e->adrfam): ""); - printf("subtype: %s\n", nvmf_subtype_str(e->subtype)); - printf("treq: %s\n", nvmf_treq_str(e->treq)); - printf("portid: %d\n", le16_to_cpu(e->portid)); - printf("trsvcid: %s\n", e->trsvcid); - printf("subnqn: %s\n", e->subnqn); - printf("traddr: %s\n", e->traddr); - printf("eflags: %s\n", - nvmf_eflags_str(le16_to_cpu(e->eflags))); - - switch (e->trtype) { - case NVMF_TRTYPE_RDMA: - printf("rdma_prtype: %s\n", - nvmf_prtype_str(e->tsas.rdma.prtype)); - printf("rdma_qptype: %s\n", - nvmf_qptype_str(e->tsas.rdma.qptype)); - printf("rdma_cms: %s\n", - nvmf_cms_str(e->tsas.rdma.cms)); - printf("rdma_pkey: 0x%04x\n", - le16_to_cpu(e->tsas.rdma.pkey)); - break; - case NVMF_TRTYPE_TCP: - printf("sectype: %s\n", - nvmf_sectype_str(e->tsas.tcp.sectype)); - break; - } - } -} - static void save_discovery_log(char *raw, struct nvmf_discovery_log *log) { uint64_t numrec = le64_to_cpu(log->numrec); int fd, len, ret; - fd = open(raw, O_CREAT|O_RDWR|O_TRUNC, S_IRUSR|S_IWUSR); + fd = open(raw, O_CREAT | O_RDWR | O_TRUNC, 0600); if (fd < 0) { - fprintf(stderr, "failed to open %s: %s\n", - raw, strerror(errno)); + fprintf(stderr, "failed to open %s: %s\n", raw, strerror(errno)); return; } - len = sizeof(struct nvmf_discovery_log) + - numrec * sizeof(struct nvmf_disc_log_entry); + len = sizeof(struct nvmf_discovery_log) + numrec * sizeof(struct nvmf_disc_log_entry); + ret = write(fd, log, len); if (ret < 0) fprintf(stderr, "failed to write to %s: %s\n", @@ -356,11 +310,6 @@ static void save_discovery_log(char *raw, struct nvmf_discovery_log *log) close(fd); } -static void print_connect_msg(nvme_ctrl_t c) -{ - printf("device: %s\n", nvme_ctrl_get_name(c)); -} - static int __discover(nvme_ctrl_t c, struct nvme_fabrics_config *defcfg, char *raw, bool connect, bool persistent, enum nvme_print_flags flags) @@ -384,28 +333,14 @@ static int __discover(nvme_ctrl_t c, struct nvme_fabrics_config *defcfg, if (!log) { fprintf(stderr, "failed to get discovery log: %s\n", nvme_strerror(errno)); - return errno; + return -errno; } numrec = le64_to_cpu(log->numrec); if (raw) save_discovery_log(raw, log); else if (!connect) { - switch (flags) { - case NORMAL: - print_discovery_log(log, numrec); - break; - case JSON: - json_discovery_log(log, numrec); - break; - case BINARY: - d_raw((unsigned char *)log, - sizeof(struct nvmf_discovery_log) + - numrec * sizeof(struct nvmf_disc_log_entry)); - break; - default: - break; - } + nvme_show_discovery_log(log, numrec, flags); } else if (connect) { int i; @@ -446,8 +381,7 @@ static int __discover(nvme_ctrl_t c, struct nvme_fabrics_config *defcfg, if (eflags & NVMF_DISC_EFLAGS_DUPRETINFO) continue; - /* Are we supposed to keep the discovery - * controller around? */ + /* Are we supposed to keep the discovery controller around? */ disconnect = !persistent; if (strcmp(e->subnqn, NVME_DISC_SUBSYS_NAME)) { @@ -497,18 +431,16 @@ static int __discover(nvme_ctrl_t c, struct nvme_fabrics_config *defcfg, } static char *get_default_trsvcid(const char *transport, - bool discovery_ctrl) + bool discovery_ctrl) { if (!transport) return NULL; if (!strcmp(transport, "tcp")) { - if (discovery_ctrl) { + if (discovery_ctrl) /* Default port for NVMe/TCP discovery controllers */ return stringify(NVME_DISC_IP_PORT); - } else { - /* Default port for NVMe/TCP io controllers */ - return stringify(NVME_RDMA_IP_PORT); - } + /* Default port for NVMe/TCP io controllers */ + return stringify(NVME_RDMA_IP_PORT); } else if (!strcmp(transport, "rdma")) { /* Default port for NVMe/RDMA controllers */ return stringify(NVME_RDMA_IP_PORT); @@ -533,16 +465,13 @@ static int discover_from_conf_file(nvme_root_t r, nvme_host_t h, struct nvme_fabrics_config cfg; bool force = false; - OPT_ARGS(opts) = { - NVMF_OPTS(cfg), - OPT_FMT("output-format", 'o', &format, output_format), - OPT_FILE("raw", 'r', &raw, "save raw output to file"), - OPT_FLAG("persistent", 'p', &persistent, "persistent discovery connection"), - OPT_FLAG("quiet", 'S', &quiet, "suppress already connected errors"), - OPT_INCR("verbose", 'v', &verbose, "Increase logging verbosity"), - OPT_FLAG("force", 0, &force, "Force persistent discovery controller creation"), - OPT_END() - }; + NVMF_ARGS(opts, cfg, + OPT_FMT("output-format", 'o', &format, output_format), + OPT_FILE("raw", 'r', &raw, "save raw output to file"), + OPT_FLAG("persistent", 'p', &persistent, "persistent discovery connection"), + OPT_FLAG("quiet", 'S', &quiet, "suppress already connected errors"), + OPT_INCR("verbose", 'v', &verbose, "Increase logging verbosity"), + OPT_FLAG("force", 0, &force, "Force persistent discovery controller creation")); nvmf_default_config(&cfg); @@ -630,7 +559,7 @@ static int discover_from_json_config_file(nvme_root_t r, nvme_host_t h, enum nvme_print_flags flags, bool force) { - const char *transport, *traddr, *trsvcid, *subsysnqn; + const char *transport, *traddr, *host_traddr, *host_iface, *trsvcid, *subsysnqn; nvme_subsystem_t s; nvme_ctrl_t c, cn; struct nvme_fabrics_config cfg; @@ -640,6 +569,8 @@ static int discover_from_json_config_file(nvme_root_t r, nvme_host_t h, nvme_subsystem_for_each_ctrl(s, c) { transport = nvme_ctrl_get_transport(c); traddr = nvme_ctrl_get_traddr(c); + host_traddr = nvme_ctrl_get_host_traddr(c); + host_iface = nvme_ctrl_get_host_iface(c); if (!transport && !traddr) continue; @@ -650,6 +581,22 @@ static int discover_from_json_config_file(nvme_root_t r, nvme_host_t h, strcmp(transport, "fc")) continue; + /* ignore if no host_traddr for fc */ + if (!strcmp(transport, "fc")) { + if (!host_traddr) { + fprintf(stderr, "host_traddr required for fc\n"); + continue; + } + } + + /* ignore if host_iface set for any transport other than tcp */ + if (!strcmp(transport, "rdma") || !strcmp(transport, "fc")) { + if (host_iface) { + fprintf(stderr, "host_iface not permitted for rdma or fc\n"); + continue; + } + } + trsvcid = nvme_ctrl_get_trsvcid(c); if (!trsvcid || !strcmp(trsvcid, "")) trsvcid = get_default_trsvcid(transport, true); @@ -668,8 +615,8 @@ static int discover_from_json_config_file(nvme_root_t r, nvme_host_t h, .subsysnqn = subsysnqn, .transport = transport, .traddr = traddr, - .host_traddr = cfg.host_traddr, - .host_iface = cfg.host_iface, + .host_traddr = host_traddr, + .host_iface = host_iface, .trsvcid = trsvcid, }; @@ -696,13 +643,49 @@ static int discover_from_json_config_file(nvme_root_t r, nvme_host_t h, return ret; } +static int nvme_read_volatile_config(nvme_root_t r) +{ + char *filename, *ext; + struct dirent *dir; + DIR *d; + int ret = -ENOENT; + + d = opendir(PATH_NVMF_RUNDIR); + if (!d) + return -ENOTDIR; + + while ((dir = readdir(d))) { + if (dir->d_type != DT_REG) + continue; + + ext = strchr(dir->d_name, '.'); + if (!ext || strcmp("json", ext + 1)) + continue; + + if (asprintf(&filename, "%s/%s", PATH_NVMF_RUNDIR, dir->d_name) < 0) { + ret = -ENOMEM; + break; + } + + if (nvme_read_config(r, filename)) + ret = 0; + + free(filename); + } + closedir(d); + + return ret; +} + int nvmf_discover(const char *desc, int argc, char **argv, bool connect) { char *subsysnqn = NVME_DISC_SUBSYS_NAME; char *hostnqn = NULL, *hostid = NULL, *hostkey = NULL; + char *hostnqn_arg, *hostid_arg; char *transport = NULL, *traddr = NULL, *trsvcid = NULL; char *config_file = PATH_NVMF_CONFIG; char *hnqn = NULL, *hid = NULL; + char *context = NULL; enum nvme_print_flags flags; nvme_root_t r; nvme_host_t h; @@ -714,20 +697,23 @@ int nvmf_discover(const char *desc, int argc, char **argv, bool connect) char *device = NULL; bool force = false; bool json_config = false; - - OPT_ARGS(opts) = { - OPT_STRING("device", 'd', "DEV", &device, "use existing discovery controller device"), - NVMF_OPTS(cfg), - OPT_FMT("output-format", 'o', &format, output_format), - OPT_FILE("raw", 'r', &raw, "save raw output to file"), - OPT_FLAG("persistent", 'p', &persistent, "persistent discovery connection"), - OPT_FLAG("quiet", 'S', &quiet, "suppress already connected errors"), - OPT_STRING("config", 'J', "FILE", &config_file, nvmf_config_file), - OPT_INCR("verbose", 'v', &verbose, "Increase logging verbosity"), - OPT_FLAG("dump-config", 'O', &dump_config, "Dump configuration file to stdout"), - OPT_FLAG("force", 0, &force, "Force persistent discovery controller creation"), - OPT_END() - }; + bool nbft = false, nonbft = false; + char *nbft_path = NBFT_SYSFS_PATH; + + NVMF_ARGS(opts, cfg, + OPT_STRING("device", 'd', "DEV", &device, "use existing discovery controller device"), + OPT_FMT("output-format", 'o', &format, output_format), + OPT_FILE("raw", 'r', &raw, "save raw output to file"), + OPT_FLAG("persistent", 'p', &persistent, "persistent discovery connection"), + OPT_FLAG("quiet", 'S', &quiet, "suppress already connected errors"), + OPT_STRING("config", 'J', "FILE", &config_file, nvmf_config_file), + OPT_INCR("verbose", 'v', &verbose, "Increase logging verbosity"), + OPT_FLAG("dump-config", 'O', &dump_config, "Dump configuration file to stdout"), + OPT_FLAG("force", 0, &force, "Force persistent discovery controller creation"), + OPT_FLAG("nbft", 0, &nbft, "Only look at NBFT tables"), + OPT_FLAG("no-nbft", 0, &nonbft, "Do not look at NBFT tables"), + OPT_STRING("nbft-path", 0, "STR", &nbft_path, "user-defined path for NBFT tables"), + OPT_STRING("context", 0, "STR", &context, nvmf_context)); nvmf_default_config(&cfg); @@ -748,6 +734,8 @@ int nvmf_discover(const char *desc, int argc, char **argv, bool connect) nvme_strerror(errno)); return -errno; } + if (context) + nvme_root_set_application(r, context); ret = nvme_scan_topology(r, NULL, NULL); if (ret < 0) { fprintf(stderr, "Failed to scan topology: %s\n", @@ -755,9 +743,14 @@ int nvmf_discover(const char *desc, int argc, char **argv, bool connect) nvme_free_tree(r); return ret; } + if (!nvme_read_config(r, config_file)) json_config = true; + if (!nvme_read_volatile_config(r)) + json_config = true; + hostnqn_arg = hostnqn; + hostid_arg = hostid; if (!hostnqn) hostnqn = hnqn = nvmf_hostnqn_from_file(); if (!hostnqn) @@ -779,6 +772,14 @@ int nvmf_discover(const char *desc, int argc, char **argv, bool connect) nvme_host_set_dhchap_key(h, hostkey); if (!device && !transport && !traddr) { + if (!nonbft) + discover_from_nbft(r, hostnqn_arg, hostid_arg, + hostnqn, hostid, desc, connect, + &cfg, nbft_path, flags, verbose); + + if (nbft) + goto out_free; + if (json_config) ret = discover_from_json_config_file(r, h, desc, connect, &cfg, @@ -808,15 +809,13 @@ int nvmf_discover(const char *desc, int argc, char **argv, bool connect) /* Check if device matches command-line options */ if (!ctrl_config_match(c, &trcfg)) { fprintf(stderr, - "ctrl device %s found, ignoring " - "non matching command-line options\n", - device); + "ctrl device %s found, ignoring non matching command-line options\n", + device); } if (!nvme_ctrl_is_discovery_ctrl(c)) { fprintf(stderr, - "ctrl device %s found, ignoring " - "non discovery controller\n", + "ctrl device %s found, ignoring non discovery controller\n", device); nvme_free_ctrl(c); @@ -863,10 +862,11 @@ int nvmf_discover(const char *desc, int argc, char **argv, bool connect) if (!c) { /* No device or non-matching device, create a new controller */ c = create_discover_ctrl(r, h, &cfg, &trcfg); - if (!c) { - fprintf(stderr, - "failed to add controller, error %s\n", - nvme_strerror(errno)); + if (!c) { + if (errno != ENVME_CONNECT_IGNORED) + fprintf(stderr, + "failed to add controller, error %s\n", + nvme_strerror(errno)); ret = errno; goto out_free; } @@ -895,24 +895,24 @@ int nvmf_connect(const char *desc, int argc, char **argv) char *hostkey = NULL, *ctrlkey = NULL; char *hnqn = NULL, *hid = NULL; char *config_file = PATH_NVMF_CONFIG; + char *context = NULL; unsigned int verbose = 0; nvme_root_t r; nvme_host_t h; nvme_ctrl_t c; int ret; - struct nvme_fabrics_config cfg; - enum nvme_print_flags flags = -1; + enum nvme_print_flags flags; + struct nvme_fabrics_config cfg = { 0 }; char *format = ""; - OPT_ARGS(opts) = { - NVMF_OPTS(cfg), - OPT_STRING("dhchap-ctrl-secret", 'C', "STR", &ctrlkey, nvmf_ctrlkey), - OPT_STRING("config", 'J', "FILE", &config_file, nvmf_config_file), - OPT_INCR("verbose", 'v', &verbose, "Increase logging verbosity"), - OPT_FLAG("dump-config", 'O', &dump_config, "Dump JSON configuration to stdout"), - OPT_FMT("output-format", 'o', &format, "Output format: normal|json"), - OPT_END() - }; + + NVMF_ARGS(opts, cfg, + OPT_STRING("dhchap-ctrl-secret", 'C', "STR", &ctrlkey, nvmf_ctrlkey), + OPT_STRING("config", 'J', "FILE", &config_file, nvmf_config_file), + OPT_INCR("verbose", 'v', &verbose, "Increase logging verbosity"), + OPT_FLAG("dump-config", 'O', &dump_config, "Dump JSON configuration to stdout"), + OPT_FMT("output-format", 'o', &format, "Output format: normal|json"), + OPT_STRING("context", 0, "STR", &context, nvmf_context)); nvmf_default_config(&cfg); @@ -920,25 +920,18 @@ int nvmf_connect(const char *desc, int argc, char **argv) if (ret) return ret; - if (!strcmp(format, "")) - flags = -1; - else if (!strcmp(format, "normal")) - flags = NORMAL; - else if (!strcmp(format, "json")) - flags = JSON; - else - return EINVAL; + flags = validate_output_format(format); if (!subsysnqn) { fprintf(stderr, "required argument [--nqn | -n] not specified\n"); - return EINVAL; + return -EINVAL; } if (!transport) { fprintf(stderr, "required argument [--transport | -t] not specified\n"); - return EINVAL; + return -EINVAL; } if (strcmp(transport, "loop")) { @@ -946,7 +939,7 @@ int nvmf_connect(const char *desc, int argc, char **argv) fprintf(stderr, "required argument [--traddr | -a] not specified for transport %s\n", transport); - return EINVAL; + return -EINVAL; } } @@ -959,6 +952,8 @@ int nvmf_connect(const char *desc, int argc, char **argv) nvme_strerror(errno)); return -errno; } + if (context) + nvme_root_set_application(r, context); ret = nvme_scan_topology(r, NULL, NULL); if (ret < 0) { fprintf(stderr, "Failed to scan topology: %s\n", @@ -967,6 +962,7 @@ int nvmf_connect(const char *desc, int argc, char **argv) return ret; } nvme_read_config(r, config_file); + nvme_read_volatile_config(r); if (!hostnqn) hostnqn = hnqn = nvmf_hostnqn_from_file(); @@ -1016,10 +1012,8 @@ int nvmf_connect(const char *desc, int argc, char **argv) nvme_strerror(errno)); else { errno = 0; - if (flags == NORMAL) - print_connect_msg(c); - else if (flags == JSON) - json_connect_msg(c); + if (flags != -EINVAL) + nvme_show_connect_msg(c, flags); } out_free: @@ -1028,7 +1022,7 @@ out_free: if (dump_config) nvme_dump_config(r); nvme_free_tree(r); - return errno; + return -errno; } static nvme_ctrl_t lookup_nvme_ctrl(nvme_root_t r, const char *name) @@ -1048,12 +1042,36 @@ static nvme_ctrl_t lookup_nvme_ctrl(nvme_root_t r, const char *name) return NULL; } +static void nvmf_disconnect_nqn(nvme_root_t r, char *nqn) +{ + int i = 0; + char *n = nqn; + char *p; + nvme_host_t h; + nvme_subsystem_t s; + nvme_ctrl_t c; + + while ((p = strsep(&n, ",")) != NULL) { + if (!strlen(p)) + continue; + nvme_for_each_host(r, h) { + nvme_for_each_subsystem(h, s) { + if (strcmp(nvme_subsystem_get_nqn(s), p)) + continue; + nvme_subsystem_for_each_ctrl(s, c) { + if (!nvme_disconnect_ctrl(c)) + i++; + } + } + } + } + printf("NQN:%s disconnected %d controller(s)\n", nqn, i); +} + int nvmf_disconnect(const char *desc, int argc, char **argv) { const char *device = "nvme device handle"; nvme_root_t r; - nvme_host_t h; - nvme_subsystem_t s; nvme_ctrl_t c; char *p; int ret; @@ -1067,9 +1085,9 @@ int nvmf_disconnect(const char *desc, int argc, char **argv) struct config cfg = { 0 }; OPT_ARGS(opts) = { - OPT_STRING("nqn", 'n', "NAME", &cfg.nqn, nvmf_nqn), - OPT_STRING("device", 'd', "DEV", &cfg.device, device), - OPT_INCR("verbose", 'v', &cfg.verbose, "Increase logging verbosity"), + OPT_STRING("nqn", 'n', "NAME", &cfg.nqn, nvmf_nqn), + OPT_STRING("device", 'd', "DEV", &cfg.device, device), + OPT_INCR("verbose", 'v', &cfg.verbose, "Increase logging verbosity"), OPT_END() }; @@ -1080,7 +1098,7 @@ int nvmf_disconnect(const char *desc, int argc, char **argv) if (!cfg.nqn && !cfg.device) { fprintf(stderr, "Neither device name [--device | -d] nor NQN [--nqn | -n] provided\n"); - return EINVAL; + return -EINVAL; } r = nvme_create_root(stderr, map_log_level(cfg.verbose, false)); @@ -1097,26 +1115,8 @@ int nvmf_disconnect(const char *desc, int argc, char **argv) return ret; } - if (cfg.nqn) { - int i = 0; - char *n = cfg.nqn; - - while ((p = strsep(&n, ",")) != NULL) { - if (!strlen(p)) - continue; - nvme_for_each_host(r, h) { - nvme_for_each_subsystem(h, s) { - if (strcmp(nvme_subsystem_get_nqn(s), p)) - continue; - nvme_subsystem_for_each_ctrl(s, c) { - if (!nvme_disconnect_ctrl(c)) - i++; - } - } - } - } - printf("NQN:%s disconnected %d controller(s)\n", cfg.nqn, i); - } + if (cfg.nqn) + nvmf_disconnect_nqn(r, cfg.nqn); if (cfg.device) { char *d; @@ -1130,7 +1130,7 @@ int nvmf_disconnect(const char *desc, int argc, char **argv) fprintf(stderr, "Did not find device %s\n", p); nvme_free_tree(r); - return errno; + return -errno; } ret = nvme_disconnect_ctrl(c); if (ret) @@ -1219,17 +1219,14 @@ int nvmf_config(const char *desc, int argc, char **argv) struct nvme_fabrics_config cfg; bool scan_tree = false, modify_config = false, update_config = false; - OPT_ARGS(opts) = { - NVMF_OPTS(cfg), - OPT_STRING("dhchap-ctrl-secret", 'C', "STR", &ctrlkey, nvmf_ctrlkey), - OPT_STRING("config", 'J', "FILE", &config_file, nvmf_config_file), - OPT_INCR("verbose", 'v', &verbose, "Increase logging verbosity"), - OPT_FLAG("scan", 'R', &scan_tree, "Scan current NVMeoF topology"), - OPT_FLAG("modify", 'M', &modify_config, "Modify JSON configuration file"), - OPT_FLAG("dump", 'O', &dump_config, "Dump JSON configuration to stdout"), - OPT_FLAG("update", 'U', &update_config, "Update JSON configuration file"), - OPT_END() - }; + NVMF_ARGS(opts, cfg, + OPT_STRING("dhchap-ctrl-secret", 'C', "STR", &ctrlkey, nvmf_ctrlkey), + OPT_STRING("config", 'J', "FILE", &config_file, nvmf_config_file), + OPT_INCR("verbose", 'v', &verbose, "Increase logging verbosity"), + OPT_FLAG("scan", 'R', &scan_tree, "Scan current NVMeoF topology"), + OPT_FLAG("modify", 'M', &modify_config, "Modify JSON configuration file"), + OPT_FLAG("dump", 'O', &dump_config, "Dump JSON configuration to stdout"), + OPT_FLAG("update", 'U', &update_config, "Update JSON configuration file")); nvmf_default_config(&cfg); @@ -1271,7 +1268,7 @@ int nvmf_config(const char *desc, int argc, char **argv) if (!transport) { fprintf(stderr, "required argument [--transport | -t] needed with --modify\n"); - return EINVAL; + return -EINVAL; } if (!hostnqn) @@ -1317,16 +1314,16 @@ out: if (hnqn) free(hnqn); nvme_free_tree(r); - return errno; + return -errno; } -static void dim_operation(nvme_ctrl_t c, enum nvmf_dim_tas tas, const char * name) +static void dim_operation(nvme_ctrl_t c, enum nvmf_dim_tas tas, const char *name) { static const char * const task[] = { [NVMF_DIM_TAS_REGISTER] = "register", [NVMF_DIM_TAS_DEREGISTER] = "deregister", }; - const char * t; + const char *t; int status; __u32 result; @@ -1373,13 +1370,13 @@ int nvmf_dim(const char *desc, int argc, char **argv) if (!cfg.nqn && !cfg.device) { fprintf(stderr, "Neither device name [--device | -d] nor NQN [--nqn | -n] provided\n"); - return EINVAL; + return -EINVAL; } if (!cfg.tas) { fprintf(stderr, "Task [--task | -t] must be specified\n"); - return EINVAL; + return -EINVAL; } /* Allow partial name (e.g. "reg" for "register" */ @@ -1389,7 +1386,7 @@ int nvmf_dim(const char *desc, int argc, char **argv) tas = NVMF_DIM_TAS_DEREGISTER; } else { fprintf(stderr, "Invalid --task: %s\n", cfg.tas); - return EINVAL; + return -EINVAL; } r = nvme_create_root(stderr, map_log_level(cfg.verbose, false)); @@ -1438,7 +1435,7 @@ int nvmf_dim(const char *desc, int argc, char **argv) "Did not find device %s: %s\n", p, nvme_strerror(errno)); nvme_free_tree(r); - return errno; + return -errno; } dim_operation(c, tas, p); } |