1
0
Fork 0

Merging upstream version 2.10.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-16 12:27:38 +01:00
parent 736f2f7c80
commit 37275c4af3
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
530 changed files with 12276 additions and 4877 deletions

467
fabrics.c
View file

@ -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)
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;
}
}
/* 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;
}
}
trsvcid = nvme_ctrl_get_trsvcid(c);
if (!trsvcid || !strcmp(trsvcid, ""))
trsvcid = nvmf_get_default_trsvcid(transport, true);
if (force)
subsysnqn = nvme_ctrl_get_subsysnqn(c);
else
subsysnqn = NVME_DISC_SUBSYS_NAME;
if (nvme_ctrl_is_persistent(c))
persistent = true;
memcpy(&cfg, defcfg, sizeof(cfg));
struct tr_config trcfg = {
.subsysnqn = subsysnqn,
.transport = transport,
.traddr = traddr,
.host_traddr = host_traddr,
.host_iface = host_iface,
.trsvcid = trsvcid,
};
if (!force) {
cn = lookup_ctrl(h, &trcfg);
if (cn) {
__discover(cn, &cfg, raw, connect, true, flags);
return 0;
}
}
cn = nvmf_create_discover_ctrl(r, h, &cfg, &trcfg);
if (!cn)
return 0;
__discover(cn, &cfg, raw, connect, persistent, flags);
if (!(persistent || is_persistent_discovery_ctrl(h, cn)))
ret = nvme_disconnect_ctrl(cn);
nvme_free_ctrl(cn);
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;
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;
/* ignore none fabric transports */
if (strcmp(transport, "tcp") &&
strcmp(transport, "rdma") &&
strcmp(transport, "fc"))
continue;
nvme_subsystem_for_each_ctrl(s, c) {
err = _discover_from_json_config_file(
r, h, c, desc, connect, defcfg,
flags, force);
/* ignore if no host_traddr for fc */
if (!strcmp(transport, "fc")) {
if (!host_traddr) {
fprintf(stderr, "host_traddr required for fc\n");
continue;
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;
}
}
/* 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);
if (force)
subsysnqn = nvme_ctrl_get_subsysnqn(c);
else
subsysnqn = NVME_DISC_SUBSYS_NAME;
if (nvme_ctrl_is_persistent(c))
persistent = true;
memcpy(&cfg, defcfg, sizeof(cfg));
struct tr_config trcfg = {
.subsysnqn = subsysnqn,
.transport = transport,
.traddr = traddr,
.host_traddr = host_traddr,
.host_iface = host_iface,
.trsvcid = trsvcid,
};
if (!force) {
cn = lookup_ctrl(h, &trcfg);
if (cn) {
__discover(cn, &cfg, raw, connect,
true, flags);
continue;
}
}
cn = create_discover_ctrl(r, h, &cfg, &trcfg);
if (!cn)
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);
}
}
@ -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);
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;
}
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);
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) {
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;
}