summaryrefslogtreecommitdiffstats
path: root/nvme.c
diff options
context:
space:
mode:
Diffstat (limited to 'nvme.c')
-rw-r--r--nvme.c4200
1 files changed, 1912 insertions, 2288 deletions
diff --git a/nvme.c b/nvme.c
index b5b0585..872dc89 100644
--- a/nvme.c
+++ b/nvme.c
@@ -27,6 +27,7 @@
#include "config.h"
#include "nvme/tree.h"
#include "nvme/types.h"
+#include "util/cleanup.h"
#include <errno.h>
#include <getopt.h>
#include <fcntl.h>
@@ -41,10 +42,6 @@
#include <libgen.h>
#include <signal.h>
-#ifdef CONFIG_LIBHUGETLBFS
-#include <hugetlbfs.h>
-#endif
-
#include <linux/fs.h>
#include <sys/mman.h>
@@ -68,6 +65,7 @@
#include "fabrics.h"
#define CREATE_CMD
#include "nvme-builtin.h"
+#include "malloc.h"
struct feat_cfg {
enum nvme_features_id feature_id;
@@ -108,6 +106,14 @@ struct passthru_config {
bool latency;
};
+#define NVME_ARGS(n, c, ...) \
+ struct argconfig_commandline_options n[] = { \
+ OPT_FLAG("verbose", 'v', NULL, verbose), \
+ OPT_FMT("output-format", 'o', &output_format_val, output_format), \
+ ##__VA_ARGS__, \
+ OPT_END() \
+ }
+
static const char nvme_version_string[] = NVME_VERSION;
static struct plugin builtin = {
@@ -130,8 +136,6 @@ static struct program nvme = {
};
const char *output_format = "Output format: normal|json|binary";
-static const char *output_format_no_binary = "Output format: normal|json";
-
static const char *app_tag = "app tag for end-to-end PI";
static const char *app_tag_mask = "app tag mask for end-to-end PI";
static const char *block_count = "number of blocks (zeroes based) on device to access";
@@ -181,58 +185,9 @@ static const char *verbose = "Increase output verbosity";
static const char dash[51] = {[0 ... 49] = '=', '\0'};
static const char space[51] = {[0 ... 49] = ' ', '\0'};
-static void *mmap_registers(nvme_root_t r, struct nvme_dev *dev);
-
-static void *__nvme_alloc(size_t len, bool *huge)
-{
- void *p;
-
- if (!posix_memalign(&p, getpagesize(), len)) {
- *huge = false;
- memset(p, 0, len);
- return p;
- }
- return NULL;
-}
-
-#define HUGE_MIN 0x80000
-
-#ifdef CONFIG_LIBHUGETLBFS
-void nvme_free(void *p, bool huge)
-{
- if (huge) {
- if (p)
- free_hugepage_region(p);
- } else {
- free(p);
- }
-}
-
-void *nvme_alloc(size_t len, bool *huge)
-{
- void *p;
-
- if (len < HUGE_MIN)
- return __nvme_alloc(len, huge);
-
- p = get_hugepage_region(len, GHR_DEFAULT);
- if (!p)
- return __nvme_alloc(len, huge);
-
- *huge = true;
- return p;
-}
-#else
-void nvme_free(void *p, bool huge)
-{
- free(p);
-}
+static char *output_format_val = "normal";
-void *nvme_alloc(size_t len, bool *huge)
-{
- return __nvme_alloc(len, huge);
-}
-#endif
+static void *mmap_registers(nvme_root_t r, struct nvme_dev *dev);
const char *nvme_strerror(int errnum)
{
@@ -246,7 +201,7 @@ int map_log_level(int verbose, bool quiet)
int log_level;
/*
- * LOG_NOTICE is unsued thus the user has to provide two 'v' for getting
+ * LOG_NOTICE is unused thus the user has to provide two 'v' for getting
* any feedback at all. Thus skip this level
*/
verbose++;
@@ -429,7 +384,7 @@ static int get_dev(struct nvme_dev **dev, int argc, char **argv, int flags)
else
ret = open_dev_direct(dev, devname, flags);
- return ret;
+ return ret != 0 ? -errno : 0;
}
int parse_and_open(struct nvme_dev **dev, int argc, char **argv,
@@ -445,6 +400,8 @@ int parse_and_open(struct nvme_dev **dev, int argc, char **argv,
ret = get_dev(dev, argc, argv, O_RDONLY);
if (ret < 0)
argconfig_print_help(desc, opts);
+ else if (argconfig_parse_seen(opts, "verbose"))
+ nvme_cli_set_debug(*dev, true);
return ret;
}
@@ -460,21 +417,35 @@ int open_exclusive(struct nvme_dev **dev, int argc, char **argv,
return get_dev(dev, argc, argv, flags);
}
-enum nvme_print_flags validate_output_format(const char *format)
+int validate_output_format(const char *format, enum nvme_print_flags *flags)
{
+ enum nvme_print_flags f;
+
if (!format)
return -EINVAL;
if (!strcmp(format, "normal"))
- return NORMAL;
+ f = NORMAL;
+ else if (!strcmp(format, "json"))
+ f = JSON;
+ else if (!strcmp(format, "binary"))
+ f = BINARY;
+ else
+ return -EINVAL;
+
+ *flags = f;
+
+ return 0;
+}
- if (!strcmp(format, "json"))
- return JSON;
+bool nvme_is_output_format_json(void)
+{
+ enum nvme_print_flags flags;
- if (!strcmp(format, "binary"))
- return BINARY;
+ if (validate_output_format(output_format_val, &flags))
+ return false;
- return -EINVAL;
+ return flags == JSON;
}
void dev_close(struct nvme_dev *dev)
@@ -493,46 +464,41 @@ void dev_close(struct nvme_dev *dev)
static int get_smart_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- struct nvme_smart_log smart_log;
const char *desc = "Retrieve SMART log for the given device\n"
"(or optionally a namespace) in either decoded format\n"
"(default) or binary.";
+
+ _cleanup_free_ struct nvme_smart_log *smart_log = NULL;
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
const char *namespace = "(optional) desired namespace";
enum nvme_print_flags flags;
- struct nvme_dev *dev;
int err = -1;
struct config {
__u32 namespace_id;
- char *output_format;
bool raw_binary;
bool human_readable;
};
struct config cfg = {
.namespace_id = NVME_NSID_ALL,
- .output_format = "normal",
.raw_binary = false,
.human_readable = false,
};
-
- OPT_ARGS(opts) = {
- OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace),
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_output),
- OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable_info),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace),
+ OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_output),
+ OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable_info));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
- err = flags = validate_output_format(cfg.output_format);
+ err = validate_output_format(output_format_val, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
- goto close_fd;
+ return err;
}
if (cfg.raw_binary)
@@ -541,18 +507,20 @@ static int get_smart_log(int argc, char **argv, struct command *cmd, struct plug
if (cfg.human_readable)
flags |= VERBOSE;
+ smart_log = nvme_alloc(sizeof(*smart_log));
+ if (!smart_log)
+ return -ENOMEM;
+
err = nvme_cli_get_log_smart(dev, cfg.namespace_id, false,
- &smart_log);
+ smart_log);
if (!err)
- nvme_show_smart_log(&smart_log, cfg.namespace_id,
+ nvme_show_smart_log(smart_log, cfg.namespace_id,
dev->name, flags);
else if (err > 0)
nvme_show_status(err);
else
nvme_show_error("smart log: %s", nvme_strerror(errno));
-close_fd:
- dev_close(dev);
-ret:
+
return err;
}
@@ -562,72 +530,67 @@ static int get_ana_log(int argc, char **argv, struct command *cmd,
const char *desc = "Retrieve ANA log for the given device in\n"
"decoded format (default), json or binary.";
const char *groups = "Return ANA groups only.";
- void *ana_log;
+
+ _cleanup_nvme_dev_ struct nvme_dev *dev= NULL;
+ _cleanup_free_ struct nvme_id_ctrl *ctrl = NULL;
+ _cleanup_free_ void *ana_log = NULL;
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;
- char *output_format;
};
struct config cfg = {
.groups = false,
- .output_format = "normal",
};
- OPT_ARGS(opts) = {
- OPT_FLAG("groups", 'g', &cfg.groups, groups),
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_FLAG("groups", 'g', &cfg.groups, groups));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
- err = flags = validate_output_format(cfg.output_format);
+ err = validate_output_format(output_format_val, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
- goto close_fd;
+ return err;
}
- err = nvme_cli_identify_ctrl(dev, &ctrl);
+ ctrl = nvme_alloc(sizeof(*ctrl));
+ if (!ctrl)
+ return -ENOMEM;
+
+ err = nvme_cli_identify_ctrl(dev, ctrl);
if (err) {
nvme_show_error("ERROR : nvme_identify_ctrl() failed: %s",
nvme_strerror(errno));
- goto close_fd;
+ return err;
}
ana_log_len = sizeof(struct nvme_ana_log) +
- le32_to_cpu(ctrl.nanagrpid) * sizeof(struct nvme_ana_group_desc);
- if (!(ctrl.anacap & (1 << 6)))
- ana_log_len += le32_to_cpu(ctrl.mnan) * sizeof(__le32);
+ le32_to_cpu(ctrl->nanagrpid) * sizeof(struct nvme_ana_group_desc);
+ if (!(ctrl->anacap & (1 << 6)))
+ ana_log_len += le32_to_cpu(ctrl->mnan) * sizeof(__le32);
- ana_log = malloc(ana_log_len);
- if (!ana_log) {
- err = -ENOMEM;
- goto close_fd;
- }
+ ana_log = nvme_alloc(ana_log_len);
+ if (!ana_log)
+ return -ENOMEM;
lsp = cfg.groups ? NVME_LOG_ANA_LSP_RGO_GROUPS_ONLY :
NVME_LOG_ANA_LSP_RGO_NAMESPACES;
err = nvme_cli_get_log_ana(dev, lsp, true, 0, ana_log_len, ana_log);
if (!err)
- nvme_show_ana_log(ana_log, dev->name, flags, ana_log_len);
+ nvme_show_ana_log(ana_log, dev->name, ana_log_len, flags);
else if (err > 0)
nvme_show_status(err);
else
nvme_show_error("ana-log: %s", nvme_strerror(errno));
- free(ana_log);
-close_fd:
- dev_close(dev);
-ret:
+
return err;
}
@@ -637,25 +600,32 @@ static int parse_telemetry_da(struct nvme_dev *dev,
size_t *size)
{
- struct nvme_id_ctrl id_ctrl;
+ _cleanup_free_ struct nvme_id_ctrl *id_ctrl = NULL;
+ size_t dalb = 0;
+
+ id_ctrl = nvme_alloc(sizeof(*id_ctrl));
+ if (!id_ctrl)
+ return -ENOMEM;
switch (da) {
case NVME_TELEMETRY_DA_1:
+ dalb = le16_to_cpu(telem->dalb1);
+ break;
case NVME_TELEMETRY_DA_2:
+ dalb = le16_to_cpu(telem->dalb2);
+ break;
case NVME_TELEMETRY_DA_3:
/* dalb3 >= dalb2 >= dalb1 */
- *size = (le16_to_cpu(telem->dalb3) + 1) *
- NVME_LOG_TELEM_BLOCK_SIZE;
+ dalb = le16_to_cpu(telem->dalb3);
break;
case NVME_TELEMETRY_DA_4:
- if (nvme_cli_identify_ctrl(dev, &id_ctrl)) {
+ if (nvme_cli_identify_ctrl(dev, id_ctrl)) {
perror("identify-ctrl");
return -errno;
}
- if (id_ctrl.lpa & 0x40) {
- *size = (le32_to_cpu(telem->dalb4) + 1) *
- NVME_LOG_TELEM_BLOCK_SIZE;
+ if (id_ctrl->lpa & 0x40) {
+ dalb = le32_to_cpu(telem->dalb4);
} else {
nvme_show_error(
"Data area 4 unsupported, bit 6 of Log Page Attributes not set");
@@ -667,10 +637,11 @@ static int parse_telemetry_da(struct nvme_dev *dev,
return -EINVAL;
}
- if (*size == NVME_LOG_TELEM_BLOCK_SIZE) {
+ if (dalb == 0) {
nvme_show_error("ERROR: No telemetry data block");
return -ENOENT;
}
+ *size = (dalb + 1) * NVME_LOG_TELEM_BLOCK_SIZE;
return 0;
}
@@ -680,7 +651,7 @@ static int get_log_telemetry_ctrl(struct nvme_dev *dev, bool rae, size_t size,
struct nvme_telemetry_log *log;
int err;
- log = calloc(1, size);
+ log = nvme_alloc(size);
if (!log)
return -errno;
@@ -700,7 +671,7 @@ static int get_log_telemetry_host(struct nvme_dev *dev, size_t size,
struct nvme_telemetry_log *log;
int err;
- log = calloc(1, size);
+ log = nvme_alloc(size);
if (!log)
return -errno;
@@ -719,10 +690,14 @@ static int __create_telemetry_log_host(struct nvme_dev *dev,
size_t *size,
struct nvme_telemetry_log **buf)
{
- struct nvme_telemetry_log log = { 0 };
+ _cleanup_free_ struct nvme_telemetry_log *log = NULL;
int err;
- err = nvme_cli_get_log_create_telemetry_host(dev, &log);
+ log = nvme_alloc(sizeof(*log));
+ if (!log)
+ return -ENOMEM;
+
+ err = nvme_cli_get_log_create_telemetry_host(dev, log);
if (err)
return -errno;
@@ -739,7 +714,7 @@ static int __get_telemetry_log_ctrl(struct nvme_dev *dev,
struct nvme_telemetry_log *log;
int err;
- log = calloc(1, NVME_LOG_TELEM_BLOCK_SIZE);
+ log = nvme_alloc(NVME_LOG_TELEM_BLOCK_SIZE);
if (!log)
return -errno;
@@ -784,16 +759,20 @@ static int __get_telemetry_log_host(struct nvme_dev *dev,
size_t *size,
struct nvme_telemetry_log **buf)
{
- struct nvme_telemetry_log log = { 0 };
+ _cleanup_free_ struct nvme_telemetry_log *log = NULL;
int err;
+ log = nvme_alloc(sizeof(*log));
+ if (!log)
+ return -errno;
+
err = nvme_cli_get_log_telemetry_host(dev, 0,
NVME_LOG_TELEM_BLOCK_SIZE,
- &log);
+ log);
if (err)
return err;
- err = parse_telemetry_da(dev, da, &log, size);
+ err = parse_telemetry_da(dev, da, log, size);
if (err)
return err;
@@ -808,12 +787,14 @@ static int get_telemetry_log(int argc, char **argv, struct command *cmd,
const char *hgen = "Have the host tell the controller to generate the report";
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 = NULL;
- int err = 0, output;
+
+ _cleanup_free_ struct nvme_telemetry_log *log = NULL;
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
+ _cleanup_file_ int output = -1;
+ int err = 0;
size_t total_size;
__u8 *data_ptr = NULL;
int data_written = 0, data_remaining = 0;
- struct nvme_dev *dev;
struct config {
char *file_name;
@@ -830,23 +811,20 @@ static int get_telemetry_log(int argc, char **argv, struct command *cmd,
.rae = true,
};
- OPT_ARGS(opts) = {
- OPT_FILE("output-file", 'o', &cfg.file_name, fname),
- OPT_UINT("host-generate", 'g', &cfg.host_gen, hgen),
- OPT_FLAG("controller-init", 'c', &cfg.ctrl_init, cgen),
- OPT_UINT("data-area", 'd', &cfg.data_area, dgen),
- OPT_FLAG("rae", 'r', &cfg.rae, rae),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_FILE("output-file", 'O', &cfg.file_name, fname),
+ OPT_UINT("host-generate", 'g', &cfg.host_gen, hgen),
+ OPT_FLAG("controller-init", 'c', &cfg.ctrl_init, cgen),
+ OPT_UINT("data-area", 'd', &cfg.data_area, dgen),
+ OPT_FLAG("rae", 'r', &cfg.rae, rae));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
if (!cfg.file_name) {
nvme_show_error("Please provide an output file!");
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
cfg.host_gen = !!cfg.host_gen;
@@ -854,10 +832,13 @@ static int get_telemetry_log(int argc, char **argv, struct command *cmd,
if (output < 0) {
nvme_show_error("Failed to open output file %s: %s!",
cfg.file_name, strerror(errno));
- err = output;
- goto close_dev;
+ return output;
}
+ log = nvme_alloc(sizeof(*log));
+ if (!log)
+ return -ENOMEM;
+
if (cfg.ctrl_init)
err = __get_telemetry_log_ctrl(dev, cfg.rae, cfg.data_area,
&total_size, &log);
@@ -870,11 +851,11 @@ static int get_telemetry_log(int argc, char **argv, struct command *cmd,
if (err < 0) {
nvme_show_error("get-telemetry-log: %s", nvme_strerror(errno));
- goto close_output;
+ return err;
} else if (err > 0) {
nvme_show_status(err);
fprintf(stderr, "Failed to acquire telemetry log %d!\n", err);
- goto close_output;
+ return err;
}
data_written = 0;
@@ -902,63 +883,54 @@ static int get_telemetry_log(int argc, char **argv, struct command *cmd,
return -1;
}
- free(log);
-
-close_output:
- close(output);
-close_dev:
- dev_close(dev);
-ret:
return err;
}
static int get_endurance_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- struct nvme_endurance_group_log endurance_log;
const char *desc = "Retrieves endurance groups log page and prints the log.";
const char *group_id = "The endurance group identifier";
+
+ _cleanup_free_ struct nvme_endurance_group_log *endurance_log = NULL;
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
enum nvme_print_flags flags;
- struct nvme_dev *dev;
int err;
struct config {
- char *output_format;
__u16 group_id;
};
struct config cfg = {
- .output_format = "normal",
.group_id = 0,
};
- OPT_ARGS(opts) = {
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_SHRT("group-id", 'g', &cfg.group_id, group_id),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_SHRT("group-id", 'g', &cfg.group_id, group_id));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
- err = flags = validate_output_format(cfg.output_format);
+ err = validate_output_format(output_format_val, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
- goto close_dev;
+ return err;
}
+ endurance_log = nvme_alloc(sizeof(*endurance_log));
+ if (!endurance_log)
+ return -ENOMEM;
+
err = nvme_cli_get_log_endurance_group(dev, cfg.group_id,
- &endurance_log);
+ endurance_log);
if (!err)
- nvme_show_endurance_log(&endurance_log, cfg.group_id,
+ nvme_show_endurance_log(endurance_log, cfg.group_id,
dev->name, flags);
else if (err > 0)
nvme_show_status(err);
else
nvme_show_error("endurance log: %s", nvme_strerror(errno));
-close_dev:
- dev_close(dev);
-ret:
+
return err;
}
@@ -968,7 +940,7 @@ static int collect_effects_log(struct nvme_dev *dev, enum nvme_csi csi,
nvme_effects_log_node_t *node;
int err;
- node = malloc(sizeof(nvme_effects_log_node_t));
+ node = nvme_alloc(sizeof(*node));
if (!node)
return -ENOMEM;
@@ -986,9 +958,10 @@ static int collect_effects_log(struct nvme_dev *dev, enum nvme_csi csi,
static int get_effects_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
const char *desc = "Retrieve command effects log page and print the table.";
+
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
struct list_head log_pages;
nvme_effects_log_node_t *node;
- struct nvme_dev *dev;
void *bar = NULL;
@@ -996,35 +969,30 @@ static int get_effects_log(int argc, char **argv, struct command *cmd, struct pl
enum nvme_print_flags flags;
struct config {
- char *output_format;
bool human_readable;
bool raw_binary;
int csi;
};
struct config cfg = {
- .output_format = "normal",
.human_readable = false,
.raw_binary = false,
.csi = -1,
};
- OPT_ARGS(opts) = {
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable_log),
- OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_log),
- OPT_INT("csi", 'c', &cfg.csi, csi),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable_log),
+ OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_log),
+ OPT_INT("csi", 'c', &cfg.csi, csi));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
- err = flags = validate_output_format(cfg.output_format);
+ err = validate_output_format(output_format_val, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
- goto close_dev;
+ return err;
}
if (cfg.raw_binary)
@@ -1056,7 +1024,7 @@ static int get_effects_log(int argc, char **argv, struct command *cmd, struct pl
};
err = nvme_get_property(&args);
if (err)
- goto close_dev;
+ goto cleanup_list;
}
if (NVME_CAP_CSS(cap) & NVME_CAP_CSS_NVM)
@@ -1077,12 +1045,10 @@ static int get_effects_log(int argc, char **argv, struct command *cmd, struct pl
else
nvme_show_perror("effects log page");
-close_dev:
+cleanup_list:
while ((node = list_pop(&log_pages, nvme_effects_log_node_t, node)))
free(node);
- dev_close(dev);
-ret:
return err;
}
@@ -1090,51 +1056,39 @@ static int get_supported_log_pages(int argc, char **argv, struct command *cmd,
struct plugin *plugin)
{
const char *desc = "Retrieve supported logs and print the table.";
- struct nvme_supported_log_pages supports;
+
+ _cleanup_free_ struct nvme_supported_log_pages *supports = NULL;
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
enum nvme_print_flags flags;
- struct nvme_dev *dev;
int err = -1;
- struct config {
- char *output_format;
- bool verbose;
- };
-
- struct config cfg = {
- .output_format = "normal",
- .verbose = false
- };
-
- OPT_ARGS(opts) = {
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_FLAG("verbose", 'v', &cfg.verbose, verbose),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg);
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
- err = flags = validate_output_format(cfg.output_format);
+ err = validate_output_format(output_format_val, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
- goto close_dev;
+ return err;
}
- if (cfg.verbose)
+ if (argconfig_parse_seen(opts, "verbose"))
flags |= VERBOSE;
- err = nvme_cli_get_log_supported_log_pages(dev, false, &supports);
+ supports = nvme_alloc(sizeof(*supports));
+ if (!supports)
+ return -ENOMEM;
+
+ err = nvme_cli_get_log_supported_log_pages(dev, false, supports);
if (!err)
- nvme_show_supported_log(&supports, dev->name, flags);
+ nvme_show_supported_log(supports, dev->name, flags);
else if (err > 0)
nvme_show_status(err);
else
nvme_show_error("supported log pages: %s", nvme_strerror(errno));
-close_dev:
- dev_close(dev);
-ret:
return err;
}
@@ -1145,39 +1099,35 @@ static int get_error_log(int argc, char **argv, struct command *cmd, struct plug
"in either decoded format (default) or binary.";
const char *log_entries = "number of entries to retrieve";
const char *raw = "dump in binary format";
- struct nvme_error_log_page *err_log;
+
+ _cleanup_free_ struct nvme_error_log_page *err_log = NULL;
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
struct nvme_id_ctrl ctrl;
enum nvme_print_flags flags;
- struct nvme_dev *dev;
int err = -1;
struct config {
__u32 log_entries;
- char *output_format;
bool raw_binary;
};
struct config cfg = {
.log_entries = 64,
- .output_format = "normal",
.raw_binary = false,
};
- OPT_ARGS(opts) = {
- OPT_UINT("log-entries", 'e', &cfg.log_entries, log_entries),
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_UINT("log-entries", 'e', &cfg.log_entries, log_entries),
+ OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
- err = flags = validate_output_format(cfg.output_format);
+ err = validate_output_format(output_format_val, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
- goto close_dev;
+ return err;
}
if (cfg.raw_binary)
@@ -1185,26 +1135,22 @@ static int get_error_log(int argc, char **argv, struct command *cmd, struct plug
if (!cfg.log_entries) {
nvme_show_error("non-zero log-entries is required param");
- err = -1;
- goto close_dev;
+ return -1;
}
err = nvme_cli_identify_ctrl(dev, &ctrl);
if (err < 0) {
nvme_show_perror("identify controller");
- goto close_dev;
+ return err;
} else if (err) {
nvme_show_error("could not identify controller");
- err = -1;
- goto close_dev;
+ return err;
}
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_dev;
- }
+ err_log = nvme_alloc(cfg.log_entries * sizeof(struct nvme_error_log_page));
+ if (!err_log)
+ return -ENOMEM;
err = nvme_cli_get_log_error(dev, cfg.log_entries, false, err_log);
if (!err)
@@ -1215,11 +1161,6 @@ static int get_error_log(int argc, char **argv, struct command *cmd, struct plug
else
nvme_show_perror("error log");
- free(err_log);
-
-close_dev:
- dev_close(dev);
-ret:
return err;
}
@@ -1227,50 +1168,48 @@ static int get_fw_log(int argc, char **argv, struct command *cmd, struct plugin
{
const char *desc = "Retrieve the firmware log for the\n"
"specified device in either decoded format (default) or binary.";
- struct nvme_firmware_slot fw_log;
+
+ _cleanup_free_ struct nvme_firmware_slot *fw_log = NULL;;
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
enum nvme_print_flags flags;
- struct nvme_dev *dev;
int err;
struct config {
- char *output_format;
bool raw_binary;
};
struct config cfg = {
- .output_format = "normal",
.raw_binary = false,
};
- OPT_ARGS(opts) = {
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_use),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_use));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
- err = flags = validate_output_format(cfg.output_format);
+ err = validate_output_format(output_format_val, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
- goto close_dev;
+ return err;
}
if (cfg.raw_binary)
flags = BINARY;
- err = nvme_cli_get_log_fw_slot(dev, false, &fw_log);
+ fw_log = nvme_alloc(sizeof(*fw_log));
+ if (!fw_log)
+ return -ENOMEM;
+
+ err = nvme_cli_get_log_fw_slot(dev, false, fw_log);
if (!err)
- nvme_show_fw_log(&fw_log, dev->name, flags);
+ nvme_show_fw_log(fw_log, dev->name, flags);
else if (err > 0)
nvme_show_status(err);
else
nvme_show_error("fw log: %s", nvme_strerror(errno));
-close_dev:
- dev_close(dev);
-ret:
+
return err;
}
@@ -1278,52 +1217,50 @@ static int get_changed_ns_list_log(int argc, char **argv, struct command *cmd, s
{
const char *desc = "Retrieve Changed Namespaces log for the given device\n"
"in either decoded format (default) or binary.";
- struct nvme_ns_list changed_ns_list_log;
+
+ _cleanup_free_ struct nvme_ns_list *changed_ns_list_log = NULL;
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
enum nvme_print_flags flags;
- struct nvme_dev *dev;
int err;
struct config {
- char *output_format;
bool raw_binary;
};
struct config cfg = {
- .output_format = "normal",
.raw_binary = false,
};
- OPT_ARGS(opts) = {
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_output),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_output));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
- err = flags = validate_output_format(cfg.output_format);
+ err = validate_output_format(output_format_val, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
- goto close_dev;
+ return err;
}
if (cfg.raw_binary)
flags = BINARY;
+ changed_ns_list_log = nvme_alloc(sizeof(*changed_ns_list_log));
+ if (!changed_ns_list_log)
+ return -ENOMEM;
+
err = nvme_cli_get_log_changed_ns_list(dev, true,
- &changed_ns_list_log);
+ changed_ns_list_log);
if (!err)
- nvme_show_changed_ns_list_log(&changed_ns_list_log,
+ nvme_show_changed_ns_list_log(changed_ns_list_log,
dev->name, flags);
else if (err > 0)
nvme_show_status(err);
else
nvme_show_error("changed ns list log: %s", nvme_strerror(errno));
-close_dev:
- dev_close(dev);
-ret:
+
return err;
}
@@ -1334,56 +1271,53 @@ static int get_pred_lat_per_nvmset_log(int argc, char **argv,
"page and prints it for the given device in either decoded\n"
"format(default),json or binary.";
const char *nvmset_id = "NVM Set Identifier";
- struct nvme_nvmset_predictable_lat_log plpns_log;
+
+ _cleanup_free_ struct nvme_nvmset_predictable_lat_log *plpns_log = NULL;
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
enum nvme_print_flags flags;
- struct nvme_dev *dev;
int err;
struct config {
__u16 nvmset_id;
- char *output_format;
bool raw_binary;
};
struct config cfg = {
.nvmset_id = 1,
- .output_format = "normal",
.raw_binary = false,
};
- OPT_ARGS(opts) = {
- OPT_SHRT("nvmset-id", 'i', &cfg.nvmset_id, nvmset_id),
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_use),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_SHRT("nvmset-id", 'i', &cfg.nvmset_id, nvmset_id),
+ OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_use));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
- err = flags = validate_output_format(cfg.output_format);
+ err = validate_output_format(output_format_val, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
- goto close_dev;
+ return err;
}
if (cfg.raw_binary)
flags = BINARY;
+ plpns_log = nvme_alloc(sizeof(*plpns_log));
+ if (!plpns_log)
+ return -ENOMEM;
+
err = nvme_cli_get_log_predictable_lat_nvmset(dev, cfg.nvmset_id,
- &plpns_log);
+ plpns_log);
if (!err)
- nvme_show_predictable_latency_per_nvmset(&plpns_log, cfg.nvmset_id, dev->name,
+ nvme_show_predictable_latency_per_nvmset(plpns_log, cfg.nvmset_id, dev->name,
flags);
else if (err > 0)
nvme_show_status(err);
else
nvme_show_error("predictable latency per nvm set: %s", nvme_strerror(errno));
-close_dev:
- dev_close(dev);
-ret:
return err;
}
@@ -1394,43 +1328,39 @@ static int get_pred_lat_event_agg_log(int argc, char **argv,
"Aggregate Log page and prints it, for the given\n"
"device in either decoded format(default), json or binary.";
const char *log_entries = "Number of pending NVM Set log Entries list";
+
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
+ _cleanup_free_ struct nvme_id_ctrl *ctrl = NULL;
+ _cleanup_free_ void *pea_log = NULL;
enum nvme_print_flags flags;
- struct nvme_id_ctrl ctrl;
- struct nvme_dev *dev;
__u32 log_size;
- void *pea_log;
int err;
struct config {
__u64 log_entries;
bool rae;
- char *output_format;
bool raw_binary;
};
struct config cfg = {
.log_entries = 2044,
.rae = false,
- .output_format = "normal",
.raw_binary = false,
};
- OPT_ARGS(opts) = {
- OPT_UINT("log-entries", 'e', &cfg.log_entries, log_entries),
- OPT_FLAG("rae", 'r', &cfg.rae, rae),
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_use),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_UINT("log-entries", 'e', &cfg.log_entries, log_entries),
+ OPT_FLAG("rae", 'r', &cfg.rae, rae),
+ OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_use));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
- err = flags = validate_output_format(cfg.output_format);
+ err = validate_output_format(output_format_val, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
- goto close_dev;
+ return err;
}
if (cfg.raw_binary)
@@ -1438,26 +1368,28 @@ static int get_pred_lat_event_agg_log(int argc, char **argv,
if (!cfg.log_entries) {
nvme_show_error("non-zero log-entries is required param");
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
- err = nvme_cli_identify_ctrl(dev, &ctrl);
+ ctrl = nvme_alloc(sizeof(*ctrl));
+ if (!ctrl)
+ return -ENOMEM;
+
+ err = nvme_cli_identify_ctrl(dev, ctrl);
if (err < 0) {
nvme_show_error("identify controller: %s", nvme_strerror(errno));
- goto close_dev;
+ return err;
} else if (err) {
nvme_show_status(err);
- goto close_dev;
+ return err;
}
- cfg.log_entries = min(cfg.log_entries, le32_to_cpu(ctrl.nsetidmax));
+ cfg.log_entries = min(cfg.log_entries, le32_to_cpu(ctrl->nsetidmax));
log_size = sizeof(__u64) + cfg.log_entries * sizeof(__u16);
- pea_log = calloc(log_size, 1);
- if (!pea_log) {
- err = -ENOMEM;
- goto close_dev;
- }
+
+ pea_log = nvme_alloc(log_size);
+ if (!pea_log)
+ return -ENOMEM;
err = nvme_cli_get_log_predictable_lat_event(dev, cfg.rae, 0,
log_size, pea_log);
@@ -1469,11 +1401,7 @@ static int get_pred_lat_event_agg_log(int argc, char **argv,
else
nvme_show_error("predictable latency event aggregate log page: %s",
nvme_strerror(errno));
- free(pea_log);
-close_dev:
- dev_close(dev);
-ret:
return err;
}
@@ -1485,74 +1413,69 @@ static int get_persistent_event_log(int argc, char **argv,
const char *action = "action the controller shall take during\n"
"processing this persistent log page command.";
const char *log_len = "number of bytes to retrieve";
- struct nvme_persistent_event_log *pevent, *pevent_collected;
+
+ _cleanup_free_ struct nvme_persistent_event_log *pevent_collected = NULL;
+ _cleanup_free_ struct nvme_persistent_event_log *pevent = NULL;
+ _cleanup_huge_ struct nvme_mem_huge mh = { 0, };
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
enum nvme_print_flags flags;
void *pevent_log_info;
- struct nvme_dev *dev;
- bool huge;
int err;
struct config {
__u8 action;
__u32 log_len;
- char *output_format;
bool raw_binary;
};
struct config cfg = {
.action = 0xff,
.log_len = 0,
- .output_format = "normal",
.raw_binary = false,
};
- OPT_ARGS(opts) = {
- OPT_BYTE("action", 'a', &cfg.action, action),
- OPT_UINT("log_len", 'l', &cfg.log_len, log_len),
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_use),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_BYTE("action", 'a', &cfg.action, action),
+ OPT_UINT("log_len", 'l', &cfg.log_len, log_len),
+ OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_use));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
- err = flags = validate_output_format(cfg.output_format);
+ err = validate_output_format(output_format_val, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
- goto close_dev;
+ return err;
}
if (cfg.raw_binary)
flags = BINARY;
- pevent = calloc(sizeof(*pevent), 1);
- if (!pevent) {
- err = -ENOMEM;
- goto close_dev;
- }
+ pevent = nvme_alloc(sizeof(*pevent));
+ if (!pevent)
+ return -ENOMEM;
err = nvme_cli_get_log_persistent_event(dev, cfg.action,
sizeof(*pevent), pevent);
if (err < 0) {
nvme_show_error("persistent event log: %s", nvme_strerror(errno));
- goto free_pevent;
+ return err;
} else if (err) {
nvme_show_status(err);
- goto free_pevent;
+ return err;
}
if (cfg.action == NVME_PEVENT_LOG_RELEASE_CTX) {
printf("Releasing Persistent Event Log Context\n");
- goto free_pevent;
+ return 0;
}
if (!cfg.log_len && cfg.action != NVME_PEVENT_LOG_EST_CTX_AND_READ) {
cfg.log_len = le64_to_cpu(pevent->tll);
} else if (!cfg.log_len && cfg.action == NVME_PEVENT_LOG_EST_CTX_AND_READ) {
printf("Establishing Persistent Event Log Context\n");
- goto free_pevent;
+ return 0;
}
/*
@@ -1565,11 +1488,10 @@ static int get_persistent_event_log(int argc, char **argv,
if (cfg.action == NVME_PEVENT_LOG_EST_CTX_AND_READ)
cfg.action = NVME_PEVENT_LOG_READ;
- pevent_log_info = nvme_alloc(cfg.log_len, &huge);
- if (!pevent_log_info) {
- err = -ENOMEM;
- goto free_pevent;
- }
+ pevent_log_info = nvme_alloc_huge(cfg.log_len, &mh);
+ if (!pevent_log_info)
+ return -ENOMEM;
+
err = nvme_cli_get_log_persistent_event(dev, cfg.action,
cfg.log_len, pevent_log_info);
if (!err) {
@@ -1578,16 +1500,16 @@ static int get_persistent_event_log(int argc, char **argv,
pevent);
if (err < 0) {
nvme_show_error("persistent event log: %s", nvme_strerror(errno));
- goto free;
+ return err;
} else if (err) {
nvme_show_status(err);
- goto free;
+ return err;
}
pevent_collected = pevent_log_info;
if (pevent_collected->gen_number != pevent->gen_number) {
printf("Collected Persistent Event Log may be invalid,\n"
"Re-read the log is required\n");
- goto free;
+ return -EINVAL;
}
nvme_show_persistent_event_log(pevent_log_info, cfg.action,
@@ -1598,13 +1520,6 @@ static int get_persistent_event_log(int argc, char **argv,
nvme_show_error("persistent event log: %s", nvme_strerror(errno));
}
-free:
- nvme_free(pevent_log_info, huge);
-free_pevent:
- free(pevent);
-close_dev:
- dev_close(dev);
-ret:
return err;
}
@@ -1615,43 +1530,39 @@ static int get_endurance_event_agg_log(int argc, char **argv,
"Event Aggregate page and prints it, for the given\n"
"device in either decoded format(default), json or binary.";
const char *log_entries = "Number of pending Endurance Group Event log Entries list";
- void *endurance_log;
- struct nvme_id_ctrl ctrl;
+
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
+ _cleanup_free_ struct nvme_id_ctrl *ctrl = NULL;
+ _cleanup_free_ void *endurance_log = NULL;
enum nvme_print_flags flags;
- struct nvme_dev *dev;
__u32 log_size;
int err;
struct config {
__u64 log_entries;
bool rae;
- char *output_format;
bool raw_binary;
};
struct config cfg = {
.log_entries = 2044,
.rae = false,
- .output_format = "normal",
.raw_binary = false,
};
- OPT_ARGS(opts) = {
- OPT_UINT("log-entries", 'e', &cfg.log_entries, log_entries),
- OPT_FLAG("rae", 'r', &cfg.rae, rae),
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_use),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_UINT("log-entries", 'e', &cfg.log_entries, log_entries),
+ OPT_FLAG("rae", 'r', &cfg.rae, rae),
+ OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_use));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
- err = flags = validate_output_format(cfg.output_format);
+ err = validate_output_format(output_format_val, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
- goto close_dev;
+ return err;
}
if (cfg.raw_binary)
@@ -1659,27 +1570,28 @@ static int get_endurance_event_agg_log(int argc, char **argv,
if (!cfg.log_entries) {
nvme_show_error("non-zero log-entries is required param");
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
- err = nvme_cli_identify_ctrl(dev, &ctrl);
+ ctrl = nvme_alloc(sizeof(*ctrl));
+ if (!ctrl)
+ return -ENOMEM;
+
+ err = nvme_cli_identify_ctrl(dev, ctrl);
if (err < 0) {
nvme_show_error("identify controller: %s", nvme_strerror(errno));
- goto close_dev;
+ return err;
} else if (err) {
nvme_show_error("could not identify controller");
- err = -ENODEV;
- goto close_dev;
+ return -ENODEV;
}
- cfg.log_entries = min(cfg.log_entries, le16_to_cpu(ctrl.endgidmax));
+ cfg.log_entries = min(cfg.log_entries, le16_to_cpu(ctrl->endgidmax));
log_size = sizeof(__u64) + cfg.log_entries * sizeof(__u16);
- endurance_log = calloc(log_size, 1);
- if (!endurance_log) {
- err = -ENOMEM;
- goto close_dev;
- }
+
+ endurance_log = nvme_alloc(log_size);
+ if (!endurance_log)
+ return -ENOMEM;
err = nvme_cli_get_log_endurance_grp_evt(dev, cfg.rae, 0, log_size,
endurance_log);
@@ -1691,11 +1603,7 @@ static int get_endurance_event_agg_log(int argc, char **argv,
else
nvme_show_error("endurance group event aggregate log page: %s",
nvme_strerror(errno));
- free(endurance_log);
-close_dev:
- dev_close(dev);
-ret:
return err;
}
@@ -1704,66 +1612,56 @@ static int get_lba_status_log(int argc, char **argv,
{
const char *desc = "Retrieve Get LBA Status Info Log and prints it,\n"
"for the given device in either decoded format(default),json or binary.";
- void *lab_status;
+
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
+ _cleanup_free_ void *lba_status = NULL;
enum nvme_print_flags flags;
- struct nvme_dev *dev;
__u32 lslplen;
int err;
struct config {
bool rae;
- char *output_format;
};
struct config cfg = {
.rae = false,
- .output_format = "normal",
};
- OPT_ARGS(opts) = {
- OPT_FLAG("rae", 'r', &cfg.rae, rae),
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_FLAG("rae", 'r', &cfg.rae, rae));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
- err = flags = validate_output_format(cfg.output_format);
+ err = validate_output_format(output_format_val, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
- goto close_dev;
+ return err;
}
err = nvme_cli_get_log_lba_status(dev, true, 0, sizeof(__u32),
&lslplen);
if (err < 0) {
nvme_show_error("lba status log page: %s", nvme_strerror(errno));
- goto close_dev;
+ return err;
} else if (err) {
nvme_show_status(err);
- goto close_dev;
+ return err;
}
- lab_status = calloc(lslplen, 1);
- if (!lab_status) {
- err = -ENOMEM;
- goto close_dev;
- }
+ lba_status = nvme_alloc(lslplen);
+ if (!lba_status)
+ return -ENOMEM;
- err = nvme_cli_get_log_lba_status(dev, cfg.rae, 0, lslplen, lab_status);
+ err = nvme_cli_get_log_lba_status(dev, cfg.rae, 0, lslplen, lba_status);
if (!err)
- nvme_show_lba_status_log(lab_status, lslplen, dev->name, flags);
+ nvme_show_lba_status_log(lba_status, lslplen, dev->name, flags);
else if (err > 0)
nvme_show_status(err);
else
nvme_show_error("lba status log page: %s", nvme_strerror(errno));
- free(lab_status);
-close_dev:
- dev_close(dev);
-ret:
return err;
}
@@ -1774,45 +1672,36 @@ static int get_resv_notif_log(int argc, char **argv,
const char *desc = "Retrieve Reservation Notification\n"
"log page and prints it, for the given\n"
"device in either decoded format(default), json or binary.";
- struct nvme_resv_notification_log resv;
+
+ _cleanup_free_ struct nvme_resv_notification_log *resv = NULL;
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
enum nvme_print_flags flags;
- struct nvme_dev *dev;
int err;
- struct config {
- char *output_format;
- };
-
- struct config cfg = {
- .output_format = "normal",
- };
-
- OPT_ARGS(opts) = {
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg);
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
- err = flags = validate_output_format(cfg.output_format);
+ err = validate_output_format(output_format_val, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
- goto close_dev;
+ return err;
}
- err = nvme_cli_get_log_reservation(dev, false, &resv);
+ resv = nvme_alloc(sizeof(*resv));
+ if (!resv)
+ return -ENOMEM;
+
+ err = nvme_cli_get_log_reservation(dev, false, resv);
if (!err)
- nvme_show_resv_notif_log(&resv, dev->name, flags);
+ nvme_show_resv_notif_log(resv, dev->name, flags);
else if (err > 0)
nvme_show_status(err);
else
nvme_show_error("resv notifi log: %s", nvme_strerror(errno));
-close_dev:
- dev_close(dev);
-ret:
return err;
}
@@ -1823,103 +1712,184 @@ static int get_boot_part_log(int argc, char **argv, struct command *cmd, struct
"log page and prints it, for the given\n"
"device in either decoded format(default), json or binary.";
const char *fname = "boot partition data output file name";
- struct nvme_boot_partition boot;
- __u8 *bp_log;
+
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
+ _cleanup_free_ struct nvme_boot_partition *boot = NULL;
+ _cleanup_free_ __u8 *bp_log = NULL;
enum nvme_print_flags flags;
- int err = -1, output = 0;
- struct nvme_dev *dev;
+ int err = -1;
+ _cleanup_file_ int output = -1;
__u32 bpsz = 0;
struct config {
__u8 lsp;
char *file_name;
- char *output_format;
};
struct config cfg = {
.lsp = 0,
- .output_format = "normal",
.file_name = NULL,
};
- OPT_ARGS(opts) = {
- OPT_BYTE("lsp", 's', &cfg.lsp, lsp),
- OPT_FILE("output-file", 'f', &cfg.file_name, fname),
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_BYTE("lsp", 's', &cfg.lsp, lsp),
+ OPT_FILE("output-file", 'f', &cfg.file_name, fname));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
- err = flags = validate_output_format(cfg.output_format);
+ err = validate_output_format(output_format_val, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
- goto close_dev;
+ return err;
}
if (!cfg.file_name) {
nvme_show_error("Please provide an output file!");
- err = -1;
- goto close_dev;
+ return -1;
}
if (cfg.lsp > 127) {
nvme_show_error("invalid lsp param: %u", cfg.lsp);
- err = -1;
- goto close_dev;
+ return -1;
}
output = open(cfg.file_name, O_WRONLY | O_CREAT | O_TRUNC, 0666);
if (output < 0) {
nvme_show_error("Failed to open output file %s: %s!",
cfg.file_name, strerror(errno));
- err = output;
- goto close_dev;
+ return output;
}
+ boot = nvme_alloc(sizeof(*boot));
+ if (!boot)
+ return -ENOMEM;
+
err = nvme_cli_get_log_boot_partition(dev, false, cfg.lsp,
- sizeof(boot), &boot);
+ sizeof(*boot), boot);
if (err < 0) {
nvme_show_error("boot partition log: %s", nvme_strerror(errno));
- goto close_output;
+ return err;
} else if (err) {
nvme_show_status(err);
- goto close_output;
+ return err;
}
- bpsz = (boot.bpinfo & 0x7fff) * 128 * 1024;
- bp_log = calloc(sizeof(boot) + bpsz, 1);
- if (!bp_log) {
- err = -1;
- goto close_output;
- }
+ bpsz = (boot->bpinfo & 0x7fff) * 128 * 1024;
+ bp_log = nvme_alloc(sizeof(*boot) + bpsz);
+ if (!bp_log)
+ return -ENOMEM;
err = nvme_cli_get_log_boot_partition(dev, false, cfg.lsp,
- sizeof(boot) + bpsz,
+ sizeof(*boot) + bpsz,
(struct nvme_boot_partition *)bp_log);
if (!err)
- nvme_show_boot_part_log(&bp_log, dev->name, flags, sizeof(boot) + bpsz);
+ nvme_show_boot_part_log(&bp_log, dev->name, sizeof(*boot) + bpsz, flags);
else if (err > 0)
nvme_show_status(err);
else
nvme_show_error("boot partition log: %s", nvme_strerror(errno));
- err = write(output, (void *) bp_log + sizeof(boot), bpsz);
+ err = write(output, (void *) bp_log + sizeof(*boot), bpsz);
if (err != bpsz)
fprintf(stderr, "Failed to flush all data to file!\n");
else
printf("Data flushed into file %s\n", cfg.file_name);
err = 0;
- free(bp_log);
+ return err;
+}
+
+static int get_phy_rx_eom_log(int argc, char **argv, struct command *cmd,
+ struct plugin *plugin)
+{
+ const char *desc = "Retrieve Physical Interface Receiver Eye Opening\n"
+ "Measurement log for the given device in decoded format\n"
+ "(default), json or binary.";
+ const char *controller = "Target Controller ID.";
+ _cleanup_free_ struct nvme_phy_rx_eom_log *phy_rx_eom_log = NULL;
+ size_t phy_rx_eom_log_len;
+ enum nvme_print_flags flags;
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
+ int err = -1;
+ __u8 lsp_tmp;
+
+ struct config {
+ __u8 lsp;
+ __u16 controller;
+ };
+
+ struct config cfg = {
+ .lsp = 0,
+ .controller = NVME_LOG_LSI_NONE,
+ };
+
+ NVME_ARGS(opts, cfg,
+ OPT_BYTE("lsp", 's', &cfg.lsp, lsp),
+ OPT_SHRT("controller", 'c', &cfg.controller, controller));
+
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
+
+ err = validate_output_format(output_format_val, &flags);
+ if (err < 0) {
+ nvme_show_error("Invalid output format");
+ return err;
+ }
+
+ if (cfg.lsp > 127) {
+ nvme_show_error("invalid lsp param: %u", cfg.lsp);
+ return -1;
+ } else if ((cfg.lsp & 3) == 3) {
+ nvme_show_error("invalid measurement quality: %u", cfg.lsp & 3);
+ return -1;
+ } else if ((cfg.lsp & 12) == 12) {
+ nvme_show_error("invalid action: %u", cfg.lsp & 12);
+ return -1;
+ }
+
+ /* Fetching header to calculate total log length */
+ phy_rx_eom_log_len = sizeof(struct nvme_phy_rx_eom_log);
+ phy_rx_eom_log = nvme_alloc(phy_rx_eom_log_len);
+ if (!phy_rx_eom_log)
+ return -ENOMEM;
+
+ /* Just read measurement, take given action when fetching full log */
+ lsp_tmp = cfg.lsp & 0xf3;
+
+ err = nvme_cli_get_log_phy_rx_eom(dev, lsp_tmp, cfg.controller, phy_rx_eom_log_len,
+ phy_rx_eom_log);
+ if (err) {
+ if (err > 0)
+ nvme_show_status(err);
+ else
+ nvme_show_error("phy-rx-eom-log: %s", nvme_strerror(errno));
+
+ return err;
+ }
+
+ if (phy_rx_eom_log->eomip == NVME_PHY_RX_EOM_COMPLETED)
+ phy_rx_eom_log_len = le16_to_cpu(phy_rx_eom_log->hsize) +
+ le32_to_cpu(phy_rx_eom_log->dsize) *
+ le16_to_cpu(phy_rx_eom_log->nd);
+ else
+ phy_rx_eom_log_len = le16_to_cpu(phy_rx_eom_log->hsize);
+
+ phy_rx_eom_log = nvme_realloc(phy_rx_eom_log, phy_rx_eom_log_len);
+ if (!phy_rx_eom_log)
+ return -ENOMEM;
+
+ err = nvme_cli_get_log_phy_rx_eom(dev, cfg.lsp, cfg.controller, phy_rx_eom_log_len,
+ phy_rx_eom_log);
+ if (!err)
+ nvme_show_phy_rx_eom_log(phy_rx_eom_log, cfg.controller, flags);
+ else if (err > 0)
+ nvme_show_status(err);
+ else
+ nvme_show_error("phy-rx-eom-log: %s", nvme_strerror(errno));
-close_output:
- close(output);
-close_dev:
- dev_close(dev);
-ret:
return err;
}
@@ -1927,54 +1897,51 @@ static int get_media_unit_stat_log(int argc, char **argv, struct command *cmd,
struct plugin *plugin)
{
const char *desc = "Retrieve the configuration and wear of media units and print it";
- struct nvme_media_unit_stat_log mus;
+
+ _cleanup_free_ struct nvme_media_unit_stat_log *mus = NULL;
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
enum nvme_print_flags flags;
- struct nvme_dev *dev;
int err = -1;
struct config {
__u16 domainid;
- char *output_format;
bool raw_binary;
};
struct config cfg = {
.domainid = 0,
- .output_format = "normal",
.raw_binary = false,
};
- OPT_ARGS(opts) = {
- OPT_UINT("domain-id", 'd', &cfg.domainid, domainid),
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_use),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_UINT("domain-id", 'd', &cfg.domainid, domainid),
+ OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_use));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
- err = flags = validate_output_format(cfg.output_format);
+ err = validate_output_format(output_format_val, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
- goto close_dev;
+ return err;
}
if (cfg.raw_binary)
flags = BINARY;
- err = nvme_cli_get_log_media_unit_stat(dev, cfg.domainid, &mus);
+ mus = nvme_alloc(sizeof(*mus));
+ if (!mus)
+ return -ENOMEM;
+
+ err = nvme_cli_get_log_media_unit_stat(dev, cfg.domainid, mus);
if (!err)
- nvme_show_media_unit_stat_log(&mus, flags);
+ nvme_show_media_unit_stat_log(mus, flags);
else if (err > 0)
nvme_show_status(err);
else
nvme_show_error("media unit status log: %s", nvme_strerror(errno));
-close_dev:
- dev_close(dev);
-ret:
return err;
}
@@ -1982,55 +1949,52 @@ static int get_supp_cap_config_log(int argc, char **argv, struct command *cmd,
struct plugin *plugin)
{
const char *desc = "Retrieve the list of Supported Capacity Configuration Descriptors";
- struct nvme_supported_cap_config_list_log cap_log;
+
+ _cleanup_free_ struct nvme_supported_cap_config_list_log *cap_log = NULL;
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
enum nvme_print_flags flags;
- struct nvme_dev *dev;
int err = -1;
struct config {
__u16 domainid;
- char *output_format;
bool raw_binary;
};
struct config cfg = {
.domainid = 0,
- .output_format = "normal",
.raw_binary = false,
};
- OPT_ARGS(opts) = {
- OPT_UINT("domain-id", 'd', &cfg.domainid, domainid),
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_use),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_UINT("domain-id", 'd', &cfg.domainid, domainid),
+ OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_use));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
- err = flags = validate_output_format(cfg.output_format);
+ err = validate_output_format(output_format_val, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
- goto close_dev;
+ return err;
}
if (cfg.raw_binary)
flags = BINARY;
+ cap_log = nvme_alloc(sizeof(*cap_log));
+ if (!cap_log)
+ return -ENOMEM;
+
err = nvme_cli_get_log_support_cap_config_list(dev, cfg.domainid,
- &cap_log);
+ cap_log);
if (!err)
- nvme_show_supported_cap_config_log(&cap_log, flags);
+ nvme_show_supported_cap_config_log(cap_log, flags);
else if (err > 0)
nvme_show_status(err);
else
nvme_show_perror("supported capacity configuration list log");
-close_dev:
- dev_close(dev);
-ret:
return err;
}
@@ -2039,8 +2003,8 @@ static int io_mgmt_send(int argc, char **argv, struct command *cmd, struct plugi
const char *desc = "I/O Management Send";
const char *data = "optional file for data (default stdin)";
- struct nvme_dev *dev;
- void *buf = NULL;
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
+ _cleanup_free_ void *buf = NULL;
int err = -1;
int dfd = STDIN_FILENO;
@@ -2056,41 +2020,36 @@ static int io_mgmt_send(int argc, char **argv, struct command *cmd, struct plugi
.mos = 0,
};
- OPT_ARGS(opts) = {
- OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired),
- OPT_SHRT("mos", 's', &cfg.mos, mos),
- OPT_BYTE("mo", 'm', &cfg.mo, mo),
- OPT_FILE("data", 'd', &cfg.file, data),
- OPT_UINT("data-len", 'l', &cfg.data_len, buf_len),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired),
+ OPT_SHRT("mos", 's', &cfg.mos, mos),
+ OPT_BYTE("mo", 'm', &cfg.mo, mo),
+ OPT_FILE("data", 'd', &cfg.file, data),
+ OPT_UINT("data-len", 'l', &cfg.data_len, buf_len));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- return errno;
+ return err;
if (!cfg.namespace_id) {
err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
nvme_show_perror("get-namespace-id");
- goto close_dev;
+ return err;
}
}
if (cfg.data_len) {
- buf = calloc(1, cfg.data_len);
- if (!buf) {
- nvme_show_perror("could not alloc memory for io mgmt receive data");
- err = -ENOMEM;
- goto close_dev;
- }
+ buf = nvme_alloc(cfg.data_len);
+ if (!buf)
+ return -ENOMEM;
}
if (cfg.file) {
dfd = open(cfg.file, O_RDONLY);
if (dfd < 0) {
nvme_show_perror(cfg.file);
- goto free;
+ return -errno;
}
}
@@ -2123,10 +2082,6 @@ static int io_mgmt_send(int argc, char **argv, struct command *cmd, struct plugi
close_fd:
if (cfg.file)
close(dfd);
-free:
- free(buf);
-close_dev:
- dev_close(dev);
return err;
}
@@ -2135,10 +2090,10 @@ static int io_mgmt_recv(int argc, char **argv, struct command *cmd, struct plugi
const char *desc = "I/O Management Receive";
const char *data = "optional file for data (default stdout)";
- struct nvme_dev *dev;
- void *buf = NULL;
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
+ _cleanup_free_ void *buf = NULL;
int err = -1;
- int dfd = STDOUT_FILENO;
+ _cleanup_file_ int dfd = -1;
struct config {
__u16 mos;
@@ -2152,34 +2107,29 @@ static int io_mgmt_recv(int argc, char **argv, struct command *cmd, struct plugi
.mos = 0,
};
- OPT_ARGS(opts) = {
- OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired),
- OPT_SHRT("mos", 's', &cfg.mos, mos),
- OPT_BYTE("mo", 'm', &cfg.mo, mo),
- OPT_FILE("data", 'd', &cfg.file, data),
- OPT_UINT("data-len", 'l', &cfg.data_len, buf_len),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired),
+ OPT_SHRT("mos", 's', &cfg.mos, mos),
+ OPT_BYTE("mo", 'm', &cfg.mo, mo),
+ OPT_FILE("data", 'd', &cfg.file, data),
+ OPT_UINT("data-len", 'l', &cfg.data_len, buf_len));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- return errno;
+ return err;
if (!cfg.namespace_id) {
err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
nvme_show_perror("get-namespace-id");
- goto close_dev;
+ return err;
}
}
if (cfg.data_len) {
- buf = calloc(1, cfg.data_len);
- if (!buf) {
- nvme_show_perror("could not alloc memory for io mgmt receive data");
- err = -ENOMEM;
- goto close_dev;
- }
+ buf = nvme_alloc(cfg.data_len);
+ if (!buf)
+ return -ENOMEM;
}
struct nvme_io_mgmt_recv_args args = {
@@ -2202,13 +2152,13 @@ static int io_mgmt_recv(int argc, char **argv, struct command *cmd, struct plugi
dfd = open(cfg.file, O_WRONLY | O_CREAT, 0644);
if (dfd < 0) {
nvme_show_perror(cfg.file);
- goto free;
+ return -errno;
}
err = write(dfd, buf, cfg.data_len);
if (err < 0) {
nvme_show_perror("write");
- goto close_fd;
+ return -errno;
}
} else {
d((unsigned char *)buf, cfg.data_len, 16, 1);
@@ -2219,14 +2169,6 @@ static int io_mgmt_recv(int argc, char **argv, struct command *cmd, struct plugi
nvme_show_perror("io-mgmt-recv");
}
-close_fd:
- if (cfg.file)
- close(dfd);
-free:
- free(buf);
-close_dev:
- dev_close(dev);
-
return err;
}
@@ -2243,8 +2185,9 @@ static int get_log(int argc, char **argv, struct command *cmd, struct plugin *pl
const char *raw = "output in raw format";
const char *offset_type = "offset type";
const char *xfer_len = "read chunk size (default 4k)";
- struct nvme_dev *dev;
- unsigned char *log;
+
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
+ _cleanup_free_ unsigned char *log = NULL;
int err;
struct config {
@@ -2279,26 +2222,24 @@ static int get_log(int argc, char **argv, struct command *cmd, struct plugin *pl
.xfer_len = 4096,
};
- OPT_ARGS(opts) = {
- OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_desired),
- OPT_BYTE("log-id", 'i', &cfg.log_id, log_id),
- OPT_UINT("log-len", 'l', &cfg.log_len, log_len),
- OPT_UINT("aen", 'a', &cfg.aen, aen),
- OPT_SUFFIX("lpo", 'o', &cfg.lpo, lpo),
- OPT_BYTE("lsp", 's', &cfg.lsp, lsp),
- OPT_SHRT("lsi", 'S', &cfg.lsi, lsi),
- OPT_FLAG("rae", 'r', &cfg.rae, rae),
- OPT_BYTE("uuid-index", 'U', &cfg.uuid_index, uuid_index),
- OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw),
- OPT_BYTE("csi", 'y', &cfg.csi, csi),
- OPT_FLAG("ot", 'O', &cfg.ot, offset_type),
- OPT_UINT("xfer-len", 'x', &cfg.xfer_len, xfer_len),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_desired),
+ OPT_BYTE("log-id", 'i', &cfg.log_id, log_id),
+ OPT_UINT("log-len", 'l', &cfg.log_len, log_len),
+ OPT_UINT("aen", 'a', &cfg.aen, aen),
+ OPT_SUFFIX("lpo", 'L', &cfg.lpo, lpo),
+ OPT_BYTE("lsp", 's', &cfg.lsp, lsp),
+ OPT_SHRT("lsi", 'S', &cfg.lsi, lsi),
+ OPT_FLAG("rae", 'r', &cfg.rae, rae),
+ OPT_BYTE("uuid-index", 'U', &cfg.uuid_index, uuid_index),
+ OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw),
+ OPT_BYTE("csi", 'y', &cfg.csi, csi),
+ OPT_FLAG("ot", 'O', &cfg.ot, offset_type),
+ OPT_UINT("xfer-len", 'x', &cfg.xfer_len, xfer_len));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
if (cfg.aen) {
cfg.log_len = 4096;
@@ -2307,34 +2248,27 @@ static int get_log(int argc, char **argv, struct command *cmd, struct plugin *pl
if (!cfg.log_len || cfg.log_len & 0x3) {
nvme_show_error("non-zero or non-dw alignment log-len is required param");
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
if (cfg.lsp > 127) {
nvme_show_error("invalid lsp param");
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
if (cfg.uuid_index > 127) {
nvme_show_error("invalid uuid index param");
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
if (cfg.xfer_len == 0 || cfg.xfer_len % 4096) {
nvme_show_error("xfer-len argument invalid. It needs to be multiple of 4k");
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
- log = malloc(cfg.log_len);
- if (!log) {
- nvme_show_perror("could not alloc buffer for log\n");
- err = -ENOMEM;
- goto close_dev;
- }
+ log = nvme_alloc(cfg.log_len);
+ if (!log)
+ return -ENOMEM;
struct nvme_get_log_args args = {
.args_size = sizeof(args),
@@ -2365,52 +2299,44 @@ static int get_log(int argc, char **argv, struct command *cmd, struct plugin *pl
} else {
nvme_show_error("log page: %s", nvme_strerror(errno));
}
- free(log);
-close_dev:
- dev_close(dev);
-ret:
return err;
}
static int sanitize_log(int argc, char **argv, struct command *command, struct plugin *plugin)
{
const char *desc = "Retrieve sanitize log and show it.";
- struct nvme_sanitize_log_page sanitize_log;
+
+ _cleanup_free_ struct nvme_sanitize_log_page *sanitize_log = NULL;
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
enum nvme_print_flags flags;
- struct nvme_dev *dev;
int err;
struct config {
bool rae;
- char *output_format;
bool human_readable;
bool raw_binary;
};
struct config cfg = {
.rae = false,
- .output_format = "normal",
.human_readable = false,
.raw_binary = false,
};
- OPT_ARGS(opts) = {
- OPT_FLAG("rae", 'r', &cfg.rae, rae),
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable_log),
- OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_log),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_FLAG("rae", 'r', &cfg.rae, rae),
+ OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable_log),
+ OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_log));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
- err = flags = validate_output_format(cfg.output_format);
+ err = validate_output_format(output_format_val, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
- goto close_dev;
+ return err;
}
if (cfg.raw_binary)
@@ -2419,16 +2345,18 @@ static int sanitize_log(int argc, char **argv, struct command *command, struct p
if (cfg.human_readable)
flags |= VERBOSE;
- err = nvme_cli_get_log_sanitize(dev, cfg.rae, &sanitize_log);
+ sanitize_log = nvme_alloc(sizeof(*sanitize_log));
+ if (!sanitize_log)
+ return -ENOMEM;
+
+ err = nvme_cli_get_log_sanitize(dev, cfg.rae, sanitize_log);
if (!err)
- nvme_show_sanitize_log(&sanitize_log, dev->name, flags);
+ nvme_show_sanitize_log(sanitize_log, dev->name, flags);
else if (err > 0)
nvme_show_status(err);
else
nvme_show_error("sanitize status log: %s", nvme_strerror(errno));
-close_dev:
- dev_close(dev);
-ret:
+
return err;
}
@@ -2436,50 +2364,48 @@ static int get_fid_support_effects_log(int argc, char **argv, struct command *cm
struct plugin *plugin)
{
const char *desc = "Retrieve FID Support and Effects log and show it.";
- struct nvme_fid_supported_effects_log fid_support_log;
+
+ _cleanup_free_ struct nvme_fid_supported_effects_log *fid_support_log = NULL;
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
enum nvme_print_flags flags;
- struct nvme_dev *dev;
int err = -1;
struct config {
- char *output_format;
bool human_readable;
};
struct config cfg = {
- .output_format = "normal",
.human_readable = false,
};
- OPT_ARGS(opts) = {
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable_log),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable_log));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
- err = flags = validate_output_format(cfg.output_format);
+ err = validate_output_format(output_format_val, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
- goto close_dev;
+ return err;
}
if (cfg.human_readable)
flags |= VERBOSE;
- err = nvme_cli_get_log_fid_supported_effects(dev, false, &fid_support_log);
+ fid_support_log = nvme_alloc(sizeof(*fid_support_log));
+ if (!fid_support_log)
+ return -ENOMEM;
+
+ err = nvme_cli_get_log_fid_supported_effects(dev, false, fid_support_log);
if (!err)
- nvme_show_fid_support_effects_log(&fid_support_log, dev->name, flags);
+ nvme_show_fid_support_effects_log(fid_support_log, dev->name, flags);
else if (err > 0)
nvme_show_status(err);
else
nvme_show_error("fid support effects log: %s", nvme_strerror(errno));
-close_dev:
- dev_close(dev);
-ret:
+
return err;
}
@@ -2487,50 +2413,48 @@ static int get_mi_cmd_support_effects_log(int argc, char **argv, struct command
struct plugin *plugin)
{
const char *desc = "Retrieve NVMe-MI Command Support and Effects log and show it.";
- struct nvme_mi_cmd_supported_effects_log mi_cmd_support_log;
+
+ _cleanup_free_ struct nvme_mi_cmd_supported_effects_log *mi_cmd_support_log = NULL;
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
enum nvme_print_flags flags;
- struct nvme_dev *dev;
int err = -1;
struct config {
- char *output_format;
bool human_readable;
};
struct config cfg = {
- .output_format = "normal",
.human_readable = false,
};
- OPT_ARGS(opts) = {
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable_log),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable_log));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
- err = flags = validate_output_format(cfg.output_format);
+ err = validate_output_format(output_format_val, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
- goto close_dev;
+ return err;
}
if (cfg.human_readable)
flags |= VERBOSE;
- err = nvme_cli_get_log_mi_cmd_supported_effects(dev, false, &mi_cmd_support_log);
+ mi_cmd_support_log = nvme_alloc(sizeof(*mi_cmd_support_log));
+ if (!mi_cmd_support_log)
+ return -ENOMEM;
+
+ 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, dev->name, flags);
+ nvme_show_mi_cmd_support_effects_log(mi_cmd_support_log, dev->name, flags);
else if (err > 0)
nvme_show_status(err);
else
nvme_show_error("mi command support effects log: %s", nvme_strerror(errno));
-close_dev:
- dev_close(dev);
-ret:
+
return err;
}
@@ -2539,45 +2463,39 @@ static int list_ctrl(int argc, char **argv, struct command *cmd, struct plugin *
const char *desc = "Show controller list information for the subsystem the\n"
"given device is part of, or optionally controllers attached to a specific namespace.";
const char *controller = "controller to display";
- struct nvme_ctrl_list *cntlist;
+
+ _cleanup_free_ struct nvme_ctrl_list *cntlist = NULL;
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
enum nvme_print_flags flags;
- struct nvme_dev *dev;
int err;
struct config {
__u16 cntid;
__u32 namespace_id;
- char *output_format;
};
struct config cfg = {
.cntid = 0,
.namespace_id = NVME_NSID_NONE,
- .output_format = "normal",
};
- OPT_ARGS(opts) = {
- OPT_SHRT("cntid", 'c', &cfg.cntid, controller),
- OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_optional),
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_SHRT("cntid", 'c', &cfg.cntid, controller),
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_optional));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
- err = flags = validate_output_format(cfg.output_format);
+ err = validate_output_format(output_format_val, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
- goto close_dev;
+ return err;
}
- if (posix_memalign((void *)&cntlist, getpagesize(), 0x1000)) {
- nvme_show_error("can not allocate controller list payload");
- err = -ENOMEM;
- goto close_dev;
- }
+ cntlist = nvme_alloc(sizeof(*cntlist));
+ if (!cntlist)
+ return -ENOMEM;
if (cfg.namespace_id == NVME_NSID_NONE)
err = nvme_cli_identify_ctrl_list(dev, cfg.cntid, cntlist);
@@ -2591,10 +2509,6 @@ static int list_ctrl(int argc, char **argv, struct command *cmd, struct plugin *
else
nvme_show_error("id controller list: %s", nvme_strerror(errno));
- free(cntlist);
-close_dev:
- dev_close(dev);
-ret:
return err;
}
@@ -2605,53 +2519,52 @@ 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";
- struct nvme_ns_list ns_list;
+
+ _cleanup_free_ struct nvme_ns_list *ns_list = NULL;
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
enum nvme_print_flags flags;
- struct nvme_dev *dev;
int err;
struct config {
__u32 namespace_id;
int csi;
bool all;
- char *output_format;
};
struct config cfg = {
.namespace_id = 1,
.csi = -1,
.all = false,
- .output_format = "normal",
};
- OPT_ARGS(opts) = {
- OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id),
- OPT_INT("csi", 'y', &cfg.csi, csi),
- OPT_FLAG("all", 'a', &cfg.all, all),
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format_no_binary),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id),
+ OPT_INT("csi", 'y', &cfg.csi, csi),
+ OPT_FLAG("all", 'a', &cfg.all, all));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
- err = flags = validate_output_format(cfg.output_format);
- if (flags != JSON && flags != NORMAL) {
+ err = validate_output_format(output_format_val, &flags);
+ if (err < 0 || (flags != JSON && flags != NORMAL)) {
nvme_show_error("Invalid output format");
- goto close_dev;
+ return -EINVAL;
}
if (!cfg.namespace_id) {
- err = -EINVAL;
nvme_show_error("invalid nsid parameter");
- goto close_dev;
+ return -EINVAL;
}
+ ns_list = nvme_alloc(sizeof(*ns_list));
+ if (!ns_list)
+ return -ENOMEM;
+
struct nvme_identify_args args = {
.args_size = sizeof(args),
.timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
- .data = &ns_list,
+ .data = ns_list,
.nsid = cfg.namespace_id - 1.
};
if (cfg.csi < 0) {
@@ -2664,16 +2577,13 @@ static int list_ns(int argc, char **argv, struct command *cmd, struct plugin *pl
}
err = nvme_cli_identify(dev, &args);
-
if (!err)
- nvme_show_list_ns(&ns_list, flags);
+ nvme_show_list_ns(ns_list, flags);
else if (err > 0)
nvme_show_status(err);
else
nvme_show_error("id namespace list: %s", nvme_strerror(errno));
-close_dev:
- dev_close(dev);
-ret:
+
return err;
}
@@ -2682,60 +2592,54 @@ static int id_ns_lba_format(int argc, char **argv, struct command *cmd, struct p
const char *desc = "Send an Identify Namespace command to the given\n"
"device, returns capability field properties of the specified\n"
"LBA Format index in various formats.";
+
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
+ _cleanup_free_ struct nvme_id_ns *ns = NULL;
enum nvme_print_flags flags;
- struct nvme_id_ns ns;
- struct nvme_dev *dev;
int err = -1;
struct config {
__u16 lba_format_index;
__u8 uuid_index;
- bool verbose;
- char *output_format;
};
struct config cfg = {
.lba_format_index = 0,
.uuid_index = NVME_UUID_NONE,
- .verbose = false,
- .output_format = "normal",
};
- OPT_ARGS(opts) = {
- OPT_UINT("lba-format-index", 'i', &cfg.lba_format_index, lba_format_index),
- OPT_BYTE("uuid-index", 'U', &cfg.uuid_index, uuid_index),
- OPT_FLAG("verbose", 'v', &cfg.verbose, verbose),
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_UINT("lba-format-index", 'i', &cfg.lba_format_index, lba_format_index),
+ OPT_BYTE("uuid-index", 'U', &cfg.uuid_index, uuid_index));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
- err = flags = validate_output_format(cfg.output_format);
+ err = validate_output_format(output_format_val, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
- goto close_dev;
+ return err;
}
- if (cfg.verbose)
+ if (argconfig_parse_seen(opts, "verbose"))
flags |= VERBOSE;
+ ns = nvme_alloc(sizeof(*ns));
+ if (!ns)
+ return -ENOMEM;
+
err = nvme_identify_ns_csi_user_data_format(dev_fd(dev),
- cfg.lba_format_index,
- cfg.uuid_index, NVME_CSI_NVM, &ns);
+ 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);
+ nvme_show_id_ns(ns, 0, cfg.lba_format_index, true, flags);
else if (err > 0)
nvme_show_status(err);
else
nvme_show_perror("identify namespace for specific LBA format");
-close_dev:
- dev_close(dev);
-ret:
- return nvme_status_to_errno(err, false);
+ return err;
}
static int id_endurance_grp_list(int argc, char **argv, struct command *cmd,
@@ -2743,41 +2647,36 @@ 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";
- struct nvme_id_endurance_group_list *endgrp_list;
+
+ _cleanup_free_ struct nvme_id_endurance_group_list *endgrp_list = NULL;
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
enum nvme_print_flags flags;
- struct nvme_dev *dev;
int err = -1;
struct config {
__u16 endgrp_id;
- char *output_format;
};
struct config cfg = {
.endgrp_id = 0,
- .output_format = "normal",
};
- OPT_ARGS(opts) = {
- OPT_SHRT("endgrp-id", 'i', &cfg.endgrp_id, endurance_grp_id),
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_SHRT("endgrp-id", 'i', &cfg.endgrp_id, endurance_grp_id));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
- err = flags = validate_output_format(cfg.output_format);
- if (flags != JSON && flags != NORMAL) {
+ err = validate_output_format(output_format_val, &flags);
+ if (err < 0 || (flags != JSON && flags != NORMAL)) {
nvme_show_error("invalid output format");
- goto close_dev;
+ return -EINVAL;
}
- if (posix_memalign((void *)&endgrp_list, getpagesize(), 0x1000)) {
- err = -1;
- goto close_dev;
- }
+ endgrp_list = nvme_alloc(sizeof(*endgrp_list));
+ if (!endgrp_list)
+ return -ENOMEM;
err = nvme_identify_endurance_group_list(dev_fd(dev), cfg.endgrp_id, endgrp_list);
if (!err)
@@ -2787,10 +2686,6 @@ static int id_endurance_grp_list(int argc, char **argv, struct command *cmd,
else
nvme_show_error("Id endurance group list: %s", nvme_strerror(errno));
- free(endgrp_list);
-close_dev:
- dev_close(dev);
-ret:
return err;
}
@@ -2803,7 +2698,8 @@ static int delete_ns(int argc, char **argv, struct command *cmd, struct plugin *
"becomes inactive when that namespace is detached or, if\n"
"the namespace is not already inactive, once deleted.";
const char *namespace_id = "namespace to delete";
- struct nvme_dev *dev;
+
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
int err;
struct config {
@@ -2816,21 +2712,19 @@ static int delete_ns(int argc, char **argv, struct command *cmd, struct plugin *
.timeout = 120000,
};
- OPT_ARGS(opts) = {
- OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id),
- OPT_UINT("timeout", 't', &cfg.timeout, timeout),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id),
+ OPT_UINT("timeout", 't', &cfg.timeout, timeout));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
if (!cfg.namespace_id) {
err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
nvme_show_error("get-namespace-id: %s", nvme_strerror(errno));
- goto close_dev;
+ return err;
}
}
@@ -2842,18 +2736,15 @@ static int delete_ns(int argc, char **argv, struct command *cmd, struct plugin *
else
nvme_show_error("delete namespace: %s", nvme_strerror(errno));
-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)
{
- struct nvme_ctrl_list cntlist;
+ _cleanup_free_ struct nvme_ctrl_list *cntlist = NULL;
+ _cleanup_free_ __u16 *ctrlist = NULL;
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
int err, num, i, list[2048];
- struct nvme_dev *dev;
- __u16 ctrlist[2048];
const char *namespace_id = "namespace to attach";
const char *cont = "optional comma-sep controller id list";
@@ -2868,20 +2759,17 @@ static int nvme_attach_ns(int argc, char **argv, int attach, const char *desc, s
.cntlist = "",
};
- OPT_ARGS(opts) = {
- OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id),
- OPT_LIST("controllers", 'c', &cfg.cntlist, cont),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id),
+ OPT_LIST("controllers", 'c', &cfg.cntlist, cont));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
if (!cfg.namespace_id) {
nvme_show_error("%s: namespace-id parameter required", cmd->name);
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
num = argconfig_parse_comma_sep_array(cfg.cntlist, list, 2047);
@@ -2890,21 +2778,28 @@ static int nvme_attach_ns(int argc, char **argv, int attach, const char *desc, s
if (num == -1) {
nvme_show_error("%s: controller id list is malformed", cmd->name);
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
+ cntlist = nvme_alloc(sizeof(*cntlist));
+ if (!cntlist)
+ return -ENOMEM;
+
+ ctrlist = nvme_alloc(sizeof(*ctrlist) * 2048);
+ if (!ctrlist)
+ return -ENOMEM;
+
for (i = 0; i < num; i++)
ctrlist[i] = (__u16)list[i];
- nvme_init_ctrl_list(&cntlist, num, ctrlist);
+ nvme_init_ctrl_list(cntlist, num, ctrlist);
if (attach)
err = nvme_cli_ns_attach_ctrls(dev, cfg.namespace_id,
- &cntlist);
+ cntlist);
else
err = nvme_cli_ns_detach_ctrls(dev, cfg.namespace_id,
- &cntlist);
+ cntlist);
if (!err)
printf("%s: Success, nsid:%d\n", cmd->name, cfg.namespace_id);
@@ -2913,9 +2808,6 @@ static int nvme_attach_ns(int argc, char **argv, int attach, const char *desc, s
else
nvme_show_perror(attach ? "attach namespace" : "detach namespace");
-close_dev:
- dev_close(dev);
-ret:
return err;
}
@@ -2943,18 +2835,18 @@ static int detach_ns(int argc, char **argv, struct command *cmd, struct plugin *
static int parse_lba_num_si(struct nvme_dev *dev, const char *opt,
const char *val, __u8 flbas, __u64 *num)
{
- struct nvme_id_ctrl ctrl;
+ _cleanup_free_ struct nvme_ns_list *ns_list = NULL;
+ _cleanup_free_ struct nvme_id_ctrl *ctrl = NULL;
+ _cleanup_free_ struct nvme_id_ns *ns = NULL;
__u32 nsid = 1;
- struct nvme_id_ns ns;
char *endptr;
int err = -EINVAL;
int i;
int lbas;
- struct nvme_ns_list ns_list;
+
struct nvme_identify_args args = {
.args_size = sizeof(args),
.timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
- .data = &ns_list,
.cns = NVME_IDENTIFY_CNS_NS_ACTIVE_LIST,
.nsid = nsid - 1.
};
@@ -2969,7 +2861,11 @@ static int parse_lba_num_si(struct nvme_dev *dev, const char *opt,
return err;
}
- err = nvme_cli_identify_ctrl(dev, &ctrl);
+ ctrl = nvme_alloc(sizeof(*ctrl));
+ if (!ctrl)
+ return -ENOMEM;
+
+ err = nvme_cli_identify_ctrl(dev, ctrl);
if (err) {
if (err < 0)
nvme_show_error("identify controller: %s", nvme_strerror(errno));
@@ -2978,7 +2874,12 @@ static int parse_lba_num_si(struct nvme_dev *dev, const char *opt,
return err;
}
- if ((ctrl.oacs & 0x8) >> 3)
+ ns_list = nvme_alloc(sizeof(*ns_list));
+ if (!ns_list)
+ return -ENOMEM;
+ args.data = ns_list;
+
+ if ((ctrl->oacs & 0x8) >> 3)
nsid = NVME_NSID_ALL;
else {
err = nvme_cli_identify(dev, &args);
@@ -2990,10 +2891,14 @@ static int parse_lba_num_si(struct nvme_dev *dev, const char *opt,
nvme_show_status(err);
return err;
}
- nsid = le32_to_cpu(ns_list.ns[0]);
+ nsid = le32_to_cpu(ns_list->ns[0]);
}
- err = nvme_cli_identify_ns(dev, nsid, &ns);
+ ns = nvme_alloc(sizeof(*ns));
+ if (!ns)
+ return -ENOMEM;
+
+ err = nvme_cli_identify_ns(dev, nsid, ns);
if (err) {
if (err < 0)
nvme_show_error("identify namespace: %s", nvme_strerror(errno));
@@ -3003,7 +2908,7 @@ static int parse_lba_num_si(struct nvme_dev *dev, const char *opt,
}
i = flbas & NVME_NS_FLBAS_LOWER_MASK;
- lbas = (1 << ns.lbaf[i].ds) + ns.lbaf[i].ms;
+ lbas = (1 << ns->lbaf[i].ds) + ns->lbaf[i].ms;
if (suffix_si_parse(val, &endptr, (uint64_t *)num)) {
nvme_show_error("Expected long suffixed integer argument for '%s-si' but got '%s'!",
@@ -3032,6 +2937,7 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin *
const char *nmic = "multipath and sharing capabilities (NMIC)";
const char *anagrpid = "ANA Group Identifier (ANAGRPID)";
const char *nvmsetid = "NVM Set Identifier (NVMSETID)";
+ const char *endgid = "Endurance Group Identifier (ENDGID)";
const char *csi = "command set identifier (CSI)";
const char *lbstm = "logical block storage tag mask (LBSTM)";
const char *nphndls = "Number of Placement Handles (NPHNDLS)";
@@ -3045,8 +2951,9 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin *
"Requested Number of ZRWA Resources (RNUMZRWA) for Zoned Namespace Command Set";
const char *phndls = "Comma separated list of Placement Handle Associated RUH";
- struct nvme_id_ns ns;
- struct nvme_dev *dev;
+ _cleanup_free_ struct nvme_ns_mgmt_host_sw_specified *data = NULL;
+ _cleanup_free_ struct nvme_id_ns *ns = NULL;
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
int err = 0, i;
__u32 nsid;
uint16_t num_phandle;
@@ -3060,6 +2967,7 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin *
__u8 nmic;
__u32 anagrpid;
__u16 nvmsetid;
+ __u16 endgid;
__u64 bs;
__u32 timeout;
__u8 csi;
@@ -3082,7 +2990,8 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin *
.nmic = 0,
.anagrpid = 0,
.nvmsetid = 0,
- .bs = 0x00,
+ .endgid = 0,
+ .bs = 0x00,
.timeout = 120000,
.csi = 0,
.lbstm = 0,
@@ -3096,48 +3005,51 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin *
.phndls = "",
};
- OPT_ARGS(opts) = {
- OPT_SUFFIX("nsze", 's', &cfg.nsze, nsze),
- OPT_SUFFIX("ncap", 'c', &cfg.ncap, ncap),
- OPT_BYTE("flbas", 'f', &cfg.flbas, flbas),
- OPT_BYTE("dps", 'd', &cfg.dps, dps),
- OPT_BYTE("nmic", 'm', &cfg.nmic, nmic),
- OPT_UINT("anagrp-id", 'a', &cfg.anagrpid, anagrpid),
- OPT_UINT("nvmset-id", 'i', &cfg.nvmsetid, nvmsetid),
- OPT_SUFFIX("block-size", 'b', &cfg.bs, bs),
- OPT_UINT("timeout", 't', &cfg.timeout, timeout),
- OPT_BYTE("csi", 'y', &cfg.csi, csi),
- OPT_SUFFIX("lbstm", 'l', &cfg.lbstm, lbstm),
- OPT_SHRT("nphndls", 'n', &cfg.nphndls, nphndls),
- OPT_STR("nsze-si", 'S', &cfg.nsze_si, nsze_si),
- OPT_STR("ncap-si", 'C', &cfg.ncap_si, ncap_si),
- OPT_FLAG("azr", 'z', &cfg.azr, azr),
- OPT_UINT("rar", 'r', &cfg.rar, rar),
- OPT_UINT("ror", 'o', &cfg.ror, ror),
- OPT_UINT("rnumzrwa", 'u', &cfg.rnumzrwa, rnumzrwa),
- OPT_LIST("phndls", 'p', &cfg.phndls, phndls),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_SUFFIX("nsze", 's', &cfg.nsze, nsze),
+ OPT_SUFFIX("ncap", 'c', &cfg.ncap, ncap),
+ OPT_BYTE("flbas", 'f', &cfg.flbas, flbas),
+ OPT_BYTE("dps", 'd', &cfg.dps, dps),
+ OPT_BYTE("nmic", 'm', &cfg.nmic, nmic),
+ OPT_UINT("anagrp-id", 'a', &cfg.anagrpid, anagrpid),
+ OPT_UINT("nvmset-id", 'i', &cfg.nvmsetid, nvmsetid),
+ OPT_UINT("endg-id", 'e', &cfg.endgid, endgid),
+ OPT_SUFFIX("block-size", 'b', &cfg.bs, bs),
+ OPT_UINT("timeout", 't', &cfg.timeout, timeout),
+ OPT_BYTE("csi", 'y', &cfg.csi, csi),
+ OPT_SUFFIX("lbstm", 'l', &cfg.lbstm, lbstm),
+ OPT_SHRT("nphndls", 'n', &cfg.nphndls, nphndls),
+ OPT_STR("nsze-si", 'S', &cfg.nsze_si, nsze_si),
+ OPT_STR("ncap-si", 'C', &cfg.ncap_si, ncap_si),
+ OPT_FLAG("azr", 'z', &cfg.azr, azr),
+ OPT_UINT("rar", 'r', &cfg.rar, rar),
+ OPT_UINT("ror", 'O', &cfg.ror, ror),
+ OPT_UINT("rnumzrwa", 'u', &cfg.rnumzrwa, rnumzrwa),
+ OPT_LIST("phndls", 'p', &cfg.phndls, phndls));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
if (cfg.flbas != 0xff && cfg.bs != 0x00) {
nvme_show_error(
"Invalid specification of both FLBAS and Block Size, please specify only one");
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
if (cfg.bs) {
if ((cfg.bs & (~cfg.bs + 1)) != cfg.bs) {
nvme_show_error(
"Invalid value for block size (%"PRIu64"). Block size must be a power of two",
(uint64_t)cfg.bs);
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
- err = nvme_cli_identify_ns(dev, NVME_NSID_ALL, &ns);
+
+
+ ns = nvme_alloc(sizeof(*ns));
+ if (!ns)
+ return -ENOMEM;
+
+ err = nvme_cli_identify_ns(dev, NVME_NSID_ALL, ns);
if (err) {
if (err < 0) {
nvme_show_error("identify-namespace: %s", nvme_strerror(errno));
@@ -3145,10 +3057,10 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin *
fprintf(stderr, "identify failed\n");
nvme_show_status(err);
}
- goto close_dev;
+ return err;
}
- for (i = 0; i <= ns.nlbaf; ++i) {
- if ((1 << ns.lbaf[i].ds) == cfg.bs && ns.lbaf[i].ms == 0) {
+ for (i = 0; i <= ns->nlbaf; ++i) {
+ if ((1 << ns->lbaf[i].ds) == cfg.bs && ns->lbaf[i].ms == 0) {
cfg.flbas = i;
break;
}
@@ -3160,51 +3072,51 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin *
(uint64_t)cfg.bs);
fprintf(stderr, "Please correct block size, or specify FLBAS directly\n");
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
err = parse_lba_num_si(dev, "nsze", cfg.nsze_si, cfg.flbas, &cfg.nsze);
if (err)
- goto close_dev;
+ return err;
err = parse_lba_num_si(dev, "ncap", cfg.ncap_si, cfg.flbas, &cfg.ncap);
if (err)
- goto close_dev;
+ return err;
if (cfg.csi != NVME_CSI_ZNS && (cfg.azr || cfg.rar || cfg.ror || cfg.rnumzrwa)) {
nvme_show_error("Invalid ZNS argument is given (CSI:%#x)", cfg.csi);
- err = -EINVAL;
- goto close_dev;
- }
-
- struct nvme_ns_mgmt_host_sw_specified data = {
- .nsze = cpu_to_le64(cfg.nsze),
- .ncap = cpu_to_le64(cfg.ncap),
- .flbas = cfg.flbas,
- .dps = cfg.dps,
- .nmic = cfg.nmic,
- .anagrpid = cpu_to_le32(cfg.anagrpid),
- .nvmsetid = cpu_to_le16(cfg.nvmsetid),
- .lbstm = cpu_to_le64(cfg.lbstm),
- .zns.znsco = cfg.azr,
- .zns.rar = cpu_to_le32(cfg.rar),
- .zns.ror = cpu_to_le32(cfg.ror),
- .zns.rnumzrwa = cpu_to_le32(cfg.rnumzrwa),
- .nphndls = cpu_to_le16(cfg.nphndls),
- };
+ return -EINVAL;
+ }
+
+ data = nvme_alloc(sizeof(*data));
+ if (!data)
+ return -ENOMEM;
+
+ data->nsze = cpu_to_le64(cfg.nsze);
+ data->ncap = cpu_to_le64(cfg.ncap);
+ data->flbas = cfg.flbas;
+ data->dps = cfg.dps;
+ data->nmic = cfg.nmic;
+ data->anagrpid = cpu_to_le32(cfg.anagrpid);
+ data->nvmsetid = cpu_to_le16(cfg.nvmsetid);
+ data->endgid = cpu_to_le16(cfg.endgid);
+ data->lbstm = cpu_to_le64(cfg.lbstm);
+ data->zns.znsco = cfg.azr;
+ data->zns.rar = cpu_to_le32(cfg.rar);
+ data->zns.ror = cpu_to_le32(cfg.ror);
+ data->zns.rnumzrwa = cpu_to_le32(cfg.rnumzrwa);
+ data->nphndls = cpu_to_le16(cfg.nphndls);
num_phandle = argconfig_parse_comma_sep_array_short(cfg.phndls, phndl, ARRAY_SIZE(phndl));
if (cfg.nphndls != num_phandle) {
nvme_show_error("Invalid Placement handle list");
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
for (i = 0; i < num_phandle; i++)
- data.phndl[i] = cpu_to_le16(phndl[i]);
+ data->phndl[i] = cpu_to_le16(phndl[i]);
- err = nvme_cli_ns_mgmt_create(dev, &data, &nsid, cfg.timeout, cfg.csi);
+ err = nvme_cli_ns_mgmt_create(dev, data, &nsid, cfg.timeout, cfg.csi);
if (!err)
printf("%s: Success, created nsid:%d\n", cmd->name, nsid);
else if (err > 0)
@@ -3212,9 +3124,6 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin *
else
nvme_show_error("create namespace: %s", nvme_strerror(errno));
-close_dev:
- dev_close(dev);
-ret:
return err;
}
@@ -3264,21 +3173,7 @@ static int list_subsys(int argc, char **argv, struct command *cmd,
int err;
int nsid = NVME_NSID_ALL;
- struct config {
- char *output_format;
- int verbose;
- };
-
- struct config cfg = {
- .output_format = "normal",
- .verbose = 0,
- };
-
- OPT_ARGS(opts) = {
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format_no_binary),
- OPT_INCR("verbose", 'v', &cfg.verbose, verbose),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg);
err = argconfig_parse(argc, argv, desc, opts);
if (err < 0)
@@ -3288,16 +3183,16 @@ static int list_subsys(int argc, char **argv, struct command *cmd,
if (optind < argc)
devname = basename(argv[optind++]);
- err = flags = validate_output_format(cfg.output_format);
- if (flags != JSON && flags != NORMAL) {
+ err = validate_output_format(output_format_val, &flags);
+ if (err < 0 || (flags != JSON && flags != NORMAL)) {
nvme_show_error("Invalid output format");
- goto ret;
+ return -EINVAL;
}
- if (cfg.verbose)
+ if (argconfig_parse_seen(opts, "verbose"))
flags |= VERBOSE;
- r = nvme_create_root(stderr, map_log_level(cfg.verbose, false));
+ r = nvme_create_root(stderr, map_log_level(!!(flags & VERBOSE), false));
if (!r) {
if (devname)
nvme_show_error("Failed to scan nvme subsystem for %s", devname);
@@ -3339,36 +3234,22 @@ static int list(int argc, char **argv, struct command *cmd, struct plugin *plugi
nvme_root_t r;
int err = 0;
- struct config {
- char *output_format;
- bool verbose;
- };
-
- struct config cfg = {
- .output_format = "normal",
- .verbose = false,
- };
-
- OPT_ARGS(opts) = {
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format_no_binary),
- OPT_FLAG("verbose", 'v', &cfg.verbose, verbose),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg);
err = argconfig_parse(argc, argv, desc, opts);
if (err < 0)
return err;
- flags = validate_output_format(cfg.output_format);
- if (flags != JSON && flags != NORMAL) {
+ err = validate_output_format(output_format_val, &flags);
+ if (err < 0 || (flags != JSON && flags != NORMAL)) {
nvme_show_error("Invalid output format");
return -EINVAL;
}
- if (cfg.verbose)
+ if (argconfig_parse_seen(opts, "verbose"))
flags |= VERBOSE;
- r = nvme_create_root(stderr, map_log_level(cfg.verbose, false));
+ r = nvme_create_root(stderr, map_log_level(!!(flags & VERBOSE), false));
if (!r) {
nvme_show_error("Failed to create topology root: %s", nvme_strerror(errno));
return -errno;
@@ -3395,41 +3276,37 @@ int __id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *plugin,
"binary format. May also return vendor-specific\n"
"controller attributes in hex-dump if requested.";
const char *vendor_specific = "dump binary vendor field";
+
+ _cleanup_free_ struct nvme_id_ctrl *ctrl = NULL;
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
enum nvme_print_flags flags;
- struct nvme_id_ctrl ctrl;
- struct nvme_dev *dev;
int err;
struct config {
bool vendor_specific;
- char *output_format;
bool raw_binary;
bool human_readable;
};
struct config cfg = {
.vendor_specific = false,
- .output_format = "normal",
.raw_binary = false,
.human_readable = false,
};
- OPT_ARGS(opts) = {
- OPT_FLAG("vendor-specific", 'v', &cfg.vendor_specific, vendor_specific),
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_identify),
- OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable_identify),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_FLAG("vendor-specific", 'V', &cfg.vendor_specific, vendor_specific),
+ OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_identify),
+ OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable_identify));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
- err = flags = validate_output_format(cfg.output_format);
+ err = validate_output_format(output_format_val, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
- goto close_dev;
+ return err;
}
if (cfg.raw_binary)
@@ -3441,16 +3318,18 @@ int __id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *plugin,
if (cfg.human_readable)
flags |= VERBOSE;
- err = nvme_cli_identify_ctrl(dev, &ctrl);
+ ctrl = nvme_alloc(sizeof(*ctrl));
+ if (!ctrl)
+ return -ENOMEM;
+
+ err = nvme_cli_identify_ctrl(dev, ctrl);
if (!err)
- nvme_show_id_ctrl(&ctrl, flags, vs);
+ nvme_show_id_ctrl(ctrl, flags, vs);
else if (err > 0)
nvme_show_status(err);
else
nvme_show_error("identify controller: %s", nvme_strerror(errno));
-close_dev:
- dev_close(dev);
-ret:
+
return err;
}
@@ -3465,44 +3344,36 @@ static int nvm_id_ctrl(int argc, char **argv, struct command *cmd,
const char *desc = "Send an Identify Controller NVM Command Set\n"
"command to the given device and report information about\n"
"the specified controller in various formats.";
+
+ _cleanup_free_ struct nvme_id_ctrl_nvm *ctrl_nvm = NULL;
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
enum nvme_print_flags flags;
- struct nvme_id_ctrl_nvm ctrl_nvm;
- struct nvme_dev *dev;
int err = -1;
- struct config {
- char *output_format;
- };
-
- struct config cfg = {
- .output_format = "normal",
- };
-
- OPT_ARGS(opts) = {
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg);
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
- err = flags = validate_output_format(cfg.output_format);
+ err = validate_output_format(output_format_val, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
- goto close_dev;
+ return err;
}
- err = nvme_nvm_identify_ctrl(dev_fd(dev), &ctrl_nvm);
+ ctrl_nvm = nvme_alloc(sizeof(*ctrl_nvm));
+ if (!ctrl_nvm)
+ return -ENOMEM;
+
+ err = nvme_nvm_identify_ctrl(dev_fd(dev), ctrl_nvm);
if (!err)
- nvme_show_id_ctrl_nvm(&ctrl_nvm, flags);
+ nvme_show_id_ctrl_nvm(ctrl_nvm, flags);
else if (err > 0)
nvme_show_status(err);
else
nvme_show_error("nvm identify controller: %s", nvme_strerror(errno));
-close_dev:
- dev_close(dev);
-ret:
+
return err;
}
@@ -3512,75 +3383,73 @@ static int nvm_id_ns(int argc, char **argv, struct command *cmd,
const char *desc = "Send an Identify Namespace NVM Command Set\n"
"command to the given device and report information about\n"
"the specified namespace in various formats.";
+
+ _cleanup_free_ struct nvme_nvm_id_ns *id_ns = NULL;
+ _cleanup_free_ struct nvme_id_ns *ns = NULL;
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
enum nvme_print_flags flags;
- struct nvme_nvm_id_ns id_ns;
- struct nvme_id_ns ns;
- struct nvme_dev *dev;
int err = -1;
struct config {
__u32 namespace_id;
__u8 uuid_index;
- char *output_format;
- bool verbose;
};
struct config cfg = {
.namespace_id = 0,
.uuid_index = NVME_UUID_NONE,
- .output_format = "normal",
- .verbose = false,
};
- OPT_ARGS(opts) = {
- OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired),
- OPT_BYTE("uuid-index", 'U', &cfg.uuid_index, uuid_index),
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_FLAG("verbose", 'v', &cfg.verbose, verbose),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired),
+ OPT_BYTE("uuid-index", 'U', &cfg.uuid_index, uuid_index));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
- err = flags = validate_output_format(cfg.output_format);
+ err = validate_output_format(output_format_val, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
- goto close_dev;
+ return err;
}
- if (cfg.verbose)
+ if (argconfig_parse_seen(opts, "verbose"))
flags |= VERBOSE;
if (!cfg.namespace_id) {
err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
nvme_show_perror("get-namespace-id");
- goto close_dev;
+ return err;
}
}
- err = nvme_cli_identify_ns(dev, cfg.namespace_id, &ns);
+ ns = nvme_alloc(sizeof(*ns));
+ if (!ns)
+ return -ENOMEM;
+
+ err = nvme_cli_identify_ns(dev, cfg.namespace_id, ns);
if (err) {
nvme_show_status(err);
- goto close_dev;
+ return err;
}
+ id_ns = nvme_alloc(sizeof(*id_ns));
+ if (!id_ns)
+ return -ENOMEM;
+
err = nvme_identify_ns_csi(dev_fd(dev), cfg.namespace_id,
- cfg.uuid_index,
- NVME_CSI_NVM, &id_ns);
+ cfg.uuid_index,
+ NVME_CSI_NVM, id_ns);
if (!err)
- nvme_show_nvm_id_ns(&id_ns, cfg.namespace_id, &ns, 0, false, flags);
+ nvme_show_nvm_id_ns(id_ns, cfg.namespace_id, ns, 0, false, flags);
else if (err > 0)
nvme_show_status(err);
else
nvme_show_perror("nvm identify namespace");
-close_dev:
- dev_close(dev);
-ret:
- return nvme_status_to_errno(err, false);
+ return err;
}
static int nvm_id_ns_lba_format(int argc, char **argv, struct command *cmd, struct plugin *plugin)
@@ -3588,66 +3457,64 @@ static int nvm_id_ns_lba_format(int argc, char **argv, struct command *cmd, stru
const char *desc = "Send an NVM Command Set specific Identify Namespace\n"
"command to the given device, returns capability field properties of\n"
"the specified LBA Format index in the specified namespace in various formats.";
+
+ _cleanup_free_ struct nvme_nvm_id_ns *nvm_ns = NULL;
+ _cleanup_free_ struct nvme_id_ns *ns = NULL;
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
enum nvme_print_flags flags;
- struct nvme_id_ns ns;
- struct nvme_nvm_id_ns nvm_ns;
- struct nvme_dev *dev;
int err = -1;
struct config {
__u16 lba_format_index;
__u8 uuid_index;
- bool verbose;
- char *output_format;
};
struct config cfg = {
.lba_format_index = 0,
.uuid_index = NVME_UUID_NONE,
- .verbose = false,
- .output_format = "normal",
};
- OPT_ARGS(opts) = {
- OPT_UINT("lba-format-index", 'i', &cfg.lba_format_index, lba_format_index),
- OPT_BYTE("uuid-index", 'U', &cfg.uuid_index, uuid_index),
- OPT_FLAG("verbose", 'v', &cfg.verbose, verbose),
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_UINT("lba-format-index", 'i', &cfg.lba_format_index, lba_format_index),
+ OPT_BYTE("uuid-index", 'U', &cfg.uuid_index, uuid_index));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
- err = flags = validate_output_format(cfg.output_format);
+ err = validate_output_format(output_format_val, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
- goto close_dev;
+ return err;
}
- if (cfg.verbose)
+ if (argconfig_parse_seen(opts, "verbose"))
flags |= VERBOSE;
- err = nvme_cli_identify_ns(dev, NVME_NSID_ALL, &ns);
+ ns = nvme_alloc(sizeof(*ns));
+ if (!ns)
+ return -ENOMEM;
+
+ err = nvme_cli_identify_ns(dev, NVME_NSID_ALL, ns);
if (err) {
- ns.nlbaf = NVME_FEAT_LBA_RANGE_MAX - 1;
- ns.nulbaf = 0;
+ ns->nlbaf = NVME_FEAT_LBA_RANGE_MAX - 1;
+ ns->nulbaf = 0;
}
+ nvm_ns = nvme_alloc(sizeof(*nvm_ns));
+ if (!nvm_ns)
+ return -ENOMEM;
+
err = nvme_identify_iocs_ns_csi_user_data_format(dev_fd(dev), cfg.lba_format_index,
- cfg.uuid_index, NVME_CSI_NVM, &nvm_ns);
+ cfg.uuid_index, NVME_CSI_NVM, nvm_ns);
if (!err)
- nvme_show_nvm_id_ns(&nvm_ns, 0, &ns, cfg.lba_format_index, true, flags);
+ nvme_show_nvm_id_ns(nvm_ns, 0, ns, cfg.lba_format_index, true, flags);
else if (err > 0)
nvme_show_status(err);
else
nvme_show_perror("NVM identify namespace for specific LBA format");
-close_dev:
- dev_close(dev);
-ret:
- return nvme_status_to_errno(err, false);
+ return err;
}
static int ns_descs(int argc, char **argv, struct command *cmd, struct plugin *plugin)
@@ -3656,38 +3523,34 @@ static int ns_descs(int argc, char **argv, struct command *cmd, struct plugin *p
"given device, returns the namespace identification descriptors\n"
"of the specific namespace in either human-readable or binary format.";
const char *raw = "show descriptors in binary format";
+
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
+ _cleanup_free_ void *nsdescs = NULL;;
enum nvme_print_flags flags;
- struct nvme_dev *dev;
- void *nsdescs;
int err;
struct config {
__u32 namespace_id;
- char *output_format;
bool raw_binary;
};
struct config cfg = {
.namespace_id = 0,
- .output_format = "normal",
.raw_binary = false,
};
- OPT_ARGS(opts) = {
- OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired),
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired),
+ OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
- err = flags = validate_output_format(cfg.output_format);
+ err = validate_output_format(output_format_val, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
- goto close_dev;
+ return err;
}
if (cfg.raw_binary)
@@ -3697,14 +3560,13 @@ static int ns_descs(int argc, char **argv, struct command *cmd, struct plugin *p
err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
nvme_show_error("get-namespace-id: %s", nvme_strerror(errno));
- goto close_dev;
+ return err;
}
}
- if (posix_memalign(&nsdescs, getpagesize(), 0x1000)) {
- err = -ENOMEM;
- goto close_dev;
- }
+ nsdescs = nvme_alloc(sizeof(*nsdescs));
+ if (!nsdescs)
+ return -ENOMEM;
err = nvme_cli_identify_ns_descs(dev, cfg.namespace_id, nsdescs);
if (!err)
@@ -3713,10 +3575,7 @@ static int ns_descs(int argc, char **argv, struct command *cmd, struct plugin *p
nvme_show_status(err);
else
nvme_show_error("identify namespace: %s", nvme_strerror(errno));
- free(nsdescs);
-close_dev:
- dev_close(dev);
-ret:
+
return err;
}
@@ -3729,9 +3588,9 @@ static int id_ns(int argc, char **argv, struct command *cmd, struct plugin *plug
const char *force = "Return this namespace, even if not attached (1.2 devices only)";
const char *vendor_specific = "dump binary vendor fields";
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
+ _cleanup_free_ struct nvme_id_ns *ns = NULL;
enum nvme_print_flags flags;
- struct nvme_id_ns ns;
- struct nvme_dev *dev;
int err;
struct config {
@@ -3739,7 +3598,6 @@ static int id_ns(int argc, char **argv, struct command *cmd, struct plugin *plug
bool force;
bool vendor_specific;
bool raw_binary;
- char *output_format;
bool human_readable;
};
@@ -3748,28 +3606,24 @@ static int id_ns(int argc, char **argv, struct command *cmd, struct plugin *plug
.force = false,
.vendor_specific = false,
.raw_binary = false,
- .output_format = "normal",
.human_readable = false,
};
- OPT_ARGS(opts) = {
- OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired),
- OPT_FLAG("force", 0, &cfg.force, force),
- OPT_FLAG("vendor-specific", 'v', &cfg.vendor_specific, vendor_specific),
- OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_identify),
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable_identify),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired),
+ OPT_FLAG("force", 0, &cfg.force, force),
+ OPT_FLAG("vendor-specific", 'V', &cfg.vendor_specific, vendor_specific),
+ OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_identify),
+ OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable_identify));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
- err = flags = validate_output_format(cfg.output_format);
+ err = validate_output_format(output_format_val, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
- goto close_dev;
+ return err;
}
if (cfg.raw_binary)
@@ -3785,24 +3639,26 @@ static int id_ns(int argc, char **argv, struct command *cmd, struct plugin *plug
err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
nvme_show_error("get-namespace-id: %s", nvme_strerror(errno));
- goto close_dev;
+ return err;
}
}
+ ns = nvme_alloc(sizeof(*ns));
+ if (!ns)
+ return -ENOMEM;
+
if (cfg.force)
- err = nvme_cli_identify_allocated_ns(dev, cfg.namespace_id, &ns);
+ err = nvme_cli_identify_allocated_ns(dev, cfg.namespace_id, ns);
else
- err = nvme_cli_identify_ns(dev, 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);
+ nvme_show_id_ns(ns, cfg.namespace_id, 0, false, flags);
else if (err > 0)
nvme_show_status(err);
else
nvme_show_error("identify namespace: %s", nvme_strerror(errno));
-close_dev:
- dev_close(dev);
-ret:
+
return err;
}
@@ -3812,41 +3668,37 @@ static int cmd_set_independent_id_ns(int argc, char **argv, struct command *cmd,
const char *desc = "Send an I/O Command Set Independent Identify\n"
"Namespace command to the given device, returns properties of the\n"
"specified namespace in human-readable or binary or json format.";
+
+ _cleanup_free_ struct nvme_id_independent_id_ns *ns = NULL;
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
enum nvme_print_flags flags;
- struct nvme_id_independent_id_ns ns;
- struct nvme_dev *dev;
int err = -1;
struct config {
__u32 namespace_id;
bool raw_binary;
- char *output_format;
bool human_readable;
};
struct config cfg = {
.namespace_id = 0,
.raw_binary = false,
- .output_format = "normal",
.human_readable = false,
};
- OPT_ARGS(opts) = {
- OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired),
- OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_identify),
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable_identify),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired),
+ OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_identify),
+ OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable_identify));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
- err = flags = validate_output_format(cfg.output_format);
+ err = validate_output_format(output_format_val, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
- goto close_dev;
+ return err;
}
if (cfg.raw_binary)
@@ -3859,21 +3711,23 @@ static int cmd_set_independent_id_ns(int argc, char **argv, struct command *cmd,
err = cfg.namespace_id = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
nvme_show_perror("get-namespace-id");
- goto close_dev;
+ return err;
}
}
- err = nvme_identify_independent_identify_ns(dev_fd(dev), cfg.namespace_id, &ns);
+ ns = nvme_alloc(sizeof(*ns));
+ if (!ns)
+ return -ENOMEM;
+
+ 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);
+ nvme_show_cmd_set_independent_id_ns(ns, cfg.namespace_id, flags);
else if (err > 0)
nvme_show_status(err);
else
nvme_show_error("I/O command set independent identify namespace: %s",
nvme_strerror(errno));
-close_dev:
- dev_close(dev);
-ret:
+
return err;
}
@@ -3882,39 +3736,27 @@ static int id_ns_granularity(int argc, char **argv, struct command *cmd, struct
const char *desc = "Send an Identify Namespace Granularity List command to the\n"
"given device, returns namespace granularity list\n"
"in either human-readable or binary format.";
- struct nvme_id_ns_granularity_list *granularity_list;
+
+ _cleanup_free_ struct nvme_id_ns_granularity_list *granularity_list = NULL;
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
enum nvme_print_flags flags;
- struct nvme_dev *dev;
int err;
- struct config {
- char *output_format;
- };
-
- struct config cfg = {
- .output_format = "normal",
- };
-
- OPT_ARGS(opts) = {
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg);
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
- err = flags = validate_output_format(cfg.output_format);
+ err = validate_output_format(output_format_val, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
- goto close_dev;
+ return err;
}
- if (posix_memalign((void *)&granularity_list, getpagesize(), NVME_IDENTIFY_DATA_SIZE)) {
- nvme_show_error("can not allocate granularity list payload");
- err = -ENOMEM;
- goto close_dev;
- }
+ granularity_list = nvme_alloc(NVME_IDENTIFY_DATA_SIZE);
+ if (!granularity_list)
+ return -ENOMEM;
err = nvme_identify_ns_granularity(dev_fd(dev), granularity_list);
if (!err)
@@ -3923,10 +3765,7 @@ static int id_ns_granularity(int argc, char **argv, struct command *cmd, struct
nvme_show_status(err);
else
nvme_show_error("identify namespace granularity: %s", nvme_strerror(errno));
- free(granularity_list);
-close_dev:
- dev_close(dev);
-ret:
+
return err;
}
@@ -3937,48 +3776,45 @@ static int id_nvmset(int argc, char **argv, struct command *cmd, struct plugin *
"than or equal to the value specified CDW11.NVMSETID\n"
"in either binary format or json format";
const char *nvmset_id = "NVM Set Identify value";
- struct nvme_id_nvmset_list nvmset;
+
+ _cleanup_free_ struct nvme_id_nvmset_list *nvmset = NULL;
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
enum nvme_print_flags flags;
- struct nvme_dev *dev;
int err;
struct config {
__u16 nvmset_id;
- char *output_format;
};
struct config cfg = {
.nvmset_id = 0,
- .output_format = "normal",
};
- OPT_ARGS(opts) = {
- OPT_SHRT("nvmset_id", 'i', &cfg.nvmset_id, nvmset_id),
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_SHRT("nvmset_id", 'i', &cfg.nvmset_id, nvmset_id));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
- err = flags = validate_output_format(cfg.output_format);
+ err = validate_output_format(output_format_val, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
- goto close_dev;
+ return err;
}
- err = nvme_identify_nvmset_list(dev_fd(dev), cfg.nvmset_id, &nvmset);
+ nvmset = nvme_alloc(sizeof(*nvmset));
+ if (!nvmset)
+ return -ENOMEM;
+
+ err = nvme_identify_nvmset_list(dev_fd(dev), cfg.nvmset_id, nvmset);
if (!err)
- nvme_show_id_nvmset(&nvmset, cfg.nvmset_id, flags);
+ nvme_show_id_nvmset(nvmset, cfg.nvmset_id, flags);
else if (err > 0)
nvme_show_status(err);
else
nvme_show_error("identify nvm set list: %s", nvme_strerror(errno));
-close_dev:
- dev_close(dev);
-ret:
return err;
}
@@ -3989,38 +3825,34 @@ static int id_uuid(int argc, char **argv, struct command *cmd, struct plugin *pl
"in either human-readable or binary format.";
const char *raw = "show uuid in binary format";
const char *human_readable = "show uuid in readable format";
- struct nvme_id_uuid_list uuid_list;
+
+ _cleanup_free_ struct nvme_id_uuid_list *uuid_list = NULL;
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
enum nvme_print_flags flags;
- struct nvme_dev *dev;
int err;
struct config {
- char *output_format;
bool raw_binary;
bool human_readable;
};
struct config cfg = {
- .output_format = "normal",
.raw_binary = false,
.human_readable = false,
};
- OPT_ARGS(opts) = {
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw),
- OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw),
+ OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
- err = flags = validate_output_format(cfg.output_format);
+ err = validate_output_format(output_format_val, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
- goto close_dev;
+ return err;
}
if (cfg.raw_binary)
@@ -4029,16 +3861,18 @@ static int id_uuid(int argc, char **argv, struct command *cmd, struct plugin *pl
if (cfg.human_readable)
flags |= VERBOSE;
- err = nvme_identify_uuid(dev_fd(dev), &uuid_list);
+ uuid_list = nvme_alloc(sizeof(*uuid_list));
+ if (!uuid_list)
+ return -ENOMEM;
+
+ err = nvme_identify_uuid(dev_fd(dev), uuid_list);
if (!err)
- nvme_show_id_uuid_list(&uuid_list, flags);
+ nvme_show_id_uuid_list(uuid_list, flags);
else if (err > 0)
nvme_show_status(err);
else
nvme_show_error("identify UUID list: %s", nvme_strerror(errno));
-close_dev:
- dev_close(dev);
-ret:
+
return err;
}
@@ -4048,8 +3882,9 @@ static int id_iocs(int argc, char **argv, struct command *cmd, struct plugin *pl
"the given device, returns properties of the specified controller\n"
"in either human-readable or binary format.";
const char *controller_id = "identifier of desired controller";
- struct nvme_id_iocs iocs;
- struct nvme_dev *dev;
+
+ _cleanup_free_ struct nvme_id_iocs *iocs = NULL;
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
int err;
struct config {
@@ -4060,27 +3895,27 @@ static int id_iocs(int argc, char **argv, struct command *cmd, struct plugin *pl
.cntid = 0xffff,
};
- OPT_ARGS(opts) = {
- OPT_SHRT("controller-id", 'c', &cfg.cntid, controller_id),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_SHRT("controller-id", 'c', &cfg.cntid, controller_id));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
+
+ iocs = nvme_alloc(sizeof(*iocs));
+ if (!iocs)
+ return -ENOMEM;
- err = nvme_identify_iocs(dev_fd(dev), 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, 0);
+ nvme_show_id_iocs(iocs, 0);
} else if (err > 0) {
nvme_show_status(err);
} else {
nvme_show_error("NVMe Identify I/O Command Set: %s", nvme_strerror(errno));
}
- dev_close(dev);
-ret:
return err;
}
@@ -4090,82 +3925,74 @@ static int id_domain(int argc, char **argv, struct command *cmd, struct plugin *
"given device, returns properties of the specified domain\n"
"in either normal|json|binary format.";
const char *domain_id = "identifier of desired domain";
- struct nvme_id_domain_list id_domain;
+
+ _cleanup_free_ struct nvme_id_domain_list *id_domain = NULL;
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
enum nvme_print_flags flags;
- struct nvme_dev *dev;
int err;
struct config {
__u16 dom_id;
- char *output_format;
};
struct config cfg = {
.dom_id = 0xffff,
- .output_format = "normal",
};
- OPT_ARGS(opts) = {
- OPT_SHRT("dom-id", 'd', &cfg.dom_id, domain_id),
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_SHRT("dom-id", 'd', &cfg.dom_id, domain_id));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
- err = flags = validate_output_format(cfg.output_format);
+ err = validate_output_format(output_format_val, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
- goto close_dev;
+ return err;
}
- err = nvme_identify_domain_list(dev_fd(dev), cfg.dom_id, &id_domain);
+ id_domain = nvme_alloc(sizeof(*id_domain));
+ if (!id_domain)
+ return -ENOMEM;
+
+ 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");
- nvme_show_id_domain_list(&id_domain, flags);
+ nvme_show_id_domain_list(id_domain, flags);
} else if (err > 0) {
nvme_show_status(err);
} else {
nvme_show_error("NVMe Identify Domain List: %s", nvme_strerror(errno));
}
-close_dev:
- dev_close(dev);
-ret:
return err;
}
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.";
- struct nvme_dev *dev;
+
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
unsigned int nsid;
- int err = 0;
+ int err;
- OPT_ARGS(opts) = {
- OPT_END()
- };
+ NVME_ARGS(opts, cfg);
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
err = nvme_get_nsid(dev_fd(dev), &nsid);
if (err < 0) {
nvme_show_error("get namespace ID: %s", nvme_strerror(errno));
- err = errno;
- goto close_fd;
+ return -errno;
}
- err = 0;
+
printf("%s: namespace-id:%d\n", dev->name, nsid);
-close_fd:
- dev_close(dev);
-ret:
- return err;
+ return 0;
}
static int virtual_mgmt(int argc, char **argv, struct command *cmd, struct plugin *plugin)
@@ -4185,7 +4012,8 @@ 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)";
- struct nvme_dev *dev;
+
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
__u32 result;
int err;
@@ -4203,17 +4031,15 @@ static int virtual_mgmt(int argc, char **argv, struct command *cmd, struct plugi
.nr = 0,
};
- OPT_ARGS(opts) = {
- OPT_UINT("cntlid", 'c', &cfg.cntlid, cntlid),
- OPT_BYTE("rt", 'r', &cfg.rt, rt),
- OPT_BYTE("act", 'a', &cfg.act, act),
- OPT_SHRT("nr", 'n', &cfg.nr, nr),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_UINT("cntlid", 'c', &cfg.cntlid, cntlid),
+ OPT_BYTE("rt", 'r', &cfg.rt, rt),
+ OPT_BYTE("act", 'a', &cfg.act, act),
+ OPT_SHRT("nr", 'n', &cfg.nr, nr));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
struct nvme_virtual_mgmt_args args = {
.args_size = sizeof(args),
@@ -4233,8 +4059,6 @@ static int virtual_mgmt(int argc, char **argv, struct command *cmd, struct plugi
else
nvme_show_error("virt-mgmt: %s", nvme_strerror(errno));
- dev_close(dev);
-ret:
return err;
}
@@ -4244,54 +4068,52 @@ static int primary_ctrl_caps(int argc, char **argv, struct command *cmd, struct
const char *desc = "Send an Identify Primary Controller Capabilities\n"
"command to the given device and report the information in a\n"
"decoded format (default), json or binary.";
- struct nvme_primary_ctrl_cap caps;
+
+ _cleanup_free_ struct nvme_primary_ctrl_cap *caps = NULL;
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
enum nvme_print_flags flags;
- struct nvme_dev *dev;
int err;
struct config {
__u16 cntlid;
- char *output_format;
bool human_readable;
};
struct config cfg = {
.cntlid = 0,
- .output_format = "normal",
.human_readable = false,
};
- OPT_ARGS(opts) = {
- OPT_UINT("cntlid", 'c', &cfg.cntlid, cntlid),
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable_info),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_UINT("cntlid", 'c', &cfg.cntlid, cntlid),
+ OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable_info));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
- err = flags = validate_output_format(cfg.output_format);
+ err = validate_output_format(output_format_val, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
- goto close_dev;
+ return err;
}
if (cfg.human_readable)
flags |= VERBOSE;
- err = nvme_cli_identify_primary_ctrl(dev, cfg.cntlid, &caps);
+ caps = nvme_alloc(sizeof(*caps));
+ if (!caps)
+ return -ENOMEM;
+
+ err = nvme_cli_identify_primary_ctrl(dev, cfg.cntlid, caps);
if (!err)
- nvme_show_primary_ctrl_cap(&caps, flags);
+ nvme_show_primary_ctrl_cap(caps, flags);
else if (err > 0)
nvme_show_status(err);
else
nvme_show_error("identify primary controller capabilities: %s",
nvme_strerror(errno));
-close_dev:
- dev_close(dev);
-ret:
+
return err;
}
@@ -4302,56 +4124,45 @@ static int list_secondary_ctrl(int argc, char **argv, struct command *cmd, struc
const char *controller = "lowest controller identifier to display";
const char *num_entries = "number of entries to retrieve";
- struct nvme_secondary_ctrl_list *sc_list;
+ _cleanup_free_ struct nvme_secondary_ctrl_list *sc_list = NULL;
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
enum nvme_print_flags flags;
- struct nvme_dev *dev;
int err;
struct config {
__u16 cntid;
- __u32 namespace_id;
__u32 num_entries;
- char *output_format;
};
struct config cfg = {
.cntid = 0,
- .namespace_id = 0,
.num_entries = ARRAY_SIZE(sc_list->sc_entry),
- .output_format = "normal",
};
- OPT_ARGS(opts) = {
- OPT_SHRT("cntid", 'c', &cfg.cntid, controller),
- OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_optional),
- OPT_UINT("num-entries", 'e', &cfg.num_entries, num_entries),
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_SHRT("cntid", 'c', &cfg.cntid, controller),
+ OPT_UINT("num-entries", 'e', &cfg.num_entries, num_entries));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
- err = flags = validate_output_format(cfg.output_format);
+ err = validate_output_format(output_format_val, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
- goto close_err;
+ return err;
}
if (!cfg.num_entries) {
nvme_show_error("non-zero num-entries is required param");
- err = -EINVAL;
- goto close_err;
+ return -EINVAL;
}
- if (posix_memalign((void *)&sc_list, getpagesize(), sizeof(*sc_list))) {
- nvme_show_error("can not allocate controller list payload");
- err = -ENOMEM;
- goto close_err;
- }
+ sc_list = nvme_alloc(sizeof(*sc_list));
+ if (!sc_list)
+ return -ENOMEM;
- err = nvme_cli_identify_secondary_ctrl_list(dev, cfg.namespace_id, cfg.cntid, sc_list);
+ err = nvme_cli_identify_secondary_ctrl_list(dev, cfg.cntid, sc_list);
if (!err)
nvme_show_list_secondary_ctrl(sc_list, cfg.num_entries, flags);
else if (err > 0)
@@ -4359,11 +4170,6 @@ static int list_secondary_ctrl(int argc, char **argv, struct command *cmd, struc
else
nvme_show_error("id secondary controller list: %s", nvme_strerror(errno));
- free(sc_list);
-
-close_err:
- dev_close(dev);
-ret:
return err;
}
@@ -4389,20 +4195,28 @@ static int sleep_self_test(unsigned int seconds)
static int wait_self_test(struct nvme_dev *dev)
{
static const char spin[] = {'-', '\\', '|', '/' };
- struct nvme_self_test_log log;
- struct nvme_id_ctrl ctrl;
+ _cleanup_free_ struct nvme_self_test_log *log = NULL;
+ _cleanup_free_ struct nvme_id_ctrl *ctrl = NULL;
int err, i = 0, p = 0, cnt = 0;
int wthr;
signal(SIGINT, intr_self_test);
- err = nvme_cli_identify_ctrl(dev, &ctrl);
+ ctrl = nvme_alloc(sizeof(*ctrl));
+ if (!ctrl)
+ return -ENOMEM;
+
+ log = nvme_alloc(sizeof(*log));
+ if (!log)
+ return -ENOMEM;
+
+ err = nvme_cli_identify_ctrl(dev, ctrl);
if (err) {
nvme_show_error("identify-ctrl: %s", nvme_strerror(errno));
return err;
}
- wthr = le16_to_cpu(ctrl.edstt) * 60 / 100 + 60;
+ wthr = le16_to_cpu(ctrl->edstt) * 60 / 100 + 60;
printf("Waiting for self test completion...\n");
while (true) {
@@ -4412,7 +4226,7 @@ static int wait_self_test(struct nvme_dev *dev)
if (err)
return err;
- err = nvme_cli_get_log_device_self_test(dev, &log);
+ err = nvme_cli_get_log_device_self_test(dev, log);
if (err) {
printf("\n");
if (err < 0)
@@ -4427,17 +4241,17 @@ static int wait_self_test(struct nvme_dev *dev)
return -EIO;
}
- if (log.completion == 0 && p > 0) {
+ if (log->completion == 0 && p > 0) {
printf("\r[%.*s] %3d%%\n", 50, dash, 100);
break;
}
- if (log.completion < p) {
+ if (log->completion < p) {
printf("\n");
- nvme_show_error("progress broken");
- return -EIO;
- } else if (log.completion != p) {
- p = log.completion;
+ nvme_show_error("progress broken");
+ return -EIO;
+ } else if (log->completion != p) {
+ p = log->completion;
cnt = 0;
}
@@ -4476,7 +4290,8 @@ static int device_self_test(int argc, char **argv, struct command *cmd, struct p
"eh Start a vendor specific device self-test operation\n"
"fh Abort the device self-test operation";
const char *wait = "Wait for the test to finish";
- struct nvme_dev *dev;
+
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
int err;
struct config {
@@ -4491,21 +4306,23 @@ static int device_self_test(int argc, char **argv, struct command *cmd, struct p
.wait = false,
};
- OPT_ARGS(opts) = {
- OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id),
- OPT_BYTE("self-test-code", 's', &cfg.stc, self_test_code),
- OPT_FLAG("wait", 'w', &cfg.wait, wait),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id),
+ OPT_BYTE("self-test-code", 's', &cfg.stc, self_test_code),
+ OPT_FLAG("wait", 'w', &cfg.wait, wait));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
if (cfg.stc == NVME_ST_CODE_RESERVED) {
- struct nvme_self_test_log log;
+ _cleanup_free_ struct nvme_self_test_log *log = NULL;
- err = nvme_cli_get_log_device_self_test(dev, &log);
+ log = nvme_alloc(sizeof(*log));
+ if (!log)
+ return -ENOMEM;
+
+ err = nvme_cli_get_log_device_self_test(dev, log);
if (err) {
printf("\n");
if (err < 0)
@@ -4514,15 +4331,16 @@ static int device_self_test(int argc, char **argv, struct command *cmd, struct p
nvme_show_status(err);
}
- if (log.completion == 0) {
+ if (log->completion == 0) {
printf("no self test running\n");
} else {
if (cfg.wait)
err = wait_self_test(dev);
else
- printf("progress %d%%\n", log.completion);
+ printf("progress %d%%\n", log->completion);
}
- goto close_dev;
+
+ goto check_abort;
}
struct nvme_dev_self_test_args args = {
@@ -4550,12 +4368,10 @@ static int device_self_test(int argc, char **argv, struct command *cmd, struct p
nvme_show_error("Device self-test: %s", nvme_strerror(errno));
}
-close_dev:
+check_abort:
if (err == -EINTR)
abort_self_test(&args);
- dev_close(dev);
-ret:
return err;
}
@@ -4565,61 +4381,54 @@ static int self_test_log(int argc, char **argv, struct command *cmd, struct plug
"(or optionally a namespace) in either decoded format (default) or binary.";
const char *dst_entries = "Indicate how many DST log entries to be retrieved,\n"
"by default all the 20 entries will be retrieved";
- struct nvme_self_test_log log;
+
+ _cleanup_free_ struct nvme_self_test_log *log = NULL;
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
enum nvme_print_flags flags;
- struct nvme_dev *dev;
int err;
struct config {
__u8 dst_entries;
- char *output_format;
- bool verbose;
};
struct config cfg = {
.dst_entries = NVME_LOG_ST_MAX_RESULTS,
- .output_format = "normal",
- .verbose = false,
};
- OPT_ARGS(opts) = {
- OPT_BYTE("dst-entries", 'e', &cfg.dst_entries, dst_entries),
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_FLAG("verbose", 'v', &cfg.verbose, verbose),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_BYTE("dst-entries", 'e', &cfg.dst_entries, dst_entries));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
- err = flags = validate_output_format(cfg.output_format);
+ err = validate_output_format(output_format_val, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
- goto close_dev;
+ return err;
}
- if (cfg.verbose)
+ if (argconfig_parse_seen(opts, "verbose"))
flags |= VERBOSE;
- err = nvme_cli_get_log_device_self_test(dev, &log);
+ log = nvme_alloc(sizeof(*log));
+ if (!log)
+ return -ENOMEM;
+
+ err = nvme_cli_get_log_device_self_test(dev, log);
if (!err)
- nvme_show_self_test_log(&log, cfg.dst_entries, 0, dev->name, flags);
+ nvme_show_self_test_log(log, cfg.dst_entries, 0, dev->name, flags);
else if (err > 0)
nvme_show_status(err);
else
nvme_show_error("self test log: %s", nvme_strerror(errno));
-close_dev:
- dev_close(dev);
-ret:
+
return err;
}
static int get_feature_id(struct nvme_dev *dev, struct feat_cfg *cfg,
void **buf, __u32 *result)
{
- size_t size;
-
if (!cfg->data_len)
nvme_get_feature_length(cfg->feature_id, cfg->cdw11,
&cfg->data_len);
@@ -4637,11 +4446,9 @@ static int get_feature_id(struct nvme_dev *dev, struct feat_cfg *cfg,
cfg->data_len = 0;
if (cfg->data_len) {
- /* rounding up size to page size */
- size = ((cfg->data_len - 1) / getpagesize() + 1) * getpagesize();
- if (posix_memalign(buf, getpagesize(), size))
+ *buf = nvme_alloc(cfg->data_len - 1);
+ if (!*buf)
return -1;
- memset(*buf, 0, size);
}
struct nvme_get_features_args args = {
@@ -4673,13 +4480,9 @@ static void get_feature_id_print(struct feat_cfg cfg, int err, __u32 result,
if (!err) {
if (!cfg.raw_binary || !buf) {
- printf("get-feature:%#0*x (%s), %s value:%#0*x\n",
- cfg.feature_id ? 4 : 2, cfg.feature_id,
- nvme_feature_to_string(cfg.feature_id),
- nvme_select_to_string(cfg.sel), result ? 10 : 8,
- result);
+ nvme_feature_show(cfg.feature_id, cfg.sel, result);
if (cfg.sel == 3)
- nvme_show_select_result(result);
+ nvme_show_select_result(cfg.feature_id, result);
else if (cfg.human_readable)
nvme_feature_show_fields(cfg.feature_id, result,
buf);
@@ -4693,7 +4496,7 @@ static void get_feature_id_print(struct feat_cfg cfg, int err, __u32 result,
!nvme_status_equals(status, type, NVME_SC_INVALID_NS))
nvme_show_status(err);
} else {
- fprintf(stderr, "get-feature: %s\n", nvme_strerror(errno));
+ nvme_show_error("get-feature: %s", nvme_strerror(errno));
}
}
@@ -4756,14 +4559,11 @@ static int get_feature_ids(struct nvme_dev *dev, struct feat_cfg cfg)
continue;
if (!nvme_status_equals(status, type, NVME_SC_INVALID_NS))
break;
- fprintf(stderr, "get-feature:%#0*x (%s): ",
- cfg.feature_id ? 4 : 2, cfg.feature_id,
- nvme_feature_to_string(cfg.feature_id));
- nvme_show_status(err);
+ nvme_show_error_status(err, "get-feature:%#0*x (%s)", cfg.feature_id ? 4 : 2,
+ cfg.feature_id, nvme_feature_to_string(cfg.feature_id));
}
- if (feat_num == 1 &&
- nvme_status_equals(status, type, NVME_SC_INVALID_FIELD))
+ if (feat_num == 1 && nvme_status_equals(status, type, NVME_SC_INVALID_FIELD))
nvme_show_status(err);
return err;
@@ -4786,7 +4586,8 @@ static int get_feature(int argc, char **argv, struct command *cmd,
const char *sel = "[0-3,8]: current/default/saved/supported/changed";
const char *cdw11 = "feature specific dword 11";
const char *human_readable = "show feature in readable format";
- struct nvme_dev *dev;
+
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
int err;
struct feat_cfg cfg = {
@@ -4800,28 +4601,26 @@ static int get_feature(int argc, char **argv, struct command *cmd,
.human_readable = false,
};
- OPT_ARGS(opts) = {
- OPT_BYTE("feature-id", 'f', &cfg.feature_id, feature_id),
- OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired),
- OPT_BYTE("sel", 's', &cfg.sel, sel),
- OPT_UINT("data-len", 'l', &cfg.data_len, buf_len),
- OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw),
- OPT_UINT("cdw11", 'c', &cfg.cdw11, cdw11),
- OPT_BYTE("uuid-index", 'U', &cfg.uuid_index, uuid_index_specify),
- OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_BYTE("feature-id", 'f', &cfg.feature_id, feature_id),
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired),
+ OPT_BYTE("sel", 's', &cfg.sel, sel),
+ OPT_UINT("data-len", 'l', &cfg.data_len, buf_len),
+ OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw),
+ OPT_UINT("cdw11", 'c', &cfg.cdw11, cdw11),
+ OPT_BYTE("uuid-index", 'U', &cfg.uuid_index, uuid_index_specify),
+ OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
if (!argconfig_parse_seen(opts, "namespace-id")) {
err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
if (errno != ENOTTY) {
nvme_show_error("get-namespace-id: %s", nvme_strerror(errno));
- goto close_dev;
+ return err;
}
cfg.namespace_id = NVME_NSID_ALL;
}
@@ -4829,22 +4628,20 @@ static int get_feature(int argc, char **argv, struct command *cmd,
if (cfg.sel > 8) {
nvme_show_error("invalid 'select' param:%d", cfg.sel);
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
if (cfg.uuid_index > 127) {
nvme_show_error("invalid uuid index param: %u", cfg.uuid_index);
- err = -1;
- goto close_dev;
+ return -1;
}
+ nvme_show_init();
+
err = get_feature_ids(dev, cfg);
-close_dev:
- dev_close(dev);
+ nvme_show_finish();
-ret:
return err;
}
@@ -4960,12 +4757,14 @@ static int fw_download(int argc, char **argv, struct command *cmd, struct plugin
const char *offset = "starting dword offset, default 0";
const char *progress = "display firmware transfer progress";
const char *ignore_ovr = "ignore overwrite errors";
- unsigned int fw_size;
- struct nvme_dev *dev;
- int err, fw_fd = -1;
+
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
+ _cleanup_huge_ struct nvme_mem_huge mh = { 0, };
+ _cleanup_file_ int fw_fd = -1;
+ unsigned int fw_size, pos;
+ int err;
struct stat sb;
void *fw_buf;
- bool huge;
struct nvme_id_ctrl ctrl;
struct config {
@@ -4984,45 +4783,41 @@ static int fw_download(int argc, char **argv, struct command *cmd, struct plugin
.ignore_ovr = false,
};
- OPT_ARGS(opts) = {
- OPT_FILE("fw", 'f', &cfg.fw, fw),
- OPT_UINT("xfer", 'x', &cfg.xfer, xfer),
- OPT_UINT("offset", 'o', &cfg.offset, offset),
- OPT_FLAG("progress", 'p', &cfg.progress, progress),
- OPT_FLAG("ignore-ovr", 'i', &cfg.ignore_ovr, ignore_ovr),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_FILE("fw", 'f', &cfg.fw, fw),
+ OPT_UINT("xfer", 'x', &cfg.xfer, xfer),
+ OPT_UINT("offset", 'O', &cfg.offset, offset),
+ OPT_FLAG("progress", 'p', &cfg.progress, progress),
+ OPT_FLAG("ignore-ovr", 'i', &cfg.ignore_ovr, ignore_ovr));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
fw_fd = open(cfg.fw, O_RDONLY);
cfg.offset <<= 2;
if (fw_fd < 0) {
nvme_show_error("Failed to open firmware file %s: %s", cfg.fw, strerror(errno));
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
err = fstat(fw_fd, &sb);
if (err < 0) {
nvme_show_perror("fstat");
- goto close_fw_fd;
+ return err;
}
fw_size = sb.st_size;
if ((fw_size & 0x3) || (fw_size == 0)) {
nvme_show_error("Invalid size:%d for f/w image", fw_size);
- err = -EINVAL;
- goto close_fw_fd;
+ return -EINVAL;
}
if (cfg.xfer == 0) {
err = nvme_cli_identify_ctrl(dev, &ctrl);
if (err) {
nvme_show_error("identify-ctrl: %s", nvme_strerror(errno));
- goto close_fw_fd;
+ return err;
}
if (ctrl.fwug == 0 || ctrl.fwug == 0xff)
cfg.xfer = 4096;
@@ -5031,32 +4826,24 @@ static int fw_download(int argc, char **argv, struct command *cmd, struct plugin
} else if (cfg.xfer % 4096)
cfg.xfer = 4096;
- if (cfg.xfer < HUGE_MIN)
- fw_buf = __nvme_alloc(fw_size, &huge);
- else
- fw_buf = nvme_alloc(fw_size, &huge);
-
- if (!fw_buf) {
- err = -ENOMEM;
- goto close_fw_fd;
- }
+ fw_buf = nvme_alloc_huge(fw_size, &mh);
+ if (!fw_buf)
+ return -ENOMEM;
if (read(fw_fd, fw_buf, fw_size) != ((ssize_t)(fw_size))) {
err = -errno;
nvme_show_error("read :%s :%s", cfg.fw, strerror(errno));
- goto free;
+ return err;
}
- while (cfg.offset < fw_size) {
- cfg.xfer = min(cfg.xfer, fw_size);
+ for (pos = 0; pos < fw_size; pos += cfg.xfer) {
+ cfg.xfer = min(cfg.xfer, fw_size - pos);
- err = fw_download_single(dev, fw_buf + cfg.offset, fw_size,
- cfg.offset, cfg.xfer, cfg.progress,
- cfg.ignore_ovr);
+ err = fw_download_single(dev, fw_buf + pos, fw_size,
+ cfg.offset + pos, cfg.xfer,
+ cfg.progress, cfg.ignore_ovr);
if (err)
break;
-
- cfg.offset += cfg.xfer;
}
if (!err) {
@@ -5066,13 +4853,6 @@ static int fw_download(int argc, char **argv, struct command *cmd, struct plugin
printf("Firmware download success\n");
}
-free:
- nvme_free(fw_buf, huge);
-close_fw_fd:
- close(fw_fd);
-close_dev:
- dev_close(dev);
-ret:
return err;
}
@@ -5092,14 +4872,18 @@ static char *nvme_fw_status_reset_type(__u16 status)
static bool fw_commit_support_mud(struct nvme_dev *dev)
{
- struct nvme_id_ctrl ctrl;
+ _cleanup_free_ struct nvme_id_ctrl *ctrl = NULL;
int err;
- err = nvme_cli_identify_ctrl(dev, &ctrl);
+ ctrl = nvme_alloc(sizeof(*ctrl));
+ if (!ctrl)
+ return false;
+
+ err = nvme_cli_identify_ctrl(dev, ctrl);
if (err)
nvme_show_error("identify-ctrl: %s", nvme_strerror(errno));
- else if (ctrl.frmw >> 5 & 0x1)
+ else if (ctrl->frmw >> 5 & 0x1)
return true;
return false;
@@ -5131,7 +4915,8 @@ 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)";
- struct nvme_dev *dev;
+
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
__u32 result;
int err;
@@ -5147,31 +4932,26 @@ static int fw_commit(int argc, char **argv, struct command *cmd, struct plugin *
.bpid = 0,
};
- OPT_ARGS(opts) = {
- OPT_BYTE("slot", 's', &cfg.slot, slot),
- OPT_BYTE("action", 'a', &cfg.action, action),
- OPT_BYTE("bpid", 'b', &cfg.bpid, bpid),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_BYTE("slot", 's', &cfg.slot, slot),
+ OPT_BYTE("action", 'a', &cfg.action, action),
+ OPT_BYTE("bpid", 'b', &cfg.bpid, bpid));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
if (cfg.slot > 7) {
nvme_show_error("invalid slot:%d", cfg.slot);
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
if (cfg.action > 7 || cfg.action == 4 || cfg.action == 5) {
nvme_show_error("invalid action:%d", cfg.action);
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
if (cfg.bpid > 1) {
nvme_show_error("invalid boot partition id:%d", cfg.bpid);
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
struct nvme_fw_commit_args args = {
@@ -5218,25 +4998,21 @@ static int fw_commit(int argc, char **argv, struct command *cmd, struct plugin *
fw_commit_print_mud(dev, result);
}
-close_dev:
- dev_close(dev);
-ret:
return err;
}
static int subsystem_reset(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
const char *desc = "Resets the NVMe subsystem\n";
- struct nvme_dev *dev;
+
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
int err;
- OPT_ARGS(opts) = {
- OPT_END()
- };
+ NVME_ARGS(opts, cfg);
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
err = nvme_subsystem_reset(dev_fd(dev));
if (err < 0) {
@@ -5246,54 +5022,46 @@ static int subsystem_reset(int argc, char **argv, struct command *cmd, struct pl
nvme_show_error("Subsystem-reset: %s", nvme_strerror(errno));
}
- dev_close(dev);
-ret:
return err;
}
static int reset(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
const char *desc = "Resets the NVMe controller\n";
- struct nvme_dev *dev;
+
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
int err;
- OPT_ARGS(opts) = {
- OPT_END()
- };
+ NVME_ARGS(opts, cfg);
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
err = nvme_ctrl_reset(dev_fd(dev));
if (err < 0)
nvme_show_error("Reset: %s", nvme_strerror(errno));
- dev_close(dev);
-ret:
return err;
}
static int ns_rescan(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
const char *desc = "Rescans the NVMe namespaces\n";
- struct nvme_dev *dev;
+
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
int err;
- OPT_ARGS(opts) = {
- OPT_END()
- };
+ NVME_ARGS(opts, cfg);
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
err = nvme_ns_rescan(dev_fd(dev));
if (err < 0)
nvme_show_error("Namespace Rescan");
- dev_close(dev);
-ret:
return err;
}
@@ -5306,7 +5074,8 @@ static int sanitize_cmd(int argc, char **argv, struct command *cmd, struct plugi
const char *ause_desc = "Allow unrestricted sanitize exit.";
const char *sanact_desc = "Sanitize action: 1 = Exit failure mode, 2 = Start block erase, 3 = Start overwrite, 4 = Start crypto erase";
const char *ovrpat_desc = "Overwrite pattern.";
- struct nvme_dev *dev;
+
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
int err;
struct config {
@@ -5335,19 +5104,17 @@ static int sanitize_cmd(int argc, char **argv, struct command *cmd, struct plugi
VAL_END()
};
- OPT_ARGS(opts) = {
- OPT_FLAG("no-dealloc", 'd', &cfg.no_dealloc, no_dealloc_desc),
- OPT_FLAG("oipbp", 'i', &cfg.oipbp, oipbp_desc),
- OPT_BYTE("owpass", 'n', &cfg.owpass, owpass_desc),
- OPT_FLAG("ause", 'u', &cfg.ause, ause_desc),
- OPT_BYTE("sanact", 'a', &cfg.sanact, sanact_desc, sanact),
- OPT_UINT("ovrpat", 'p', &cfg.ovrpat, ovrpat_desc),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_FLAG("no-dealloc", 'd', &cfg.no_dealloc, no_dealloc_desc),
+ OPT_FLAG("oipbp", 'i', &cfg.oipbp, oipbp_desc),
+ OPT_BYTE("owpass", 'n', &cfg.owpass, owpass_desc),
+ OPT_FLAG("ause", 'u', &cfg.ause, ause_desc),
+ OPT_BYTE("sanact", 'a', &cfg.sanact, sanact_desc, sanact),
+ OPT_UINT("ovrpat", 'p', &cfg.ovrpat, ovrpat_desc));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
switch (cfg.sanact) {
case NVME_SANITIZE_SANACT_EXIT_FAILURE:
@@ -5357,29 +5124,25 @@ static int sanitize_cmd(int argc, char **argv, struct command *cmd, struct plugi
break;
default:
nvme_show_error("Invalid Sanitize Action");
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
if (cfg.sanact == NVME_SANITIZE_SANACT_EXIT_FAILURE) {
if (cfg.ause || cfg.no_dealloc) {
nvme_show_error("SANACT is Exit Failure Mode");
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
}
if (cfg.sanact == NVME_SANITIZE_SANACT_START_OVERWRITE) {
if (cfg.owpass > 15) {
nvme_show_error("OWPASS out of range [0-15]");
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
} else {
if (cfg.owpass || cfg.oipbp || cfg.ovrpat) {
nvme_show_error("SANACT is not Overwrite");
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
}
@@ -5399,9 +5162,6 @@ static int sanitize_cmd(int argc, char **argv, struct command *cmd, struct plugi
else if (err > 0)
nvme_show_status(err);
-close_dev:
- dev_close(dev);
-ret:
return err;
}
@@ -5503,38 +5263,34 @@ static int show_registers(int argc, char **argv, struct command *cmd, struct plu
"in binary or human-readable format";
const char *human_readable =
"show info in readable format in case of output_format == normal";
+
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
enum nvme_print_flags flags;
- struct nvme_dev *dev;
bool fabrics = false;
nvme_root_t r;
void *bar;
int err;
struct config {
- char *output_format;
bool human_readable;
};
struct config cfg = {
- .output_format = "normal",
.human_readable = false,
};
- OPT_ARGS(opts) = {
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
r = nvme_scan(NULL);
- err = flags = validate_output_format(cfg.output_format);
+ err = validate_output_format(output_format_val, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
- goto close_dev;
+ goto free_tree;
}
if (cfg.human_readable)
@@ -5544,7 +5300,7 @@ static int show_registers(int argc, char **argv, struct command *cmd, struct plu
if (!bar) {
err = nvme_get_properties(dev_fd(dev), &bar);
if (err)
- goto close_dev;
+ goto free_tree;
fabrics = true;
}
@@ -5553,10 +5309,8 @@ static int show_registers(int argc, char **argv, struct command *cmd, struct plu
free(bar);
else
munmap(bar, getpagesize());
-close_dev:
- dev_close(dev);
+free_tree:
nvme_free_tree(r);
-ret:
return err;
}
@@ -5567,7 +5321,8 @@ static int get_property(int argc, char **argv, struct command *cmd, struct plugi
"CAP=0x0, VS=0x8, CC=0x14, CSTS=0x1c, NSSR=0x20";
const char *offset = "offset of the requested property";
const char *human_readable = "show property in readable format";
- struct nvme_dev *dev;
+
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
__u64 value;
int err;
@@ -5581,20 +5336,17 @@ static int get_property(int argc, char **argv, struct command *cmd, struct plugi
.human_readable = false,
};
- OPT_ARGS(opts) = {
- OPT_UINT("offset", 'o', &cfg.offset, offset),
- OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_UINT("offset", 'O', &cfg.offset, offset),
+ OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
if (cfg.offset == -1) {
nvme_show_error("offset required param");
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
struct nvme_get_property_args args = {
@@ -5612,9 +5364,6 @@ static int get_property(int argc, char **argv, struct command *cmd, struct plugi
else if (err > 0)
nvme_show_status(err);
-close_dev:
- dev_close(dev);
-ret:
return err;
}
@@ -5624,7 +5373,8 @@ static int set_property(int argc, char **argv, struct command *cmd, struct plugi
"Writes and shows the defined NVMe controller property for NVMe over Fabric";
const char *offset = "the offset of the property";
const char *value = "the value of the property to be set";
- struct nvme_dev *dev;
+
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
int err;
struct config {
@@ -5637,25 +5387,21 @@ static int set_property(int argc, char **argv, struct command *cmd, struct plugi
.value = -1,
};
- OPT_ARGS(opts) = {
- OPT_UINT("offset", 'o', &cfg.offset, offset),
- OPT_UINT("value", 'v', &cfg.value, value),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_UINT("offset", 'O', &cfg.offset, offset),
+ OPT_UINT("value", 'V', &cfg.value, value));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
if (cfg.offset == -1) {
nvme_show_error("offset required param");
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
if (cfg.value == -1) {
nvme_show_error("value required param");
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
struct nvme_set_property_args args = {
@@ -5675,9 +5421,6 @@ static int set_property(int argc, char **argv, struct command *cmd, struct plugi
else if (err > 0)
nvme_show_status(err);
-close_dev:
- dev_close(dev);
-ret:
return err;
}
@@ -5695,9 +5438,10 @@ static int format_cmd(int argc, char **argv, struct command *cmd, struct plugin
const char *reset = "Automatically reset the controller after successful format";
const char *bs = "target block size";
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;
- struct nvme_dev *dev;
+
+ _cleanup_free_ struct nvme_id_ctrl *ctrl = NULL;
+ _cleanup_free_ struct nvme_id_ns *ns = NULL;
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
__u8 prev_lbaf = 0;
int block_size;
int err, i;
@@ -5728,23 +5472,21 @@ static int format_cmd(int argc, char **argv, struct command *cmd, struct plugin
.bs = 0,
};
- OPT_ARGS(opts) = {
- OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired),
- OPT_UINT("timeout", 't', &cfg.timeout, timeout),
- OPT_BYTE("lbaf", 'l', &cfg.lbaf, lbaf),
- OPT_BYTE("ses", 's', &cfg.ses, ses),
- OPT_BYTE("pi", 'i', &cfg.pi, pi),
- OPT_BYTE("pil", 'p', &cfg.pil, pil),
- OPT_BYTE("ms", 'm', &cfg.ms, ms),
- OPT_FLAG("reset", 'r', &cfg.reset, reset),
- OPT_FLAG("force", 0, &cfg.force, force),
- OPT_SUFFIX("block-size", 'b', &cfg.bs, bs),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired),
+ OPT_UINT("timeout", 't', &cfg.timeout, timeout),
+ OPT_BYTE("lbaf", 'l', &cfg.lbaf, lbaf),
+ OPT_BYTE("ses", 's', &cfg.ses, ses),
+ OPT_BYTE("pi", 'i', &cfg.pi, pi),
+ OPT_BYTE("pil", 'p', &cfg.pil, pil),
+ OPT_BYTE("ms", 'm', &cfg.ms, ms),
+ OPT_FLAG("reset", 'r', &cfg.reset, reset),
+ OPT_FLAG("force", 0, &cfg.force, force),
+ OPT_SUFFIX("block-size", 'b', &cfg.bs, bs));
err = argconfig_parse(argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
err = open_exclusive(&dev, argc, argv, cfg.force);
if (err) {
@@ -5756,32 +5498,34 @@ static int format_cmd(int argc, char **argv, struct command *cmd, struct plugin
} else {
argconfig_print_help(desc, opts);
}
- goto ret;
+ return err;
}
if (cfg.lbaf != 0xff && cfg.bs != 0) {
nvme_show_error(
"Invalid specification of both LBAF and Block Size, please specify only one");
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
if (cfg.bs) {
if ((cfg.bs & (~cfg.bs + 1)) != cfg.bs) {
nvme_show_error(
"Invalid value for block size (%"PRIu64"), must be a power of two",
(uint64_t) cfg.bs);
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
}
- err = nvme_cli_identify_ctrl(dev, &ctrl);
+ ctrl = nvme_alloc(sizeof(*ctrl));
+ if (!ctrl)
+ return -ENOMEM;
+
+ err = nvme_cli_identify_ctrl(dev, ctrl);
if (err) {
nvme_show_error("identify-ctrl: %s", nvme_strerror(errno));
- goto close_dev;
+ return -errno;
}
- if ((ctrl.fna & 1) == 1) {
+ if ((ctrl->fna & 1) == 1) {
/*
* FNA bit 0 set to 1: all namespaces ... shall be configured with the same
* attributes and a format (excluding secure erase) of any namespace results in a
@@ -5792,7 +5536,7 @@ static int format_cmd(int argc, char **argv, struct command *cmd, struct plugin
err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
nvme_show_error("get-namespace-id: %s", nvme_strerror(errno));
- goto close_dev;
+ return -errno;
}
}
@@ -5800,12 +5544,15 @@ static int format_cmd(int argc, char **argv, struct command *cmd, struct plugin
nvme_show_error(
"Invalid namespace ID, specify a namespace to format or use\n"
"'-n 0xffffffff' to format all namespaces on this controller.");
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
if (cfg.namespace_id != NVME_NSID_ALL) {
- err = nvme_cli_identify_ns(dev, cfg.namespace_id, &ns);
+ ns = nvme_alloc(sizeof(*ns));
+ if (!ns)
+ return -ENOMEM;
+
+ err = nvme_cli_identify_ns(dev, cfg.namespace_id, ns);
if (err) {
if (err < 0) {
nvme_show_error("identify-namespace: %s", nvme_strerror(errno));
@@ -5813,13 +5560,13 @@ static int format_cmd(int argc, char **argv, struct command *cmd, struct plugin
fprintf(stderr, "identify failed\n");
nvme_show_status(err);
}
- goto close_dev;
+ return err;
}
- nvme_id_ns_flbas_to_lbaf_inuse(ns.flbas, &prev_lbaf);
+ nvme_id_ns_flbas_to_lbaf_inuse(ns->flbas, &prev_lbaf);
if (cfg.bs) {
- for (i = 0; i <= ns.nlbaf; ++i) {
- if ((1ULL << ns.lbaf[i].ds) == cfg.bs && ns.lbaf[i].ms == 0) {
+ for (i = 0; i <= ns->nlbaf; ++i) {
+ if ((1ULL << ns->lbaf[i].ds) == cfg.bs && ns->lbaf[i].ms == 0) {
cfg.lbaf = i;
break;
}
@@ -5830,8 +5577,7 @@ static int format_cmd(int argc, char **argv, struct command *cmd, struct plugin
(uint64_t)cfg.bs);
fprintf(stderr,
"Please correct block size, or specify LBAF directly\n");
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
} else if (cfg.lbaf == 0xff) {
cfg.lbaf = prev_lbaf;
@@ -5844,28 +5590,23 @@ static int format_cmd(int argc, char **argv, struct command *cmd, struct plugin
/* ses & pi checks set to 7 for forward-compatibility */
if (cfg.ses > 7) {
nvme_show_error("invalid secure erase settings:%d", cfg.ses);
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
if (cfg.lbaf > 63) {
nvme_show_error("invalid lbaf:%d", cfg.lbaf);
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
if (cfg.pi > 7) {
nvme_show_error("invalid pi:%d", cfg.pi);
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
if (cfg.pil > 1) {
nvme_show_error("invalid pil:%d", cfg.pil);
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
if (cfg.ms > 1) {
nvme_show_error("invalid ms:%d", cfg.ms);
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
if (!cfg.force) {
@@ -5904,11 +5645,10 @@ static int format_cmd(int argc, char **argv, struct command *cmd, struct plugin
if (is_chardev(dev)) {
if (ioctl(dev_fd(dev), NVME_IOCTL_RESCAN) < 0) {
nvme_show_error("failed to rescan namespaces");
- err = -errno;
- goto close_dev;
+ return -errno;
}
} else if (cfg.namespace_id != NVME_NSID_ALL) {
- block_size = 1 << ns.lbaf[cfg.lbaf].ds;
+ block_size = 1 << ns->lbaf[cfg.lbaf].ds;
/*
* If block size has been changed by the format
@@ -5920,14 +5660,12 @@ static int format_cmd(int argc, char **argv, struct command *cmd, struct plugin
if (ioctl(dev_fd(dev), BLKBSZSET, &block_size) < 0) {
nvme_show_error("failed to set block size to %d",
block_size);
- err = -errno;
- goto close_dev;
+ return -errno;
}
if (ioctl(dev_fd(dev), BLKRRPART) < 0) {
nvme_show_error("failed to re-read partition table");
- err = -errno;
- goto close_dev;
+ return -errno;
}
}
}
@@ -5935,9 +5673,6 @@ static int format_cmd(int argc, char **argv, struct command *cmd, struct plugin
nvme_ctrl_reset(dev_fd(dev));
}
-close_dev:
- dev_close(dev);
-ret:
return err;
}
@@ -5960,11 +5695,12 @@ static int set_feature(int argc, char **argv, struct command *cmd, struct plugin
const char *value = "new value of feature (required)";
const char *cdw12 = "feature cdw12, if used";
const char *save = "specifies that the controller shall save the attribute";
- struct nvme_dev *dev;
+
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
+ _cleanup_free_ void *buf = NULL;
+ _cleanup_file_ int ffd = STDIN_FILENO;
int err;
__u32 result;
- void *buf = NULL;
- int ffd = STDIN_FILENO;
struct config {
__u32 namespace_id;
@@ -5987,28 +5723,26 @@ static int set_feature(int argc, char **argv, struct command *cmd, struct plugin
.save = false,
};
- OPT_ARGS(opts) = {
- OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_desired),
- OPT_BYTE("feature-id", 'f', &cfg.feature_id, feature_id),
- OPT_SUFFIX("value", 'v', &cfg.value, value),
- OPT_UINT("cdw12", 'c', &cfg.cdw12, cdw12),
- OPT_BYTE("uuid-index", 'U', &cfg.uuid_index, uuid_index_specify),
- OPT_UINT("data-len", 'l', &cfg.data_len, buf_len),
- OPT_FILE("data", 'd', &cfg.file, data),
- OPT_FLAG("save", 's', &cfg.save, save),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_desired),
+ OPT_BYTE("feature-id", 'f', &cfg.feature_id, feature_id),
+ OPT_SUFFIX("value", 'V', &cfg.value, value),
+ OPT_UINT("cdw12", 'c', &cfg.cdw12, cdw12),
+ OPT_BYTE("uuid-index", 'U', &cfg.uuid_index, uuid_index_specify),
+ OPT_UINT("data-len", 'l', &cfg.data_len, buf_len),
+ OPT_FILE("data", 'd', &cfg.file, data),
+ OPT_FLAG("save", 's', &cfg.save, save));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
if (!argconfig_parse_seen(opts, "namespace-id")) {
err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
if (errno != ENOTTY) {
nvme_show_error("get-namespace-id: %s", nvme_strerror(errno));
- goto close_dev;
+ return -errno;
}
cfg.namespace_id = NVME_NSID_ALL;
}
@@ -6016,14 +5750,12 @@ static int set_feature(int argc, char **argv, struct command *cmd, struct plugin
if (!cfg.feature_id) {
nvme_show_error("feature-id required param");
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
if (cfg.uuid_index > 127) {
nvme_show_error("invalid uuid index param: %u", cfg.uuid_index);
- err = -1;
- goto close_dev;
+ return -1;
}
if (!cfg.data_len)
@@ -6032,12 +5764,9 @@ static int set_feature(int argc, char **argv, struct command *cmd, struct plugin
&cfg.data_len);
if (cfg.data_len) {
- if (posix_memalign(&buf, getpagesize(), cfg.data_len)) {
- nvme_show_error("can not allocate feature payload");
- err = -ENOMEM;
- goto close_dev;
- }
- memset(buf, 0, cfg.data_len);
+ buf = nvme_alloc(cfg.data_len);
+ if (!buf)
+ return -ENOMEM;
}
if (buf) {
@@ -6050,22 +5779,20 @@ static int set_feature(int argc, char **argv, struct command *cmd, struct plugin
if (cfg.feature_id == NVME_FEAT_FID_TIMESTAMP && cfg.value) {
memcpy(buf, &cfg.value, NVME_FEAT_TIMESTAMP_DATA_SIZE);
} else {
- if (strlen(cfg.file)) {
+ if (strlen(cfg.file))
ffd = open(cfg.file, O_RDONLY);
- if (ffd <= 0) {
- nvme_show_error("Failed to open file %s: %s",
- cfg.file, strerror(errno));
- err = -EINVAL;
- goto free;
- }
+
+ if (ffd < 0) {
+ nvme_show_error("Failed to open file %s: %s",
+ cfg.file, strerror(errno));
+ return -EINVAL;
}
- err = read(ffd, (void *)buf, cfg.data_len);
+ err = read(ffd, buf, cfg.data_len);
if (err < 0) {
- err = -errno;
nvme_show_error("failed to read data buffer from input file: %s",
strerror(errno));
- goto close_ffd;
+ return -errno;
}
}
}
@@ -6106,14 +5833,6 @@ static int set_feature(int argc, char **argv, struct command *cmd, struct plugin
nvme_show_status(err);
}
-close_ffd:
- if (ffd != STDIN_FILENO)
- close(ffd);
-free:
- free(buf);
-close_dev:
- dev_close(dev);
-ret:
return err;
}
@@ -6126,10 +5845,12 @@ static int sec_send(int argc, char **argv, struct command *cmd, struct plugin *p
"associates Security Sends (security-send) and Security Receives (security-recv).";
const char *file = "transfer payload";
const char *tl = "transfer length (cf. SPC-4)";
- int err, sec_fd = STDIN_FILENO;
- struct nvme_dev *dev;
- void *sec_buf;
+
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
+ _cleanup_free_ void *sec_buf = NULL;
+ _cleanup_file_ int sec_fd = -1;
unsigned int sec_size;
+ int err;
struct config {
__u32 namespace_id;
@@ -6149,24 +5870,21 @@ static int sec_send(int argc, char **argv, struct command *cmd, struct plugin *p
.tl = 0,
};
- OPT_ARGS(opts) = {
- OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_desired),
- OPT_FILE("file", 'f', &cfg.file, file),
- OPT_BYTE("nssf", 'N', &cfg.nssf, nssf),
- OPT_BYTE("secp", 'p', &cfg.secp, secp),
- OPT_SHRT("spsp", 's', &cfg.spsp, spsp),
- OPT_UINT("tl", 't', &cfg.tl, tl),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_desired),
+ OPT_FILE("file", 'f', &cfg.file, file),
+ OPT_BYTE("nssf", 'N', &cfg.nssf, nssf),
+ OPT_BYTE("secp", 'p', &cfg.secp, secp),
+ OPT_SHRT("spsp", 's', &cfg.spsp, spsp),
+ OPT_UINT("tl", 't', &cfg.tl, tl));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
if (cfg.tl == 0) {
nvme_show_error("--tl unspecified or zero");
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
if ((cfg.tl & 3) != 0)
nvme_show_error(
@@ -6179,33 +5897,27 @@ static int sec_send(int argc, char **argv, struct command *cmd, struct plugin *p
sec_fd = open(cfg.file, O_RDONLY);
if (sec_fd < 0) {
nvme_show_error("Failed to open %s: %s", cfg.file, strerror(errno));
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
err = fstat(sec_fd, &sb);
if (err < 0) {
nvme_show_perror("fstat");
- goto close_sec_fd;
+ return err;
}
sec_size = cfg.tl > sb.st_size ? cfg.tl : sb.st_size;
}
- if (posix_memalign(&sec_buf, getpagesize(), cfg.tl)) {
- nvme_show_error("No memory for security size:%d", cfg.tl);
- err = -ENOMEM;
- goto close_sec_fd;
- }
-
- memset(sec_buf, 0, cfg.tl); // ensure zero fill if buf_size > sec_size
+ sec_buf = nvme_alloc(cfg.tl);
+ if (!sec_buf)
+ return -ENOMEM;
err = read(sec_fd, sec_buf, sec_size);
if (err < 0) {
- err = -errno;
nvme_show_error("Failed to read data from security file %s with %s", cfg.file,
strerror(errno));
- goto free;
+ return -errno;
}
struct nvme_security_send_args args = {
@@ -6231,13 +5943,6 @@ static int sec_send(int argc, char **argv, struct command *cmd, struct plugin *p
else
printf("NVME Security Send Command Success\n");
-free:
- free(sec_buf);
-close_sec_fd:
- close(sec_fd);
-close_dev:
- dev_close(dev);
-ret:
return err;
}
@@ -6247,11 +5952,12 @@ static int dir_send(int argc, char **argv, struct command *cmd, struct plugin *p
const char *endir = "directive enable";
const char *ttype = "target directive type to be enabled/disabled";
const char *input = "write/send file (default stdin)";
- struct nvme_dev *dev;
+
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
+ _cleanup_free_ void *buf = NULL;
__u32 result;
__u32 dw12 = 0;
- void *buf = NULL;
- int ffd = STDIN_FILENO;
+ _cleanup_file_ int ffd = STDIN_FILENO;
int err;
struct config {
@@ -6280,23 +5986,21 @@ static int dir_send(int argc, char **argv, struct command *cmd, struct plugin *p
.file = "",
};
- OPT_ARGS(opts) = {
- OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired),
- OPT_UINT("data-len", 'l', &cfg.data_len, buf_len),
- OPT_BYTE("dir-type", 'D', &cfg.dtype, dtype),
- OPT_BYTE("target-dir", 'T', &cfg.ttype, ttype),
- OPT_SHRT("dir-spec", 'S', &cfg.dspec, dspec_w_dtype),
- OPT_BYTE("dir-oper", 'O', &cfg.doper, doper),
- OPT_SHRT("endir", 'e', &cfg.endir, endir),
- OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable_directive),
- OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_directive),
- OPT_FILE("input-file", 'i', &cfg.file, input),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired),
+ OPT_UINT("data-len", 'l', &cfg.data_len, buf_len),
+ OPT_BYTE("dir-type", 'D', &cfg.dtype, dtype),
+ OPT_BYTE("target-dir", 'T', &cfg.ttype, ttype),
+ OPT_SHRT("dir-spec", 'S', &cfg.dspec, dspec_w_dtype),
+ OPT_BYTE("dir-oper", 'O', &cfg.doper, doper),
+ OPT_SHRT("endir", 'e', &cfg.endir, endir),
+ OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable_directive),
+ OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_directive),
+ OPT_FILE("input-file", 'i', &cfg.file, input));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
switch (cfg.dtype) {
case NVME_DIRECTIVE_DTYPE_IDENTIFY:
@@ -6304,15 +6008,13 @@ static int dir_send(int argc, char **argv, struct command *cmd, struct plugin *p
case NVME_DIRECTIVE_SEND_IDENTIFY_DOPER_ENDIR:
if (!cfg.ttype) {
nvme_show_error("target-dir required param\n");
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
dw12 = cfg.ttype << 8 | cfg.endir;
break;
default:
nvme_show_error("invalid directive operations for Identify Directives");
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
break;
case NVME_DIRECTIVE_DTYPE_STREAMS:
@@ -6322,22 +6024,18 @@ static int dir_send(int argc, char **argv, struct command *cmd, struct plugin *p
break;
default:
nvme_show_error("invalid directive operations for Streams Directives");
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
break;
default:
nvme_show_error("invalid directive type");
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
if (cfg.data_len) {
- if (posix_memalign(&buf, getpagesize(), cfg.data_len)) {
- err = -ENOMEM;
- goto close_dev;
- }
- memset(buf, 0, cfg.data_len);
+ buf = nvme_alloc(cfg.data_len);
+ if (!buf)
+ return -ENOMEM;
}
if (buf) {
@@ -6346,16 +6044,14 @@ static int dir_send(int argc, char **argv, struct command *cmd, struct plugin *p
if (ffd <= 0) {
nvme_show_error("Failed to open file %s: %s",
cfg.file, strerror(errno));
- err = -EINVAL;
- goto free;
+ return -EINVAL;
}
}
err = read(ffd, (void *)buf, cfg.data_len);
if (err < 0) {
- err = -errno;
nvme_show_error("failed to read data buffer from input file %s",
strerror(errno));
- goto close_ffd;
+ return -errno;
}
}
@@ -6375,7 +6071,7 @@ static int dir_send(int argc, char **argv, struct command *cmd, struct plugin *p
err = nvme_directive_send(&args);
if (err < 0) {
nvme_show_error("dir-send: %s", nvme_strerror(errno));
- goto close_ffd;
+ return err;
}
if (!err) {
printf("dir-send: type %#x, operation %#x, spec_val %#x, nsid %#x, result %#x\n",
@@ -6390,13 +6086,6 @@ static int dir_send(int argc, char **argv, struct command *cmd, struct plugin *p
nvme_show_status(err);
}
-close_ffd:
- close(ffd);
-free:
- free(buf);
-close_dev:
- dev_close(dev);
-ret:
return err;
}
@@ -6404,7 +6093,8 @@ static int write_uncor(int argc, char **argv, struct command *cmd, struct plugin
{
const char *desc =
"The Write Uncorrectable command is used to set a range of logical blocks to invalid.";
- struct nvme_dev *dev;
+
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
int err;
struct config {
@@ -6423,31 +6113,28 @@ static int write_uncor(int argc, char **argv, struct command *cmd, struct plugin
.dspec = 0,
};
- OPT_ARGS(opts) = {
- OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_desired),
- OPT_SUFFIX("start-block", 's', &cfg.start_block, start_block),
- OPT_SHRT("block-count", 'c', &cfg.block_count, block_count),
- OPT_BYTE("dir-type", 'T', &cfg.dtype, dtype),
- OPT_SHRT("dir-spec", 'S', &cfg.dspec, dspec_w_dtype),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_desired),
+ OPT_SUFFIX("start-block", 's', &cfg.start_block, start_block),
+ OPT_SHRT("block-count", 'c', &cfg.block_count, block_count),
+ OPT_BYTE("dir-type", 'T', &cfg.dtype, dtype),
+ OPT_SHRT("dir-spec", 'S', &cfg.dspec, dspec_w_dtype));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
if (!cfg.namespace_id) {
err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
nvme_show_error("get-namespace-id: %s", nvme_strerror(errno));
- goto close_dev;
+ return err;
}
}
if (cfg.dtype > 0xf) {
nvme_show_error("Invalid directive type, %x", cfg.dtype);
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
struct nvme_io_args args = {
@@ -6469,9 +6156,6 @@ static int write_uncor(int argc, char **argv, struct command *cmd, struct plugin
else
printf("NVME Write Uncorrectable Success\n");
-close_dev:
- dev_close(dev);
-ret:
return err;
}
@@ -6511,11 +6195,11 @@ 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)
{
- __u16 control = 0;
+ _cleanup_free_ struct nvme_nvm_id_ns *nvm_ns = NULL;
+ _cleanup_free_ struct nvme_id_ns *ns = NULL;
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
__u8 lba_index, sts = 0, pif = 0;
- struct nvme_id_ns ns;
- struct nvme_dev *dev;
- struct nvme_nvm_id_ns nvm_ns;
+ __u16 control = 0;
int err;
const char *desc =
@@ -6560,37 +6244,32 @@ static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugi
.dspec = 0,
};
- OPT_ARGS(opts) = {
- OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_desired),
- OPT_SUFFIX("start-block", 's', &cfg.start_block, start_block),
- OPT_SHRT("block-count", 'c', &cfg.block_count, block_count),
- OPT_BYTE("dir-type", 'T', &cfg.dtype, dtype),
- OPT_FLAG("deac", 'd', &cfg.deac, deac),
- OPT_FLAG("limited-retry", 'l', &cfg.limited_retry, limited_retry),
- OPT_FLAG("force-unit-access", 'f', &cfg.force_unit_access, force_unit_access),
- OPT_BYTE("prinfo", 'p', &cfg.prinfo, prinfo),
- OPT_SUFFIX("ref-tag", 'r', &cfg.ref_tag, ref_tag),
- OPT_SHRT("app-tag-mask", 'm', &cfg.app_tag_mask, app_tag_mask),
- OPT_SHRT("app-tag", 'a', &cfg.app_tag, app_tag),
- OPT_SUFFIX("storage-tag", 'S', &cfg.storage_tag, storage_tag),
- OPT_FLAG("storage-tag-check", 'C', &cfg.storage_tag_check, storage_tag_check),
- OPT_SHRT("dir-spec", 'D', &cfg.dspec, dspec_w_dtype),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_desired),
+ OPT_SUFFIX("start-block", 's', &cfg.start_block, start_block),
+ OPT_SHRT("block-count", 'c', &cfg.block_count, block_count),
+ OPT_BYTE("dir-type", 'T', &cfg.dtype, dtype),
+ OPT_FLAG("deac", 'd', &cfg.deac, deac),
+ OPT_FLAG("limited-retry", 'l', &cfg.limited_retry, limited_retry),
+ OPT_FLAG("force-unit-access", 'f', &cfg.force_unit_access, force_unit_access),
+ OPT_BYTE("prinfo", 'p', &cfg.prinfo, prinfo),
+ OPT_SUFFIX("ref-tag", 'r', &cfg.ref_tag, ref_tag),
+ OPT_SHRT("app-tag-mask", 'm', &cfg.app_tag_mask, app_tag_mask),
+ OPT_SHRT("app-tag", 'a', &cfg.app_tag, app_tag),
+ OPT_SUFFIX("storage-tag", 'S', &cfg.storage_tag, storage_tag),
+ OPT_FLAG("storage-tag-check", 'C', &cfg.storage_tag_check, storage_tag_check),
+ OPT_SHRT("dir-spec", 'D', &cfg.dspec, dspec_w_dtype));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
- if (cfg.prinfo > 0xf) {
- err = -EINVAL;
- goto close_dev;
- }
+ if (cfg.prinfo > 0xf)
+ return -EINVAL;
if (cfg.dtype > 0xf) {
nvme_show_error("Invalid directive type, %x", cfg.dtype);
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
control |= (cfg.prinfo << 10);
@@ -6607,30 +6286,36 @@ static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugi
err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
nvme_show_error("get-namespace-id: %s", nvme_strerror(errno));
- goto close_dev;
+ return err;
}
}
- err = nvme_cli_identify_ns(dev, cfg.namespace_id, &ns);
+ ns = nvme_alloc(sizeof(*ns));
+ if (!ns)
+ return -ENOMEM;
+
+ err = nvme_cli_identify_ns(dev, cfg.namespace_id, ns);
if (err < 0) {
nvme_show_error("identify namespace: %s", nvme_strerror(errno));
- goto close_dev;
+ return err;
} else if (err) {
nvme_show_status(err);
- goto close_dev;
+ return err;
}
- err = nvme_identify_ns_csi(dev_fd(dev), cfg.namespace_id, 0, NVME_CSI_NVM, &nvm_ns);
+ nvm_ns = nvme_alloc(sizeof(*nvm_ns));
+ if (!nvm_ns)
+ return -ENOMEM;
+
+ 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;
- pif = (nvm_ns.elbaf[lba_index] & NVME_NVM_ELBAF_PIF_MASK) >> 7;
+ nvme_id_ns_flbas_to_lbaf_inuse(ns->flbas, &lba_index);
+ sts = nvm_ns->elbaf[lba_index] & NVME_NVM_ELBAF_STS_MASK;
+ pif = (nvm_ns->elbaf[lba_index] & NVME_NVM_ELBAF_PIF_MASK) >> 7;
}
- if (invalid_tags(cfg.storage_tag, cfg.ref_tag, sts, pif)) {
- err = -EINVAL;
- goto close_dev;
- }
+ if (invalid_tags(cfg.storage_tag, cfg.ref_tag, sts, pif))
+ return -EINVAL;
struct nvme_io_args args = {
.args_size = sizeof(args),
@@ -6657,9 +6342,6 @@ static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugi
else
printf("NVME Write Zeroes Success\n");
-close_dev:
- dev_close(dev);
-ret:
return err;
}
@@ -6677,12 +6359,12 @@ 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";
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
+ _cleanup_free_ struct nvme_dsm_range *dsm = NULL;
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 {
@@ -6707,42 +6389,43 @@ static int dsm(int argc, char **argv, struct command *cmd, struct plugin *plugin
.cdw11 = 0,
};
- OPT_ARGS(opts) = {
- OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired),
- OPT_LIST("ctx-attrs", 'a', &cfg.ctx_attrs, context_attrs),
- OPT_LIST("blocks", 'b', &cfg.blocks, blocks),
- OPT_LIST("slbs", 's', &cfg.slbas, starting_blocks),
- OPT_FLAG("ad", 'd', &cfg.ad, ad),
- OPT_FLAG("idw", 'w', &cfg.idw, idw),
- OPT_FLAG("idr", 'r', &cfg.idr, idr),
- OPT_UINT("cdw11", 'c', &cfg.cdw11, cdw11),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired),
+ OPT_LIST("ctx-attrs", 'a', &cfg.ctx_attrs, context_attrs),
+ OPT_LIST("blocks", 'b', &cfg.blocks, blocks),
+ OPT_LIST("slbs", 's', &cfg.slbas, starting_blocks),
+ OPT_FLAG("ad", 'd', &cfg.ad, ad),
+ OPT_FLAG("idw", 'w', &cfg.idw, idw),
+ OPT_FLAG("idr", 'r', &cfg.idr, idr),
+ OPT_UINT("cdw11", 'c', &cfg.cdw11, cdw11));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
- nc = argconfig_parse_comma_sep_array(cfg.ctx_attrs, (int *)ctx_attrs, ARRAY_SIZE(ctx_attrs));
- nb = argconfig_parse_comma_sep_array(cfg.blocks, (int *)nlbs, ARRAY_SIZE(nlbs));
- ns = argconfig_parse_comma_sep_array_long(cfg.slbas, (unsigned long long *)slbas, ARRAY_SIZE(slbas));
+ nc = argconfig_parse_comma_sep_array_u32(cfg.ctx_attrs, ctx_attrs, ARRAY_SIZE(ctx_attrs));
+ nb = argconfig_parse_comma_sep_array_u32(cfg.blocks, nlbs, ARRAY_SIZE(nlbs));
+ ns = argconfig_parse_comma_sep_array_u64(cfg.slbas, slbas, ARRAY_SIZE(slbas));
nr = max(nc, max(nb, ns));
if (!nr || nr > 256) {
nvme_show_error("No range definition provided");
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
if (!cfg.namespace_id) {
err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
nvme_show_error("get-namespace-id: %s", nvme_strerror(errno));
- goto close_dev;
+ return err;
}
}
if (!cfg.cdw11)
cfg.cdw11 = (cfg.ad << 2) | (cfg.idw << 1) | (cfg.idr << 0);
+ dsm = nvme_alloc(sizeof(*dsm) * 256);
+ if (!dsm)
+ return -ENOMEM;
+
nvme_init_dsm_range(dsm, ctx_attrs, nlbs, slbas, nr);
struct nvme_dsm_args args = {
.args_size = sizeof(args),
@@ -6762,9 +6445,6 @@ static int dsm(int argc, char **argv, struct command *cmd, struct plugin *plugin
else
printf("NVMe DSM: success\n");
-close_dev:
- dev_close(dev);
-ret:
return err;
}
@@ -6776,6 +6456,8 @@ static int copy_cmd(int argc, char **argv, struct command *cmd, struct plugin *p
const char *d_sdlba = "64-bit addr of first destination logical block";
const char *d_slbas = "64-bit addr of first block per range (comma-separated list)";
const char *d_nlbs = "number of blocks per range (comma-separated list, zeroes-based values)";
+ const char *d_snsids = "source namespace identifier per range (comma-separated list)";
+ const char *d_sopts = "source options per range (comma-separated list)";
const char *d_lr = "limited retry";
const char *d_fua = "force unit access";
const char *d_prinfor = "protection information and check field (read part)";
@@ -6790,30 +6472,36 @@ static int copy_cmd(int argc, char **argv, struct command *cmd, struct plugin *p
const char *d_dspec = "directive specific (write part)";
const char *d_format = "source range entry format";
- uint16_t nr, nb, ns, nrts, natms, nats;
- __u16 nlbs[128] = { 0 };
- unsigned long long slbas[128] = {0,};
- struct nvme_dev *dev;
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
+ __u16 nr, nb, ns, nrts, natms, nats, nids;
+ __u16 nlbs[256] = { 0 };
+ __u64 slbas[256] = { 0 };
+ __u32 snsids[256] = { 0 };
+ __u16 sopts[256] = { 0 };
int err;
union {
- __u32 f0[128];
- __u64 f1[101];
+ __u32 short_pi[256];
+ __u64 long_pi[256];
} eilbrts;
- __u32 elbatms[128] = { 0 };
- __u32 elbats[128] = { 0 };
+ __u32 elbatms[256] = { 0 };
+ __u32 elbats[256] = { 0 };
union {
- struct nvme_copy_range f0[128];
- struct nvme_copy_range_f1 f1[101];
- } copy;
+ struct nvme_copy_range f0[256];
+ struct nvme_copy_range_f1 f1[256];
+ struct nvme_copy_range_f2 f2[256];
+ struct nvme_copy_range_f3 f3[256];
+ } *copy;
struct config {
__u32 namespace_id;
__u64 sdlba;
char *slbas;
char *nlbs;
+ char *snsids;
+ char *sopts;
bool lr;
bool fua;
__u8 prinfow;
@@ -6834,6 +6522,8 @@ static int copy_cmd(int argc, char **argv, struct command *cmd, struct plugin *p
.sdlba = 0,
.slbas = "",
.nlbs = "",
+ .snsids = "",
+ .sopts = "",
.lr = false,
.fua = false,
.prinfow = 0,
@@ -6849,77 +6539,93 @@ static int copy_cmd(int argc, char **argv, struct command *cmd, struct plugin *p
.format = 0,
};
- OPT_ARGS(opts) = {
- OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired),
- OPT_SUFFIX("sdlba", 'd', &cfg.sdlba, d_sdlba),
- OPT_LIST("slbs", 's', &cfg.slbas, d_slbas),
- OPT_LIST("blocks", 'b', &cfg.nlbs, d_nlbs),
- OPT_FLAG("limited-retry", 'l', &cfg.lr, d_lr),
- OPT_FLAG("force-unit-access", 'f', &cfg.fua, d_fua),
- OPT_BYTE("prinfow", 'p', &cfg.prinfow, d_prinfow),
- OPT_BYTE("prinfor", 'P', &cfg.prinfor, d_prinfor),
- OPT_SUFFIX("ref-tag", 'r', &cfg.ilbrt, d_ilbrt),
- OPT_LIST("expected-ref-tags", 'R', &cfg.eilbrts, d_eilbrts),
- OPT_SHRT("app-tag", 'a', &cfg.lbat, d_lbat),
- OPT_LIST("expected-app-tags", 'A', &cfg.elbats, d_elbats),
- OPT_SHRT("app-tag-mask", 'm', &cfg.lbatm, d_lbatm),
- OPT_LIST("expected-app-tag-masks", 'M', &cfg.elbatms, d_elbatms),
- OPT_BYTE("dir-type", 'T', &cfg.dtype, d_dtype),
- OPT_SHRT("dir-spec", 'S', &cfg.dspec, d_dspec),
- OPT_BYTE("format", 'F', &cfg.format, d_format),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired),
+ OPT_SUFFIX("sdlba", 'd', &cfg.sdlba, d_sdlba),
+ OPT_LIST("slbs", 's', &cfg.slbas, d_slbas),
+ OPT_LIST("blocks", 'b', &cfg.nlbs, d_nlbs),
+ OPT_LIST("snsids", 'N', &cfg.snsids, d_snsids),
+ OPT_LIST("sopts", 'O', &cfg.sopts, d_sopts),
+ OPT_FLAG("limited-retry", 'l', &cfg.lr, d_lr),
+ OPT_FLAG("force-unit-access", 'f', &cfg.fua, d_fua),
+ OPT_BYTE("prinfow", 'p', &cfg.prinfow, d_prinfow),
+ OPT_BYTE("prinfor", 'P', &cfg.prinfor, d_prinfor),
+ OPT_SUFFIX("ref-tag", 'r', &cfg.ilbrt, d_ilbrt),
+ OPT_LIST("expected-ref-tags", 'R', &cfg.eilbrts, d_eilbrts),
+ OPT_SHRT("app-tag", 'a', &cfg.lbat, d_lbat),
+ OPT_LIST("expected-app-tags", 'A', &cfg.elbats, d_elbats),
+ OPT_SHRT("app-tag-mask", 'm', &cfg.lbatm, d_lbatm),
+ OPT_LIST("expected-app-tag-masks", 'M', &cfg.elbatms, d_elbatms),
+ OPT_BYTE("dir-type", 'T', &cfg.dtype, d_dtype),
+ OPT_SHRT("dir-spec", 'S', &cfg.dspec, d_dspec),
+ OPT_BYTE("format", 'F', &cfg.format, d_format));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
-
- 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));
+ return err;
- 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,
- (unsigned long long *)eilbrts.f1,
- ARRAY_SIZE(eilbrts.f1));
+ nb = argconfig_parse_comma_sep_array_u16(cfg.nlbs, nlbs, ARRAY_SIZE(nlbs));
+ ns = argconfig_parse_comma_sep_array_u64(cfg.slbas, slbas, ARRAY_SIZE(slbas));
+ nids = argconfig_parse_comma_sep_array_u32(cfg.snsids, snsids, ARRAY_SIZE(snsids));
+ argconfig_parse_comma_sep_array_u16(cfg.sopts, sopts, ARRAY_SIZE(sopts));
+
+ if (cfg.format == 0 || cfg.format == 2) {
+ nrts = argconfig_parse_comma_sep_array_u32(cfg.eilbrts, eilbrts.short_pi,
+ ARRAY_SIZE(eilbrts.short_pi));
+ } else if (cfg.format == 1 || cfg.format == 3) {
+ nrts = argconfig_parse_comma_sep_array_u64(cfg.eilbrts, eilbrts.long_pi,
+ ARRAY_SIZE(eilbrts.long_pi));
} else {
nvme_show_error("invalid format");
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
- natms = argconfig_parse_comma_sep_array(cfg.elbatms, (int *)elbatms, ARRAY_SIZE(elbatms));
- nats = argconfig_parse_comma_sep_array(cfg.elbats, (int *)elbats, ARRAY_SIZE(elbats));
+ natms = argconfig_parse_comma_sep_array_u32(cfg.elbatms, elbatms, ARRAY_SIZE(elbatms));
+ nats = argconfig_parse_comma_sep_array_u32(cfg.elbats, elbats, ARRAY_SIZE(elbats));
nr = max(nb, max(ns, max(nrts, max(natms, nats))));
- if (!nr || nr > 128 || (cfg.format == 1 && nr > 101)) {
+ if (cfg.format == 2 || cfg.format == 3) {
+ if (nr != nids) {
+ nvme_show_error("formats 2 and 3 require source namespace ids for each source range");
+ return -EINVAL;
+ }
+ } else if (nids) {
+ nvme_show_error("formats 0 and 1 do not support cross-namespace copy");
+ return -EINVAL;
+ }
+ if (!nr || nr > 256) {
nvme_show_error("invalid range");
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
if (!cfg.namespace_id) {
err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
nvme_show_error("get-namespace-id: %s", nvme_strerror(errno));
- goto close_dev;
+ return err;
}
}
+ copy = nvme_alloc(sizeof(*copy));
+ if (!copy)
+ return -ENOMEM;
+
if (cfg.format == 0)
- nvme_init_copy_range(copy.f0, nlbs, (__u64 *)slbas,
- eilbrts.f0, elbatms, elbats, nr);
+ nvme_init_copy_range(copy->f0, nlbs, slbas, eilbrts.short_pi, elbatms, elbats, nr);
else if (cfg.format == 1)
- nvme_init_copy_range_f1(copy.f1, nlbs, (__u64 *)slbas,
- eilbrts.f1, elbatms, elbats, nr);
+ nvme_init_copy_range_f1(copy->f1, nlbs, slbas, eilbrts.long_pi, elbatms, elbats, nr);
+ else if (cfg.format == 2)
+ nvme_init_copy_range_f2(copy->f2, snsids, nlbs, slbas, sopts, eilbrts.short_pi, elbatms,
+ elbats, nr);
+ else if (cfg.format == 3)
+ nvme_init_copy_range_f3(copy->f3, snsids, nlbs, slbas, sopts, eilbrts.long_pi, elbatms,
+ elbats, nr);
struct nvme_copy_args args = {
.args_size = sizeof(args),
.fd = dev_fd(dev),
.nsid = cfg.namespace_id,
- .copy = copy.f0,
+ .copy = copy->f0,
.sdlba = cfg.sdlba,
.nr = nr,
.prinfor = cfg.prinfor,
@@ -6943,9 +6649,6 @@ static int copy_cmd(int argc, char **argv, struct command *cmd, struct plugin *p
else
printf("NVMe Copy: success\n");
-close_dev:
- dev_close(dev);
-ret:
return err;
}
@@ -6956,7 +6659,8 @@ static int flush_cmd(int argc, char **argv, struct command *cmd, struct plugin *
"finished before the flush was submitted. Additional data may also be\n"
"flushed by the controller, from any namespace, depending on controller and\n"
"associated namespace status.";
- struct nvme_dev *dev;
+
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
int err;
struct config {
@@ -6967,20 +6671,18 @@ static int flush_cmd(int argc, char **argv, struct command *cmd, struct plugin *
.namespace_id = 0,
};
- OPT_ARGS(opts) = {
- OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
if (!cfg.namespace_id) {
err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
nvme_show_error("get-namespace-id: %s", nvme_strerror(errno));
- goto close_dev;
+ return err;
}
}
@@ -6991,9 +6693,7 @@ static int flush_cmd(int argc, char **argv, struct command *cmd, struct plugin *
nvme_show_status(err);
else
printf("NVMe Flush: success\n");
-close_dev:
- dev_close(dev);
-ret:
+
return err;
}
@@ -7006,7 +6706,8 @@ static int resv_acquire(int argc, char **argv, struct command *cmd, struct plugi
"status Reservation Conflict if the given namespace is already reserved.";
const char *prkey = "pre-empt reservation key";
const char *racqa = "reservation acquire action";
- struct nvme_dev *dev;
+
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
int err;
struct config {
@@ -7027,31 +6728,28 @@ static int resv_acquire(int argc, char **argv, struct command *cmd, struct plugi
.iekey = false,
};
- OPT_ARGS(opts) = {
- OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired),
- OPT_SUFFIX("crkey", 'c', &cfg.crkey, crkey),
- OPT_SUFFIX("prkey", 'p', &cfg.prkey, prkey),
- OPT_BYTE("rtype", 't', &cfg.rtype, rtype),
- OPT_BYTE("racqa", 'a', &cfg.racqa, racqa),
- OPT_FLAG("iekey", 'i', &cfg.iekey, iekey),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired),
+ OPT_SUFFIX("crkey", 'c', &cfg.crkey, crkey),
+ OPT_SUFFIX("prkey", 'p', &cfg.prkey, prkey),
+ OPT_BYTE("rtype", 't', &cfg.rtype, rtype),
+ OPT_BYTE("racqa", 'a', &cfg.racqa, racqa),
+ OPT_FLAG("iekey", 'i', &cfg.iekey, iekey));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
if (!cfg.namespace_id) {
err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
nvme_show_error("get-namespace-id: %s", nvme_strerror(errno));
- goto close_dev;
+ return err;
}
}
if (cfg.racqa > 7) {
nvme_show_error("invalid racqa:%d", cfg.racqa);
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
struct nvme_resv_acquire_args args = {
@@ -7074,9 +6772,6 @@ static int resv_acquire(int argc, char **argv, struct command *cmd, struct plugi
else
printf("NVME Reservation Acquire success\n");
-close_dev:
- dev_close(dev);
-ret:
return err;
}
@@ -7088,7 +6783,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";
- struct nvme_dev *dev;
+
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
int err;
struct config {
@@ -7108,37 +6804,33 @@ static int resv_register(int argc, char **argv, struct command *cmd, struct plug
.cptpl = false,
};
- OPT_ARGS(opts) = {
- OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired),
- OPT_SUFFIX("crkey", 'c', &cfg.crkey, crkey),
- OPT_SUFFIX("nrkey", 'k', &cfg.nrkey, nrkey),
- OPT_BYTE("rrega", 'r', &cfg.rrega, rrega),
- OPT_BYTE("cptpl", 'p', &cfg.cptpl, cptpl),
- OPT_FLAG("iekey", 'i', &cfg.iekey, iekey),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired),
+ OPT_SUFFIX("crkey", 'c', &cfg.crkey, crkey),
+ OPT_SUFFIX("nrkey", 'k', &cfg.nrkey, nrkey),
+ OPT_BYTE("rrega", 'r', &cfg.rrega, rrega),
+ OPT_BYTE("cptpl", 'p', &cfg.cptpl, cptpl),
+ OPT_FLAG("iekey", 'i', &cfg.iekey, iekey));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
if (!cfg.namespace_id) {
err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
nvme_show_error("get-namespace-id: %s", nvme_strerror(errno));
- goto close_dev;
+ return err;
}
}
if (cfg.cptpl > 3) {
nvme_show_error("invalid cptpl:%d", cfg.cptpl);
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
if (cfg.rrega > 7) {
nvme_show_error("invalid rrega:%d", cfg.rrega);
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
struct nvme_resv_register_args args = {
@@ -7161,9 +6853,6 @@ static int resv_register(int argc, char **argv, struct command *cmd, struct plug
else
printf("NVME Reservation success\n");
-close_dev:
- dev_close(dev);
-ret:
return err;
}
@@ -7178,7 +6867,8 @@ static int resv_release(int argc, char **argv, struct command *cmd, struct plugi
"Exclusive Access, all registrants on the namespace except\n"
"the issuing controller are notified.";
const char *rrela = "reservation release action";
- struct nvme_dev *dev;
+
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
int err;
struct config {
@@ -7197,30 +6887,27 @@ static int resv_release(int argc, char **argv, struct command *cmd, struct plugi
.iekey = 0,
};
- OPT_ARGS(opts) = {
- OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_desired),
- OPT_SUFFIX("crkey", 'c', &cfg.crkey, crkey),
- OPT_BYTE("rtype", 't', &cfg.rtype, rtype),
- OPT_BYTE("rrela", 'a', &cfg.rrela, rrela),
- OPT_FLAG("iekey", 'i', &cfg.iekey, iekey),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_desired),
+ OPT_SUFFIX("crkey", 'c', &cfg.crkey, crkey),
+ OPT_BYTE("rtype", 't', &cfg.rtype, rtype),
+ OPT_BYTE("rrela", 'a', &cfg.rrela, rrela),
+ OPT_FLAG("iekey", 'i', &cfg.iekey, iekey));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
if (!cfg.namespace_id) {
err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
nvme_show_error("get-namespace-id: %s", nvme_strerror(errno));
- goto close_dev;
+ return err;
}
}
if (cfg.rrela > 7) {
nvme_show_error("invalid rrela:%d", cfg.rrela);
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
struct nvme_resv_release_args args = {
@@ -7242,9 +6929,6 @@ static int resv_release(int argc, char **argv, struct command *cmd, struct plugi
else
printf("NVME Reservation Release success\n");
-close_dev:
- dev_close(dev);
-ret:
return err;
}
@@ -7257,16 +6941,15 @@ static int resv_report(int argc, char **argv, struct command *cmd, struct plugin
const char *numd = "number of dwords to transfer";
const char *eds = "request extended data structure";
- struct nvme_resv_status *status;
+ _cleanup_free_ struct nvme_resv_status *status = NULL;
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
enum nvme_print_flags flags;
- struct nvme_dev *dev;
int err, size;
struct config {
__u32 namespace_id;
__u32 numd;
__u8 eds;
- char *output_format;
bool raw_binary;
};
@@ -7274,27 +6957,23 @@ static int resv_report(int argc, char **argv, struct command *cmd, struct plugin
.namespace_id = 0,
.numd = 0,
.eds = false,
- .output_format = "normal",
.raw_binary = false,
};
- OPT_ARGS(opts) = {
- OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired),
- OPT_UINT("numd", 'd', &cfg.numd, numd),
- OPT_FLAG("eds", 'e', &cfg.eds, eds),
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_dump),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired),
+ OPT_UINT("numd", 'd', &cfg.numd, numd),
+ OPT_FLAG("eds", 'e', &cfg.eds, eds),
+ OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_dump));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
- err = flags = validate_output_format(cfg.output_format);
+ err = validate_output_format(output_format_val, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
- goto close_dev;
+ return err;
}
if (cfg.raw_binary)
@@ -7304,7 +6983,7 @@ static int resv_report(int argc, char **argv, struct command *cmd, struct plugin
err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
nvme_show_error("get-namespace-id: %s", nvme_strerror(errno));
- goto close_dev;
+ return err;
}
}
@@ -7315,12 +6994,9 @@ static int resv_report(int argc, char **argv, struct command *cmd, struct plugin
size = (cfg.numd + 1) << 2;
- if (posix_memalign((void **)&status, getpagesize(), size)) {
- nvme_show_error("No memory for resv report:%d", size);
- err = -ENOMEM;
- goto close_dev;
- }
- memset(status, 0, size);
+ status = nvme_alloc(size);
+ if (!status)
+ return -ENOMEM;
struct nvme_resv_report_args args = {
.args_size = sizeof(args),
@@ -7339,10 +7015,7 @@ static int resv_report(int argc, char **argv, struct command *cmd, struct plugin
nvme_show_status(err);
else
nvme_show_error("reservation report: %s", nvme_strerror(errno));
- free(status);
-close_dev:
- dev_close(dev);
-ret:
+
return err;
}
@@ -7357,20 +7030,21 @@ unsigned long long elapsed_utime(struct timeval start_time,
static int submit_io(int opcode, char *command, const char *desc, int argc, char **argv)
{
struct timeval start_time, end_time;
- void *buffer, *mbuffer = NULL;
+ void *buffer;
+ _cleanup_free_ void *mbuffer = NULL;
int err = 0;
- int dfd, mfd;
- int flags = opcode & 1 ? O_RDONLY : O_WRONLY | O_CREAT;
+ _cleanup_file_ int dfd = -1, mfd = -1;
+ int flags;
int mode = 0644;
__u16 control = 0, nblocks = 0;
__u32 dsmgmt = 0;
- int logical_block_size = 0;
+ unsigned int logical_block_size = 0;
unsigned long long buffer_size = 0, mbuffer_size = 0;
- bool huge;
- struct nvme_id_ns ns;
- struct nvme_nvm_id_ns nvm_ns;
+ _cleanup_huge_ struct nvme_mem_huge mh = { 0, };
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
+ _cleanup_free_ struct nvme_nvm_id_ns *nvm_ns = NULL;
+ _cleanup_free_ struct nvme_id_ns *ns = NULL;
__u8 lba_index, ms = 0, sts = 0, pif = 0;
- struct nvme_dev *dev;
const char *start_block_addr = "64-bit addr of first block to access";
const char *data_size = "size of data in bytes";
@@ -7436,40 +7110,38 @@ static int submit_io(int opcode, char *command, const char *desc, int argc, char
.force = false,
};
- OPT_ARGS(opts) = {
- OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired),
- OPT_SUFFIX("start-block", 's', &cfg.start_block, start_block_addr),
- OPT_SHRT("block-count", 'c', &cfg.block_count, block_count),
- OPT_SUFFIX("data-size", 'z', &cfg.data_size, data_size),
- OPT_SUFFIX("metadata-size", 'y', &cfg.metadata_size, metadata_size),
- OPT_SUFFIX("ref-tag", 'r', &cfg.ref_tag, ref_tag),
- OPT_FILE("data", 'd', &cfg.data, data),
- OPT_FILE("metadata", 'M', &cfg.metadata, metadata),
- OPT_BYTE("prinfo", 'p', &cfg.prinfo, prinfo),
- OPT_SHRT("app-tag-mask", 'm', &cfg.app_tag_mask, app_tag_mask),
- OPT_SHRT("app-tag", 'a', &cfg.app_tag, app_tag),
- OPT_SUFFIX("storage-tag", 'g', &cfg.storage_tag, storage_tag),
- OPT_FLAG("limited-retry", 'l', &cfg.limited_retry, limited_retry_num),
- OPT_FLAG("force-unit-access", 'f', &cfg.force_unit_access, force_unit_access),
- OPT_FLAG("storage-tag-check", 'C', &cfg.storage_tag_check, storage_tag_check),
- OPT_BYTE("dir-type", 'T', &cfg.dtype, dtype_for_write),
- OPT_SHRT("dir-spec", 'S', &cfg.dspec, dspec),
- OPT_BYTE("dsm", 'D', &cfg.dsmgmt, dsm),
- OPT_FLAG("show-command", 'v', &cfg.show, show),
- OPT_FLAG("dry-run", 'w', &cfg.dry_run, dry),
- OPT_FLAG("latency", 't', &cfg.latency, latency),
- OPT_FLAG("force", 0, &cfg.force, force),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired),
+ OPT_SUFFIX("start-block", 's', &cfg.start_block, start_block_addr),
+ OPT_SHRT("block-count", 'c', &cfg.block_count, block_count),
+ OPT_SUFFIX("data-size", 'z', &cfg.data_size, data_size),
+ OPT_SUFFIX("metadata-size", 'y', &cfg.metadata_size, metadata_size),
+ OPT_SUFFIX("ref-tag", 'r', &cfg.ref_tag, ref_tag),
+ OPT_FILE("data", 'd', &cfg.data, data),
+ OPT_FILE("metadata", 'M', &cfg.metadata, metadata),
+ OPT_BYTE("prinfo", 'p', &cfg.prinfo, prinfo),
+ OPT_SHRT("app-tag-mask", 'm', &cfg.app_tag_mask, app_tag_mask),
+ OPT_SHRT("app-tag", 'a', &cfg.app_tag, app_tag),
+ OPT_SUFFIX("storage-tag", 'g', &cfg.storage_tag, storage_tag),
+ OPT_FLAG("limited-retry", 'l', &cfg.limited_retry, limited_retry_num),
+ OPT_FLAG("force-unit-access", 'f', &cfg.force_unit_access, force_unit_access),
+ OPT_FLAG("storage-tag-check", 'C', &cfg.storage_tag_check, storage_tag_check),
+ OPT_BYTE("dir-type", 'T', &cfg.dtype, dtype_for_write),
+ OPT_SHRT("dir-spec", 'S', &cfg.dspec, dspec),
+ OPT_BYTE("dsm", 'D', &cfg.dsmgmt, dsm),
+ OPT_FLAG("show-command", 'V', &cfg.show, show),
+ OPT_FLAG("dry-run", 'w', &cfg.dry_run, dry),
+ OPT_FLAG("latency", 't', &cfg.latency, latency),
+ OPT_FLAG("force", 0, &cfg.force, force));
if (opcode != nvme_cmd_write) {
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
} else {
err = argconfig_parse(argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
err = open_exclusive(&dev, argc, argv, cfg.force);
if (err) {
if (errno == EBUSY) {
@@ -7481,7 +7153,7 @@ static int submit_io(int opcode, char *command, const char *desc, int argc, char
} else {
argconfig_print_help(desc, opts);
}
- goto ret;
+ return err;
}
}
@@ -7489,15 +7161,12 @@ static int submit_io(int opcode, char *command, const char *desc, int argc, char
err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
nvme_show_error("get-namespace-id: %s", nvme_strerror(errno));
- goto close_dev;
+ return err;
}
}
- dfd = mfd = opcode & 1 ? STDIN_FILENO : STDOUT_FILENO;
- if (cfg.prinfo > 0xf) {
- err = -EINVAL;
- goto close_dev;
- }
+ if (cfg.prinfo > 0xf)
+ return err;
dsmgmt = cfg.dsmgmt;
control |= (cfg.prinfo << 10);
@@ -7510,19 +7179,25 @@ static int submit_io(int opcode, char *command, const char *desc, int argc, char
if (cfg.dtype) {
if (cfg.dtype > 0xf) {
nvme_show_error("Invalid directive type, %x", cfg.dtype);
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
control |= cfg.dtype << 4;
dsmgmt |= ((__u32)cfg.dspec) << 16;
}
+ if (opcode & 1) {
+ dfd = mfd = STDIN_FILENO;
+ flags = O_RDONLY;
+ } else {
+ dfd = mfd = STDOUT_FILENO;
+ flags = O_WRONLY | O_CREAT;
+ }
+
if (strlen(cfg.data)) {
dfd = open(cfg.data, flags, mode);
if (dfd < 0) {
nvme_show_perror(cfg.data);
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
}
@@ -7530,19 +7205,40 @@ static int submit_io(int opcode, char *command, const char *desc, int argc, char
mfd = open(cfg.metadata, flags, mode);
if (mfd < 0) {
nvme_show_perror(cfg.metadata);
- err = -EINVAL;
- goto close_dfd;
+ return -EINVAL;
}
}
if (!cfg.data_size) {
nvme_show_error("data size not provided");
- err = -EINVAL;
- goto close_mfd;
+ return -EINVAL;
}
- if (nvme_get_logical_block_size(dev_fd(dev), cfg.namespace_id, &logical_block_size) < 0)
- goto close_mfd;
+ ns = nvme_alloc(sizeof(*ns));
+ if (!ns)
+ return -ENOMEM;
+
+ err = nvme_cli_identify_ns(dev, cfg.namespace_id, ns);
+ if (err > 0) {
+ nvme_show_status(err);
+ return err;
+ } else if (err < 0) {
+ nvme_show_error("identify namespace: %s", nvme_strerror(errno));
+ return err;
+ }
+
+ nvme_id_ns_flbas_to_lbaf_inuse(ns->flbas, &lba_index);
+ logical_block_size = 1 << ns->lbaf[lba_index].ds;
+ ms = ns->lbaf[lba_index].ms;
+ if (NVME_FLBAS_META_EXT(ns->flbas)) {
+ /*
+ * No meta data is transferred for PRACT=1 and MD=8:
+ * 5.2.2.1 Protection Information and Write Commands
+ * 5.2.2.2 Protection Information and Read Commands
+ */
+ if (!(cfg.prinfo == 0x1 && ms == 8))
+ logical_block_size += ms;
+ }
buffer_size = ((long long)cfg.block_count + 1) * logical_block_size;
if (cfg.data_size < buffer_size)
@@ -7550,35 +7246,30 @@ static int submit_io(int opcode, char *command, const char *desc, int argc, char
else
buffer_size = cfg.data_size;
- /* Get the required block count. Note this is a zeroes based value. */
- nblocks = ((buffer_size + (logical_block_size - 1)) / logical_block_size) - 1;
-
- /* Update the data size based on the required block count */
- buffer_size = (nblocks + 1) * logical_block_size;
+ if (argconfig_parse_seen(opts, "block-count")) {
+ /* Use the value provided */
+ nblocks = cfg.block_count;
+ } else {
+ /* Get the required block count. Note this is a zeroes based value. */
+ nblocks = ((buffer_size + (logical_block_size - 1)) / logical_block_size) - 1;
- buffer = nvme_alloc(buffer_size, &huge);
- if (!buffer) {
- err = -ENOMEM;
- goto close_mfd;
+ /* Update the data size based on the required block count */
+ buffer_size = ((unsigned long long)nblocks + 1) * logical_block_size;
}
- if (cfg.metadata_size) {
- err = nvme_cli_identify_ns(dev, cfg.namespace_id, &ns);
- if (err > 0) {
- nvme_show_status(err);
- goto free_buffer;
- } else if (err < 0) {
- nvme_show_error("identify namespace: %s", nvme_strerror(errno));
- goto free_buffer;
- }
+ buffer = nvme_alloc_huge(buffer_size, &mh);
+ if (!buffer)
+ return -ENOMEM;
- nvme_id_ns_flbas_to_lbaf_inuse(ns.flbas, &lba_index);
- ms = ns.lbaf[lba_index].ms;
+ nvm_ns = nvme_alloc(sizeof(*nvm_ns));
+ if (!nvm_ns)
+ return -ENOMEM;
- err = nvme_identify_ns_csi(dev_fd(dev), 1, 0, NVME_CSI_NVM, &nvm_ns);
+ if (cfg.metadata_size) {
+ 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;
+ sts = nvm_ns->elbaf[lba_index] & NVME_NVM_ELBAF_STS_MASK;
+ pif = (nvm_ns->elbaf[lba_index] & NVME_NVM_ELBAF_PIF_MASK) >> 7;
}
mbuffer_size = ((unsigned long long)cfg.block_count + 1) * ms;
@@ -7589,24 +7280,20 @@ static int submit_io(int opcode, char *command, const char *desc, int argc, char
mbuffer_size = cfg.metadata_size;
mbuffer = malloc(mbuffer_size);
- if (!mbuffer) {
- err = -ENOMEM;
- goto free_buffer;
- }
+ if (!mbuffer)
+ return -ENOMEM;
memset(mbuffer, 0, mbuffer_size);
}
- if (invalid_tags(cfg.storage_tag, cfg.ref_tag, sts, pif)) {
- err = -EINVAL;
- goto free_buffer;
- }
+ if (invalid_tags(cfg.storage_tag, cfg.ref_tag, sts, pif))
+ return -EINVAL;
if (opcode & 1) {
err = read(dfd, (void *)buffer, cfg.data_size);
if (err < 0) {
err = -errno;
nvme_show_error("failed to read data buffer from input file %s", strerror(errno));
- goto free_mbuffer;
+ return err;
}
}
@@ -7615,7 +7302,7 @@ static int submit_io(int opcode, char *command, const char *desc, int argc, char
if (err < 0) {
err = -errno;
nvme_show_error("failed to read meta-data buffer from input file %s", strerror(errno));
- goto free_mbuffer;
+ return err;
}
}
@@ -7638,7 +7325,7 @@ static int submit_io(int opcode, char *command, const char *desc, int argc, char
printf("sts : %02x\n", sts);
}
if (cfg.dry_run)
- goto free_mbuffer;
+ return 0;
struct nvme_io_args args = {
.args_size = sizeof(args),
@@ -7683,22 +7370,10 @@ static int submit_io(int opcode, char *command, const char *desc, int argc, char
strerror(errno));
err = -EINVAL;
} else {
- printf("%s: Success\n", command);
+ fprintf(stderr, "%s: Success\n", command);
}
}
-free_mbuffer:
- free(mbuffer);
-free_buffer:
- nvme_free(buffer, huge);
-close_mfd:
- if (strlen(cfg.metadata))
- close(mfd);
-close_dfd:
- close(dfd);
-close_dev:
- dev_close(dev);
-ret:
return err;
}
@@ -7731,9 +7406,9 @@ static int verify_cmd(int argc, char **argv, struct command *cmd, struct plugin
{
__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;
+ _cleanup_free_ struct nvme_nvm_id_ns *nvm_ns = NULL;
+ _cleanup_free_ struct nvme_id_ns *ns = NULL;
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
int err;
const char *desc = "Verify specified logical blocks on the given device.";
@@ -7770,29 +7445,25 @@ static int verify_cmd(int argc, char **argv, struct command *cmd, struct plugin
.storage_tag_check = false,
};
- OPT_ARGS(opts) = {
- OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_desired),
- OPT_SUFFIX("start-block", 's', &cfg.start_block, start_block),
- OPT_SHRT("block-count", 'c', &cfg.block_count, block_count),
- OPT_FLAG("limited-retry", 'l', &cfg.limited_retry, limited_retry),
- OPT_FLAG("force-unit-access", 'f', &cfg.force_unit_access, force_unit_access_verify),
- OPT_BYTE("prinfo", 'p', &cfg.prinfo, prinfo),
- OPT_SUFFIX("ref-tag", 'r', &cfg.ref_tag, ref_tag),
- OPT_SHRT("app-tag", 'a', &cfg.app_tag, app_tag),
- OPT_SHRT("app-tag-mask", 'm', &cfg.app_tag_mask, app_tag_mask),
- OPT_SUFFIX("storage-tag", 'S', &cfg.storage_tag, storage_tag),
- OPT_FLAG("storage-tag-check", 'C', &cfg.storage_tag_check, storage_tag_check),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_desired),
+ OPT_SUFFIX("start-block", 's', &cfg.start_block, start_block),
+ OPT_SHRT("block-count", 'c', &cfg.block_count, block_count),
+ OPT_FLAG("limited-retry", 'l', &cfg.limited_retry, limited_retry),
+ OPT_FLAG("force-unit-access", 'f', &cfg.force_unit_access, force_unit_access_verify),
+ OPT_BYTE("prinfo", 'p', &cfg.prinfo, prinfo),
+ OPT_SUFFIX("ref-tag", 'r', &cfg.ref_tag, ref_tag),
+ OPT_SHRT("app-tag", 'a', &cfg.app_tag, app_tag),
+ OPT_SHRT("app-tag-mask", 'm', &cfg.app_tag_mask, app_tag_mask),
+ OPT_SUFFIX("storage-tag", 'S', &cfg.storage_tag, storage_tag),
+ OPT_FLAG("storage-tag-check", 'C', &cfg.storage_tag_check, storage_tag_check));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
- if (cfg.prinfo > 0xf) {
- err = EINVAL;
- goto close_dev;
- }
+ if (cfg.prinfo > 0xf)
+ return -EINVAL;
control |= (cfg.prinfo << 10);
if (cfg.limited_retry)
@@ -7806,31 +7477,37 @@ static int verify_cmd(int argc, char **argv, struct command *cmd, struct plugin
err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
nvme_show_error("get-namespace-id: %s", nvme_strerror(errno));
- goto close_dev;
+ return err;
}
}
- err = nvme_cli_identify_ns(dev, cfg.namespace_id, &ns);
+ ns = nvme_alloc(sizeof(*ns));
+ if (!ns)
+ return -ENOMEM;
+
+ err = nvme_cli_identify_ns(dev, cfg.namespace_id, ns);
if (err < 0) {
nvme_show_error("identify namespace: %s", nvme_strerror(errno));
- goto close_dev;
+ return err;
} else if (err) {
nvme_show_status(err);
- goto close_dev;
+ return err;
}
+ nvm_ns = nvme_alloc(sizeof(*nvm_ns));
+ if (!nvm_ns)
+ return -ENOMEM;
+
err = nvme_identify_ns_csi(dev_fd(dev), cfg.namespace_id, 0,
- NVME_CSI_NVM, &nvm_ns);
+ 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;
- pif = (nvm_ns.elbaf[lba_index] & NVME_NVM_ELBAF_PIF_MASK) >> 7;
+ nvme_id_ns_flbas_to_lbaf_inuse(ns->flbas, &lba_index);
+ sts = nvm_ns->elbaf[lba_index] & NVME_NVM_ELBAF_STS_MASK;
+ pif = (nvm_ns->elbaf[lba_index] & NVME_NVM_ELBAF_PIF_MASK) >> 7;
}
- if (invalid_tags(cfg.storage_tag, cfg.ref_tag, sts, pif)) {
- err = -EINVAL;
- goto close_dev;
- }
+ if (invalid_tags(cfg.storage_tag, cfg.ref_tag, sts, pif))
+ return -EINVAL;
struct nvme_io_args args = {
.args_size = sizeof(args),
@@ -7856,9 +7533,6 @@ static int verify_cmd(int argc, char **argv, struct command *cmd, struct plugin
else
printf("NVME Verify Success\n");
-close_dev:
- dev_close(dev);
-ret:
return err;
}
@@ -7872,8 +7546,9 @@ static int sec_recv(int argc, char **argv, struct command *cmd, struct plugin *p
"the same security protocol.";
const char *size = "size of buffer (prints to stdout on success)";
const char *al = "allocation length (cf. SPC-4)";
- struct nvme_dev *dev;
- void *sec_buf = NULL;
+
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
+ _cleanup_free_ void *sec_buf = NULL;
int err;
struct config {
@@ -7896,27 +7571,23 @@ static int sec_recv(int argc, char **argv, struct command *cmd, struct plugin *p
.raw_binary = false,
};
- OPT_ARGS(opts) = {
- OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_desired),
- OPT_UINT("size", 'x', &cfg.size, size),
- OPT_BYTE("nssf", 'N', &cfg.nssf, nssf),
- OPT_BYTE("secp", 'p', &cfg.secp, secp),
- OPT_SHRT("spsp", 's', &cfg.spsp, spsp),
- OPT_UINT("al", 't', &cfg.al, al),
- OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_dump),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_desired),
+ OPT_UINT("size", 'x', &cfg.size, size),
+ OPT_BYTE("nssf", 'N', &cfg.nssf, nssf),
+ OPT_BYTE("secp", 'p', &cfg.secp, secp),
+ OPT_SHRT("spsp", 's', &cfg.spsp, spsp),
+ OPT_UINT("al", 't', &cfg.al, al),
+ OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_dump));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
if (cfg.size) {
- if (posix_memalign(&sec_buf, getpagesize(), cfg.size)) {
- nvme_show_error("No memory for security size:%d", cfg.size);
- err = -ENOMEM;
- goto close_dev;
- }
+ sec_buf = nvme_alloc(sizeof(*sec_buf));
+ if (!sec_buf)
+ return -ENOMEM;
}
struct nvme_security_receive_args args = {
@@ -7946,11 +7617,6 @@ static int sec_recv(int argc, char **argv, struct command *cmd, struct plugin *p
d_raw((unsigned char *)sec_buf, cfg.size);
}
- free(sec_buf);
-
-close_dev:
- dev_close(dev);
-ret:
return err;
}
@@ -7967,10 +7633,10 @@ static int get_lba_status(int argc, char **argv, struct command *cmd,
const char *rl =
"Range Length(RL) specifies the length of the range of contiguous LBAs beginning at SLBA";
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
+ _cleanup_free_ void *buf = NULL;
enum nvme_print_flags flags;
unsigned long buf_len;
- struct nvme_dev *dev;
- void *buf;
int err;
struct config {
@@ -7980,7 +7646,6 @@ static int get_lba_status(int argc, char **argv, struct command *cmd,
__u8 atype;
__u16 rl;
__u32 timeout;
- char *output_format;
};
struct config cfg = {
@@ -7990,42 +7655,35 @@ static int get_lba_status(int argc, char **argv, struct command *cmd,
.atype = 0,
.rl = 0,
.timeout = 0,
- .output_format = "normal",
};
- OPT_ARGS(opts) = {
- OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_desired),
- OPT_SUFFIX("start-lba", 's', &cfg.slba, slba),
- OPT_UINT("max-dw", 'm', &cfg.mndw, mndw),
- OPT_BYTE("action", 'a', &cfg.atype, atype),
- OPT_SHRT("range-len", 'l', &cfg.rl, rl),
- OPT_UINT("timeout", 't', &cfg.timeout, timeout),
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_desired),
+ OPT_SUFFIX("start-lba", 's', &cfg.slba, slba),
+ OPT_UINT("max-dw", 'm', &cfg.mndw, mndw),
+ OPT_BYTE("action", 'a', &cfg.atype, atype),
+ OPT_SHRT("range-len", 'l', &cfg.rl, rl),
+ OPT_UINT("timeout", 't', &cfg.timeout, timeout));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto err;
+ return err;
- err = flags = validate_output_format(cfg.output_format);
+ err = validate_output_format(output_format_val, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
- goto close_dev;
+ return err;
}
if (!cfg.atype) {
nvme_show_error("action type (--action) has to be given");
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
buf_len = (cfg.mndw + 1) * 4;
- buf = calloc(1, buf_len);
- if (!buf) {
- err = -ENOMEM;
- goto close_dev;
- }
+ buf = nvme_alloc(buf_len);
+ if (!buf)
+ return -ENOMEM;
struct nvme_get_lba_status_args args = {
.args_size = sizeof(args),
@@ -8046,10 +7704,7 @@ static int get_lba_status(int argc, char **argv, struct command *cmd,
nvme_show_status(err);
else
nvme_show_error("get lba status: %s", nvme_strerror(errno));
- free(buf);
-close_dev:
- dev_close(dev);
-err:
+
return err;
}
@@ -8066,7 +7721,7 @@ 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";
- struct nvme_dev *dev;
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
int err = -1;
__u32 result;
@@ -8084,22 +7739,19 @@ static int capacity_mgmt(int argc, char **argv, struct command *cmd, struct plug
.dw12 = 0,
};
- OPT_ARGS(opts) = {
- OPT_BYTE("operation", 'o', &cfg.operation, operation),
- OPT_SHRT("element-id", 'i', &cfg.element_id, element_id),
- OPT_UINT("cap-lower", 'l', &cfg.dw11, cap_lower),
- OPT_UINT("cap-upper", 'u', &cfg.dw12, cap_upper),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_BYTE("operation", 'O', &cfg.operation, operation),
+ OPT_SHRT("element-id", 'i', &cfg.element_id, element_id),
+ OPT_UINT("cap-lower", 'l', &cfg.dw11, cap_lower),
+ OPT_UINT("cap-upper", 'u', &cfg.dw12, cap_upper));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
if (cfg.operation > 0xf) {
nvme_show_error("invalid operation field: %u", cfg.operation);
- err = -1;
- goto close_dev;
+ return -1;
}
struct nvme_capacity_mgmt_args args = {
@@ -8125,9 +7777,6 @@ static int capacity_mgmt(int argc, char **argv, struct command *cmd, struct plug
nvme_show_error("capacity management: %s", nvme_strerror(errno));
}
-close_dev:
- dev_close(dev);
-ret:
return err;
}
@@ -8137,10 +7786,10 @@ static int dir_receive(int argc, char **argv, struct command *cmd, struct plugin
const char *nsr = "namespace stream requested";
enum nvme_print_flags flags = NORMAL;
- struct nvme_dev *dev;
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
+ _cleanup_free_ void *buf = NULL;
__u32 result;
__u32 dw12 = 0;
- void *buf = NULL;
int err;
struct config {
@@ -8165,21 +7814,19 @@ static int dir_receive(int argc, char **argv, struct command *cmd, struct plugin
.human_readable = false,
};
- OPT_ARGS(opts) = {
- OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired),
- OPT_UINT("data-len", 'l', &cfg.data_len, buf_len),
- OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_directive),
- OPT_BYTE("dir-type", 'D', &cfg.dtype, dtype),
- OPT_SHRT("dir-spec", 'S', &cfg.dspec, dspec_w_dtype),
- OPT_BYTE("dir-oper", 'O', &cfg.doper, doper),
- OPT_SHRT("req-resource", 'r', &cfg.nsr, nsr),
- OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable_directive),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired),
+ OPT_UINT("data-len", 'l', &cfg.data_len, buf_len),
+ OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_directive),
+ OPT_BYTE("dir-type", 'D', &cfg.dtype, dtype),
+ OPT_SHRT("dir-spec", 'S', &cfg.dspec, dspec_w_dtype),
+ OPT_BYTE("dir-oper", 'O', &cfg.doper, doper),
+ OPT_SHRT("req-resource", 'r', &cfg.nsr, nsr),
+ OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable_directive));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
if (cfg.human_readable)
flags |= VERBOSE;
@@ -8195,8 +7842,7 @@ static int dir_receive(int argc, char **argv, struct command *cmd, struct plugin
break;
default:
nvme_show_error("invalid directive operations for Identify Directives");
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
break;
case NVME_DIRECTIVE_DTYPE_STREAMS:
@@ -8214,22 +7860,18 @@ static int dir_receive(int argc, char **argv, struct command *cmd, struct plugin
break;
default:
nvme_show_error("invalid directive operations for Streams Directives");
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
break;
default:
nvme_show_error("invalid directive type");
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
if (cfg.data_len) {
- if (posix_memalign(&buf, getpagesize(), cfg.data_len)) {
- err = -ENOMEM;
- goto close_dev;
- }
- memset(buf, 0, cfg.data_len);
+ buf = nvme_alloc(cfg.data_len);
+ if (!buf)
+ return -ENOMEM;
}
struct nvme_directive_recv_args args = {
@@ -8254,10 +7896,6 @@ static int dir_receive(int argc, char **argv, struct command *cmd, struct plugin
else if (err < 0)
nvme_show_error("dir-receive: %s", nvme_strerror(errno));
- free(buf);
-close_dev:
- dev_close(dev);
-ret:
return err;
}
@@ -8289,7 +7927,7 @@ 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,\n"
"then no UUID index is specified";
- struct nvme_dev *dev;
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
int err = -1;
struct config {
@@ -8308,39 +7946,33 @@ static int lockdown_cmd(int argc, char **argv, struct command *cmd, struct plugi
.uuid = 0,
};
- OPT_ARGS(opts) = {
- OPT_BYTE("ofi", 'o', &cfg.ofi, ofi_desc),
- OPT_BYTE("ifc", 'f', &cfg.ifc, ifc_desc),
- OPT_BYTE("prhbt", 'p', &cfg.prhbt, prhbt_desc),
- OPT_BYTE("scp", 's', &cfg.scp, scp_desc),
- OPT_BYTE("uuid", 'U', &cfg.uuid, uuid_desc),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_BYTE("ofi", 'O', &cfg.ofi, ofi_desc),
+ OPT_BYTE("ifc", 'f', &cfg.ifc, ifc_desc),
+ OPT_BYTE("prhbt", 'p', &cfg.prhbt, prhbt_desc),
+ OPT_BYTE("scp", 's', &cfg.scp, scp_desc),
+ OPT_BYTE("uuid", 'U', &cfg.uuid, uuid_desc));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
/* check for input argument limit */
if (cfg.ifc > 3) {
nvme_show_error("invalid interface settings:%d", cfg.ifc);
- err = -1;
- goto close_dev;
+ return -1;
}
if (cfg.prhbt > 1) {
nvme_show_error("invalid prohibit settings:%d", cfg.prhbt);
- err = -1;
- goto close_dev;
+ return -1;
}
if (cfg.scp > 15) {
nvme_show_error("invalid scope settings:%d", cfg.scp);
- err = -1;
- goto close_dev;
+ return -1;
}
if (cfg.uuid > 127) {
nvme_show_error("invalid UUID index settings:%d", cfg.uuid);
- err = -1;
- goto close_dev;
+ return -1;
}
struct nvme_lockdown_args args = {
@@ -8362,9 +7994,6 @@ static int lockdown_cmd(int argc, char **argv, struct command *cmd, struct plugi
else
printf("Lockdown Command is Successful\n");
-close_dev:
- dev_close(dev);
-ret:
return err;
}
@@ -8416,13 +8045,15 @@ static int passthru(int argc, char **argv, bool admin,
const char *wr = "set dataflow direction to send";
const char *prefill = "prefill buffers with known byte-value, default 0";
+ _cleanup_huge_ struct nvme_mem_huge mh = { 0, };
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
+ _cleanup_file_ int dfd = -1, mfd = -1;
int flags;
int mode = 0644;
- void *data = NULL, *mdata = NULL;
- int err = 0, dfd, mfd;
- struct nvme_dev *dev;
+ void *data = NULL;
+ _cleanup_free_ void *mdata = NULL;
+ int err = 0;
__u32 result;
- bool huge = false;
const char *cmd_name = NULL;
struct timeval start_time, end_time;
@@ -8453,50 +8084,44 @@ static int passthru(int argc, char **argv, bool admin,
.latency = false,
};
- OPT_ARGS(opts) = {
- OPT_BYTE("opcode", 'o', &cfg.opcode, opcode),
- OPT_BYTE("flags", 'f', &cfg.flags, cflags),
- OPT_BYTE("prefill", 'p', &cfg.prefill, prefill),
- OPT_SHRT("rsvd", 'R', &cfg.rsvd, rsvd),
- OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_desired),
- OPT_UINT("data-len", 'l', &cfg.data_len, data_len),
- OPT_UINT("metadata-len", 'm', &cfg.metadata_len, metadata_len),
- OPT_UINT("timeout", 't', &cfg.timeout, timeout),
- OPT_UINT("cdw2", '2', &cfg.cdw2, cdw2),
- OPT_UINT("cdw3", '3', &cfg.cdw3, cdw3),
- OPT_UINT("cdw10", '4', &cfg.cdw10, cdw10),
- OPT_UINT("cdw11", '5', &cfg.cdw11, cdw11),
- OPT_UINT("cdw12", '6', &cfg.cdw12, cdw12),
- OPT_UINT("cdw13", '7', &cfg.cdw13, cdw13),
- OPT_UINT("cdw14", '8', &cfg.cdw14, cdw14),
- OPT_UINT("cdw15", '9', &cfg.cdw15, cdw15),
- OPT_FILE("input-file", 'i', &cfg.input_file, input),
- OPT_FILE("metadata", 'M', &cfg.metadata, metadata),
- OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_dump),
- OPT_FLAG("show-command", 's', &cfg.show_command, show),
- OPT_FLAG("dry-run", 'd', &cfg.dry_run, dry),
- OPT_FLAG("read", 'r', &cfg.read, re),
- OPT_FLAG("write", 'w', &cfg.write, wr),
- OPT_FLAG("latency", 'T', &cfg.latency, latency),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_BYTE("opcode", 'O', &cfg.opcode, opcode),
+ OPT_BYTE("flags", 'f', &cfg.flags, cflags),
+ OPT_BYTE("prefill", 'p', &cfg.prefill, prefill),
+ OPT_SHRT("rsvd", 'R', &cfg.rsvd, rsvd),
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_desired),
+ OPT_UINT("data-len", 'l', &cfg.data_len, data_len),
+ OPT_UINT("metadata-len", 'm', &cfg.metadata_len, metadata_len),
+ OPT_UINT("timeout", 't', &cfg.timeout, timeout),
+ OPT_UINT("cdw2", '2', &cfg.cdw2, cdw2),
+ OPT_UINT("cdw3", '3', &cfg.cdw3, cdw3),
+ OPT_UINT("cdw10", '4', &cfg.cdw10, cdw10),
+ OPT_UINT("cdw11", '5', &cfg.cdw11, cdw11),
+ OPT_UINT("cdw12", '6', &cfg.cdw12, cdw12),
+ OPT_UINT("cdw13", '7', &cfg.cdw13, cdw13),
+ OPT_UINT("cdw14", '8', &cfg.cdw14, cdw14),
+ OPT_UINT("cdw15", '9', &cfg.cdw15, cdw15),
+ OPT_FILE("input-file", 'i', &cfg.input_file, input),
+ OPT_FILE("metadata", 'M', &cfg.metadata, metadata),
+ OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_dump),
+ OPT_FLAG("show-command", 's', &cfg.show_command, show),
+ OPT_FLAG("dry-run", 'd', &cfg.dry_run, dry),
+ OPT_FLAG("read", 'r', &cfg.read, re),
+ OPT_FLAG("write", 'w', &cfg.write, wr),
+ OPT_FLAG("latency", 'T', &cfg.latency, latency));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
- if (cfg.opcode & 0x01)
+ if (cfg.opcode & 0x01) {
cfg.write = true;
-
- if (cfg.opcode & 0x02)
- cfg.read = true;
-
- if (cfg.write) {
flags = O_RDONLY;
dfd = mfd = STDIN_FILENO;
}
- if (cfg.read) {
+ if (cfg.opcode & 0x02) {
+ cfg.read = true;
flags = O_WRONLY | O_CREAT;
dfd = mfd = STDOUT_FILENO;
}
@@ -8505,8 +8130,7 @@ static int passthru(int argc, char **argv, bool admin,
dfd = open(cfg.input_file, flags, mode);
if (dfd < 0) {
nvme_show_perror(cfg.input_file);
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
}
@@ -8514,23 +8138,20 @@ static int passthru(int argc, char **argv, bool admin,
mfd = open(cfg.metadata, flags, mode);
if (mfd < 0) {
nvme_show_perror(cfg.metadata);
- err = -EINVAL;
- goto close_dfd;
+ return -EINVAL;
}
}
if (cfg.metadata_len) {
mdata = malloc(cfg.metadata_len);
- if (!mdata) {
- err = -ENOMEM;
- goto close_mfd;
- }
+ if (!mdata)
+ return -ENOMEM;
if (cfg.write) {
if (read(mfd, mdata, cfg.metadata_len) < 0) {
err = -errno;
nvme_show_perror("failed to read metadata write buffer");
- goto free_metadata;
+ return err;
}
} else {
memset(mdata, cfg.prefill, cfg.metadata_len);
@@ -8538,22 +8159,19 @@ static int passthru(int argc, char **argv, bool admin,
}
if (cfg.data_len) {
- data = nvme_alloc(cfg.data_len, &huge);
- if (!data) {
- err = -ENOMEM;
- goto free_metadata;
- }
+ data = nvme_alloc_huge(cfg.data_len, &mh);
+ if (!data)
+ return -ENOMEM;
memset(data, cfg.prefill, cfg.data_len);
if (!cfg.read && !cfg.write) {
nvme_show_error("data direction not given");
- err = -EINVAL;
- goto free_data;
+ return -EINVAL;
} else if (cfg.write) {
if (read(dfd, data, cfg.data_len) < 0) {
err = -errno;
nvme_show_error("failed to read write buffer %s", strerror(errno));
- goto free_data;
+ return err;
}
}
}
@@ -8578,7 +8196,7 @@ static int passthru(int argc, char **argv, bool admin,
printf("timeout_ms : %08x\n", cfg.timeout);
}
if (cfg.dry_run)
- goto free_data;
+ return 0;
gettimeofday(&start_time, NULL);
@@ -8615,24 +8233,12 @@ static int passthru(int argc, char **argv, bool admin,
} else if (err) {
nvme_show_status(err);
} else {
- printf("%s Command %s is Success and result: 0x%08x\n", admin ? "Admin" : "IO",
- strcmp(cmd_name, "Unknown") ? cmd_name : "Vendor Specific", result);
+ fprintf(stderr, "%s Command %s is Success and result: 0x%08x\n", admin ? "Admin" : "IO",
+ strcmp(cmd_name, "Unknown") ? cmd_name : "Vendor Specific", result);
if (cfg.read)
passthru_print_read_output(cfg, data, dfd, mdata, mfd, err);
}
-free_metadata:
- free(mdata);
-free_data:
- nvme_free(data, huge);
-close_dfd:
- if (strlen(cfg.input_file))
- close(dfd);
-close_mfd:
- if (cfg.metadata && strlen(cfg.metadata))
- close(mfd);
-close_dev:
- dev_close(dev);
-ret:
+
return err;
}
@@ -8718,13 +8324,11 @@ static int gen_dhchap_key(int argc, char **argv, struct command *command, struct
.hmac = 0,
};
- OPT_ARGS(opts) = {
- OPT_STR("secret", 's', &cfg.secret, secret),
- OPT_UINT("key-length", 'l', &cfg.key_len, key_len),
- OPT_STR("nqn", 'n', &cfg.nqn, nqn),
- OPT_UINT("hmac", 'm', &cfg.hmac, hmac),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_STR("secret", 's', &cfg.secret, secret),
+ OPT_UINT("key-length", 'l', &cfg.key_len, key_len),
+ OPT_STR("nqn", 'n', &cfg.nqn, nqn),
+ OPT_UINT("hmac", 'm', &cfg.hmac, hmac));
err = argconfig_parse(argc, argv, desc, opts);
if (err)
@@ -8837,10 +8441,8 @@ static int check_dhchap_key(int argc, char **argv, struct command *command, stru
.key = NULL,
};
- OPT_ARGS(opts) = {
- OPT_STR("key", 'k', &cfg.key, key),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_STR("key", 'k', &cfg.key, key));
err = argconfig_parse(argc, argv, desc, opts);
if (err)
@@ -8915,6 +8517,7 @@ static int gen_tls_key(int argc, char **argv, struct command *command, struct pl
const char *secret =
"Optional secret (in hexadecimal characters) to be used for the TLS key.";
const char *hmac = "HMAC function to use for the retained key (1 = SHA-256, 2 = SHA-384).";
+ const char *identity = "TLS identity version to use (0 = NVMe TCP 1.0c, 1 = NVMe TCP 2.0";
const char *hostnqn = "Host NQN for the retained key.";
const char *subsysnqn = "Subsystem NQN for the retained key.";
const char *keyring = "Keyring for the retained key.";
@@ -8935,6 +8538,7 @@ static int gen_tls_key(int argc, char **argv, struct command *command, struct pl
char *subsysnqn;
char *secret;
unsigned int hmac;
+ unsigned int identity;
bool insert;
};
@@ -8945,31 +8549,45 @@ static int gen_tls_key(int argc, char **argv, struct command *command, struct pl
.subsysnqn = NULL,
.secret = NULL,
.hmac = 1,
+ .identity = 0,
.insert = false,
};
- OPT_ARGS(opts) = {
- OPT_STR("keyring", 'k', &cfg.keyring, keyring),
- OPT_STR("keytype", 't', &cfg.keytype, keytype),
- OPT_STR("hostnqn", 'n', &cfg.hostnqn, hostnqn),
- OPT_STR("subsysnqn", 'c', &cfg.subsysnqn, subsysnqn),
- OPT_STR("secret", 's', &cfg.secret, secret),
- OPT_UINT("hmac", 'm', &cfg.hmac, hmac),
- OPT_FLAG("insert", 'i', &cfg.insert, insert),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_STR("keyring", 'k', &cfg.keyring, keyring),
+ OPT_STR("keytype", 't', &cfg.keytype, keytype),
+ OPT_STR("hostnqn", 'n', &cfg.hostnqn, hostnqn),
+ OPT_STR("subsysnqn", 'c', &cfg.subsysnqn, subsysnqn),
+ OPT_STR("secret", 's', &cfg.secret, secret),
+ OPT_UINT("hmac", 'm', &cfg.hmac, hmac),
+ OPT_UINT("identity", 'I', &cfg.identity, identity),
+ OPT_FLAG("insert", 'i', &cfg.insert, insert));
err = argconfig_parse(argc, argv, desc, opts);
if (err)
return err;
- if (cfg.hmac < 1 || cfg.hmac > 3) {
+ if (cfg.hmac < 1 || cfg.hmac > 2) {
nvme_show_error("Invalid HMAC identifier %u", cfg.hmac);
return -EINVAL;
}
- if (cfg.insert && !cfg.subsysnqn) {
- nvme_show_error("No subsystem NQN specified");
+ if (cfg.identity > 1) {
+ nvme_show_error("Invalid TLS identity version %u",
+ cfg.identity);
return -EINVAL;
}
+ if (cfg.insert) {
+ if (!cfg.subsysnqn) {
+ nvme_show_error("No subsystem NQN specified");
+ return -EINVAL;
+ }
+ if (!cfg.hostnqn) {
+ cfg.hostnqn = nvmf_hostnqn_from_file();
+ if (!cfg.hostnqn) {
+ nvme_show_error("Failed to read host NQN");
+ return -EINVAL;
+ }
+ }
+ }
if (cfg.hmac == 2)
key_len = 48;
@@ -8988,7 +8606,7 @@ static int gen_tls_key(int argc, char **argv, struct command *command, struct pl
nvme_show_error("Invalid secret '%s'", cfg.secret);
return -EINVAL;
}
- if (i >= key_len) {
+ if (i >= key_len * 2) {
fprintf(stderr, "Skipping excess secret bytes\n");
break;
}
@@ -9000,30 +8618,18 @@ static int gen_tls_key(int argc, char **argv, struct command *command, struct pl
}
}
- if (cfg.hostnqn && !cfg.subsysnqn) {
- nvme_show_error("Need to specify subsystem NQN to insert a TLS key");
- return -EINVAL;
- }
- if (cfg.subsysnqn) {
- if (!cfg.hostnqn) {
- cfg.hostnqn = nvmf_hostnqn_from_file();
- if (!cfg.hostnqn) {
- nvme_show_error("Failed to read host NQN");
- return -EINVAL;
- }
- }
-
- tls_key = nvme_insert_tls_key(cfg.keyring, cfg.keytype, cfg.hostnqn, cfg.subsysnqn,
- cfg.hmac, raw_secret, key_len);
+ if (cfg.insert) {
+ tls_key = nvme_insert_tls_key_versioned(cfg.keyring,
+ cfg.keytype, cfg.hostnqn,
+ cfg.subsysnqn, cfg.identity,
+ cfg.hmac, raw_secret, key_len);
if (tls_key < 0) {
nvme_show_error("Failed to insert key, error %d", errno);
return -errno;
}
- if (cfg.insert) {
- printf("Inserted TLS key %08x\n", (unsigned int)tls_key);
- return 0;
- }
+ printf("Inserted TLS key %08x\n", (unsigned int)tls_key);
+ return 0;
}
crc = crc32(crc, raw_secret, key_len);
raw_secret[key_len++] = crc & 0xff;
@@ -9042,10 +8648,12 @@ static int check_tls_key(int argc, char **argv, struct command *command, struct
{
const char *desc = "Check a TLS key for NVMe PSK Interchange format.\n";
const char *keydata = "TLS key (in PSK Interchange format) to be validated.";
+ const char *identity = "TLS identity version to use (0 = NVMe TCP 1.0c, 1 = NVMe TCP 2.0)";
const char *hostnqn = "Host NQN for the retained key.";
const char *subsysnqn = "Subsystem NQN for the retained key.";
const char *keyring = "Keyring for the retained key.";
const char *keytype = "Key type of the retained key.";
+ const char *insert = "Insert retained key into the keyring.";
unsigned char decoded_key[128];
unsigned int decoded_len;
@@ -9054,11 +8662,13 @@ static int check_tls_key(int argc, char **argv, struct command *command, struct
int err = 0, hmac;
long tls_key;
struct config {
- char *keyring;
- char *keytype;
- char *hostnqn;
- char *subsysnqn;
- char *keydata;
+ char *keyring;
+ char *keytype;
+ char *hostnqn;
+ char *subsysnqn;
+ char *keydata;
+ unsigned int identity;
+ bool insert;
};
struct config cfg = {
@@ -9067,16 +8677,18 @@ static int check_tls_key(int argc, char **argv, struct command *command, struct
.hostnqn = NULL,
.subsysnqn = NULL,
.keydata = NULL,
+ .identity = 0,
+ .insert = false,
};
- OPT_ARGS(opts) = {
- OPT_STR("keyring", 'k', &cfg.keyring, keyring),
- OPT_STR("keytype", 't', &cfg.keytype, keytype),
- OPT_STR("hostnqn", 'n', &cfg.hostnqn, hostnqn),
- OPT_STR("subsysnqn", 'c', &cfg.subsysnqn, subsysnqn),
- OPT_STR("keydata", 'd', &cfg.keydata, keydata),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_STR("keyring", 'k', &cfg.keyring, keyring),
+ OPT_STR("keytype", 't', &cfg.keytype, keytype),
+ OPT_STR("hostnqn", 'n', &cfg.hostnqn, hostnqn),
+ OPT_STR("subsysnqn", 'c', &cfg.subsysnqn, subsysnqn),
+ OPT_STR("keydata", 'd', &cfg.keydata, keydata),
+ OPT_UINT("identity", 'I', &cfg.identity, identity),
+ OPT_FLAG("insert", 'i', &cfg.insert, insert));
err = argconfig_parse(argc, argv, desc, opts);
if (err)
@@ -9086,6 +8698,11 @@ static int check_tls_key(int argc, char **argv, struct command *command, struct
nvme_show_error("No key data");
return -EINVAL;
}
+ if (cfg.identity > 1) {
+ nvme_show_error("Invalid TLS identity version %u",
+ cfg.identity);
+ return -EINVAL;
+ }
if (sscanf(cfg.keydata, "NVMeTLSkey-1:%02x:*s", &hmac) != 1) {
nvme_show_error("Invalid key '%s'", cfg.keydata);
@@ -9109,6 +8726,18 @@ static int check_tls_key(int argc, char **argv, struct command *command, struct
return -EINVAL;
}
+ if (cfg.subsysnqn) {
+ if (cfg.insert && !cfg.hostnqn) {
+ cfg.hostnqn = nvmf_hostnqn_from_file();
+ if (!cfg.hostnqn) {
+ nvme_show_error("Failed to read host NQN");
+ return -EINVAL;
+ }
+ }
+ } else if (cfg.insert || cfg.identity == 1) {
+ nvme_show_error("Need to specify a subsystem NQN");
+ return -EINVAL;
+ }
err = base64_decode(cfg.keydata + 16, strlen(cfg.keydata) - 17, decoded_key);
if (err < 0) {
nvme_show_error("Base64 decoding failed (%s, error %d)", cfg.keydata + 16, err);
@@ -9129,23 +8758,28 @@ static int check_tls_key(int argc, char **argv, struct command *command, struct
nvme_show_error("CRC mismatch (key %08x, crc %08x)", key_crc, crc);
return -EINVAL;
}
- if (cfg.subsysnqn) {
- if (!cfg.hostnqn) {
- cfg.hostnqn = nvmf_hostnqn_from_file();
- if (!cfg.hostnqn) {
- nvme_show_error("Failed to read host NQN");
- return -EINVAL;
- }
- }
-
- tls_key = nvme_insert_tls_key(cfg.keyring, cfg.keytype, cfg.hostnqn, cfg.subsysnqn,
- hmac, decoded_key, decoded_len);
+ if (cfg.insert) {
+ tls_key = nvme_insert_tls_key_versioned(cfg.keyring,
+ cfg.keytype, cfg.hostnqn,
+ cfg.subsysnqn, cfg.identity,
+ hmac, decoded_key, decoded_len);
if (tls_key < 0) {
nvme_show_error("Failed to insert key, error %d", errno);
return -errno;
}
} else {
- printf("Key is valid (HMAC %d, length %d, CRC %08x)\n", hmac, decoded_len, crc);
+ char *tls_id;
+
+ tls_id = nvme_generate_tls_key_identity(cfg.hostnqn,
+ cfg.subsysnqn, cfg.identity,
+ hmac, decoded_key, decoded_len);
+ if (!tls_id) {
+ nvme_show_error("Failed to generated identity, error %d",
+ errno);
+ return -errno;
+ }
+ printf("%s\n", tls_id);
+ free(tls_id);
}
return 0;
}
@@ -9160,35 +8794,27 @@ static int show_topology_cmd(int argc, char **argv, struct command *command, str
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()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_FMT("ranking", 'r', &cfg.ranking, ranking));
err = argconfig_parse(argc, argv, desc, opts);
if (err)
return err;
- err = flags = validate_output_format(cfg.output_format);
+ err = validate_output_format(output_format_val, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
return err;
}
- if (cfg.verbose)
+ if (argconfig_parse_seen(opts, "verbose"))
flags |= VERBOSE;
if (!strcmp(cfg.ranking, "namespace")) {
@@ -9200,7 +8826,7 @@ static int show_topology_cmd(int argc, char **argv, struct command *command, str
return -EINVAL;
}
- r = nvme_create_root(stderr, map_log_level(cfg.verbose, false));
+ r = nvme_create_root(stderr, map_log_level(!!(flags & VERBOSE), false));
if (!r) {
nvme_show_error("Failed to create topology root: %s", nvme_strerror(errno));
return -errno;
@@ -9282,12 +8908,12 @@ static int nvme_mi(int argc, char **argv, __u8 admin_opcode, const char *desc)
int mode = 0644;
void *data = NULL;
int err = 0;
- bool send = admin_opcode == nvme_admin_nvme_mi_send ? true : false;
- int fd = send ? STDIN_FILENO : STDOUT_FILENO;
- int flags = send ? O_RDONLY : O_WRONLY | O_CREAT;
- struct nvme_dev *dev;
+ bool send;
+ _cleanup_file_ int fd = -1;
+ int flags;
+ _cleanup_huge_ struct nvme_mem_huge mh = { 0, };
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
__u32 result;
- bool huge = false;
struct config {
__u8 opcode;
@@ -9309,41 +8935,47 @@ static int nvme_mi(int argc, char **argv, __u8 admin_opcode, const char *desc)
.input_file = "",
};
- OPT_ARGS(opts) = {
- OPT_BYTE("opcode", 'o', &cfg.opcode, opcode),
- OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_desired),
- OPT_UINT("data-len", 'l', &cfg.data_len, data_len),
- OPT_UINT("nmimt", 'm', &cfg.nmimt, nmimt),
- OPT_UINT("nmd0", '0', &cfg.nmd0, nmd0),
- OPT_UINT("nmd1", '1', &cfg.nmd1, nmd1),
- OPT_FILE("input-file", 'i', &cfg.input_file, input),
- OPT_END()
- };
+ NVME_ARGS(opts, cfg,
+ OPT_BYTE("opcode", 'O', &cfg.opcode, opcode),
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_desired),
+ OPT_UINT("data-len", 'l', &cfg.data_len, data_len),
+ OPT_UINT("nmimt", 'm', &cfg.nmimt, nmimt),
+ OPT_UINT("nmd0", '0', &cfg.nmd0, nmd0),
+ OPT_UINT("nmd1", '1', &cfg.nmd1, nmd1),
+ OPT_FILE("input-file", 'i', &cfg.input_file, input));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
- goto ret;
+ return err;
+
+ if (admin_opcode == nvme_admin_nvme_mi_send) {
+ flags = O_RDONLY;
+ fd = STDIN_FILENO;
+ send = true;
+ } else {
+ flags = O_WRONLY | O_CREAT;
+ fd = STDOUT_FILENO;
+ send = false;
+ }
if (strlen(cfg.input_file)) {
fd = open(cfg.input_file, flags, mode);
if (fd < 0) {
nvme_show_perror(cfg.input_file);
- err = -EINVAL;
- goto close_dev;
+ return -EINVAL;
}
}
if (cfg.data_len) {
- data = nvme_alloc(cfg.data_len, &huge);
- if (!data) {
- err = -ENOMEM;
- goto close_fd;
- }
+ data = nvme_alloc_huge(cfg.data_len, &mh);
+ if (!data)
+ return -ENOMEM;
+
if (send) {
if (read(fd, data, cfg.data_len) < 0) {
err = -errno;
nvme_show_error("failed to read write buffer %s", strerror(errno));
- goto free_data;
+ return err;
}
}
}
@@ -9369,14 +9001,6 @@ static int nvme_mi(int argc, char **argv, __u8 admin_opcode, const char *desc)
}
}
-free_data:
- nvme_free(data, huge);
-close_fd:
- if (strlen(cfg.input_file))
- close(fd);
-close_dev:
- dev_close(dev);
-ret:
return err;
}