summaryrefslogtreecommitdiffstats
path: root/fabrics.c
diff options
context:
space:
mode:
Diffstat (limited to 'fabrics.c')
-rw-r--r--fabrics.c451
1 files changed, 222 insertions, 229 deletions
diff --git a/fabrics.c b/fabrics.c
index 871c20e..db1b7cb 100644
--- a/fabrics.c
+++ b/fabrics.c
@@ -45,6 +45,7 @@
#include "nbft.h"
#include "nvme-print.h"
#include "fabrics.h"
+#include "util/cleanup.h"
#include "util/logging.h"
#define PATH_NVMF_DISC SYSCONFDIR "/nvme/discovery.conf"
@@ -114,7 +115,7 @@ static const char *nvmf_context = "execution context identification string";
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("disable-sqflow", 0, &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), \
@@ -195,9 +196,9 @@ static nvme_ctrl_t __create_discover_ctrl(nvme_root_t r, nvme_host_t h,
return c;
}
-static nvme_ctrl_t create_discover_ctrl(nvme_root_t r, nvme_host_t h,
- struct nvme_fabrics_config *cfg,
- struct tr_config *trcfg)
+nvme_ctrl_t nvmf_create_discover_ctrl(nvme_root_t r, nvme_host_t h,
+ struct nvme_fabrics_config *cfg,
+ struct tr_config *trcfg)
{
_cleanup_free_ struct nvme_id_ctrl *id = NULL;
nvme_ctrl_t c;
@@ -261,7 +262,7 @@ static void save_discovery_log(char *raw, struct nvmf_discovery_log *log)
static int __discover(nvme_ctrl_t c, struct nvme_fabrics_config *defcfg,
char *raw, bool connect, bool persistent,
- enum nvme_print_flags flags)
+ nvme_print_flags_t flags)
{
struct nvmf_discovery_log *log = NULL;
nvme_subsystem_t s = nvme_ctrl_get_subsystem(c);
@@ -365,11 +366,15 @@ static int __discover(nvme_ctrl_t c, struct nvme_fabrics_config *defcfg,
nvme_free_ctrl(child);
}
} else if (errno == ENVME_CONNECT_ALREADY && !quiet) {
- char *traddr = log->entries[i].traddr;
+ const char *subnqn = log->entries[i].subnqn;
+ const char *trtype = nvmf_trtype_str(log->entries[i].trtype);
+ const char *traddr = log->entries[i].traddr;
+ const char *trsvcid = log->entries[i].trsvcid;
fprintf(stderr,
- "traddr=%s is already connected\n",
- traddr);
+ "already connected to hostnqn=%s,nqn=%s,transport=%s,traddr=%s,trsvcid=%s\n",
+ nvme_host_get_hostnqn(h), subnqn,
+ trtype, traddr, trsvcid);
}
}
}
@@ -378,8 +383,7 @@ static int __discover(nvme_ctrl_t c, struct nvme_fabrics_config *defcfg,
return 0;
}
-static char *get_default_trsvcid(const char *transport,
- bool discovery_ctrl)
+char *nvmf_get_default_trsvcid(const char *transport, bool discovery_ctrl)
{
if (!transport)
return NULL;
@@ -407,8 +411,8 @@ static int discover_from_conf_file(nvme_root_t r, nvme_host_t h,
char *ptr, **argv, *p, line[4096];
int argc, ret = 0;
unsigned int verbose = 0;
- FILE *f;
- enum nvme_print_flags flags;
+ _cleanup_file_ FILE *f = NULL;
+ nvme_print_flags_t flags;
char *format = "normal";
struct nvme_fabrics_config cfg;
bool force = false;
@@ -417,7 +421,7 @@ static int discover_from_conf_file(nvme_root_t r, nvme_host_t h,
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_FLAG("quiet", 0, &quiet, "suppress already connected errors"),
OPT_INCR("verbose", 'v', &verbose, "Increase logging verbosity"),
OPT_FLAG("force", 0, &force, "Force persistent discovery controller creation"));
@@ -432,15 +436,12 @@ static int discover_from_conf_file(nvme_root_t r, nvme_host_t h,
f = fopen(PATH_NVMF_DISC, "r");
if (f == NULL) {
fprintf(stderr, "No params given and no %s\n", PATH_NVMF_DISC);
- errno = ENOENT;
- return -1;
+ return -ENOENT;
}
argv = calloc(MAX_DISC_ARGS, sizeof(char *));
- if (!argv) {
- ret = -1;
- goto out;
- }
+ if (!argv)
+ return -1;
argv[0] = "discover";
memset(line, 0, sizeof(line));
@@ -465,7 +466,7 @@ static int discover_from_conf_file(nvme_root_t r, nvme_host_t h,
goto next;
if (!trsvcid)
- trsvcid = get_default_trsvcid(transport, true);
+ trsvcid = nvmf_get_default_trsvcid(transport, true);
struct tr_config trcfg = {
.subsysnqn = subsysnqn,
@@ -485,7 +486,7 @@ static int discover_from_conf_file(nvme_root_t r, nvme_host_t h,
}
}
- c = create_discover_ctrl(r, h, &cfg, &trcfg);
+ c = nvmf_create_discover_ctrl(r, h, &cfg, &trcfg);
if (!c)
goto next;
@@ -498,95 +499,134 @@ next:
memset(&cfg, 0, sizeof(cfg));
}
free(argv);
-out:
- fclose(f);
+
return ret;
}
-static int discover_from_json_config_file(nvme_root_t r, nvme_host_t h,
- const char *desc, bool connect,
+static int _discover_from_json_config_file(nvme_root_t r, nvme_host_t h,
+ nvme_ctrl_t c, const char *desc, bool connect,
const struct nvme_fabrics_config *defcfg,
- enum nvme_print_flags flags,
+ nvme_print_flags_t flags,
bool force)
{
- const char *transport, *traddr, *host_traddr, *host_iface, *trsvcid, *subsysnqn;
- nvme_subsystem_t s;
- nvme_ctrl_t c, cn;
+ const char *transport, *traddr, *host_traddr;
+ const char *host_iface, *trsvcid, *subsysnqn;
struct nvme_fabrics_config cfg;
+ nvme_ctrl_t cn;
int ret = 0;
- nvme_for_each_subsystem(h, s) {
- 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);
+ 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)
+ return 0;
+
+ /* ignore none fabric transports */
+ if (strcmp(transport, "tcp") &&
+ strcmp(transport, "rdma") &&
+ strcmp(transport, "fc"))
+ return 0;
+
+ /* ignore if no host_traddr for fc */
+ if (!strcmp(transport, "fc")) {
+ if (!host_traddr) {
+ fprintf(stderr, "host_traddr required for fc\n");
+ return 0;
+ }
+ }
- if (!transport && !traddr)
- 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");
+ return 0;
+ }
+ }
- /* ignore none fabric transports */
- if (strcmp(transport, "tcp") &&
- strcmp(transport, "rdma") &&
- strcmp(transport, "fc"))
- continue;
+ trsvcid = nvme_ctrl_get_trsvcid(c);
+ if (!trsvcid || !strcmp(trsvcid, ""))
+ trsvcid = nvmf_get_default_trsvcid(transport, true);
- /* ignore if no host_traddr for fc */
- if (!strcmp(transport, "fc")) {
- if (!host_traddr) {
- fprintf(stderr, "host_traddr required for fc\n");
- continue;
- }
- }
+ if (force)
+ subsysnqn = nvme_ctrl_get_subsysnqn(c);
+ else
+ subsysnqn = NVME_DISC_SUBSYS_NAME;
- /* 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;
- }
- }
+ if (nvme_ctrl_is_persistent(c))
+ persistent = true;
- trsvcid = nvme_ctrl_get_trsvcid(c);
- if (!trsvcid || !strcmp(trsvcid, ""))
- trsvcid = get_default_trsvcid(transport, true);
+ memcpy(&cfg, defcfg, sizeof(cfg));
- if (force)
- subsysnqn = nvme_ctrl_get_subsysnqn(c);
- else
- subsysnqn = NVME_DISC_SUBSYS_NAME;
+ struct tr_config trcfg = {
+ .subsysnqn = subsysnqn,
+ .transport = transport,
+ .traddr = traddr,
+ .host_traddr = host_traddr,
+ .host_iface = host_iface,
+ .trsvcid = trsvcid,
+ };
- if (nvme_ctrl_is_persistent(c))
- persistent = true;
+ if (!force) {
+ cn = lookup_ctrl(h, &trcfg);
+ if (cn) {
+ __discover(cn, &cfg, raw, connect, true, flags);
+ return 0;
+ }
+ }
- memcpy(&cfg, defcfg, sizeof(cfg));
+ cn = nvmf_create_discover_ctrl(r, h, &cfg, &trcfg);
+ if (!cn)
+ return 0;
- struct tr_config trcfg = {
- .subsysnqn = subsysnqn,
- .transport = transport,
- .traddr = traddr,
- .host_traddr = host_traddr,
- .host_iface = host_iface,
- .trsvcid = trsvcid,
- };
+ __discover(cn, &cfg, raw, connect, persistent, flags);
+ if (!(persistent || is_persistent_discovery_ctrl(h, cn)))
+ ret = nvme_disconnect_ctrl(cn);
+ nvme_free_ctrl(cn);
- if (!force) {
- cn = lookup_ctrl(h, &trcfg);
- if (cn) {
- __discover(cn, &cfg, raw, connect,
- true, flags);
- continue;
- }
- }
+ return ret;
+}
+
+static int discover_from_json_config_file(nvme_root_t r, const char *hostnqn,
+ const char *hostid, const char *desc,
+ bool connect,
+ const struct nvme_fabrics_config *defcfg,
+ nvme_print_flags_t flags,
+ bool force)
+{
+ const char *hnqn, *hid;
+ nvme_host_t h;
+ nvme_subsystem_t s;
+ nvme_ctrl_t c;
+ int ret = 0, err;
- cn = create_discover_ctrl(r, h, &cfg, &trcfg);
- if (!cn)
+ nvme_for_each_host(r, h) {
+ nvme_for_each_subsystem(h, s) {
+ hnqn = nvme_host_get_hostnqn(h);
+ if (hostnqn && hnqn && strcmp(hostnqn, hnqn))
+ continue;
+ hid = nvme_host_get_hostid(h);
+ if (hostid && hid && strcmp(hostid, hid))
continue;
- __discover(cn, &cfg, raw, connect, persistent, flags);
- if (!(persistent || is_persistent_discovery_ctrl(h, cn)))
- ret = nvme_disconnect_ctrl(cn);
- nvme_free_ctrl(cn);
+ nvme_subsystem_for_each_ctrl(s, c) {
+ err = _discover_from_json_config_file(
+ r, h, c, desc, connect, defcfg,
+ flags, force);
+
+ if (err) {
+ fprintf(stderr,
+ "failed to connect to hostnqn=%s,nqn=%s,%s\n",
+ nvme_host_get_hostnqn(h),
+ nvme_subsystem_get_name(s),
+ nvme_ctrl_get_address(c));
+
+ if (!ret)
+ ret = err;
+ }
+ }
}
}
@@ -627,57 +667,26 @@ static int nvme_read_volatile_config(nvme_root_t r)
return ret;
}
-char *nvmf_hostid_from_hostnqn(const char *hostnqn)
+static int nvme_read_config_checked(nvme_root_t r, const char *filename)
{
- 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, unsigned int verbose)
-{
- _cleanup_free_ char *hostid_from_file = NULL;
- _cleanup_free_ char *hostid_from_hostnqn = NULL;
-
- if (!hostid)
- return;
-
- hostid_from_file = nvmf_hostid_from_file();
- if (hostid_from_file && strcmp(hostid_from_file, hostid)) {
- if (verbose)
- fprintf(stderr,
- "warning: use generated hostid instead of hostid file\n");
- }
-
- if (!hostnqn)
- return;
-
- hostid_from_hostnqn = nvmf_hostid_from_hostnqn(hostnqn);
- if (hostid_from_hostnqn && strcmp(hostid_from_hostnqn, hostid)) {
- if (verbose)
- fprintf(stderr,
- "warning: use hostid which does not match uuid in hostnqn\n");
- }
+ if (!access(filename, F_OK))
+ return -ENOENT;
+ if (nvme_read_config(r, filename))
+ return -errno;
+ return 0;
}
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;
+ _cleanup_free_ char *hnqn = NULL;
+ _cleanup_free_ char *hid = NULL;
char *context = NULL;
- enum nvme_print_flags flags;
- nvme_root_t r;
+ nvme_print_flags_t flags;
+ _cleanup_nvme_root_ nvme_root_t r = NULL;
nvme_host_t h;
nvme_ctrl_t c = NULL;
unsigned int verbose = 0;
@@ -695,7 +704,7 @@ int nvmf_discover(const char *desc, int argc, char **argv, bool connect)
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_FLAG("quiet", 0, &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"),
@@ -730,38 +739,30 @@ int nvmf_discover(const char *desc, int argc, char **argv, bool connect)
}
if (context)
nvme_root_set_application(r, context);
- ret = nvme_scan_topology(r, NULL, NULL);
- if (ret < 0) {
- if (errno != ENOENT)
- fprintf(stderr, "Failed to scan topology: %s\n",
- nvme_strerror(errno));
- nvme_free_tree(r);
- return ret;
- }
- if (!nvme_read_config(r, config_file))
+ if (!nvme_read_config_checked(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) {
- hostnqn = hnqn = nvmf_hostnqn_generate();
- hostid = hid = nvmf_hostid_from_hostnqn(hostnqn);
+ nvme_root_skip_namespaces(r);
+ ret = nvme_scan_topology(r, NULL, NULL);
+ if (ret < 0) {
+ fprintf(stderr, "Failed to scan topology: %s\n",
+ nvme_strerror(errno));
+ return ret;
}
- 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, verbose);
- h = nvme_lookup_host(r, hostnqn, hostid);
+
+ ret = nvme_host_get_ids(r, hostnqn, hostid, &hnqn, &hid);
+ if (ret < 0)
+ return -errno;
+
+ h = nvme_lookup_host(r, hnqn, hid);
if (!h) {
ret = ENOMEM;
goto out_free;
}
+
if (device) {
if (!strcmp(device, "none"))
device = NULL;
@@ -773,16 +774,16 @@ int nvmf_discover(const char *desc, int argc, char **argv, bool connect)
if (!device && !transport && !traddr) {
if (!nonbft)
- discover_from_nbft(r, hostnqn_arg, hostid_arg,
- hostnqn, hostid, desc, connect,
+ discover_from_nbft(r, hostnqn, hostid,
+ hnqn, hid, 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,
+ ret = discover_from_json_config_file(r, hostnqn, hostid,
+ desc, connect, &cfg,
flags, force);
if (ret || access(PATH_NVMF_DISC, F_OK))
goto out_free;
@@ -792,7 +793,7 @@ int nvmf_discover(const char *desc, int argc, char **argv, bool connect)
}
if (!trsvcid)
- trsvcid = get_default_trsvcid(transport, true);
+ trsvcid = nvmf_get_default_trsvcid(transport, true);
struct tr_config trcfg = {
.subsysnqn = subsysnqn,
@@ -862,7 +863,7 @@ 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);
+ c = nvmf_create_discover_ctrl(r, h, &cfg, &trcfg);
if (!c) {
if (errno != ENVME_CONNECT_IGNORED)
fprintf(stderr,
@@ -879,11 +880,8 @@ int nvmf_discover(const char *desc, int argc, char **argv, bool connect)
nvme_free_ctrl(c);
out_free:
- free(hnqn);
- free(hid);
if (dump_config)
nvme_dump_config(r);
- nvme_free_tree(r);
return ret;
}
@@ -894,15 +892,16 @@ int nvmf_connect(const char *desc, int argc, char **argv)
char *transport = NULL, *traddr = NULL;
char *trsvcid = NULL, *hostnqn = NULL, *hostid = NULL;
char *hostkey = NULL, *ctrlkey = NULL;
- char *hnqn = NULL, *hid = NULL;
+ _cleanup_free_ char *hnqn = NULL;
+ _cleanup_free_ char *hid = NULL;
char *config_file = PATH_NVMF_CONFIG;
char *context = NULL;
unsigned int verbose = 0;
- nvme_root_t r;
+ _cleanup_nvme_root_ nvme_root_t r = NULL;
nvme_host_t h;
- nvme_ctrl_t c;
+ _cleanup_nvme_ctrl_ nvme_ctrl_t c = NULL;
int ret;
- enum nvme_print_flags flags;
+ nvme_print_flags_t flags;
struct nvme_fabrics_config cfg = { 0 };
char *format = "normal";
@@ -961,29 +960,23 @@ int nvmf_connect(const char *desc, int argc, char **argv)
}
if (context)
nvme_root_set_application(r, context);
+
+ nvme_read_config(r, config_file);
+ nvme_read_volatile_config(r);
+
+ nvme_root_skip_namespaces(r);
ret = nvme_scan_topology(r, NULL, NULL);
if (ret < 0) {
- if (errno != ENOENT)
- fprintf(stderr, "Failed to scan topology: %s\n",
- nvme_strerror(errno));
- nvme_free_tree(r);
+ fprintf(stderr, "Failed to scan topology: %s\n",
+ nvme_strerror(errno));
return ret;
}
- nvme_read_config(r, config_file);
- nvme_read_volatile_config(r);
- if (!hostnqn)
- hostnqn = hnqn = nvmf_hostnqn_from_file();
- 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, verbose);
- h = nvme_lookup_host(r, hostnqn, hostid);
+ ret = nvme_host_get_ids(r, hostnqn, hostid, &hnqn, &hid);
+ if (ret < 0)
+ return -errno;
+
+ h = nvme_lookup_host(r, hnqn, hid);
if (!h) {
errno = ENOMEM;
goto out_free;
@@ -991,7 +984,7 @@ int nvmf_connect(const char *desc, int argc, char **argv)
if (hostkey)
nvme_host_set_dhchap_key(h, hostkey);
if (!trsvcid)
- trsvcid = get_default_trsvcid(transport, false);
+ trsvcid = nvmf_get_default_trsvcid(transport, false);
struct tr_config trcfg = {
.subsysnqn = subsysnqn,
@@ -1030,11 +1023,8 @@ int nvmf_connect(const char *desc, int argc, char **argv)
}
out_free:
- free(hnqn);
- free(hid);
if (dump_config)
nvme_dump_config(r);
- nvme_free_tree(r);
return -errno;
}
@@ -1084,7 +1074,7 @@ static void nvmf_disconnect_nqn(nvme_root_t r, char *nqn)
int nvmf_disconnect(const char *desc, int argc, char **argv)
{
const char *device = "nvme device handle";
- nvme_root_t r;
+ _cleanup_nvme_root_ nvme_root_t r = NULL;
nvme_ctrl_t c;
char *p;
int ret;
@@ -1122,13 +1112,20 @@ int nvmf_disconnect(const char *desc, int argc, char **argv)
nvme_strerror(errno));
return -errno;
}
+ nvme_root_skip_namespaces(r);
ret = nvme_scan_topology(r, NULL, NULL);
if (ret < 0) {
- if (errno != ENOENT)
- fprintf(stderr, "Failed to scan topology: %s\n",
- nvme_strerror(errno));
- nvme_free_tree(r);
- return ret;
+ /*
+ * Do not report an error when the modules are not
+ * loaded, this allows the user to unconditionally call
+ * disconnect.
+ */
+ if (errno == ENOENT)
+ return 0;
+
+ fprintf(stderr, "Failed to scan topology: %s\n",
+ nvme_strerror(errno));
+ return -errno;
}
if (cfg.nqn)
@@ -1145,7 +1142,6 @@ int nvmf_disconnect(const char *desc, int argc, char **argv)
if (!c) {
fprintf(stderr,
"Did not find device %s\n", p);
- nvme_free_tree(r);
return -errno;
}
ret = nvme_disconnect_ctrl(c);
@@ -1155,16 +1151,15 @@ int nvmf_disconnect(const char *desc, int argc, char **argv)
p, nvme_strerror(errno));
}
}
- nvme_free_tree(r);
return 0;
}
int nvmf_disconnect_all(const char *desc, int argc, char **argv)
{
+ _cleanup_nvme_root_ nvme_root_t r = NULL;
nvme_host_t h;
nvme_subsystem_t s;
- nvme_root_t r;
nvme_ctrl_t c;
int ret;
@@ -1193,13 +1188,20 @@ int nvmf_disconnect_all(const char *desc, int argc, char **argv)
nvme_strerror(errno));
return -errno;
}
+ nvme_root_skip_namespaces(r);
ret = nvme_scan_topology(r, NULL, NULL);
if (ret < 0) {
- if (errno != ENOENT)
- fprintf(stderr, "Failed to scan topology: %s\n",
- nvme_strerror(errno));
- nvme_free_tree(r);
- return ret;
+ /*
+ * Do not report an error when the modules are not
+ * loaded, this allows the user to unconditionally call
+ * disconnect.
+ */
+ if (errno == ENOENT)
+ return 0;
+
+ fprintf(stderr, "Failed to scan topology: %s\n",
+ nvme_strerror(errno));
+ return -errno;
}
nvme_for_each_host(r, h) {
@@ -1219,7 +1221,6 @@ int nvmf_disconnect_all(const char *desc, int argc, char **argv)
}
}
}
- nvme_free_tree(r);
return 0;
}
@@ -1229,11 +1230,12 @@ int nvmf_config(const char *desc, int argc, char **argv)
char *subsysnqn = NULL;
char *transport = NULL, *traddr = NULL;
char *trsvcid = NULL, *hostnqn = NULL, *hostid = NULL;
- char *hnqn = NULL, *hid = NULL;
+ _cleanup_free_ char *hnqn = NULL;
+ _cleanup_free_ char *hid = NULL;
char *hostkey = NULL, *ctrlkey = NULL;
char *config_file = PATH_NVMF_CONFIG;
unsigned int verbose = 0;
- nvme_root_t r;
+ _cleanup_nvme_root_ nvme_root_t r = NULL;
int ret;
struct nvme_fabrics_config cfg;
bool scan_tree = false, modify_config = false, update_config = false;
@@ -1264,17 +1266,18 @@ int nvmf_config(const char *desc, int argc, char **argv)
nvme_strerror(errno));
return -errno;
}
+
+ nvme_read_config(r, config_file);
+
if (scan_tree) {
+ nvme_root_skip_namespaces(r);
ret = nvme_scan_topology(r, NULL, NULL);
if (ret < 0) {
- if (errno != ENOENT)
- fprintf(stderr, "Failed to scan topology: %s\n",
- nvme_strerror(errno));
- nvme_free_tree(r);
- return ret;
+ fprintf(stderr, "Failed to scan topology: %s\n",
+ nvme_strerror(errno));
+ return -errno;
}
}
- nvme_read_config(r, config_file);
if (modify_config) {
nvme_host_t h;
@@ -1301,7 +1304,7 @@ int nvmf_config(const char *desc, int argc, char **argv)
if (!h) {
fprintf(stderr, "Failed to lookup host '%s': %s\n",
hostnqn, nvme_strerror(errno));
- goto out;
+ return -errno;
}
if (hostkey)
nvme_host_set_dhchap_key(h, hostkey);
@@ -1309,7 +1312,7 @@ int nvmf_config(const char *desc, int argc, char **argv)
if (!s) {
fprintf(stderr, "Failed to lookup subsystem '%s': %s\n",
subsysnqn, nvme_strerror(errno));
- goto out;
+ return -errno;
}
c = nvme_lookup_ctrl(s, transport, traddr,
cfg.host_traddr, cfg.host_iface,
@@ -1317,7 +1320,7 @@ int nvmf_config(const char *desc, int argc, char **argv)
if (!c) {
fprintf(stderr, "Failed to lookup controller: %s\n",
nvme_strerror(errno));
- goto out;
+ return -errno;
}
nvmf_update_config(c, &cfg);
if (ctrlkey)
@@ -1330,13 +1333,7 @@ int nvmf_config(const char *desc, int argc, char **argv)
if (dump_config)
nvme_dump_config(r);
-out:
- if (hid)
- free(hid);
- if (hnqn)
- free(hnqn);
- nvme_free_tree(r);
- return -errno;
+ return 0;
}
static void dim_operation(nvme_ctrl_t c, enum nvmf_dim_tas tas, const char *name)
@@ -1364,8 +1361,8 @@ static void dim_operation(nvme_ctrl_t c, enum nvmf_dim_tas tas, const char *name
int nvmf_dim(const char *desc, int argc, char **argv)
{
+ _cleanup_nvme_root_ nvme_root_t r = NULL;
enum nvmf_dim_tas tas;
- nvme_root_t r;
nvme_ctrl_t c;
char *p;
int ret;
@@ -1419,13 +1416,12 @@ int nvmf_dim(const char *desc, int argc, char **argv)
nvme_strerror(errno));
return -errno;
}
+ nvme_root_skip_namespaces(r);
ret = nvme_scan_topology(r, NULL, NULL);
if (ret < 0) {
- if (errno != ENOENT)
- fprintf(stderr, "Failed to scan topology: %s\n",
- nvme_strerror(errno));
- nvme_free_tree(r);
- return ret;
+ fprintf(stderr, "Failed to scan topology: %s\n",
+ nvme_strerror(errno));
+ return -errno;
}
if (cfg.nqn) {
@@ -1459,14 +1455,11 @@ int nvmf_dim(const char *desc, int argc, char **argv)
fprintf(stderr,
"Did not find device %s: %s\n",
p, nvme_strerror(errno));
- nvme_free_tree(r);
return -errno;
}
dim_operation(c, tas, p);
}
}
- nvme_free_tree(r);
-
return 0;
}