summaryrefslogtreecommitdiffstats
path: root/nvme.c
diff options
context:
space:
mode:
Diffstat (limited to 'nvme.c')
-rw-r--r--nvme.c1959
1 files changed, 1123 insertions, 836 deletions
diff --git a/nvme.c b/nvme.c
index 4096a91..df4d297 100644
--- a/nvme.c
+++ b/nvme.c
@@ -61,6 +61,7 @@
#include "nvme-print.h"
#include "plugin.h"
#include "util/base64.h"
+#include "nvme-wrap.h"
#include "util/argconfig.h"
#include "fabrics.h"
@@ -79,9 +80,6 @@ struct feat_cfg {
bool human_readable;
};
-static struct stat nvme_stat;
-const char *devicename;
-
static const char nvme_version_string[] = NVME_VERSION;
static struct plugin builtin = {
@@ -97,15 +95,16 @@ static struct program nvme = {
.version = nvme_version_string,
.usage = "<command> [<device>] [<args>]",
.desc = "The '<device>' may be either an NVMe character "\
- "device (ex: /dev/nvme0) or an nvme block device "\
- "(ex: /dev/nvme0n1).",
+ "device (ex: /dev/nvme0), an nvme block device "\
+ "(ex: /dev/nvme0n1), or a mctp address in the form "\
+ "mctp:<net>,<eid>[:ctrl-id]",
.extensions = &builtin,
};
const char *output_format = "Output format: normal|json|binary";
static const char *output_format_no_binary = "Output format: normal|json";
-static void *mmap_registers(nvme_root_t r, const char *dev);
+static void *mmap_registers(nvme_root_t r, struct nvme_dev *dev);
static void *__nvme_alloc(size_t len, bool *huge) {
void *p;
@@ -208,42 +207,119 @@ static ssize_t getrandom_bytes(void *buf, size_t buflen)
#endif
}
-static bool is_chardev(void)
+static bool is_chardev(struct nvme_dev *dev)
{
- return S_ISCHR(nvme_stat.st_mode);
+ return S_ISCHR(dev->direct.stat.st_mode);
}
-static bool is_blkdev(void)
+static bool is_blkdev(struct nvme_dev *dev)
{
- return S_ISBLK(nvme_stat.st_mode);
+ return S_ISBLK(dev->direct.stat.st_mode);
}
-static int open_dev(char *dev, int flags)
+static int open_dev_direct(struct nvme_dev **devp, char *devstr, int flags)
{
- int err, fd;
+ struct nvme_dev *dev;
+ int err;
- devicename = basename(dev);
- err = open(dev, flags);
- if (err < 0)
- goto perror;
- fd = err;
+ dev = calloc(1, sizeof(*dev));
+ if (!dev)
+ return -1;
+
+ dev->type = NVME_DEV_DIRECT;
+ dev->name = basename(devstr);
+ err = open(devstr, flags);
+ if (err < 0) {
+ perror(devstr);
+ goto err_free;
+ }
+ dev->direct.fd = err;
- err = fstat(fd, &nvme_stat);
+ err = fstat(dev_fd(dev), &dev->direct.stat);
if (err < 0) {
- close(fd);
- goto perror;
+ perror(devstr);
+ goto err_close;
}
- if (!is_chardev() && !is_blkdev()) {
- fprintf(stderr, "%s is not a block or character device\n", dev);
- close(fd);
- return -ENODEV;
+ if (!is_chardev(dev) && !is_blkdev(dev)) {
+ fprintf(stderr, "%s is not a block or character device\n",
+ devstr);
+ err = -ENODEV;
+ goto err_close;
}
- return fd;
-perror:
- perror(dev);
+ *devp = dev;
+ return 0;
+
+err_close:
+ close(dev_fd(dev));
+err_free:
+ free(dev);
return err;
}
+static int parse_mi_dev(char *dev, unsigned int *net, uint8_t *eid,
+ unsigned int *ctrl)
+{
+ int rc;
+
+ /* <net>,<eid>:<ctrl-id> form */
+ rc = sscanf(dev, "mctp:%u,%hhu:%u", net, eid, ctrl);
+ if (rc == 3)
+ return 0;
+
+ /* <net>,<eid> form, implicit ctrl-id = 0 */
+ *ctrl = 0;
+ rc = sscanf(dev, "mctp:%u,%hhu", net, eid);
+ if (rc == 2)
+ return 0;
+
+ return -1;
+}
+
+static int open_dev_mi_mctp(struct nvme_dev **devp, char *devstr)
+{
+ unsigned int net, ctrl_id;
+ struct nvme_dev *dev;
+ unsigned char eid;
+ int rc;
+
+ rc = parse_mi_dev(devstr, &net, &eid, &ctrl_id);
+ if (rc) {
+ fprintf(stderr, "invalid device specifier '%s'\n", devstr);
+ return rc;
+ }
+
+ dev = calloc(1, sizeof(*dev));
+ if (!dev)
+ return -1;
+
+ dev->type = NVME_DEV_MI;
+ dev->name = devstr;
+
+ /* todo: verbose argument */
+ dev->mi.root = nvme_mi_create_root(stderr, LOG_WARNING);
+ if (!dev->mi.root)
+ goto err_free;
+
+ dev->mi.ep = nvme_mi_open_mctp(dev->mi.root, net, eid);
+ if (!dev->mi.ep)
+ goto err_free_root;
+
+ dev->mi.ctrl = nvme_mi_init_ctrl(dev->mi.ep, ctrl_id);
+ if (!dev->mi.ctrl)
+ goto err_close_ep;
+
+ *devp = dev;
+ return 0;
+
+err_close_ep:
+ nvme_mi_close(dev->mi.ep);
+err_free_root:
+ nvme_mi_free_root(dev->mi.root);
+err_free:
+ free(dev);
+ return -1;
+}
+
static int check_arg_dev(int argc, char **argv)
{
if (optind >= argc) {
@@ -254,19 +330,28 @@ static int check_arg_dev(int argc, char **argv)
return 0;
}
-static int get_dev(int argc, char **argv, int flags)
+static int get_dev(struct nvme_dev **dev, int argc, char **argv, int flags)
{
+ char *devname;
int ret;
ret = check_arg_dev(argc, argv);
if (ret)
return ret;
- return open_dev(argv[optind], flags);
+ devname = argv[optind];
+
+ if (!strncmp(devname, "mctp:", strlen("mctp:")))
+ ret = open_dev_mi_mctp(dev, devname);
+ else
+ ret = open_dev_direct(dev, devname, flags);
+
+ return ret;
}
-int parse_and_open(int argc, char **argv, const char *desc,
- const struct argconfig_commandline_options *opts)
+int parse_and_open(struct nvme_dev **dev, int argc, char **argv,
+ const char *desc,
+ const struct argconfig_commandline_options *opts)
{
int ret;
@@ -274,21 +359,22 @@ int parse_and_open(int argc, char **argv, const char *desc,
if (ret)
return ret;
- ret = get_dev(argc, argv, O_RDONLY);
+ ret = get_dev(dev, argc, argv, O_RDONLY);
if (ret < 0)
argconfig_print_help(desc, opts);
return ret;
}
-int open_exclusive(int argc, char **argv, int ignore_exclusive)
+int open_exclusive(struct nvme_dev **dev, int argc, char **argv,
+ int ignore_exclusive)
{
- int flags = O_RDONLY;
+ int flags = O_RDONLY;
if (!ignore_exclusive)
flags |= O_EXCL;
- return get_dev(argc, argv, flags);
+ return get_dev(dev, argc, argv, flags);
}
enum nvme_print_flags validate_output_format(const char *format)
@@ -304,6 +390,20 @@ enum nvme_print_flags validate_output_format(const char *format)
return -EINVAL;
}
+void dev_close(struct nvme_dev *dev)
+{
+ switch (dev->type) {
+ case NVME_DEV_DIRECT:
+ close(dev_fd(dev));
+ break;
+ case NVME_DEV_MI:
+ nvme_mi_close(dev->mi.ep);
+ nvme_mi_free_root(dev->mi.root);
+ break;
+ }
+ free(dev);
+}
+
static int get_smart_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
struct nvme_smart_log smart_log;
@@ -314,7 +414,8 @@ static int get_smart_log(int argc, char **argv, struct command *cmd, struct plug
const char *raw = "output in binary format";
const char *human_readable = "show info in readable format";
enum nvme_print_flags flags;
- int err = -1, fd;
+ struct nvme_dev *dev;
+ int err = -1;
struct config {
__u32 namespace_id;
@@ -339,8 +440,8 @@ static int get_smart_log(int argc, char **argv, struct command *cmd, struct plug
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
err = flags = validate_output_format(cfg.output_format);
@@ -351,16 +452,17 @@ static int get_smart_log(int argc, char **argv, struct command *cmd, struct plug
if (cfg.human_readable)
flags |= VERBOSE;
- err = nvme_get_log_smart(fd, cfg.namespace_id, false, &smart_log);
+ err = nvme_cli_get_log_smart(dev, cfg.namespace_id, true,
+ &smart_log);
if (!err)
- nvme_show_smart_log(&smart_log, cfg.namespace_id, devicename,
- flags);
+ nvme_show_smart_log(&smart_log, cfg.namespace_id,
+ dev->name, flags);
else if (err > 0)
nvme_show_status(err);
else
fprintf(stderr, "smart log: %s\n", nvme_strerror(errno));
close_fd:
- close(fd);
+ dev_close(dev);
ret:
return err;
}
@@ -372,11 +474,12 @@ static int get_ana_log(int argc, char **argv, struct command *cmd,
"decoded format (default), json or binary.";
const char *groups = "Return ANA groups only.";
void *ana_log;
- int err = -1, fd;
size_t ana_log_len;
struct nvme_id_ctrl ctrl;
enum nvme_print_flags flags;
enum nvme_log_ana_lsp lsp;
+ struct nvme_dev *dev;
+ int err = -1;
struct config {
bool groups;
@@ -394,15 +497,15 @@ static int get_ana_log(int argc, char **argv, struct command *cmd,
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
err = flags = validate_output_format(cfg.output_format);
if (flags < 0)
goto close_fd;
- err = nvme_identify_ctrl(fd, &ctrl);
+ err = nvme_cli_identify_ctrl(dev, &ctrl);
if (err) {
fprintf(stderr, "ERROR : nvme_identify_ctrl() failed: %s\n",
nvme_strerror(errno));
@@ -423,16 +526,16 @@ static int get_ana_log(int argc, char **argv, struct command *cmd,
lsp = cfg.groups ? NVME_LOG_ANA_LSP_RGO_GROUPS_ONLY :
NVME_LOG_ANA_LSP_RGO_NAMESPACES;
- err = nvme_get_log_ana(fd, lsp, true, 0, ana_log_len, ana_log);
+ err = nvme_cli_get_log_ana(dev, lsp, true, 0, ana_log_len, ana_log);
if (!err) {
- nvme_show_ana_log(ana_log, devicename, flags, ana_log_len);
+ nvme_show_ana_log(ana_log, dev->name, flags, ana_log_len);
} else if (err > 0)
nvme_show_status(err);
else
fprintf(stderr, "ana-log: %s", nvme_strerror(errno));
free(ana_log);
close_fd:
- close(fd);
+ dev_close(dev);
ret:
return err;
}
@@ -446,10 +549,11 @@ static int get_telemetry_log(int argc, char **argv, struct command *cmd,
const char *cgen = "Gather report generated by the controller.";
const char *dgen = "Pick which telemetry data area to report. Default is 3 to fetch areas 1-3. Valid options are 1, 2, 3, 4.";
struct nvme_telemetry_log *log;
- int err = 0, fd, output;
+ int err = 0, output;
size_t total_size;
__u8 *data_ptr = NULL;
int data_written = 0, data_remaining = 0;
+ struct nvme_dev *dev;
struct config {
char *file_name;
@@ -472,14 +576,14 @@ static int get_telemetry_log(int argc, char **argv, struct command *cmd,
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
if (!cfg.file_name) {
fprintf(stderr, "Please provide an output file!\n");
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
cfg.host_gen = !!cfg.host_gen;
@@ -488,15 +592,18 @@ static int get_telemetry_log(int argc, char **argv, struct command *cmd,
fprintf(stderr, "Failed to open output file %s: %s!\n",
cfg.file_name, strerror(errno));
err = output;
- goto close_fd;
+ goto close_dev;
}
if (cfg.ctrl_init)
- err = nvme_get_ctrl_telemetry(fd, true, &log, cfg.data_area, &total_size);
+ err = nvme_get_ctrl_telemetry(dev_fd(dev), true, &log,
+ cfg.data_area, &total_size);
else if (cfg.host_gen)
- err = nvme_get_new_host_telemetry(fd, &log, cfg.data_area, &total_size);
+ err = nvme_get_new_host_telemetry(dev_fd(dev), &log,
+ cfg.data_area, &total_size);
else
- err = nvme_get_host_telemetry(fd, &log, cfg.data_area, &total_size);
+ err = nvme_get_host_telemetry(dev_fd(dev), &log,
+ cfg.data_area, &total_size);
if (err < 0) {
fprintf(stderr, "get-telemetry-log: %s\n",
@@ -536,8 +643,8 @@ static int get_telemetry_log(int argc, char **argv, struct command *cmd,
close_output:
close(output);
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -548,7 +655,8 @@ static int get_endurance_log(int argc, char **argv, struct command *cmd, struct
const char *desc = "Retrieves endurance groups log page and prints the log.";
const char *group_id = "The endurance group identifier";
enum nvme_print_flags flags;
- int err, fd;
+ struct nvme_dev *dev;
+ int err;
struct config {
char *output_format;
@@ -566,28 +674,30 @@ static int get_endurance_log(int argc, char **argv, struct command *cmd, struct
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
err = flags = validate_output_format(cfg.output_format);
if (flags < 0)
- goto close_fd;
+ goto close_dev;
- err = nvme_get_log_endurance_group(fd, cfg.group_id, &endurance_log);
+ err = nvme_cli_get_log_endurance_group(dev, cfg.group_id,
+ &endurance_log);
if (!err)
- nvme_show_endurance_log(&endurance_log, cfg.group_id, devicename, flags);
+ nvme_show_endurance_log(&endurance_log, cfg.group_id,
+ dev->name, flags);
else if (err > 0)
nvme_show_status(err);
else
fprintf(stderr, "endurance log: %s\n", nvme_strerror(errno));
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
-static int collect_effects_log(int fd, enum nvme_csi csi,
+static int collect_effects_log(struct nvme_dev *dev, enum nvme_csi csi,
struct list_head *list, int flags)
{
nvme_effects_log_node_t *node;
@@ -599,7 +709,7 @@ static int collect_effects_log(int fd, enum nvme_csi csi,
node->csi = csi;
- err = nvme_get_log_cmd_effects(fd, csi, &node->effects);
+ err = nvme_cli_get_log_cmd_effects(dev, csi, &node->effects);
if (err) {
free(node);
return err;
@@ -616,10 +726,11 @@ static int get_effects_log(int argc, char **argv, struct command *cmd, struct pl
const char *csi = "";
struct list_head log_pages;
nvme_effects_log_node_t *node;
+ struct nvme_dev *dev;
void *bar = NULL;
- int err = -1, fd;
+ int err = -1;
enum nvme_print_flags flags;
struct config {
@@ -644,13 +755,13 @@ static int get_effects_log(int argc, char **argv, struct command *cmd, struct pl
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
err = flags = validate_output_format(cfg.output_format);
if (flags < 0)
- goto close_fd;
+ goto close_dev;
if (cfg.raw_binary)
flags = BINARY;
if (cfg.human_readable)
@@ -664,11 +775,11 @@ static int get_effects_log(int argc, char **argv, struct command *cmd, struct pl
int nvme_command_set_supported;
int other_command_sets_supported;
nvme_root = nvme_scan(NULL);
- bar = mmap_registers(nvme_root, devicename);
+ bar = mmap_registers(nvme_root, dev);
nvme_free_tree(nvme_root);
if (!bar) {
- goto close_fd;
+ goto close_dev;
}
cap = mmio_read64(bar + NVME_REG_CAP);
munmap(bar, getpagesize());
@@ -677,15 +788,15 @@ static int get_effects_log(int argc, char **argv, struct command *cmd, struct pl
other_command_sets_supported = NVME_CAP_CSS(cap) & NVME_CAP_CSS_CSI;
if (nvme_command_set_supported)
- err = collect_effects_log(fd, NVME_CSI_NVM,
+ err = collect_effects_log(dev, NVME_CSI_NVM,
&log_pages, flags);
if (!err && other_command_sets_supported)
- err = collect_effects_log(fd, NVME_CSI_ZNS,
+ err = collect_effects_log(dev, NVME_CSI_ZNS,
&log_pages, flags);
} else {
- err = collect_effects_log(fd, cfg.csi, &log_pages, flags);
+ err = collect_effects_log(dev, cfg.csi, &log_pages, flags);
}
if (!err)
@@ -695,10 +806,12 @@ static int get_effects_log(int argc, char **argv, struct command *cmd, struct pl
else
perror("effects log page");
-close_fd:
- while ((node = list_pop(&log_pages, nvme_effects_log_node_t, node)))
+close_dev:
+ while ((node = list_pop(&log_pages, nvme_effects_log_node_t, node))) {
free(node);
- close(fd);
+ }
+
+ dev_close(dev);
ret:
return err;
}
@@ -709,9 +822,9 @@ static int get_supported_log_pages(int argc, char **argv, struct command *cmd,
const char *desc = "Retrieve supported logs and print the table.";
const char *verbose = "Increase output verbosity";
struct nvme_supported_log_pages supports;
-
- int err = -1, fd;
enum nvme_print_flags flags;
+ struct nvme_dev *dev;
+ int err = -1;
struct config {
char *output_format;
@@ -729,28 +842,28 @@ static int get_supported_log_pages(int argc, char **argv, struct command *cmd,
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
err = flags = validate_output_format(cfg.output_format);
if (flags < 0)
- goto close_fd;
+ goto close_dev;
if (cfg.verbose)
flags |= VERBOSE;
- err = nvme_get_log_supported_log_pages(fd, false, &supports);
+ err = nvme_cli_get_log_supported_log_pages(dev, false, &supports);
if (!err)
- nvme_show_supported_log(&supports, devicename, flags);
+ nvme_show_supported_log(&supports, dev->name, flags);
else if (err > 0)
nvme_show_status(err);
else
fprintf(stderr, "supported log pages: %s",
nvme_strerror(errno));
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -765,7 +878,8 @@ static int get_error_log(int argc, char **argv, struct command *cmd, struct plug
struct nvme_error_log_page *err_log;
struct nvme_id_ctrl ctrl;
enum nvme_print_flags flags;
- int err = -1, fd;
+ struct nvme_dev *dev;
+ int err = -1;
struct config {
__u32 log_entries;
@@ -786,49 +900,50 @@ static int get_error_log(int argc, char **argv, struct command *cmd, struct plug
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
err = flags = validate_output_format(cfg.output_format);
if (flags < 0)
- goto close_fd;
+ goto close_dev;
if (cfg.raw_binary)
flags = BINARY;
if (!cfg.log_entries) {
fprintf(stderr, "non-zero log-entries is required param\n");
err = -1;
- goto close_fd;
+ goto close_dev;
}
- err = nvme_identify_ctrl(fd, &ctrl);
+ err = nvme_cli_identify_ctrl(dev, &ctrl);
if (err < 0) {
perror("identify controller");
- goto close_fd;
+ goto close_dev;
} else if (err) {
fprintf(stderr, "could not identify controller\n");
err = -1;
- goto close_fd;
+ goto close_dev;
}
cfg.log_entries = min(cfg.log_entries, ctrl.elpe + 1);
err_log = calloc(cfg.log_entries, sizeof(struct nvme_error_log_page));
if (!err_log) {
err = -1;
- goto close_fd;
+ goto close_dev;
}
- err = nvme_get_log_error(fd, cfg.log_entries, false, err_log);
+ err = nvme_cli_get_log_error(dev, cfg.log_entries, false, err_log);
if (!err)
- nvme_show_error_log(err_log, cfg.log_entries, devicename, flags);
+ nvme_show_error_log(err_log, cfg.log_entries,
+ dev->name, flags);
else if (err > 0)
nvme_show_status(err);
else
perror("error log");
free(err_log);
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -840,7 +955,8 @@ static int get_fw_log(int argc, char **argv, struct command *cmd, struct plugin
const char *raw = "use binary output";
struct nvme_firmware_slot fw_log;
enum nvme_print_flags flags;
- int err, fd;
+ struct nvme_dev *dev;
+ int err;
struct config {
char *output_format;
@@ -858,25 +974,25 @@ static int get_fw_log(int argc, char **argv, struct command *cmd, struct plugin
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
err = flags = validate_output_format(cfg.output_format);
if (flags < 0)
- goto close_fd;
+ goto close_dev;
if (cfg.raw_binary)
flags = BINARY;
- err = nvme_get_log_fw_slot(fd, false, &fw_log);
+ err = nvme_cli_get_log_fw_slot(dev, false, &fw_log);
if (!err)
- nvme_show_fw_log(&fw_log, devicename, flags);
+ nvme_show_fw_log(&fw_log, dev->name, flags);
else if (err > 0)
nvme_show_status(err);
else
fprintf(stderr, "fw log: %s\n", nvme_strerror(errno));
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -889,7 +1005,8 @@ static int get_changed_ns_list_log(int argc, char **argv, struct command *cmd, s
const char *raw = "output in binary format";
struct nvme_ns_list changed_ns_list_log;
enum nvme_print_flags flags;
- int err, fd;
+ struct nvme_dev *dev;
+ int err;
struct config {
char *output_format;
@@ -907,27 +1024,28 @@ static int get_changed_ns_list_log(int argc, char **argv, struct command *cmd, s
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
err = flags = validate_output_format(cfg.output_format);
if (flags < 0)
- goto close_fd;
+ goto close_dev;
if (cfg.raw_binary)
flags = BINARY;
- err = nvme_get_log_changed_ns_list(fd, true, &changed_ns_list_log);
+ err = nvme_cli_get_log_changed_ns_list(dev, true,
+ &changed_ns_list_log);
if (!err)
- nvme_show_changed_ns_list_log(&changed_ns_list_log, devicename,
- flags);
+ nvme_show_changed_ns_list_log(&changed_ns_list_log,
+ dev->name, flags);
else if (err > 0)
nvme_show_status(err);
else
fprintf(stderr, "changed ns list log: %s\n",
nvme_strerror(errno));
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -942,7 +1060,8 @@ static int get_pred_lat_per_nvmset_log(int argc, char **argv,
const char *raw = "use binary output";
struct nvme_nvmset_predictable_lat_log plpns_log;
enum nvme_print_flags flags;
- int err, fd;
+ struct nvme_dev *dev;
+ int err;
struct config {
__u16 nvmset_id;
@@ -963,28 +1082,29 @@ static int get_pred_lat_per_nvmset_log(int argc, char **argv,
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
err = flags = validate_output_format(cfg.output_format);
if (flags < 0)
- goto close_fd;
+ goto close_dev;
if (cfg.raw_binary)
flags = BINARY;
- err = nvme_get_log_predictable_lat_nvmset(fd, cfg.nvmset_id, &plpns_log);
+ err = nvme_cli_get_log_predictable_lat_nvmset(dev, cfg.nvmset_id,
+ &plpns_log);
if (!err)
nvme_show_predictable_latency_per_nvmset(&plpns_log,
- cfg.nvmset_id, devicename, flags);
+ cfg.nvmset_id, dev->name, flags);
else if (err > 0)
nvme_show_status(err);
else
fprintf(stderr, "predictable latency per nvm set: %s\n",
nvme_strerror(errno));
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -1002,9 +1122,10 @@ static int get_pred_lat_event_agg_log(int argc, char **argv,
const char *raw = "use binary output";
enum nvme_print_flags flags;
struct nvme_id_ctrl ctrl;
+ struct nvme_dev *dev;
__u32 log_size;
void *pea_log;
- int err, fd;
+ int err;
struct config {
__u64 log_entries;
@@ -1028,30 +1149,30 @@ static int get_pred_lat_event_agg_log(int argc, char **argv,
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
err = flags = validate_output_format(cfg.output_format);
if (flags < 0)
- goto close_fd;
+ goto close_dev;
if (cfg.raw_binary)
flags = BINARY;
if (!cfg.log_entries) {
fprintf(stderr, "non-zero log-entries is required param\n");
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
- err = nvme_identify_ctrl(fd, &ctrl);
+ err = nvme_cli_identify_ctrl(dev, &ctrl);
if (err < 0) {
fprintf(stderr, "identify controller: %s\n",
nvme_strerror(errno));
- goto close_fd;
+ goto close_dev;
} else if (err) {
nvme_show_status(err);
- goto close_fd;
+ goto close_dev;
}
cfg.log_entries = min(cfg.log_entries, le32_to_cpu(ctrl.nsetidmax));
@@ -1059,13 +1180,14 @@ static int get_pred_lat_event_agg_log(int argc, char **argv,
pea_log = calloc(log_size, 1);
if (!pea_log) {
err = -ENOMEM;
- goto close_fd;
+ goto close_dev;
}
- err = nvme_get_log_predictable_lat_event(fd, cfg.rae, 0, log_size, pea_log);
+ err = nvme_cli_get_log_predictable_lat_event(dev, cfg.rae, 0,
+ log_size, pea_log);
if (!err)
nvme_show_predictable_latency_event_agg_log(pea_log, cfg.log_entries,
- log_size, devicename, flags);
+ log_size, dev->name, flags);
else if (err > 0)
nvme_show_status(err);
else
@@ -1073,8 +1195,8 @@ static int get_pred_lat_event_agg_log(int argc, char **argv,
nvme_strerror(errno));
free(pea_log);
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -1092,8 +1214,9 @@ static int get_persistent_event_log(int argc, char **argv,
struct nvme_persistent_event_log *pevent, *pevent_collected;
enum nvme_print_flags flags;
void *pevent_log_info;
- int err, fd;
+ struct nvme_dev *dev;
bool huge;
+ int err;
struct config {
__u8 action;
@@ -1117,24 +1240,24 @@ static int get_persistent_event_log(int argc, char **argv,
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
err = flags = validate_output_format(cfg.output_format);
if (flags < 0)
- goto close_fd;
+ goto close_dev;
if (cfg.raw_binary)
flags = BINARY;
pevent = calloc(sizeof(*pevent), 1);
if (!pevent) {
err = -ENOMEM;
- goto close_fd;
+ goto close_dev;
}
- err = nvme_get_log_persistent_event(fd, cfg.action,
- sizeof(*pevent), pevent);
+ err = nvme_cli_get_log_persistent_event(dev, cfg.action,
+ sizeof(*pevent), pevent);
if (err < 0) {
fprintf(stderr, "persistent event log: %s\n",
nvme_strerror(errno));
@@ -1171,11 +1294,12 @@ static int get_persistent_event_log(int argc, char **argv,
err = -ENOMEM;
goto free_pevent;
}
- err = nvme_get_log_persistent_event(fd, cfg.action,
- cfg.log_len, pevent_log_info);
+ err = nvme_cli_get_log_persistent_event(dev, cfg.action,
+ cfg.log_len, pevent_log_info);
if (!err) {
- err = nvme_get_log_persistent_event(fd, cfg.action,
- sizeof(*pevent), pevent);
+ err = nvme_cli_get_log_persistent_event(dev, cfg.action,
+ sizeof(*pevent),
+ pevent);
if (err < 0) {
fprintf(stderr, "persistent event log: %s\n",
nvme_strerror(errno));
@@ -1192,7 +1316,7 @@ static int get_persistent_event_log(int argc, char **argv,
}
nvme_show_persistent_event_log(pevent_log_info, cfg.action,
- cfg.log_len, devicename, flags);
+ cfg.log_len, dev->name, flags);
} else if (err > 0)
nvme_show_status(err);
else
@@ -1203,8 +1327,8 @@ free:
nvme_free(pevent_log_info, huge);
free_pevent:
free(pevent);
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -1223,8 +1347,9 @@ static int get_endurance_event_agg_log(int argc, char **argv,
void *endurance_log;
struct nvme_id_ctrl ctrl;
enum nvme_print_flags flags;
- int err, fd;
+ struct nvme_dev *dev;
__u32 log_size;
+ int err;
struct config {
__u64 log_entries;
@@ -1248,31 +1373,31 @@ static int get_endurance_event_agg_log(int argc, char **argv,
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
err = flags = validate_output_format(cfg.output_format);
if (flags < 0)
- goto close_fd;
+ goto close_dev;
if (cfg.raw_binary)
flags = BINARY;
if (!cfg.log_entries) {
fprintf(stderr, "non-zero log-entries is required param\n");
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
- err = nvme_identify_ctrl(fd, &ctrl);
+ err = nvme_cli_identify_ctrl(dev, &ctrl);
if (err < 0) {
fprintf(stderr, "identify controller: %s\n",
nvme_strerror(errno));
- goto close_fd;
+ goto close_dev;
} else if (err) {
fprintf(stderr, "could not identify controller\n");
err = -ENODEV;
- goto close_fd;
+ goto close_dev;
}
cfg.log_entries = min(cfg.log_entries, le16_to_cpu(ctrl.endgidmax));
@@ -1280,13 +1405,14 @@ static int get_endurance_event_agg_log(int argc, char **argv,
endurance_log = calloc(log_size, 1);
if (!endurance_log) {
err = -ENOMEM;
- goto close_fd;
+ goto close_dev;
}
- err = nvme_get_log_endurance_grp_evt(fd, cfg.rae, 0, log_size, endurance_log);
+ err = nvme_cli_get_log_endurance_grp_evt(dev, cfg.rae, 0, log_size,
+ endurance_log);
if (!err)
nvme_show_endurance_group_event_agg_log(endurance_log, cfg.log_entries,
- log_size, devicename, flags);
+ log_size, dev->name, flags);
else if (err > 0)
nvme_show_status(err);
else
@@ -1294,8 +1420,8 @@ static int get_endurance_event_agg_log(int argc, char **argv,
nvme_strerror(errno));
free(endurance_log);
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -1309,8 +1435,9 @@ static int get_lba_status_log(int argc, char **argv,
const char *rae = "Retain an Asynchronous Event";
void *lab_status;
enum nvme_print_flags flags;
- int err, fd;
+ struct nvme_dev *dev;
__u32 lslplen;
+ int err;
struct config {
bool rae;
@@ -1328,33 +1455,35 @@ static int get_lba_status_log(int argc, char **argv,
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
err = flags = validate_output_format(cfg.output_format);
if (flags < 0)
- goto close_fd;
+ goto close_dev;
- err = nvme_get_log_lba_status(fd, true, 0, sizeof(__u32), &lslplen);
+ err = nvme_cli_get_log_lba_status(dev, true, 0, sizeof(__u32),
+ &lslplen);
if (err < 0) {
fprintf(stderr, "lba status log page: %s\n",
nvme_strerror(errno));
- goto close_fd;
+ goto close_dev;
} else if (err) {
nvme_show_status(err);
- goto close_fd;
+ goto close_dev;
}
lab_status = calloc(lslplen, 1);
if (!lab_status) {
err = -ENOMEM;
- goto close_fd;
+ goto close_dev;
}
- err = nvme_get_log_lba_status(fd, cfg.rae, 0, lslplen, lab_status);
+ err = nvme_cli_get_log_lba_status(dev, cfg.rae, 0, lslplen,
+ lab_status);
if (!err)
- nvme_show_lba_status_log(lab_status, lslplen, devicename, flags);
+ nvme_show_lba_status_log(lab_status, lslplen, dev->name, flags);
else if (err > 0)
nvme_show_status(err);
else
@@ -1362,8 +1491,8 @@ static int get_lba_status_log(int argc, char **argv,
nvme_strerror(errno));
free(lab_status);
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -1378,7 +1507,8 @@ static int get_resv_notif_log(int argc, char **argv,
"json or binary.";
struct nvme_resv_notification_log resv;
enum nvme_print_flags flags;
- int err, fd;
+ struct nvme_dev *dev;
+ int err;
struct config {
char *output_format;
@@ -1393,25 +1523,25 @@ static int get_resv_notif_log(int argc, char **argv,
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
err = flags = validate_output_format(cfg.output_format);
if (flags < 0)
- goto close_fd;
+ goto close_dev;
- err = nvme_get_log_reservation(fd, false, &resv);
+ err = nvme_cli_get_log_reservation(dev, false, &resv);
if (!err)
- nvme_show_resv_notif_log(&resv, devicename, flags);
+ nvme_show_resv_notif_log(&resv, dev->name, flags);
else if (err > 0)
nvme_show_status(err);
else
fprintf(stderr, "resv notifi log: %s\n",
nvme_strerror(errno));
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
@@ -1428,7 +1558,8 @@ static int get_boot_part_log(int argc, char **argv, struct command *cmd, struct
struct nvme_boot_partition boot;
__u8 *bp_log;
enum nvme_print_flags flags;
- int err = -1, fd = 0, output = 0;
+ int err = -1, output = 0;
+ struct nvme_dev *dev;
__u32 bpsz = 0;
struct config {
@@ -1450,24 +1581,24 @@ static int get_boot_part_log(int argc, char **argv, struct command *cmd, struct
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
err = flags = validate_output_format(cfg.output_format);
if (flags < 0)
- goto close_fd;
+ goto close_dev;
if (!cfg.file_name) {
fprintf(stderr, "Please provide an output file!\n");
err = -1;
- goto close_fd;
+ goto close_dev;
}
if (cfg.lsp > 128) {
fprintf(stderr, "invalid lsp param: %u\n", cfg.lsp);
err = -1;
- goto close_fd;
+ goto close_dev;
}
output = open(cfg.file_name, O_WRONLY | O_CREAT | O_TRUNC, 0666);
@@ -1475,11 +1606,11 @@ static int get_boot_part_log(int argc, char **argv, struct command *cmd, struct
fprintf(stderr, "Failed to open output file %s: %s!\n",
cfg.file_name, strerror(errno));
err = output;
- goto close_fd;
+ goto close_dev;
}
- err = nvme_get_log_boot_partition(fd, false, cfg.lsp,
- sizeof(boot), &boot);
+ err = nvme_cli_get_log_boot_partition(dev, false, cfg.lsp,
+ sizeof(boot), &boot);
if (err < 0) {
fprintf(stderr, "boot partition log: %s\n",
nvme_strerror(errno));
@@ -1496,11 +1627,12 @@ static int get_boot_part_log(int argc, char **argv, struct command *cmd, struct
goto close_output;
}
- err = nvme_get_log_boot_partition(fd, false, cfg.lsp,
- sizeof(boot) + bpsz,
- (struct nvme_boot_partition *)bp_log);
+ err = nvme_cli_get_log_boot_partition(dev, false, cfg.lsp,
+ sizeof(boot) + bpsz,
+ (struct nvme_boot_partition *)bp_log);
if (!err)
- nvme_show_boot_part_log(&bp_log, devicename, flags, sizeof(boot) + bpsz);
+ nvme_show_boot_part_log(&bp_log, dev->name, flags,
+ sizeof(boot) + bpsz);
else if (err > 0)
nvme_show_status(err);
else
@@ -1519,8 +1651,8 @@ static int get_boot_part_log(int argc, char **argv, struct command *cmd, struct
close_output:
close(output);
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -1532,9 +1664,9 @@ static int get_media_unit_stat_log(int argc, char **argv, struct command *cmd,
const char *domainid = "Domain Identifier";
const char *raw = "use binary output";
struct nvme_media_unit_stat_log mus;
-
- int err = -1, fd;
enum nvme_print_flags flags;
+ struct nvme_dev *dev;
+ int err = -1;
struct config {
__u16 domainid;
@@ -1555,18 +1687,18 @@ static int get_media_unit_stat_log(int argc, char **argv, struct command *cmd,
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
err = flags = validate_output_format(cfg.output_format);
if (flags < 0)
- goto close_fd;
+ goto close_dev;
if (cfg.raw_binary)
flags = BINARY;
- err = nvme_get_log_media_unit_stat(fd, cfg.domainid, &mus);
+ err = nvme_cli_get_log_media_unit_stat(dev, cfg.domainid, &mus);
if (!err)
nvme_show_media_unit_stat_log(&mus, flags);
else if (err > 0)
@@ -1575,8 +1707,8 @@ static int get_media_unit_stat_log(int argc, char **argv, struct command *cmd,
fprintf(stderr, "media unit status log: %s\n",
nvme_strerror(errno));
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -1588,9 +1720,9 @@ static int get_supp_cap_config_log(int argc, char **argv, struct command *cmd,
const char *domainid = "Domain Identifier";
const char *raw = "use binary output";
struct nvme_supported_cap_config_list_log cap_log;
-
- int err = -1, fd;
enum nvme_print_flags flags;
+ struct nvme_dev *dev;
+ int err = -1;
struct config {
__u16 domainid;
@@ -1611,18 +1743,19 @@ static int get_supp_cap_config_log(int argc, char **argv, struct command *cmd,
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
err = flags = validate_output_format(cfg.output_format);
if (flags < 0)
- goto close_fd;
+ goto close_dev;
if (cfg.raw_binary)
flags = BINARY;
- err = nvme_get_log_support_cap_config_list(fd, cfg.domainid, &cap_log);
+ err = nvme_cli_get_log_support_cap_config_list(dev, cfg.domainid,
+ &cap_log);
if (!err)
nvme_show_supported_cap_config_log(&cap_log, flags);
else if (err > 0)
@@ -1630,8 +1763,8 @@ static int get_supp_cap_config_log(int argc, char **argv, struct command *cmd,
else
perror("supported capacity configuration list log");
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -1653,8 +1786,9 @@ static int get_log(int argc, char **argv, struct command *cmd, struct plugin *pl
const char *uuid_index = "UUID index";
const char *csi = "command set identifier";
const char *offset_type = "offset type";
- int err, fd;
+ struct nvme_dev *dev;
unsigned char *log;
+ int err;
struct config {
__u32 namespace_id;
@@ -1702,8 +1836,8 @@ static int get_log(int argc, char **argv, struct command *cmd, struct plugin *pl
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
if (cfg.aen) {
@@ -1714,31 +1848,30 @@ static int get_log(int argc, char **argv, struct command *cmd, struct plugin *pl
if (!cfg.log_len) {
perror("non-zero log-len is required param\n");
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
if (cfg.lsp > 128) {
perror("invalid lsp param\n");
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
if (cfg.uuid_index > 128) {
perror("invalid uuid index param\n");
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
log = malloc(cfg.log_len);
if (!log) {
perror("could not alloc buffer for log\n");
err = -ENOMEM;
- goto close_fd;
+ goto close_dev;
}
struct nvme_get_log_args args = {
.args_size = sizeof(args),
- .fd = fd,
.lid = cfg.log_id,
.nsid = cfg.namespace_id,
.lpo = cfg.lpo,
@@ -1750,14 +1883,13 @@ static int get_log(int argc, char **argv, struct command *cmd, struct plugin *pl
.ot = cfg.ot,
.len = cfg.log_len,
.log = log,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
.result = NULL,
};
- err = nvme_get_log(&args);
+ err = nvme_cli_get_log(dev, &args);
if (!err) {
if (!cfg.raw_binary) {
printf("Device:%s log-id:%d namespace-id:%#x\n",
- devicename, cfg.log_id,
+ dev->name, cfg.log_id,
cfg.namespace_id);
d(log, cfg.log_len, 16, 1);
} else
@@ -1768,8 +1900,8 @@ static int get_log(int argc, char **argv, struct command *cmd, struct plugin *pl
fprintf(stderr, "log page: %s\n", nvme_strerror(errno));
free(log);
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -1782,7 +1914,8 @@ static int sanitize_log(int argc, char **argv, struct command *command, struct p
const char *human_readable = "show log in readable format";
struct nvme_sanitize_log_page sanitize_log;
enum nvme_print_flags flags;
- int fd, err;
+ struct nvme_dev *dev;
+ int err;
struct config {
bool rae;
@@ -1806,28 +1939,28 @@ static int sanitize_log(int argc, char **argv, struct command *command, struct p
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
err = flags = validate_output_format(cfg.output_format);
if (flags < 0)
- goto close_fd;
+ goto close_dev;
if (cfg.raw_binary)
flags = BINARY;
if (cfg.human_readable)
flags |= VERBOSE;
- err = nvme_get_log_sanitize(fd, cfg.rae, &sanitize_log);
+ err = nvme_cli_get_log_sanitize(dev, cfg.rae, &sanitize_log);
if (!err)
- nvme_show_sanitize_log(&sanitize_log, devicename, flags);
+ nvme_show_sanitize_log(&sanitize_log, dev->name, flags);
else if (err > 0)
nvme_show_status(err);
else
fprintf(stderr, "sanitize status log: %s\n",
nvme_strerror(errno));
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -1839,7 +1972,8 @@ static int get_fid_support_effects_log(int argc, char **argv, struct command *cm
const char *human_readable = "show log in readable format";
struct nvme_fid_supported_effects_log fid_support_log;
enum nvme_print_flags flags;
- int fd, err = -1;
+ struct nvme_dev *dev;
+ int err = -1;
struct config {
char *output_format;
@@ -1857,26 +1991,28 @@ static int get_fid_support_effects_log(int argc, char **argv, struct command *cm
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
err = flags = validate_output_format(cfg.output_format);
if (flags < 0)
- goto close_fd;
+ goto close_dev;
if (cfg.human_readable)
flags |= VERBOSE;
- err = nvme_get_log_fid_supported_effects(fd, false, &fid_support_log);
+ err = nvme_cli_get_log_fid_supported_effects(dev, false,
+ &fid_support_log);
if (!err)
- nvme_show_fid_support_effects_log(&fid_support_log, devicename, flags);
+ nvme_show_fid_support_effects_log(&fid_support_log,
+ dev->name, flags);
else if (err > 0)
nvme_show_status(err);
else
fprintf(stderr, "fid support effects log: %s\n",
nvme_strerror(errno));
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -1888,7 +2024,8 @@ static int get_mi_cmd_support_effects_log(int argc, char **argv, struct command
const char *human_readable = "show log in readable format";
struct nvme_mi_cmd_supported_effects_log mi_cmd_support_log;
enum nvme_print_flags flags;
- int fd, err = -1;
+ struct nvme_dev *dev;
+ int err = -1;
struct config {
char *output_format;
@@ -1906,26 +2043,28 @@ static int get_mi_cmd_support_effects_log(int argc, char **argv, struct command
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
err = flags = validate_output_format(cfg.output_format);
if (flags < 0)
- goto close_fd;
+ goto close_dev;
if (cfg.human_readable)
flags |= VERBOSE;
- err = nvme_get_log_mi_cmd_supported_effects(fd, false, &mi_cmd_support_log);
+ err = nvme_cli_get_log_mi_cmd_supported_effects(dev, false,
+ &mi_cmd_support_log);
if (!err)
- nvme_show_mi_cmd_support_effects_log(&mi_cmd_support_log, devicename, flags);
+ nvme_show_mi_cmd_support_effects_log(&mi_cmd_support_log,
+ dev->name, flags);
else if (err > 0)
nvme_show_status(err);
else
fprintf(stderr, "mi command support effects log: %s\n",
nvme_strerror(errno));
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -1936,9 +2075,10 @@ static int list_ctrl(int argc, char **argv, struct command *cmd, struct plugin *
"given device is part of, or optionally controllers attached to a specific namespace.";
const char *controller = "controller to display";
const char *namespace_id = "optional namespace attached to controller";
- int err, fd;
struct nvme_ctrl_list *cntlist;
enum nvme_print_flags flags;
+ struct nvme_dev *dev;
+ int err;
struct config {
__u16 cntid;
@@ -1959,25 +2099,25 @@ static int list_ctrl(int argc, char **argv, struct command *cmd, struct plugin *
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
err = flags = validate_output_format(cfg.output_format);
if (flags < 0)
- goto close_fd;
+ goto close_dev;
if (posix_memalign((void *)&cntlist, getpagesize(), 0x1000)) {
fprintf(stderr, "can not allocate controller list payload\n");
err = -ENOMEM;
- goto close_fd;
+ goto close_dev;
}
if (cfg.namespace_id == NVME_NSID_NONE)
- err = nvme_identify_ctrl_list(fd, cfg.cntid, cntlist);
- else
- err = nvme_identify_nsid_ctrl_list(fd, cfg.namespace_id,
- cfg.cntid, cntlist);
+ err = nvme_cli_identify_ctrl_list(dev, cfg.cntid, cntlist);
+ else
+ err = nvme_cli_identify_nsid_ctrl_list(dev, cfg.namespace_id,
+ cfg.cntid, cntlist);
if (!err)
nvme_show_list_ctrl(cntlist, flags);
else if (err > 0)
@@ -1987,8 +2127,8 @@ static int list_ctrl(int argc, char **argv, struct command *cmd, struct plugin *
nvme_strerror(errno));
free(cntlist);
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -2000,9 +2140,10 @@ static int list_ns(int argc, char **argv, struct command *cmd, struct plugin *pl
const char *namespace_id = "first nsid returned list should start from";
const char *csi = "I/O command set identifier";
const char *all = "show all namespaces in the subsystem, whether attached or inactive";
- int err, fd;
struct nvme_ns_list ns_list;
enum nvme_print_flags flags;
+ struct nvme_dev *dev;
+ int err;
struct config {
__u32 namespace_id;
@@ -2026,27 +2167,26 @@ static int list_ns(int argc, char **argv, struct command *cmd, struct plugin *pl
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
err = flags = validate_output_format(cfg.output_format);
if (flags < 0)
- goto close_fd;
+ goto close_dev;
if (flags != JSON && flags != NORMAL) {
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
if (!cfg.namespace_id) {
err = -EINVAL;
fprintf(stderr, "invalid nsid parameter\n");
- goto close_fd;
+ goto close_dev;
}
struct nvme_identify_args args = {
.args_size = sizeof(args),
- .fd = fd,
.timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
.data = &ns_list,
.nsid = cfg.namespace_id - 1.
@@ -2060,7 +2200,7 @@ static int list_ns(int argc, char **argv, struct command *cmd, struct plugin *pl
args.csi = cfg.csi;
}
- err = nvme_identify(&args);
+ err = nvme_cli_identify(dev, &args);
if (!err)
nvme_show_list_ns(&ns_list, flags);
@@ -2069,8 +2209,8 @@ static int list_ns(int argc, char **argv, struct command *cmd, struct plugin *pl
else
fprintf(stderr, "id namespace list: %s",
nvme_strerror(errno));
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -2086,7 +2226,8 @@ static int id_ns_lba_format(int argc, char **argv, struct command *cmd, struct p
const char *verbose = "Increase output verbosity";
enum nvme_print_flags flags;
struct nvme_id_ns ns;
- int err = -1, fd;
+ struct nvme_dev *dev;
+ int err = -1;
struct config {
__u16 lba_format_index;
@@ -2110,18 +2251,19 @@ static int id_ns_lba_format(int argc, char **argv, struct command *cmd, struct p
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
err = flags = validate_output_format(cfg.output_format);
if (flags < 0)
- goto close_fd;
+ goto close_dev;
if (cfg.verbose)
flags |= VERBOSE;
- err = nvme_identify_ns_csi_user_data_format(fd, cfg.lba_format_index,
+ err = nvme_identify_ns_csi_user_data_format(dev_fd(dev),
+ cfg.lba_format_index,
cfg.uuid_index, NVME_CSI_NVM, &ns);
if (!err)
nvme_show_id_ns(&ns, 0, cfg.lba_format_index, true, flags);
@@ -2129,8 +2271,8 @@ static int id_ns_lba_format(int argc, char **argv, struct command *cmd, struct p
nvme_show_status(err);
else
perror("identify namespace for specific LBA format");
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return nvme_status_to_errno(err, false);
}
@@ -2141,9 +2283,10 @@ static int id_endurance_grp_list(int argc, char **argv, struct command *cmd,
const char *desc = "Show endurance group list information for the given endurance "\
"group id";
const char *endurance_grp_id = "Endurance Group ID";
- int err = -1, fd;
struct nvme_id_endurance_group_list *endgrp_list;
enum nvme_print_flags flags;
+ struct nvme_dev *dev;
+ int err = -1;
struct config {
__u16 endgrp_id;
@@ -2161,25 +2304,26 @@ static int id_endurance_grp_list(int argc, char **argv, struct command *cmd,
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
err = flags = validate_output_format(cfg.output_format);
if (flags < 0)
- goto close_fd;
+ goto close_dev;
if (flags != JSON && flags != NORMAL) {
err = -EINVAL;
fprintf(stderr, "invalid output format\n");
- goto close_fd;
+ goto close_dev;
}
if (posix_memalign((void *)&endgrp_list, getpagesize(), 0x1000)) {
err = -1;
- goto close_fd;
+ goto close_dev;
}
- err = nvme_identify_endurance_group_list(fd, cfg.endgrp_id, endgrp_list);
+ err = nvme_identify_endurance_group_list(dev_fd(dev), cfg.endgrp_id,
+ endgrp_list);
if (!err)
nvme_show_endurance_group_list(endgrp_list, flags);
else if (err > 0)
@@ -2189,8 +2333,8 @@ static int id_endurance_grp_list(int argc, char **argv, struct command *cmd,
nvme_strerror(errno));
free(endgrp_list);
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -2205,7 +2349,8 @@ static int delete_ns(int argc, char **argv, struct command *cmd, struct plugin *
"the namespace is not already inactive, once deleted.";
const char *namespace_id = "namespace to delete";
const char *timeout = "timeout value, in milliseconds";
- int err, fd;
+ struct nvme_dev *dev;
+ int err;
struct config {
__u32 namespace_id;
@@ -2223,20 +2368,20 @@ static int delete_ns(int argc, char **argv, struct command *cmd, struct plugin *
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
if (!cfg.namespace_id) {
- err = nvme_get_nsid(fd, &cfg.namespace_id);
+ err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
fprintf(stderr, "get-namespace-id: %s\n",
nvme_strerror(errno));
- goto close_fd;
+ goto close_dev;
}
}
- err = nvme_ns_mgmt_delete(fd, cfg.namespace_id);
+ err = nvme_cli_ns_mgmt_delete(dev, cfg.namespace_id);
if (!err)
printf("%s: Success, deleted nsid:%d\n", cmd->name,
cfg.namespace_id);
@@ -2245,16 +2390,17 @@ static int delete_ns(int argc, char **argv, struct command *cmd, struct plugin *
else
fprintf(stderr, "delete namespace: %s\n", nvme_strerror(errno));
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
static int nvme_attach_ns(int argc, char **argv, int attach, const char *desc, struct command *cmd)
{
- int err, num, fd, i, list[2048];
struct nvme_ctrl_list cntlist;
+ int err, num, i, list[2048];
+ struct nvme_dev *dev;
__u16 ctrlist[2048];
const char *namespace_id = "namespace to attach";
@@ -2276,15 +2422,15 @@ static int nvme_attach_ns(int argc, char **argv, int attach, const char *desc, s
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
if (!cfg.namespace_id) {
fprintf(stderr, "%s: namespace-id parameter required\n",
cmd->name);
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
num = argconfig_parse_comma_sep_array(cfg.cntlist, list, 2047);
@@ -2296,7 +2442,7 @@ static int nvme_attach_ns(int argc, char **argv, int attach, const char *desc, s
fprintf(stderr, "%s: controller id list is malformed\n",
cmd->name);
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
for (i = 0; i < num; i++)
@@ -2305,9 +2451,11 @@ static int nvme_attach_ns(int argc, char **argv, int attach, const char *desc, s
nvme_init_ctrl_list(&cntlist, num, ctrlist);
if (attach)
- err = nvme_ns_attach_ctrls(fd, cfg.namespace_id, &cntlist);
+ err = nvme_cli_ns_attach_ctrls(dev, cfg.namespace_id,
+ &cntlist);
else
- err = nvme_ns_detach_ctrls(fd, cfg.namespace_id, &cntlist);
+ err = nvme_cli_ns_detach_ctrls(dev, cfg.namespace_id,
+ &cntlist);
if (!err)
printf("%s: Success, nsid:%d\n", cmd->name, cfg.namespace_id);
@@ -2316,8 +2464,8 @@ static int nvme_attach_ns(int argc, char **argv, int attach, const char *desc, s
else
perror(attach ? "attach namespace" : "detach namespace");
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -2362,8 +2510,9 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin *
const char *bs = "target block size, specify only if \'FLBAS\' "\
"value not entered";
- int err = 0, fd, i;
struct nvme_id_ns ns;
+ struct nvme_dev *dev;
+ int err = 0, i;
__u32 nsid;
struct config {
@@ -2409,15 +2558,15 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin *
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
if (cfg.flbas != 0xff && cfg.bs != 0x00) {
fprintf(stderr,
"Invalid specification of both FLBAS and Block Size, please specify only one\n");
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
if (cfg.bs) {
if ((cfg.bs & (~cfg.bs + 1)) != cfg.bs) {
@@ -2425,9 +2574,9 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin *
"Invalid value for block size (%"PRIu64"). Block size must be a power of two\n",
(uint64_t)cfg.bs);
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
- err = nvme_identify_ns(fd, NVME_NSID_ALL, &ns);
+ err = nvme_cli_identify_ns(dev, NVME_NSID_ALL, &ns);
if (err) {
if (err < 0)
fprintf(stderr, "identify-namespace: %s",
@@ -2436,7 +2585,7 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin *
fprintf(stderr, "identify failed\n");
nvme_show_status(err);
}
- goto close_fd;
+ goto close_dev;
}
for (i = 0; i <= ns.nlbaf; ++i) {
if ((1 << ns.lbaf[i].ds) == cfg.bs && ns.lbaf[i].ms == 0) {
@@ -2454,7 +2603,7 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin *
"Please correct block size, or specify FLBAS directly\n");
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
struct nvme_id_ns ns2 = {
@@ -2468,7 +2617,7 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin *
.lbstm = cpu_to_le64(cfg.lbstm),
};
- err = nvme_ns_mgmt_create(fd, &ns2, &nsid, cfg.timeout, cfg.csi);
+ err = nvme_cli_ns_mgmt_create(dev, &ns2, &nsid, cfg.timeout, cfg.csi);
if (!err)
printf("%s: Success, created nsid:%d\n", cmd->name, nsid);
else if (err > 0)
@@ -2476,8 +2625,8 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin *
else
fprintf(stderr, "create namespace: %s\n", nvme_strerror(errno));
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -2525,6 +2674,7 @@ static int list_subsys(int argc, char **argv, struct command *cmd,
const char *desc = "Retrieve information for subsystems";
const char *verbose = "Increase output verbosity";
nvme_scan_filter_t filter = NULL;
+ char *devname;
int err;
int nsid = NVME_NSID_ALL;
@@ -2548,9 +2698,9 @@ static int list_subsys(int argc, char **argv, struct command *cmd,
if (err < 0)
goto ret;
- devicename = NULL;
+ devname = NULL;
if (optind < argc)
- devicename = basename(argv[optind++]);
+ devname = basename(argv[optind++]);
err = flags = validate_output_format(cfg.output_format);
if (flags < 0)
@@ -2564,29 +2714,28 @@ static int list_subsys(int argc, char **argv, struct command *cmd,
r = nvme_create_root(stderr, map_log_level(cfg.verbose, false));
if (!r) {
- if (devicename)
+ if (devname)
fprintf(stderr,
"Failed to scan nvme subsystem for %s\n",
- devicename);
+ devname);
else
fprintf(stderr, "Failed to scan nvme subsystem\n");
err = -errno;
goto ret;
}
- if (devicename) {
+ if (devname) {
int subsys_num;
- if (sscanf(devicename,"nvme%dn%d",
- &subsys_num, &nsid) != 2) {
- fprintf(stderr, "Invalid device name %s\n", devicename);
+ if (sscanf(devname, "nvme%dn%d", &subsys_num, &nsid) != 2) {
+ fprintf(stderr, "Invalid device name %s\n", devname);
err = -EINVAL;
goto ret;
}
filter = nvme_match_device_filter;
}
- err = nvme_scan_topology(r, filter, (void *)devicename);
+ err = nvme_scan_topology(r, filter, (void *)devname);
if (err) {
fprintf(stderr, "Failed to scan topology: %s\n",
nvme_strerror(errno));
@@ -2672,7 +2821,8 @@ int __id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *plugin,
const char *human_readable = "show identify in readable format";
enum nvme_print_flags flags;
struct nvme_id_ctrl ctrl;
- int err, fd;
+ struct nvme_dev *dev;
+ int err;
struct config {
bool vendor_specific;
@@ -2696,13 +2846,13 @@ int __id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *plugin,
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
err = flags = validate_output_format(cfg.output_format);
if (flags < 0)
- goto close_fd;
+ goto close_dev;
if (cfg.raw_binary)
flags = BINARY;
if (cfg.vendor_specific)
@@ -2710,15 +2860,15 @@ int __id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *plugin,
if (cfg.human_readable)
flags |= VERBOSE;
- err = nvme_identify_ctrl(fd, &ctrl);
+ err = nvme_cli_identify_ctrl(dev, &ctrl);
if (!err)
nvme_show_id_ctrl(&ctrl, flags, vs);
else if (err > 0)
nvme_show_status(err);
else
fprintf(stderr, "identify controller: %s\n", nvme_strerror(errno));
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -2736,7 +2886,8 @@ static int nvm_id_ctrl(int argc, char **argv, struct command *cmd,
"the specified controller in various formats.";
enum nvme_print_flags flags;
struct nvme_id_ctrl_nvm ctrl_nvm;
- int fd, err = -1;
+ struct nvme_dev *dev;
+ int err = -1;
struct config {
char *output_format;
@@ -2751,23 +2902,23 @@ static int nvm_id_ctrl(int argc, char **argv, struct command *cmd,
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
err = flags = validate_output_format(cfg.output_format);
if (flags < 0)
- goto close_fd;
+ goto close_dev;
- err = nvme_nvm_identify_ctrl(fd, &ctrl_nvm);
+ err = nvme_nvm_identify_ctrl(dev_fd(dev), &ctrl_nvm);
if (!err)
nvme_show_id_ctrl_nvm(&ctrl_nvm, flags);
else if (err > 0)
nvme_show_status(err);
else
fprintf(stderr, "nvm identify controller: %s\n", nvme_strerror(errno));
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -2784,7 +2935,8 @@ static int nvm_id_ns(int argc, char **argv, struct command *cmd,
enum nvme_print_flags flags;
struct nvme_nvm_id_ns id_ns;
struct nvme_id_ns ns;
- int fd, err = -1;
+ struct nvme_dev *dev;
+ int err = -1;
struct config {
__u32 namespace_id;
@@ -2808,32 +2960,33 @@ static int nvm_id_ns(int argc, char **argv, struct command *cmd,
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
err = flags = validate_output_format(cfg.output_format);
if (flags < 0)
- goto close_fd;
+ goto close_dev;
if (cfg.verbose)
flags |= VERBOSE;
if (!cfg.namespace_id) {
- err = nvme_get_nsid(fd, &cfg.namespace_id);
+ err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
perror("get-namespace-id");
- goto close_fd;
+ goto close_dev;
}
}
- err = nvme_identify_ns(fd, cfg.namespace_id, &ns);
+ err = nvme_cli_identify_ns(dev, cfg.namespace_id, &ns);
if (err) {
nvme_show_status(err);
- goto close_fd;
+ goto close_dev;
}
- err = nvme_identify_ns_csi(fd, cfg.namespace_id, cfg.uuid_index,
+ err = nvme_identify_ns_csi(dev_fd(dev), cfg.namespace_id,
+ cfg.uuid_index,
NVME_CSI_NVM, &id_ns);
if (!err)
nvme_show_nvm_id_ns(&id_ns, cfg.namespace_id, &ns, 0, false, flags);
@@ -2841,8 +2994,8 @@ static int nvm_id_ns(int argc, char **argv, struct command *cmd,
nvme_show_status(err);
else
perror("nvm identify namespace");
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return nvme_status_to_errno(err, false);
}
@@ -2860,7 +3013,8 @@ static int nvm_id_ns_lba_format(int argc, char **argv, struct command *cmd, stru
enum nvme_print_flags flags;
struct nvme_id_ns ns;
struct nvme_nvm_id_ns nvm_ns;
- int err = -1, fd;
+ struct nvme_dev *dev;
+ int err = -1;
struct config {
__u16 lba_format_index;
@@ -2884,23 +3038,24 @@ static int nvm_id_ns_lba_format(int argc, char **argv, struct command *cmd, stru
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
err = flags = validate_output_format(cfg.output_format);
if (flags < 0)
- goto close_fd;
+ goto close_dev;
if (cfg.verbose)
flags |= VERBOSE;
- err = nvme_identify_ns(fd, NVME_NSID_ALL, &ns);
+ err = nvme_cli_identify_ns(dev, NVME_NSID_ALL, &ns);
if (err) {
ns.nlbaf = NVME_FEAT_LBA_RANGE_MAX - 1;
ns.nulbaf = 0;
}
- err = nvme_identify_iocs_ns_csi_user_data_format(fd, cfg.lba_format_index,
+ err = nvme_identify_iocs_ns_csi_user_data_format(dev_fd(dev),
+ cfg.lba_format_index,
cfg.uuid_index, NVME_CSI_NVM, &nvm_ns);
if (!err)
nvme_show_nvm_id_ns(&nvm_ns, 0, &ns, cfg.lba_format_index, true,
@@ -2909,8 +3064,8 @@ static int nvm_id_ns_lba_format(int argc, char **argv, struct command *cmd, stru
nvme_show_status(err);
else
perror("NVM identify namespace for specific LBA format");
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return nvme_status_to_errno(err, false);
}
@@ -2923,8 +3078,9 @@ static int ns_descs(int argc, char **argv, struct command *cmd, struct plugin *p
const char *raw = "show descriptors in binary format";
const char *namespace_id = "identifier of desired namespace";
enum nvme_print_flags flags;
- int err, fd;
+ struct nvme_dev *dev;
void *nsdescs;
+ int err;
struct config {
__u32 namespace_id;
@@ -2945,30 +3101,30 @@ static int ns_descs(int argc, char **argv, struct command *cmd, struct plugin *p
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
err = flags = validate_output_format(cfg.output_format);
if (flags < 0)
- goto close_fd;
+ goto close_dev;
if (cfg.raw_binary)
flags = BINARY;
if (!cfg.namespace_id) {
- err = nvme_get_nsid(fd, &cfg.namespace_id);
+ err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
- goto close_fd;
+ goto close_dev;
}
}
if (posix_memalign(&nsdescs, getpagesize(), 0x1000)) {
err = -ENOMEM;
- goto close_fd;
+ goto close_dev;
}
- err = nvme_identify_ns_descs(fd, cfg.namespace_id, nsdescs);
+ err = nvme_identify_ns_descs(dev_fd(dev), cfg.namespace_id, nsdescs);
if (!err)
nvme_show_id_ns_descs(nsdescs, cfg.namespace_id, flags);
else if (err > 0)
@@ -2976,8 +3132,8 @@ static int ns_descs(int argc, char **argv, struct command *cmd, struct plugin *p
else
fprintf(stderr, "identify namespace: %s\n", nvme_strerror(errno));
free(nsdescs);
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -2996,7 +3152,8 @@ static int id_ns(int argc, char **argv, struct command *cmd, struct plugin *plug
enum nvme_print_flags flags;
struct nvme_id_ns ns;
- int err, fd;
+ struct nvme_dev *dev;
+ int err;
struct config {
__u32 namespace_id;
@@ -3026,13 +3183,13 @@ static int id_ns(int argc, char **argv, struct command *cmd, struct plugin *plug
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
err = flags = validate_output_format(cfg.output_format);
if (flags < 0)
- goto close_fd;
+ goto close_dev;
if (cfg.raw_binary)
flags = BINARY;
if (cfg.vendor_specific)
@@ -3041,17 +3198,18 @@ static int id_ns(int argc, char **argv, struct command *cmd, struct plugin *plug
flags |= VERBOSE;
if (!cfg.namespace_id) {
- err = nvme_get_nsid(fd, &cfg.namespace_id);
+ err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
- goto close_fd;
+ goto close_dev;
}
}
if (cfg.force)
- err = nvme_identify_allocated_ns(fd, cfg.namespace_id, &ns);
+ err = nvme_cli_identify_allocated_ns(dev,
+ cfg.namespace_id, &ns);
else
- err = nvme_identify_ns(fd, cfg.namespace_id, &ns);
+ err = nvme_cli_identify_ns(dev, cfg.namespace_id, &ns);
if (!err)
nvme_show_id_ns(&ns, cfg.namespace_id, 0, false, flags);
@@ -3059,8 +3217,8 @@ static int id_ns(int argc, char **argv, struct command *cmd, struct plugin *plug
nvme_show_status(err);
else
fprintf(stderr, "identify namespace: %s\n", nvme_strerror(errno));
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -3077,7 +3235,8 @@ static int cmd_set_independent_id_ns(int argc, char **argv,
enum nvme_print_flags flags;
struct nvme_id_independent_id_ns ns;
- int err = -1, fd;
+ struct nvme_dev *dev;
+ int err = -1;
struct config {
__u32 namespace_id;
@@ -3101,35 +3260,37 @@ static int cmd_set_independent_id_ns(int argc, char **argv,
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
err = flags = validate_output_format(cfg.output_format);
if (flags < 0)
- goto close_fd;
+ goto close_dev;
if (cfg.raw_binary)
flags = BINARY;
if (cfg.human_readable)
flags |= VERBOSE;
if (!cfg.namespace_id) {
- err = cfg.namespace_id = nvme_get_nsid(fd, &cfg.namespace_id);
+ err = cfg.namespace_id = nvme_get_nsid(dev_fd(dev),
+ &cfg.namespace_id);
if (err < 0) {
perror("get-namespace-id");
- goto close_fd;
+ goto close_dev;
}
}
- err = nvme_identify_independent_identify_ns(fd, cfg.namespace_id, &ns);
+ err = nvme_identify_independent_identify_ns(dev_fd(dev),
+ cfg.namespace_id, &ns);
if (!err)
nvme_show_cmd_set_independent_id_ns(&ns, cfg.namespace_id, flags);
else if (err > 0)
nvme_show_status(err);
else
fprintf(stderr, "I/O command set independent identify namespace: %s\n", nvme_strerror(errno));
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -3142,7 +3303,8 @@ static int id_ns_granularity(int argc, char **argv, struct command *cmd, struct
struct nvme_id_ns_granularity_list *granularity_list;
enum nvme_print_flags flags;
- int err, fd;
+ struct nvme_dev *dev;
+ int err;
struct config {
char *output_format;
@@ -3157,21 +3319,21 @@ static int id_ns_granularity(int argc, char **argv, struct command *cmd, struct
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
err = flags = validate_output_format(cfg.output_format);
if (flags < 0)
- goto close_fd;
+ goto close_dev;
if (posix_memalign((void *)&granularity_list, getpagesize(), NVME_IDENTIFY_DATA_SIZE)) {
fprintf(stderr, "can not allocate granularity list payload\n");
err = -ENOMEM;
- goto close_fd;
+ goto close_dev;
}
- err = nvme_identify_ns_granularity(fd, granularity_list);
+ err = nvme_identify_ns_granularity(dev_fd(dev), granularity_list);
if (!err)
nvme_show_id_ns_granularity_list(granularity_list, flags);
else if (err > 0)
@@ -3179,8 +3341,8 @@ static int id_ns_granularity(int argc, char **argv, struct command *cmd, struct
else
fprintf(stderr, "identify namespace granularity: %s\n", nvme_strerror(errno));
free(granularity_list);
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -3195,7 +3357,8 @@ static int id_nvmset(int argc, char **argv, struct command *cmd, struct plugin *
struct nvme_id_nvmset_list nvmset;
enum nvme_print_flags flags;
- int err, fd;
+ struct nvme_dev *dev;
+ int err;
struct config {
__u16 nvmset_id;
@@ -3213,15 +3376,15 @@ static int id_nvmset(int argc, char **argv, struct command *cmd, struct plugin *
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
err = flags = validate_output_format(cfg.output_format);
if (flags < 0)
- goto close_fd;
+ goto close_dev;
- err = nvme_identify_nvmset_list(fd, cfg.nvmset_id, &nvmset);
+ err = nvme_identify_nvmset_list(dev_fd(dev), cfg.nvmset_id, &nvmset);
if (!err)
nvme_show_id_nvmset(&nvmset, cfg.nvmset_id, flags);
else if (err > 0)
@@ -3229,8 +3392,8 @@ static int id_nvmset(int argc, char **argv, struct command *cmd, struct plugin *
else
fprintf(stderr, "identify nvm set list: %s\n", nvme_strerror(errno));
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -3245,7 +3408,8 @@ static int id_uuid(int argc, char **argv, struct command *cmd, struct plugin *pl
struct nvme_id_uuid_list uuid_list;
enum nvme_print_flags flags;
- int err, fd;
+ struct nvme_dev *dev;
+ int err;
struct config {
char *output_format;
@@ -3266,27 +3430,27 @@ static int id_uuid(int argc, char **argv, struct command *cmd, struct plugin *pl
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
err = flags = validate_output_format(cfg.output_format);
if (flags < 0)
- goto close_fd;
+ goto close_dev;
if (cfg.raw_binary)
flags = BINARY;
if (cfg.human_readable)
flags |= VERBOSE;
- err = nvme_identify_uuid(fd, &uuid_list);
+ err = nvme_identify_uuid(dev_fd(dev), &uuid_list);
if (!err)
nvme_show_id_uuid_list(&uuid_list, flags);
else if (err > 0)
nvme_show_status(err);
else
fprintf(stderr, "identify UUID list: %s\n", nvme_strerror(errno));
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;;
}
@@ -3298,7 +3462,8 @@ static int id_iocs(int argc, char **argv, struct command *cmd, struct plugin *pl
"in either human-readable or binary format.";
const char *controller_id = "identifier of desired controller";
struct nvme_id_iocs iocs;
- int err, fd;
+ struct nvme_dev *dev;
+ int err;
struct config {
__u16 cntid;
@@ -3313,13 +3478,11 @@ static int id_iocs(int argc, char **argv, struct command *cmd, struct plugin *pl
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0) {
- err = fd;
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
- }
- err = nvme_identify_iocs(fd, cfg.cntid, &iocs);
+ err = nvme_identify_iocs(dev_fd(dev), cfg.cntid, &iocs);
if (!err) {
printf("NVMe Identify I/O Command Set:\n");
nvme_show_id_iocs(&iocs);
@@ -3328,7 +3491,7 @@ static int id_iocs(int argc, char **argv, struct command *cmd, struct plugin *pl
else
fprintf(stderr, "NVMe Identify I/O Command Set: %s\n", nvme_strerror(errno));
- close(fd);
+ dev_close(dev);
ret:
return err;
}
@@ -3340,7 +3503,8 @@ static int id_domain(int argc, char **argv, struct command *cmd, struct plugin *
const char *domain_id = "identifier of desired domain";
struct nvme_id_domain_list id_domain;
enum nvme_print_flags flags;
- int err, fd;
+ struct nvme_dev *dev;
+ int err;
struct config {
__u16 dom_id;
@@ -3358,17 +3522,15 @@ static int id_domain(int argc, char **argv, struct command *cmd, struct plugin *
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0) {
- err = fd;
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
- }
err = flags = validate_output_format(cfg.output_format);
if (flags < 0)
- goto close_fd;
+ goto close_dev;
- err = nvme_identify_domain_list(fd, cfg.dom_id, &id_domain);
+ err = nvme_identify_domain_list(dev_fd(dev), cfg.dom_id, &id_domain);
if (!err) {
printf("NVMe Identify command for Domain List is successful:\n");
printf("NVMe Identify Domain List:\n");
@@ -3378,8 +3540,8 @@ static int id_domain(int argc, char **argv, struct command *cmd, struct plugin *
else
fprintf(stderr, "NVMe Identify Domain List: %s\n", nvme_strerror(errno));
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -3387,28 +3549,29 @@ ret:
static int get_ns_id(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
const char *desc = "Get namespace ID of a the block device.";
- int err = 0, fd;
+ struct nvme_dev *dev;
unsigned int nsid;
+ int err = 0;
OPT_ARGS(opts) = {
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
- err = nvme_get_nsid(fd, &nsid);
+ err = nvme_get_nsid(dev_fd(dev), &nsid);
if (err < 0) {
fprintf(stderr, "get namespace ID: %s\n", nvme_strerror(errno));
err = errno;
goto close_fd;
}
err = 0;
- printf("%s: namespace-id:%d\n", devicename, nsid);
+ printf("%s: namespace-id:%d\n", dev->name, nsid);
close_fd:
- close(fd);
+ dev_close(dev);
ret:
return err;
}
@@ -3430,8 +3593,9 @@ static int virtual_mgmt(int argc, char **argv, struct command *cmd, struct plugi
"8h: Secondary Assign\n"\
"9h: Secondary Online";
const char *nr = "Number of Controller Resources(NR)";
- int fd, err;
+ struct nvme_dev *dev;
__u32 result;
+ int err;
struct config {
__u16 cntlid;
@@ -3455,13 +3619,13 @@ static int virtual_mgmt(int argc, char **argv, struct command *cmd, struct plugi
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
struct nvme_virtual_mgmt_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.act = cfg.act,
.rt = cfg.rt,
.cntlid = cfg.cntlid,
@@ -3478,7 +3642,7 @@ static int virtual_mgmt(int argc, char **argv, struct command *cmd, struct plugi
} else
fprintf(stderr, "virt-mgmt: %s\n", nvme_strerror(errno));
- close(fd);
+ dev_close(dev);
ret:
return err;
}
@@ -3491,9 +3655,9 @@ static int primary_ctrl_caps(int argc, char **argv, struct command *cmd, struct
"decoded format (default), json or binary.";
const char *human_readable = "show info in readable format";
struct nvme_primary_ctrl_cap caps;
-
- int err, fd;
enum nvme_print_flags flags;
+ struct nvme_dev *dev;
+ int err;
struct config {
__u16 cntlid;
@@ -3514,25 +3678,25 @@ static int primary_ctrl_caps(int argc, char **argv, struct command *cmd, struct
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
err = flags = validate_output_format(cfg.output_format);
if (flags < 0)
- goto close_fd;
+ goto close_dev;
if (cfg.human_readable)
flags |= VERBOSE;
- err = nvme_identify_primary_ctrl(fd, cfg.cntlid, &caps);
+ err = nvme_identify_primary_ctrl(dev_fd(dev), cfg.cntlid, &caps);
if (!err)
nvme_show_primary_ctrl_cap(&caps, flags);
else if (err > 0)
nvme_show_status(err);
else
fprintf(stderr, "identify primary controller capabilities: %s\n", nvme_strerror(errno));
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -3547,7 +3711,8 @@ static int list_secondary_ctrl(int argc, char **argv, struct command *cmd, struc
struct nvme_secondary_ctrl_list *sc_list;
enum nvme_print_flags flags;
- int err, fd;
+ struct nvme_dev *dev;
+ int err;
struct config {
__u16 cntid;
@@ -3571,27 +3736,28 @@ static int list_secondary_ctrl(int argc, char **argv, struct command *cmd, struc
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
err = flags = validate_output_format(cfg.output_format);
if (flags < 0)
- goto close_fd;
+ goto close_err;
if (!cfg.num_entries) {
fprintf(stderr, "non-zero num-entries is required param\n");
err = -EINVAL;
- goto close_fd;
+ goto close_err;
}
if (posix_memalign((void *)&sc_list, getpagesize(), sizeof(*sc_list))) {
fprintf(stderr, "can not allocate controller list payload\n");
err = -ENOMEM;
- goto close_fd;
+ goto close_err;
}
- err = nvme_identify_secondary_ctrl_list(fd, cfg.namespace_id, cfg.cntid, sc_list);
+ err = nvme_identify_secondary_ctrl_list(dev_fd(dev), cfg.namespace_id,
+ cfg.cntid, sc_list);
if (!err)
nvme_show_list_secondary_ctrl(sc_list, cfg.num_entries, flags);
else if (err > 0)
@@ -3601,8 +3767,8 @@ static int list_secondary_ctrl(int argc, char **argv, struct command *cmd, struc
free(sc_list);
-close_fd:
- close(fd);
+close_err:
+ dev_close(dev);
ret:
return err;
}
@@ -3618,7 +3784,8 @@ static int device_self_test(int argc, char **argv, struct command *cmd, struct p
"2h Start a extended device self-test operation\n"\
"eh Start a vendor specific device self-test operation\n"\
"fh abort the device self-test operation\n";
- int fd, err;
+ struct nvme_dev *dev;
+ int err;
struct config {
__u32 namespace_id;
@@ -3636,13 +3803,13 @@ static int device_self_test(int argc, char **argv, struct command *cmd, struct p
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
struct nvme_dev_self_test_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.nsid = cfg.namespace_id,
.stc = cfg.stc,
.timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
@@ -3661,7 +3828,7 @@ static int device_self_test(int argc, char **argv, struct command *cmd, struct p
} else
fprintf(stderr, "Device self-test: %s\n", nvme_strerror(errno));
- close(fd);
+ dev_close(dev);
ret:
return err;
}
@@ -3677,7 +3844,8 @@ static int self_test_log(int argc, char **argv, struct command *cmd, struct plug
struct nvme_self_test_log log;
enum nvme_print_flags flags;
- int err, fd;
+ struct nvme_dev *dev;
+ int err;
struct config {
__u8 dst_entries;
@@ -3698,32 +3866,32 @@ static int self_test_log(int argc, char **argv, struct command *cmd, struct plug
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
err = flags = validate_output_format(cfg.output_format);
if (flags < 0)
- goto close_fd;
+ goto close_dev;
if (cfg.verbose)
flags |= VERBOSE;
- err = nvme_get_log_device_self_test(fd, &log);
+ err = nvme_cli_get_log_device_self_test(dev, &log);
if (!err)
nvme_show_self_test_log(&log, cfg.dst_entries, 0,
- devicename, flags);
+ dev->name, flags);
else if (err > 0)
nvme_show_status(err);
else
fprintf(stderr, "self test log: %s\n", nvme_strerror(errno));
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
-static int get_feature_id(int fd, struct feat_cfg *cfg, void **buf,
- __u32 *result)
+static int get_feature_id(struct nvme_dev *dev, struct feat_cfg *cfg,
+ void **buf, __u32 *result)
{
if (!cfg->data_len)
nvme_get_feature_length(cfg->feature_id, cfg->cdw11,
@@ -3745,7 +3913,6 @@ static int get_feature_id(int fd, struct feat_cfg *cfg, void **buf,
struct nvme_get_features_args args = {
.args_size = sizeof(args),
- .fd = fd,
.fid = cfg->feature_id,
.nsid = cfg->namespace_id,
.sel = cfg->sel,
@@ -3756,7 +3923,7 @@ static int get_feature_id(int fd, struct feat_cfg *cfg, void **buf,
.timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
.result = result,
};
- return nvme_get_features(&args);
+ return nvme_cli_get_features(dev, &args);
}
static void get_feature_id_print(struct feat_cfg cfg, int err, __u32 result,
@@ -3780,14 +3947,16 @@ static void get_feature_id_print(struct feat_cfg cfg, int err, __u32 result,
d_raw(buf, cfg.data_len);
}
} else if (err > 0) {
- if (err != NVME_SC_INVALID_FIELD)
+ if (!nvme_status_equals(err, NVME_STATUS_TYPE_NVME,
+ NVME_SC_INVALID_FIELD))
nvme_show_status(err);
} else {
fprintf(stderr, "get-feature: %s\n", nvme_strerror(errno));
}
}
-static int get_feature_id_changed(int fd, struct feat_cfg cfg, bool changed)
+static int get_feature_id_changed(struct nvme_dev *dev, struct feat_cfg cfg,
+ bool changed)
{
int err;
int err_def = 0;
@@ -3799,11 +3968,11 @@ static int get_feature_id_changed(int fd, struct feat_cfg cfg, bool changed)
if (changed)
cfg.sel = 0;
- err = get_feature_id(fd, &cfg, &buf, &result);
+ err = get_feature_id(dev, &cfg, &buf, &result);
if (!err && changed) {
cfg.sel = 1;
- err_def = get_feature_id(fd, &cfg, &buf_def, &result_def);
+ err_def = get_feature_id(dev, &cfg, &buf_def, &result_def);
}
if (changed)
@@ -3819,7 +3988,7 @@ static int get_feature_id_changed(int fd, struct feat_cfg cfg, bool changed)
return err;
}
-static int get_feature_ids(int fd, struct feat_cfg cfg)
+static int get_feature_ids(struct nvme_dev *dev, struct feat_cfg cfg)
{
int err = 0;
int i;
@@ -3835,12 +4004,14 @@ static int get_feature_ids(int fd, struct feat_cfg cfg)
for (i = cfg.feature_id; i < feat_max; i++, feat_num++) {
cfg.feature_id = i;
- err = get_feature_id_changed(fd, cfg, changed);
- if (err && err != NVME_SC_INVALID_FIELD)
+ err = get_feature_id_changed(dev, cfg, changed);
+ if (err && !nvme_status_equals(err, NVME_STATUS_TYPE_NVME,
+ NVME_SC_INVALID_FIELD))
break;
}
- if (err == NVME_SC_INVALID_FIELD && feat_num == 1)
+ if (feat_num == 1 && nvme_status_equals(err, NVME_STATUS_TYPE_NVME,
+ NVME_SC_INVALID_FIELD))
nvme_show_status(err);
return err;
@@ -3866,8 +4037,8 @@ static int get_feature(int argc, char **argv, struct command *cmd,
const char *cdw11 = "dword 11 for interrupt vector config";
const char *human_readable = "show feature in readable format";
const char *uuid_index = "specify uuid index";
+ struct nvme_dev *dev;
int err;
- int fd;
struct feat_cfg cfg = {
.feature_id = 0,
@@ -3892,16 +4063,16 @@ static int get_feature(int argc, char **argv, struct command *cmd,
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
if (!cfg.namespace_id) {
- err = nvme_get_nsid(fd, &cfg.namespace_id);
+ err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
if (errno != ENOTTY) {
fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
- goto close_fd;
+ goto close_dev;
}
cfg.namespace_id = NVME_NSID_ALL;
}
@@ -3910,19 +4081,19 @@ static int get_feature(int argc, char **argv, struct command *cmd,
if (cfg.sel > 8) {
fprintf(stderr, "invalid 'select' param:%d\n", cfg.sel);
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
if (cfg.uuid_index > 128) {
fprintf(stderr, "invalid uuid index param: %u\n", cfg.uuid_index);
err = -1;
- goto close_fd;
+ goto close_dev;
}
- err = get_feature_ids(fd, cfg);
+ err = get_feature_ids(dev, cfg);
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
@@ -3941,10 +4112,11 @@ static int fw_download(int argc, char **argv, struct command *cmd, struct plugin
const char *fw = "firmware file (required)";
const char *xfer = "transfer chunksize limit";
const char *offset = "starting dword offset, default 0";
- int err, fd, fw_fd = -1;
unsigned int fw_size;
- struct stat sb;
+ struct nvme_dev *dev;
void *fw_buf, *buf;
+ int err, fw_fd = -1;
+ struct stat sb;
bool huge;
struct config {
@@ -3966,8 +4138,8 @@ static int fw_download(int argc, char **argv, struct command *cmd, struct plugin
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
fw_fd = open(cfg.fw, O_RDONLY);
@@ -3976,7 +4148,7 @@ static int fw_download(int argc, char **argv, struct command *cmd, struct plugin
fprintf(stderr, "Failed to open firmware file %s: %s\n",
cfg.fw, strerror(errno));
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
err = fstat(fw_fd, &sb);
@@ -4017,14 +4189,13 @@ static int fw_download(int argc, char **argv, struct command *cmd, struct plugin
struct nvme_fw_download_args args = {
.args_size = sizeof(args),
- .fd = fd,
.offset = cfg.offset,
.data_len = cfg.xfer,
.data = fw_buf,
.timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
.result = NULL,
};
- err = nvme_fw_download(&args);
+ err = nvme_cli_fw_download(dev, &args);
if (err < 0) {
fprintf(stderr, "fw-download: %s\n", nvme_strerror(errno));
break;
@@ -4043,8 +4214,8 @@ free:
nvme_free(buf, huge);
close_fw_fd:
close(fw_fd);
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -4069,8 +4240,9 @@ static int fw_commit(int argc, char **argv, struct command *cmd, struct plugin *
const char *slot = "[0-7]: firmware slot for commit action";
const char *action = "[0-7]: commit action";
const char *bpid = "[0,1]: boot partition identifier, if applicable (default: 0)";
- int err, fd;
+ struct nvme_dev *dev;
__u32 result;
+ int err;
struct config {
__u8 slot;
@@ -4091,54 +4263,62 @@ static int fw_commit(int argc, char **argv, struct command *cmd, struct plugin *
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
if (cfg.slot > 7) {
fprintf(stderr, "invalid slot:%d\n", cfg.slot);
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
if (cfg.action > 7 || cfg.action == 4 || cfg.action == 5) {
fprintf(stderr, "invalid action:%d\n", cfg.action);
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
if (cfg.bpid > 1) {
fprintf(stderr, "invalid boot partition id:%d\n", cfg.bpid);
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
struct nvme_fw_commit_args args = {
.args_size = sizeof(args),
- .fd = fd,
.slot = cfg.slot,
.action = cfg.action,
.bpid = cfg.bpid,
.timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
.result = &result,
};
- err = nvme_fw_commit(&args);
+ err = nvme_cli_fw_commit(dev, &args);
+
if (err < 0)
fprintf(stderr, "fw-commit: %s\n", nvme_strerror(errno));
- else if (err != 0)
- switch (err & 0x7ff) {
- case NVME_SC_FW_NEEDS_CONV_RESET:
- case NVME_SC_FW_NEEDS_SUBSYS_RESET:
- case NVME_SC_FW_NEEDS_RESET:
- printf("Success activating firmware action:%d slot:%d",
- cfg.action, cfg.slot);
- if (cfg.action == 6 || cfg.action == 7)
- printf(" bpid:%d", cfg.bpid);
- printf(", but firmware requires %s reset\n", nvme_fw_status_reset_type(err));
- break;
- default:
+ else if (err != 0) {
+ __u32 val = nvme_status_get_value(err);
+ int type = nvme_status_get_type(err);
+
+ if (type == NVME_STATUS_TYPE_NVME) {
+ switch (val & 0x7ff) {
+ case NVME_SC_FW_NEEDS_CONV_RESET:
+ case NVME_SC_FW_NEEDS_SUBSYS_RESET:
+ case NVME_SC_FW_NEEDS_RESET:
+ printf("Success activating firmware action:%d slot:%d",
+ cfg.action, cfg.slot);
+ if (cfg.action == 6 || cfg.action == 7)
+ printf(" bpid:%d", cfg.bpid);
+ printf(", but firmware requires %s reset\n",
+ nvme_fw_status_reset_type(val));
+ break;
+ default:
+ nvme_show_status(err);
+ break;
+ }
+ } else {
nvme_show_status(err);
- break;
}
- else {
+ } else {
printf("Success committing firmware action:%d slot:%d",
cfg.action, cfg.slot);
if (cfg.action == 6 || cfg.action == 7)
@@ -4156,8 +4336,8 @@ static int fw_commit(int argc, char **argv, struct command *cmd, struct plugin *
"sequence due to processing a command from an Admin SQ on a controller");
}
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -4165,17 +4345,18 @@ ret:
static int subsystem_reset(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
const char *desc = "Resets the NVMe subsystem\n";
- int err, fd;
+ struct nvme_dev *dev;
+ int err;
OPT_ARGS(opts) = {
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
- err = nvme_subsystem_reset(fd);
+ err = nvme_subsystem_reset(dev_fd(dev));
if (err < 0) {
if (errno == ENOTTY)
fprintf(stderr,
@@ -4184,7 +4365,7 @@ static int subsystem_reset(int argc, char **argv, struct command *cmd, struct pl
fprintf(stderr, "Subsystem-reset: %s\n", nvme_strerror(errno));
}
- close(fd);
+ dev_close(dev);
ret:
return err;
}
@@ -4192,21 +4373,22 @@ ret:
static int reset(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
const char *desc = "Resets the NVMe controller\n";
- int err, fd;
+ struct nvme_dev *dev;
+ int err;
OPT_ARGS(opts) = {
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
- err = nvme_ctrl_reset(fd);
+ err = nvme_ctrl_reset(dev_fd(dev));
if (err < 0)
fprintf(stderr, "Reset: %s\n", nvme_strerror(errno));
- close(fd);
+ dev_close(dev);
ret:
return err;
}
@@ -4214,21 +4396,22 @@ ret:
static int ns_rescan(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
const char *desc = "Rescans the NVMe namespaces\n";
- int err, fd;
+ struct nvme_dev *dev;
+ int err;
OPT_ARGS(opts) = {
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
- err = nvme_ns_rescan(fd);
+ err = nvme_ns_rescan(dev_fd(dev));
if (err < 0)
fprintf(stderr, "Namespace Rescan");
- close(fd);
+ dev_close(dev);
ret:
return err;
}
@@ -4242,7 +4425,8 @@ static int sanitize(int argc, char **argv, struct command *cmd, struct plugin *p
const char *ause_desc = "Allow unrestricted sanitize exit.";
const char *sanact_desc = "Sanitize action.";
const char *ovrpat_desc = "Overwrite pattern.";
- int fd, err;
+ struct nvme_dev *dev;
+ int err;
struct config {
bool no_dealloc;
@@ -4272,8 +4456,8 @@ static int sanitize(int argc, char **argv, struct command *cmd, struct plugin *p
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
switch (cfg.sanact) {
@@ -4285,14 +4469,14 @@ static int sanitize(int argc, char **argv, struct command *cmd, struct plugin *p
default:
fprintf(stderr, "Invalid Sanitize Action\n");
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
if (cfg.sanact == NVME_SANITIZE_SANACT_EXIT_FAILURE) {
if (cfg.ause || cfg.no_dealloc) {
fprintf(stderr, "SANACT is Exit Failure Mode\n");
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
}
@@ -4300,36 +4484,34 @@ static int sanitize(int argc, char **argv, struct command *cmd, struct plugin *p
if (cfg.owpass > 16) {
fprintf(stderr, "OWPASS out of range [0-16]\n");
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
} else {
if (cfg.owpass || cfg.oipbp || cfg.ovrpat) {
fprintf(stderr, "SANACT is not Overwrite\n");
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
}
struct nvme_sanitize_nvm_args args = {
.args_size = sizeof(args),
- .fd = fd,
.sanact = cfg.sanact,
.ause = cfg.ause,
.owpass = cfg.owpass,
.oipbp = cfg.oipbp,
.nodas = cfg.no_dealloc,
.ovrpat = cfg.ovrpat,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
.result = NULL,
};
- err = nvme_sanitize_nvm(&args);
+ err = nvme_cli_sanitize_nvm(dev, &args);
if (err < 0)
fprintf(stderr, "sanitize: %s\n", nvme_strerror(errno));
else if (err > 0)
nvme_show_status(err);
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -4354,8 +4536,10 @@ static int nvme_get_properties(int fd, void **pbar)
.value = &value,
.timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
};
+
err = nvme_get_property(&args);
- if (err > 0 && (err & 0xff) == NVME_SC_INVALID_FIELD) {
+ if (nvme_status_equals(err, NVME_STATUS_TYPE_NVME,
+ NVME_SC_INVALID_FIELD)) {
err = 0;
value = -1;
} else if (err) {
@@ -4374,7 +4558,7 @@ static int nvme_get_properties(int fd, void **pbar)
return err;
}
-static void *mmap_registers(nvme_root_t r, const char *dev)
+static void *mmap_registers(nvme_root_t r, struct nvme_dev *dev)
{
nvme_ctrl_t c = NULL;
nvme_ns_t n = NULL;
@@ -4383,15 +4567,15 @@ static void *mmap_registers(nvme_root_t r, const char *dev)
void *membase;
int fd;
- c = nvme_scan_ctrl(r, devicename);
+ c = nvme_scan_ctrl(r, dev->name);
if (c) {
snprintf(path, sizeof(path), "%s/device/resource0",
nvme_ctrl_get_sysfs_dir(c));
nvme_free_ctrl(c);
} else {
- n = nvme_scan_namespace(devicename);
+ n = nvme_scan_namespace(dev->name);
if (!n) {
- fprintf(stderr, "Unable to find %s\n", devicename);
+ fprintf(stderr, "Unable to find %s\n", dev->name);
return NULL;
}
snprintf(path, sizeof(path), "%s/device/device/resource0",
@@ -4402,13 +4586,13 @@ static void *mmap_registers(nvme_root_t r, const char *dev)
fd = open(path, O_RDONLY);
if (fd < 0) {
fprintf(stderr, "%s did not find a pci resource, open failed %s\n",
- devicename, strerror(errno));
+ dev->name, strerror(errno));
return NULL;
}
membase = mmap(NULL, getpagesize(), PROT_READ, MAP_SHARED, fd, 0);
if (membase == MAP_FAILED) {
- fprintf(stderr, "%s failed to map. ", devicename);
+ fprintf(stderr, "%s failed to map. ", dev->name);
fprintf(stderr, "Did your kernel enable CONFIG_IO_STRICT_DEVMEM?\n");
membase = NULL;
}
@@ -4425,10 +4609,11 @@ static int show_registers(int argc, char **argv, struct command *cmd, struct plu
"output_format == normal";
enum nvme_print_flags flags;
- nvme_root_t r;
+ struct nvme_dev *dev;
bool fabrics = true;
- int fd, err;
+ nvme_root_t r;
void *bar;
+ int err;
struct config {
char *output_format;
@@ -4446,34 +4631,34 @@ static int show_registers(int argc, char **argv, struct command *cmd, struct plu
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
r = nvme_scan(NULL);
err = flags = validate_output_format(cfg.output_format);
if (flags < 0)
- goto close_fd;
+ goto close_dev;
if (cfg.human_readable)
flags |= VERBOSE;
- err = nvme_get_properties(fd, &bar);
+ err = nvme_get_properties(dev_fd(dev), &bar);
if (err) {
- bar = mmap_registers(r, devicename);
+ bar = mmap_registers(r, dev);
fabrics = false;
if (bar)
err = 0;
}
if (!bar)
- goto close_fd;
+ goto close_dev;
nvme_show_ctrl_registers(bar, fabrics, flags);
if (fabrics)
free(bar);
else
munmap(bar, getpagesize());
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
nvme_free_tree(r);
ret:
return err;
@@ -4487,8 +4672,9 @@ static int get_property(int argc, char **argv, struct command *cmd, struct plugi
const char *offset = "offset of the requested property";
const char *human_readable = "show property in readable format";
- int fd, err;
+ struct nvme_dev *dev;
__u64 value;
+ int err;
struct config {
int offset;
@@ -4506,19 +4692,19 @@ static int get_property(int argc, char **argv, struct command *cmd, struct plugi
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
if (cfg.offset == -1) {
fprintf(stderr, "offset required param\n");
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
struct nvme_get_property_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.offset = cfg.offset,
.value = &value,
.timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
@@ -4532,8 +4718,8 @@ static int get_property(int argc, char **argv, struct command *cmd, struct plugi
nvme_show_status(err);
}
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -4544,7 +4730,8 @@ static int set_property(int argc, char **argv, struct command *cmd, struct plugi
"for NVMe over Fabric";
const char *offset = "the offset of the property";
const char *value = "the value of the property to be set";
- int fd, err;
+ struct nvme_dev *dev;
+ int err;
struct config {
int offset;
@@ -4562,24 +4749,24 @@ static int set_property(int argc, char **argv, struct command *cmd, struct plugi
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
if (cfg.offset == -1) {
fprintf(stderr, "offset required param\n");
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
if (cfg.value == -1) {
fprintf(stderr, "value required param\n");
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
struct nvme_set_property_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.offset = cfg.offset,
.value = cfg.value,
.timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
@@ -4595,8 +4782,8 @@ static int set_property(int argc, char **argv, struct command *cmd, struct plugi
nvme_show_status(err);
}
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -4619,9 +4806,10 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
const char *force = "The \"I know what I'm doing\" flag, skip confirmation before sending command";
struct nvme_id_ns ns;
struct nvme_id_ctrl ctrl;
- int err, fd, i;
- int block_size;
+ struct nvme_dev *dev;
__u8 prev_lbaf = 0;
+ int block_size;
+ int err, i;
struct config {
__u32 namespace_id;
@@ -4667,8 +4855,8 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
if (err)
goto ret;
- err = fd = open_exclusive(argc, argv, cfg.force);
- if (fd < 0) {
+ err = open_exclusive(&dev, argc, argv, cfg.force);
+ if (err) {
if (errno == EBUSY) {
fprintf(stderr, "Failed to open %s.\n",
basename(argv[optind]));
@@ -4687,7 +4875,7 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
fprintf(stderr,
"Invalid specification of both LBAF and Block Size, please specify only one\n");
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
if (cfg.bs) {
if ((cfg.bs & (~cfg.bs + 1)) != cfg.bs) {
@@ -4695,14 +4883,14 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
"Invalid value for block size (%"PRIu64"), must be a power of two\n",
(uint64_t) cfg.bs);
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
}
- err = nvme_identify_ctrl(fd, &ctrl);
+ err = nvme_cli_identify_ctrl(dev, &ctrl);
if (err) {
fprintf(stderr, "identify-ctrl: %s\n", nvme_strerror(errno));
- goto close_fd;
+ goto close_dev;
}
if ((ctrl.fna & 1) == 1) {
@@ -4713,10 +4901,10 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
*/
cfg.namespace_id = NVME_NSID_ALL;
} else if (!cfg.namespace_id) {
- err = nvme_get_nsid(fd, &cfg.namespace_id);
+ err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
- goto close_fd;
+ goto close_dev;
}
}
@@ -4726,11 +4914,11 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
"specify a namespace to format or use '-n 0xffffffff' "
"to format all namespaces on this controller.\n");
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
if (cfg.namespace_id != NVME_NSID_ALL) {
- err = nvme_identify_ns(fd, cfg.namespace_id, &ns);
+ err = nvme_cli_identify_ns(dev, cfg.namespace_id, &ns);
if (err) {
if (err < 0)
fprintf(stderr, "identify-namespace: %s\n", nvme_strerror(errno));
@@ -4738,7 +4926,7 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
fprintf(stderr, "identify failed\n");
nvme_show_status(err);
}
- goto close_fd;
+ goto close_dev;
}
nvme_id_ns_flbas_to_lbaf_inuse(ns.flbas, &prev_lbaf);
@@ -4757,7 +4945,7 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
fprintf(stderr,
"Please correct block size, or specify LBAF directly\n");
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
} else if (cfg.lbaf == 0xff)
cfg.lbaf = prev_lbaf;
@@ -4769,34 +4957,34 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
if (cfg.ses > 7) {
fprintf(stderr, "invalid secure erase settings:%d\n", cfg.ses);
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
if (cfg.lbaf > 63) {
fprintf(stderr, "invalid lbaf:%d\n", cfg.lbaf);
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
if (cfg.pi > 7) {
fprintf(stderr, "invalid pi:%d\n", cfg.pi);
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
if (cfg.pil > 1) {
fprintf(stderr, "invalid pil:%d\n", cfg.pil);
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
if (cfg.ms > 1) {
fprintf(stderr, "invalid ms:%d\n", cfg.ms);
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
if (!cfg.force) {
fprintf(stderr, "You are about to format %s, namespace %#x%s.\n",
- devicename, cfg.namespace_id,
+ dev->name, cfg.namespace_id,
cfg.namespace_id == NVME_NSID_ALL ? "(ALL namespaces)" : "");
- nvme_show_relatives(devicename);
+ nvme_show_relatives(dev->name);
fprintf(stderr, "WARNING: Format may irrevocably delete this device's data.\n"
"You have 10 seconds to press Ctrl-C to cancel this operation.\n\n"
"Use the force [--force] option to suppress this warning.\n");
@@ -4806,7 +4994,6 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
struct nvme_format_nvm_args args = {
.args_size = sizeof(args),
- .fd = fd,
.nsid = cfg.namespace_id,
.lbafu = (cfg.lbaf & NVME_NS_FLBAS_HIGHER_MASK) >> 4,
.lbaf = cfg.lbaf & NVME_NS_FLBAS_LOWER_MASK,
@@ -4817,19 +5004,19 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
.timeout = cfg.timeout,
.result = NULL,
};
- err = nvme_format_nvm(&args);
+ err = nvme_cli_format_nvm(dev, &args);
if (err < 0)
fprintf(stderr, "format: %s\n", nvme_strerror(errno));
else if (err != 0)
nvme_show_status(err);
else {
printf("Success formatting namespace:%x\n", cfg.namespace_id);
- if (cfg.lbaf != prev_lbaf){
- if (is_chardev()) {
- if(ioctl(fd, NVME_IOCTL_RESCAN) < 0){
+ if (dev->type == NVME_DEV_DIRECT && cfg.lbaf != prev_lbaf){
+ if (is_chardev(dev)) {
+ if (ioctl(dev_fd(dev), NVME_IOCTL_RESCAN) < 0) {
fprintf(stderr, "failed to rescan namespaces\n");
err = -errno;
- goto close_fd;
+ goto close_dev;
}
} else {
block_size = 1 << ns.lbaf[cfg.lbaf].ds;
@@ -4841,26 +5028,26 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
* to the given one because blkdev will not
* update by itself without re-opening fd.
*/
- if (ioctl(fd, BLKBSZSET, &block_size) < 0) {
+ if (ioctl(dev_fd(dev), BLKBSZSET, &block_size) < 0) {
fprintf(stderr, "failed to set block size to %d\n",
block_size);
err = -errno;
- goto close_fd;
+ goto close_dev;
}
- if(ioctl(fd, BLKRRPART) < 0) {
+ if (ioctl(dev_fd(dev), BLKRRPART) < 0) {
fprintf(stderr, "failed to re-read partition table\n");
err = -errno;
- goto close_fd;
+ goto close_dev;
}
}
}
- if (cfg.reset && is_chardev())
- nvme_ctrl_reset(fd);
+ if (dev->type == NVME_DEV_DIRECT && cfg.reset && is_chardev(dev))
+ nvme_ctrl_reset(dev_fd(dev));
}
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -4887,10 +5074,11 @@ static int set_feature(int argc, char **argv, struct command *cmd, struct plugin
const char *cdw12 = "feature cdw12, if used";
const char *save = "specifies that the controller shall save the attribute";
const char *uuid_index = "specify uuid index";
+ struct nvme_dev *dev;
int err;
__u32 result;
void *buf = NULL;
- int fd, ffd = STDIN_FILENO;
+ int ffd = STDIN_FILENO;
struct config {
__u32 namespace_id;
@@ -4925,16 +5113,16 @@ static int set_feature(int argc, char **argv, struct command *cmd, struct plugin
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
if (!cfg.namespace_id) {
- err = nvme_get_nsid(fd, &cfg.namespace_id);
+ err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
if (errno != ENOTTY) {
fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
- goto close_fd;
+ goto close_dev;
}
cfg.namespace_id = NVME_NSID_ALL;
@@ -4944,24 +5132,25 @@ static int set_feature(int argc, char **argv, struct command *cmd, struct plugin
if (!cfg.feature_id) {
fprintf(stderr, "feature-id required param\n");
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
if (cfg.uuid_index > 128) {
fprintf(stderr, "invalid uuid index param: %u\n", cfg.uuid_index);
err = -1;
- goto close_fd;
+ goto close_dev;
}
if (!cfg.data_len)
- nvme_get_feature_length(cfg.feature_id, cfg.value,
- &cfg.data_len);
+ nvme_cli_get_feature_length2(cfg.feature_id, cfg.value,
+ NVME_DATA_TFR_HOST_TO_CTRL,
+ &cfg.data_len);
if (cfg.data_len) {
if (posix_memalign(&buf, getpagesize(), cfg.data_len)) {
fprintf(stderr, "can not allocate feature payload\n");
err = -ENOMEM;
- goto close_fd;
+ goto close_dev;
}
memset(buf, 0, cfg.data_len);
}
@@ -4998,7 +5187,7 @@ static int set_feature(int argc, char **argv, struct command *cmd, struct plugin
struct nvme_set_features_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.fid = cfg.feature_id,
.nsid = cfg.namespace_id,
.cdw11 = cfg.value,
@@ -5038,8 +5227,8 @@ close_ffd:
close(ffd);
free:
free(buf);
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -5058,7 +5247,8 @@ static int sec_send(int argc, char **argv, struct command *cmd, struct plugin *p
const char *tl = "transfer length (cf. SPC-4)";
const char *namespace_id = "desired namespace";
const char *nssf = "NVMe Security Specific Field";
- int err, fd, sec_fd = STDIN_FILENO;
+ int err, sec_fd = STDIN_FILENO;
+ struct nvme_dev *dev;
void *sec_buf;
unsigned int sec_size;
@@ -5090,14 +5280,14 @@ static int sec_send(int argc, char **argv, struct command *cmd, struct plugin *p
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
if (cfg.tl == 0) {
fprintf(stderr, "--tl unspecified or zero\n");
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
if ((cfg.tl & 3) != 0)
fprintf(stderr, "WARNING: --tl not dword aligned; unaligned bytes may be truncated\n");
@@ -5111,7 +5301,7 @@ static int sec_send(int argc, char **argv, struct command *cmd, struct plugin *p
fprintf(stderr, "Failed to open %s: %s\n",
cfg.file, strerror(errno));
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
err = fstat(sec_fd, &sb);
@@ -5141,7 +5331,7 @@ static int sec_send(int argc, char **argv, struct command *cmd, struct plugin *p
struct nvme_security_send_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.nsid = cfg.namespace_id,
.nssf = cfg.nssf,
.spsp0 = cfg.spsp & 0xff,
@@ -5165,8 +5355,8 @@ free:
free(sec_buf);
close_sec_fd:
close(sec_fd);
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -5185,11 +5375,12 @@ static int dir_send(int argc, char **argv, struct command *cmd, struct plugin *p
const char *ttype = "target directive type to be enabled/disabled";
const char *human_readable = "show directive in readable format";
const char *input = "write/send file (default stdin)";
- int err, fd;
+ struct nvme_dev *dev;
__u32 result;
__u32 dw12 = 0;
void *buf = NULL;
int ffd = STDIN_FILENO;
+ int err;
struct config {
__u32 namespace_id;
@@ -5231,8 +5422,8 @@ static int dir_send(int argc, char **argv, struct command *cmd, struct plugin *p
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
switch (cfg.dtype) {
@@ -5242,14 +5433,14 @@ static int dir_send(int argc, char **argv, struct command *cmd, struct plugin *p
if (!cfg.ttype) {
fprintf(stderr, "target-dir required param\n");
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
dw12 = cfg.ttype << 8 | cfg.endir;
break;
default:
fprintf(stderr, "invalid directive operations for Identify Directives\n");
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
break;
case NVME_DIRECTIVE_DTYPE_STREAMS:
@@ -5260,20 +5451,20 @@ static int dir_send(int argc, char **argv, struct command *cmd, struct plugin *p
default:
fprintf(stderr, "invalid directive operations for Streams Directives\n");
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
break;
default:
fprintf(stderr, "invalid directive type\n");
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
if (cfg.data_len) {
if (posix_memalign(&buf, getpagesize(), cfg.data_len)) {
err = -ENOMEM;
- goto close_fd;
+ goto close_dev;
}
memset(buf, 0, cfg.data_len);
}
@@ -5299,7 +5490,7 @@ static int dir_send(int argc, char **argv, struct command *cmd, struct plugin *p
struct nvme_directive_send_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.nsid = cfg.namespace_id,
.dspec = cfg.dspec,
.doper = cfg.doper,
@@ -5331,20 +5522,21 @@ close_ffd:
close(ffd);
free:
free(buf);
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
static int write_uncor(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- int err, fd;
const char *desc = "The Write Uncorrectable command is used to set a "\
"range of logical blocks to invalid.";
const char *namespace_id = "desired namespace";
const char *start_block = "64-bit LBA of first block to access";
const char *block_count = "number of blocks (zeroes based) on device to access";
+ struct nvme_dev *dev;
+ int err;
struct config {
__u32 namespace_id;
@@ -5365,21 +5557,21 @@ static int write_uncor(int argc, char **argv, struct command *cmd, struct plugin
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
if (!cfg.namespace_id) {
- err = nvme_get_nsid(fd, &cfg.namespace_id);
+ err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
- goto close_fd;
+ goto close_dev;
}
}
struct nvme_io_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.nsid = cfg.namespace_id,
.slba = cfg.start_block,
.nlb = cfg.block_count,
@@ -5394,8 +5586,8 @@ static int write_uncor(int argc, char **argv, struct command *cmd, struct plugin
else
printf("NVME Write Uncorrectable Success\n");
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -5435,11 +5627,12 @@ static int invalid_tags(__u64 storage_tag, __u64 ref_tag, __u8 sts, __u8 pif)
static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- int err, fd;
__u16 control = 0;
__u8 lba_index, sts = 0, pif = 0;
struct nvme_id_ns ns;
+ struct nvme_dev *dev;
struct nvme_nvm_id_ns nvm_ns;
+ int err;
const char *desc = "The Write Zeroes command is used to set a "\
"range of logical blocks to zero.";
@@ -5503,13 +5696,13 @@ static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugi
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
if (cfg.prinfo > 0xf) {
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
control |= (cfg.prinfo << 10);
@@ -5522,23 +5715,24 @@ static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugi
if (cfg.storage_tag_check)
control |= NVME_IO_STC;
if (!cfg.namespace_id) {
- err = nvme_get_nsid(fd, &cfg.namespace_id);
+ err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
- goto close_fd;
+ goto close_dev;
}
}
- err = nvme_identify_ns(fd, cfg.namespace_id, &ns);
+ err = nvme_cli_identify_ns(dev, cfg.namespace_id, &ns);
if (err) {
nvme_show_status(err);
- goto close_fd;
+ goto close_dev;
} else if (err < 0) {
fprintf(stderr, "identify namespace: %s\n", nvme_strerror(errno));
- goto close_fd;
+ goto close_dev;
}
- err = nvme_identify_ns_csi(fd, cfg.namespace_id, 0, NVME_CSI_NVM, &nvm_ns);
+ err = nvme_identify_ns_csi(dev_fd(dev), cfg.namespace_id, 0,
+ NVME_CSI_NVM, &nvm_ns);
if (!err) {
nvme_id_ns_flbas_to_lbaf_inuse(ns.flbas, &lba_index);
sts = nvm_ns.elbaf[lba_index] & NVME_NVM_ELBAF_STS_MASK;
@@ -5547,12 +5741,12 @@ static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugi
if (invalid_tags(cfg.storage_tag, cfg.ref_tag, sts, pif)) {
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
struct nvme_io_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.nsid = cfg.namespace_id,
.slba = cfg.start_block,
.nlb = cfg.block_count,
@@ -5574,8 +5768,8 @@ static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugi
else
printf("NVME Write Zeroes Success\n");
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -5595,12 +5789,13 @@ static int dsm(int argc, char **argv, struct command *cmd, struct plugin *plugin
const char *idr = "Attribute Integral Dataset for Read";
const char *cdw11 = "All the command DWORD 11 attributes. Use instead of specifying individual attributes";
- int err, fd;
uint16_t nr, nc, nb, ns;
__u32 ctx_attrs[256] = {0,};
__u32 nlbs[256] = {0,};
__u64 slbas[256] = {0,};
struct nvme_dsm_range dsm[256];
+ struct nvme_dev *dev;
+ int err;
struct config {
__u32 namespace_id;
@@ -5636,8 +5831,8 @@ static int dsm(int argc, char **argv, struct command *cmd, struct plugin *plugin
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
nc = argconfig_parse_comma_sep_array(cfg.ctx_attrs, (int *)ctx_attrs, ARRAY_SIZE(ctx_attrs));
@@ -5647,14 +5842,14 @@ static int dsm(int argc, char **argv, struct command *cmd, struct plugin *plugin
if (!nr || nr > 256) {
fprintf(stderr, "No range definition provided\n");
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
if (!cfg.namespace_id) {
- err = nvme_get_nsid(fd, &cfg.namespace_id);
+ err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
- goto close_fd;
+ goto close_dev;
}
}
if (!cfg.cdw11)
@@ -5663,7 +5858,7 @@ static int dsm(int argc, char **argv, struct command *cmd, struct plugin *plugin
nvme_init_dsm_range(dsm, ctx_attrs, nlbs, slbas, nr);
struct nvme_dsm_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.nsid = cfg.namespace_id,
.attrs = cfg.cdw11,
.nr_ranges = nr,
@@ -5679,8 +5874,8 @@ static int dsm(int argc, char **argv, struct command *cmd, struct plugin *plugin
else
printf("NVMe DSM: success\n");
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -5710,10 +5905,11 @@ static int copy(int argc, char **argv, struct command *cmd, struct plugin *plugi
const char *d_dspec = "directive specific (write part)";
const char *d_format = "source range entry format";
- int err, fd;
uint16_t nr, nb, ns, nrts, natms, nats;
__u16 nlbs[128] = { 0 };
unsigned long long slbas[128] = {0,};
+ struct nvme_dev *dev;
+ int err;
union {
__u32 f0[128];
@@ -5789,23 +5985,21 @@ static int copy(int argc, char **argv, struct command *cmd, struct plugin *plugi
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0) {
- err = fd;
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
- }
- nb = argconfig_parse_comma_sep_array(cfg.nlbs, (int *)nlbs, ARRAY_SIZE(nlbs));
+ nb = argconfig_parse_comma_sep_array_short(cfg.nlbs, nlbs, ARRAY_SIZE(nlbs));
ns = argconfig_parse_comma_sep_array_long(cfg.slbas, slbas, ARRAY_SIZE(slbas));
if (cfg.format == 0)
nrts = argconfig_parse_comma_sep_array(cfg.eilbrts, (int *)eilbrts.f0, ARRAY_SIZE(eilbrts.f0));
else if (cfg.format == 1)
- nrts = argconfig_parse_comma_sep_array_long(cfg.eilbrts, (__u64 *)eilbrts.f1, ARRAY_SIZE(eilbrts.f1));
+ nrts = argconfig_parse_comma_sep_array_long(cfg.eilbrts, (unsigned long long *)eilbrts.f1, ARRAY_SIZE(eilbrts.f1));
else {
fprintf(stderr, "invalid format\n");
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
natms = argconfig_parse_comma_sep_array(cfg.elbatms, (int *)elbatms, ARRAY_SIZE(elbatms));
@@ -5815,14 +6009,14 @@ static int copy(int argc, char **argv, struct command *cmd, struct plugin *plugi
if (!nr || nr > 128 || (cfg.format == 1 && nr > 101)) {
fprintf(stderr, "invalid range\n");
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
if (!cfg.namespace_id) {
- err = nvme_get_nsid(fd, &cfg.namespace_id);
+ err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
- goto close_fd;
+ goto close_dev;
}
}
@@ -5835,7 +6029,7 @@ static int copy(int argc, char **argv, struct command *cmd, struct plugin *plugi
struct nvme_copy_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.nsid = cfg.namespace_id,
.copy = copy.f0,
.sdlba = cfg.sdlba,
@@ -5861,8 +6055,8 @@ static int copy(int argc, char **argv, struct command *cmd, struct plugin *plugi
else
printf("NVMe Copy: success\n");
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -5875,7 +6069,8 @@ static int flush(int argc, char **argv, struct command *cmd, struct plugin *plug
"flushed by the controller, from any namespace, depending on controller and "\
"associated namespace status.";
const char *namespace_id = "identifier of desired namespace";
- int err, fd;
+ struct nvme_dev *dev;
+ int err;
struct config {
__u32 namespace_id;
@@ -5890,27 +6085,27 @@ static int flush(int argc, char **argv, struct command *cmd, struct plugin *plug
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
if (!cfg.namespace_id) {
- err = nvme_get_nsid(fd, &cfg.namespace_id);
+ err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
- goto close_fd;
+ goto close_dev;
}
}
- err = nvme_flush(fd, cfg.namespace_id);
+ err = nvme_flush(dev_fd(dev), cfg.namespace_id);
if (err < 0)
fprintf(stderr, "flush: %s\n", nvme_strerror(errno));
else if (err != 0)
nvme_show_status(err);
else
printf("NVMe Flush: success\n");
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -5929,7 +6124,8 @@ static int resv_acquire(int argc, char **argv, struct command *cmd, struct plugi
const char *rtype = "reservation type";
const char *racqa = "reservation acquire action";
const char *iekey = "ignore existing res. key";
- int err, fd;
+ struct nvme_dev *dev;
+ int err;
struct config {
__u32 namespace_id;
@@ -5959,26 +6155,26 @@ static int resv_acquire(int argc, char **argv, struct command *cmd, struct plugi
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
if (!cfg.namespace_id) {
- err = nvme_get_nsid(fd, &cfg.namespace_id);
+ err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
- goto close_fd;
+ goto close_dev;
}
}
if (cfg.racqa > 7) {
fprintf(stderr, "invalid racqa:%d\n", cfg.racqa);
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
struct nvme_resv_acquire_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.nsid = cfg.namespace_id,
.rtype = cfg.rtype,
.racqa = cfg.racqa,
@@ -5996,8 +6192,8 @@ static int resv_acquire(int argc, char **argv, struct command *cmd, struct plugi
else
printf("NVME Reservation Acquire success\n");
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -6013,7 +6209,8 @@ static int resv_register(int argc, char **argv, struct command *cmd, struct plug
const char *nrkey = "new reservation key";
const char *rrega = "reservation registration action";
const char *cptpl = "change persistence through power loss setting";
- int err, fd;
+ struct nvme_dev *dev;
+ int err;
struct config {
__u32 namespace_id;
@@ -6042,32 +6239,32 @@ static int resv_register(int argc, char **argv, struct command *cmd, struct plug
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
if (!cfg.namespace_id) {
- err = nvme_get_nsid(fd, &cfg.namespace_id);
+ err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
- goto close_fd;
+ goto close_dev;
}
}
if (cfg.cptpl > 3) {
fprintf(stderr, "invalid cptpl:%d\n", cfg.cptpl);
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
if (cfg.rrega > 7) {
fprintf(stderr, "invalid rrega:%d\n", cfg.rrega);
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
struct nvme_resv_register_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.nsid = cfg.namespace_id,
.rrega = cfg.rrega,
.cptpl = cfg.cptpl,
@@ -6085,8 +6282,8 @@ static int resv_register(int argc, char **argv, struct command *cmd, struct plug
else
printf("NVME Reservation success\n");
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -6106,7 +6303,8 @@ static int resv_release(int argc, char **argv, struct command *cmd, struct plugi
const char *iekey = "ignore existing res. key";
const char *rtype = "reservation type";
const char *rrela = "reservation release action";
- int err, fd;
+ struct nvme_dev *dev;
+ int err;
struct config {
__u32 namespace_id;
@@ -6133,26 +6331,26 @@ static int resv_release(int argc, char **argv, struct command *cmd, struct plugi
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
if (!cfg.namespace_id) {
- err = nvme_get_nsid(fd, &cfg.namespace_id);
+ err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
- goto close_fd;
+ goto close_dev;
}
}
if (cfg.rrela > 7) {
fprintf(stderr, "invalid rrela:%d\n", cfg.rrela);
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
struct nvme_resv_release_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.nsid = cfg.namespace_id,
.rtype = cfg.rtype,
.rrela = cfg.rrela,
@@ -6169,8 +6367,8 @@ static int resv_release(int argc, char **argv, struct command *cmd, struct plugi
else
printf("NVME Reservation Release success\n");
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -6189,7 +6387,8 @@ static int resv_report(int argc, char **argv, struct command *cmd, struct plugin
struct nvme_resv_status *status;
enum nvme_print_flags flags;
- int err, fd, size;
+ struct nvme_dev *dev;
+ int err, size;
struct config {
__u32 namespace_id;
@@ -6216,21 +6415,21 @@ static int resv_report(int argc, char **argv, struct command *cmd, struct plugin
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
err = flags = validate_output_format(cfg.output_format);
if (flags < 0)
- goto close_fd;
+ goto close_dev;
if (cfg.raw_binary)
flags = BINARY;
if (!cfg.namespace_id) {
- err = nvme_get_nsid(fd, &cfg.namespace_id);
+ err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
- goto close_fd;
+ goto close_dev;
}
}
@@ -6244,13 +6443,13 @@ static int resv_report(int argc, char **argv, struct command *cmd, struct plugin
if (posix_memalign((void **)&status, getpagesize(), size)) {
fprintf(stderr, "No memory for resv report:%d\n", size);
err = -ENOMEM;
- goto close_fd;
+ goto close_dev;
}
memset(status, 0, size);
struct nvme_resv_report_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.nsid = cfg.namespace_id,
.eds = cfg.eds,
.len = size,
@@ -6266,8 +6465,8 @@ static int resv_report(int argc, char **argv, struct command *cmd, struct plugin
else
fprintf(stderr, "reservation report: %s\n", nvme_strerror(errno));
free(status);
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -6286,7 +6485,7 @@ static int submit_io(int opcode, char *command, const char *desc,
struct timeval start_time, end_time;
void *buffer, *mbuffer = NULL;
int err = 0;
- int dfd, mfd, fd;
+ int dfd, mfd;
int flags = opcode & 1 ? O_RDONLY : O_WRONLY | O_CREAT;
int mode = S_IRUSR | S_IWUSR |S_IRGRP | S_IWGRP| S_IROTH;
__u16 control = 0;
@@ -6297,6 +6496,7 @@ static int submit_io(int opcode, char *command, const char *desc,
struct nvme_id_ns ns;
struct nvme_nvm_id_ns nvm_ns;
__u8 lba_index, ms = 0, sts = 0, pif = 0;
+ struct nvme_dev *dev;
const char *namespace_id = "Identifier of desired namespace";
const char *start_block = "64-bit addr of first block to access";
@@ -6399,15 +6599,15 @@ static int submit_io(int opcode, char *command, const char *desc,
};
if (opcode != nvme_cmd_write) {
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
} else {
err = argconfig_parse(argc, argv, desc, opts);
if (err)
goto ret;
- err = fd = open_exclusive(argc, argv, cfg.force);
- if (err < 0) {
+ err = open_exclusive(&dev, argc, argv, cfg.force);
+ if (err) {
if (errno == EBUSY) {
fprintf(stderr, "Failed to open %s.\n",
basename(argv[optind]));
@@ -6424,17 +6624,17 @@ static int submit_io(int opcode, char *command, const char *desc,
}
if (!cfg.namespace_id) {
- err = nvme_get_nsid(fd, &cfg.namespace_id);
+ err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
- goto close_fd;
+ goto close_dev;
}
}
dfd = mfd = opcode & 1 ? STDIN_FILENO : STDOUT_FILENO;
if (cfg.prinfo > 0xf) {
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
dsmgmt = cfg.dsmgmt;
@@ -6450,7 +6650,7 @@ static int submit_io(int opcode, char *command, const char *desc,
fprintf(stderr, "Invalid directive type, %x\n",
cfg.dtype);
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
control |= cfg.dtype << 4;
dsmgmt |= ((__u32)cfg.dspec) << 16;
@@ -6461,7 +6661,7 @@ static int submit_io(int opcode, char *command, const char *desc,
if (dfd < 0) {
perror(cfg.data);
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
}
@@ -6480,9 +6680,9 @@ static int submit_io(int opcode, char *command, const char *desc,
goto close_mfd;
}
- if (nvme_get_logical_block_size(fd, cfg.namespace_id,
+ if (nvme_get_logical_block_size(dev_fd(dev), cfg.namespace_id,
&logical_block_size) < 0)
- goto close_mfd;
+ goto close_mfd;
buffer_size = ((long long)cfg.block_count + 1) * logical_block_size;
if (cfg.data_size < buffer_size) {
@@ -6499,7 +6699,7 @@ static int submit_io(int opcode, char *command, const char *desc,
}
if (cfg.metadata_size) {
- err = nvme_identify_ns(fd, cfg.namespace_id, &ns);
+ err = nvme_cli_identify_ns(dev, cfg.namespace_id, &ns);
if (err > 0) {
nvme_show_status(err);
goto free_buffer;
@@ -6511,7 +6711,8 @@ static int submit_io(int opcode, char *command, const char *desc,
nvme_id_ns_flbas_to_lbaf_inuse(ns.flbas, &lba_index);
ms = ns.lbaf[lba_index].ms;
- err = nvme_identify_ns_csi(fd, 1, 0, NVME_CSI_NVM, &nvm_ns);
+ err = nvme_identify_ns_csi(dev_fd(dev), 1, 0, NVME_CSI_NVM,
+ &nvm_ns);
if (!err) {
sts = nvm_ns.elbaf[lba_index] & NVME_NVM_ELBAF_STS_MASK;
pif = (nvm_ns.elbaf[lba_index] & NVME_NVM_ELBAF_PIF_MASK) >> 7;
@@ -6580,7 +6781,7 @@ static int submit_io(int opcode, char *command, const char *desc,
struct nvme_io_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.nsid = cfg.namespace_id,
.slba = cfg.start_block,
.nlb = cfg.block_count,
@@ -6633,8 +6834,8 @@ close_mfd:
close(mfd);
close_dfd:
close(dfd);
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -6664,11 +6865,12 @@ static int write_cmd(int argc, char **argv, struct command *cmd, struct plugin *
static int verify_cmd(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- int err, fd;
__u16 control = 0;
__u8 lba_index, sts = 0, pif = 0;
struct nvme_id_ns ns;
struct nvme_nvm_id_ns nvm_ns;
+ struct nvme_dev *dev;
+ int err;
const char *desc = "Verify specified logical blocks on the given device.";
const char *namespace_id = "desired namespace";
@@ -6727,13 +6929,13 @@ static int verify_cmd(int argc, char **argv, struct command *cmd, struct plugin
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
if (cfg.prinfo > 0xf) {
err = EINVAL;
- goto close_fd;
+ goto close_dev;
}
control |= (cfg.prinfo << 10);
@@ -6745,23 +6947,24 @@ static int verify_cmd(int argc, char **argv, struct command *cmd, struct plugin
control |= NVME_IO_STC;
if (!cfg.namespace_id) {
- err = nvme_get_nsid(fd, &cfg.namespace_id);
+ err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
- goto close_fd;
+ goto close_dev;
}
}
- err = nvme_identify_ns(fd, cfg.namespace_id, &ns);
+ err = nvme_cli_identify_ns(dev, cfg.namespace_id, &ns);
if (err) {
nvme_show_status(err);
- goto close_fd;
+ goto close_dev;
} else if (err < 0) {
fprintf(stderr, "identify namespace: %s\n", nvme_strerror(errno));
- goto close_fd;
+ goto close_dev;
}
- err = nvme_identify_ns_csi(fd, cfg.namespace_id, 0, NVME_CSI_NVM, &nvm_ns);
+ err = nvme_identify_ns_csi(dev_fd(dev), cfg.namespace_id, 0,
+ NVME_CSI_NVM, &nvm_ns);
if (!err) {
nvme_id_ns_flbas_to_lbaf_inuse(ns.flbas, &lba_index);
sts = nvm_ns.elbaf[lba_index] & NVME_NVM_ELBAF_STS_MASK;
@@ -6770,12 +6973,12 @@ static int verify_cmd(int argc, char **argv, struct command *cmd, struct plugin
if (invalid_tags(cfg.storage_tag, cfg.ref_tag, sts, pif)) {
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
struct nvme_io_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.nsid = cfg.namespace_id,
.slba = cfg.start_block,
.nlb = cfg.block_count,
@@ -6797,8 +7000,8 @@ static int verify_cmd(int argc, char **argv, struct command *cmd, struct plugin
else
printf("NVME Verify Success\n");
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -6818,8 +7021,9 @@ static int sec_recv(int argc, char **argv, struct command *cmd, struct plugin *p
const char *raw = "dump output in binary format";
const char *namespace_id = "desired namespace";
const char *nssf = "NVMe Security Specific Field";
- int err, fd;
+ struct nvme_dev *dev;
void *sec_buf = NULL;
+ int err;
struct config {
__u32 namespace_id;
@@ -6852,8 +7056,8 @@ static int sec_recv(int argc, char **argv, struct command *cmd, struct plugin *p
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
if (cfg.size) {
@@ -6861,13 +7065,13 @@ static int sec_recv(int argc, char **argv, struct command *cmd, struct plugin *p
fprintf(stderr, "No memory for security size:%d\n",
cfg.size);
err = -ENOMEM;
- goto close_fd;
+ goto close_dev;
}
}
struct nvme_security_receive_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.nsid = cfg.namespace_id,
.nssf = cfg.nssf,
.spsp0 = cfg.spsp & 0xff,
@@ -6894,8 +7098,8 @@ static int sec_recv(int argc, char **argv, struct command *cmd, struct plugin *p
free(sec_buf);
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -6918,8 +7122,9 @@ static int get_lba_status(int argc, char **argv, struct command *cmd,
enum nvme_print_flags flags;
unsigned long buf_len;
- int err, fd;
+ struct nvme_dev *dev;
void *buf;
+ int err;
struct config {
__u32 namespace_id;
@@ -6952,30 +7157,30 @@ static int get_lba_status(int argc, char **argv, struct command *cmd,
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto err;
err = flags = validate_output_format(cfg.output_format);
if (flags < 0)
- goto close_fd;
+ goto close_dev;
if (!cfg.atype) {
fprintf(stderr, "action type (--action) has to be given\n");
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
buf_len = (cfg.mndw + 1) * 4;
buf = calloc(1, buf_len);
if (!buf) {
err = -ENOMEM;
- goto close_fd;
+ goto close_dev;
}
struct nvme_get_lba_status_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.nsid = cfg.namespace_id,
.slba = cfg.slba,
.mndw = cfg.mndw,
@@ -6993,8 +7198,8 @@ static int get_lba_status(int argc, char **argv, struct command *cmd,
else
fprintf(stderr, "get lba status: %s\n", nvme_strerror(errno));
free(buf);
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
err:
return err;
}
@@ -7012,7 +7217,8 @@ static int capacity_mgmt(int argc, char **argv, struct command *cmd, struct plug
const char *cap_upper = "Most significant 32 bits of the capacity in bytes of the "\
"Endurance Group or NVM Set to be created";
- int err = -1, fd;
+ struct nvme_dev *dev;
+ int err = -1;
__u32 result;
struct config {
@@ -7037,19 +7243,19 @@ static int capacity_mgmt(int argc, char **argv, struct command *cmd, struct plug
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
if (cfg.operation > 0xf) {
fprintf(stderr, "invalid operation field: %u\n", cfg.operation);
err = -1;
- goto close_fd;
+ goto close_dev;
}
struct nvme_capacity_mgmt_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.op = cfg.operation,
.element_id = cfg.element_id,
.cdw11 = cfg.dw11,
@@ -7070,8 +7276,8 @@ static int capacity_mgmt(int argc, char **argv, struct command *cmd, struct plug
else if (err < 0)
fprintf(stderr, "capacity management: %s\n", nvme_strerror(errno));
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -7090,10 +7296,11 @@ static int dir_receive(int argc, char **argv, struct command *cmd, struct plugin
const char *human_readable = "show directive in readable format";
enum nvme_print_flags flags = NORMAL;
- int err, fd;
+ struct nvme_dev *dev;
__u32 result;
__u32 dw12 = 0;
void *buf = NULL;
+ int err;
struct config {
__u32 namespace_id;
@@ -7129,8 +7336,8 @@ static int dir_receive(int argc, char **argv, struct command *cmd, struct plugin
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
if (cfg.human_readable)
@@ -7148,7 +7355,7 @@ static int dir_receive(int argc, char **argv, struct command *cmd, struct plugin
default:
fprintf(stderr, "invalid directive operations for Identify Directives\n");
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
break;
case NVME_DIRECTIVE_DTYPE_STREAMS:
@@ -7167,26 +7374,26 @@ static int dir_receive(int argc, char **argv, struct command *cmd, struct plugin
default:
fprintf(stderr, "invalid directive operations for Streams Directives\n");
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
break;
default:
fprintf(stderr, "invalid directive type\n");
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
if (cfg.data_len) {
if (posix_memalign(&buf, getpagesize(), cfg.data_len)) {
err = -ENOMEM;
- goto close_fd;
+ goto close_dev;
}
memset(buf, 0, cfg.data_len);
}
struct nvme_directive_recv_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.nsid = cfg.namespace_id,
.dspec = cfg.dspec,
.doper = cfg.doper,
@@ -7208,8 +7415,8 @@ static int dir_receive(int argc, char **argv, struct command *cmd, struct plugin
fprintf(stderr, "dir-receive: %s\n", nvme_strerror(errno));
free(buf);
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -7242,7 +7449,8 @@ static int lockdown_cmd(int argc, char **argv, struct command *cmd, struct plugi
"List that is used by the command.If this field is cleared to 0h,"\
"then no UUID index is specified";
- int fd, err = -1;
+ struct nvme_dev *dev;
+ int err = -1;
struct config {
__u8 ofi;
@@ -7269,35 +7477,35 @@ static int lockdown_cmd(int argc, char **argv, struct command *cmd, struct plugi
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
/* check for input argument limit */
if (cfg.ifc > 3) {
fprintf(stderr, "invalid interface settings:%d\n", cfg.ifc);
err = -1;
- goto close_fd;
+ goto close_dev;
}
if (cfg.prhbt > 1) {
fprintf(stderr, "invalid prohibit settings:%d\n", cfg.prhbt);
err = -1;
- goto close_fd;
+ goto close_dev;
}
if (cfg.scp > 15) {
fprintf(stderr, "invalid scope settings:%d\n", cfg.scp);
err = -1;
- goto close_fd;
+ goto close_dev;
}
if (cfg.uuid > 127) {
fprintf(stderr, "invalid UUID index settings:%d\n", cfg.uuid);
err = -1;
- goto close_fd;
+ goto close_dev;
}
struct nvme_lockdown_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.scp = cfg.scp,
.prhbt = cfg.prhbt,
.ifc = cfg.ifc,
@@ -7314,8 +7522,8 @@ static int lockdown_cmd(int argc, char **argv, struct command *cmd, struct plugi
else
printf("Lockdown Command is Successful\n");
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -7351,7 +7559,8 @@ static int passthru(int argc, char **argv, bool admin,
int flags;
int mode = S_IRUSR | S_IWUSR |S_IRGRP | S_IWGRP| S_IROTH;
void *data = NULL, *mdata = NULL;
- int err = 0, dfd, mfd, fd;
+ int err = 0, dfd, mfd;
+ struct nvme_dev *dev;
__u32 result;
bool huge = false;
const char *cmd_name = NULL;
@@ -7439,8 +7648,8 @@ static int passthru(int argc, char **argv, bool admin,
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
if (cfg.opcode & 0x01)
@@ -7464,7 +7673,7 @@ static int passthru(int argc, char **argv, bool admin,
if (dfd < 0) {
perror(cfg.input_file);
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
}
@@ -7541,17 +7750,25 @@ static int passthru(int argc, char **argv, bool admin,
gettimeofday(&start_time, NULL);
if (admin)
- err = nvme_admin_passthru(fd, cfg.opcode, cfg.flags, cfg.rsvd,
- cfg.namespace_id, cfg.cdw2, cfg.cdw3, cfg.cdw10,
- cfg.cdw11, cfg.cdw12, cfg.cdw13, cfg.cdw14,
- cfg.cdw15, cfg.data_len, data, cfg.metadata_len,
- mdata, cfg.timeout, &result);
+ err = nvme_admin_passthru(dev_fd(dev), cfg.opcode, cfg.flags,
+ cfg.rsvd,
+ cfg.namespace_id, cfg.cdw2,
+ cfg.cdw3, cfg.cdw10,
+ cfg.cdw11, cfg.cdw12, cfg.cdw13,
+ cfg.cdw14,
+ cfg.cdw15, cfg.data_len, data,
+ cfg.metadata_len,
+ mdata, cfg.timeout, &result);
else
- err = nvme_io_passthru(fd, cfg.opcode, cfg.flags, cfg.rsvd,
- cfg.namespace_id, cfg.cdw2, cfg.cdw3, cfg.cdw10,
- cfg.cdw11, cfg.cdw12, cfg.cdw13, cfg.cdw14,
- cfg.cdw15, cfg.data_len, data, cfg.metadata_len,
- mdata, cfg.timeout, &result);
+ err = nvme_io_passthru(dev_fd(dev), cfg.opcode, cfg.flags,
+ cfg.rsvd,
+ cfg.namespace_id, cfg.cdw2, cfg.cdw3,
+ cfg.cdw10,
+ cfg.cdw11, cfg.cdw12, cfg.cdw13,
+ cfg.cdw14,
+ cfg.cdw15, cfg.data_len, data,
+ cfg.metadata_len,
+ mdata, cfg.timeout, &result);
gettimeofday(&end_time, NULL);
cmd_name = nvme_cmd_to_string(admin, cfg.opcode);
@@ -7590,10 +7807,10 @@ close_dfd:
if (strlen(cfg.input_file))
close(dfd);
close_mfd:
- if (strlen(cfg.metadata))
+ if (cfg.metadata && strlen(cfg.metadata))
close(mfd);
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -8006,14 +8223,14 @@ static int check_tls_key(int argc, char **argv, struct command *command, struct
switch (hmac) {
case 1:
if (strlen(cfg.key) != 65) {
- fprintf(stderr, "Invalid key length %lu for SHA(256)\n",
+ fprintf(stderr, "Invalid key length %zu for SHA(256)\n",
strlen(cfg.key));
return -EINVAL;
}
break;
case 2:
if (strlen(cfg.key) != 89) {
- fprintf(stderr, "Invalid key length %lu for SHA(384)\n",
+ fprintf(stderr, "Invalid key length %zu for SHA(384)\n",
strlen(cfg.key));
return -EINVAL;
}
@@ -8052,6 +8269,76 @@ static int check_tls_key(int argc, char **argv, struct command *command, struct
return 0;
}
+static int show_topology_cmd(int argc, char **argv, struct command *command, struct plugin *plugin)
+{
+ const char *desc = "Show the topolog\n";
+ const char *verbose = "Increase output verbosity";
+ const char *ranking = "Ranking order: namespace|ctrl";
+ enum nvme_print_flags flags;
+ nvme_root_t r;
+ enum nvme_cli_topo_ranking rank;
+ int err;
+
+ struct config {
+ char *output_format;
+ int verbose;
+ char *ranking;
+ };
+
+ struct config cfg = {
+ .output_format = "normal",
+ .verbose = 0,
+ .ranking = "namespace",
+ };
+
+ OPT_ARGS(opts) = {
+ OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
+ OPT_INCR("verbose", 'v', &cfg.verbose, verbose),
+ OPT_FMT("ranking", 'r', &cfg.ranking, ranking),
+ OPT_END()
+ };
+
+ err = argconfig_parse(argc, argv, desc, opts);
+ if (err)
+ return err;
+
+ err = flags = validate_output_format(cfg.output_format);
+ if (flags < 0)
+ return err;
+ if (cfg.verbose)
+ flags |= VERBOSE;
+
+ if (!strcmp(cfg.ranking, "namespace"))
+ rank = NVME_CLI_TOPO_NAMESPACE;
+ else if (!strcmp(cfg.ranking, "ctrl"))
+ rank = NVME_CLI_TOPO_CTRL;
+ else {
+ fprintf(stderr, "Invalid ranking argument: %s\n",
+ cfg.ranking);
+ return -EINVAL;
+ }
+
+ r = nvme_create_root(stderr, map_log_level(cfg.verbose, false));
+ if (!r) {
+ fprintf(stderr, "Failed to create topology root: %s\n",
+ nvme_strerror(errno));
+ return -errno;
+ }
+
+ err = nvme_scan_topology(r, NULL, NULL);
+ if (err < 0) {
+ fprintf(stderr, "Failed to scan topology: %s\n",
+ nvme_strerror(errno));
+ nvme_free_tree(r);
+ return err;
+ }
+
+ nvme_show_topology(r, flags, rank);
+ nvme_free_tree(r);
+
+ return err;
+}
+
static int discover_cmd(int argc, char **argv, struct command *command, struct plugin *plugin)
{
const char *desc = "Send Get Log Page request to Discovery Controller.";