summaryrefslogtreecommitdiffstats
path: root/nvme.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-08-05 08:38:36 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-08-05 08:38:36 +0000
commit3c0f1ed2ea093dd0d3e8ba70f3c9963e66321f87 (patch)
tree2020852fabf5e530c687d41e36ddc5c453b0c9ed /nvme.c
parentAdding upstream version 2.9.1. (diff)
downloadnvme-cli-3c0f1ed2ea093dd0d3e8ba70f3c9963e66321f87.tar.xz
nvme-cli-3c0f1ed2ea093dd0d3e8ba70f3c9963e66321f87.zip
Adding upstream version 2.10.upstream/2.10
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'nvme.c')
-rw-r--r--nvme.c738
1 files changed, 383 insertions, 355 deletions
diff --git a/nvme.c b/nvme.c
index 4a65c4b..20dfee6 100644
--- a/nvme.c
+++ b/nvme.c
@@ -34,6 +34,7 @@
#include <inttypes.h>
#include <locale.h>
#include <stdio.h>
+#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -88,7 +89,6 @@ struct passthru_config {
__u32 namespace_id;
__u32 data_len;
__u32 metadata_len;
- __u32 timeout;
__u32 cdw2;
__u32 cdw3;
__u32 cdw10;
@@ -163,14 +163,6 @@ struct set_reg_config {
__u32 pmrmscu;
};
-#define NVME_ARGS(n, ...) \
- struct argconfig_commandline_options n[] = { \
- OPT_INCR("verbose", 'v', &verbose_level, 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 = {
@@ -193,6 +185,9 @@ static struct program nvme = {
};
const char *output_format = "Output format: normal|json|binary";
+const char *timeout = "timeout value, in milliseconds";
+const char *verbose = "Increase output verbosity";
+
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";
@@ -235,10 +230,8 @@ static const char *secp = "security protocol (cf. SPC-4)";
static const char *spsp = "security-protocol-specific (cf. SPC-4)";
static const char *start_block = "64-bit LBA of first block to access";
static const char *storage_tag = "storage tag for end-to-end PI";
-static const char *timeout = "timeout value, in milliseconds";
static const char *uuid_index = "UUID index";
static const char *uuid_index_specify = "specify uuid index";
-static const char *verbose = "Increase output verbosity";
static const char dash[51] = {[0 ... 49] = '=', '\0'};
static const char space[51] = {[0 ... 49] = ' ', '\0'};
static const char *offset = "offset of the requested register";
@@ -258,8 +251,9 @@ static const char *pmrctl = "PMRCTL=0xe04 register offset";
static const char *pmrmscl = "PMRMSCL=0xe14 register offset";
static const char *pmrmscu = "PMRMSCU=0xe18 register offset";
-static char *output_format_val = "normal";
-int verbose_level;
+struct nvme_config nvme_cfg = {
+ .output_format = "normal",
+};
static void *mmap_registers(struct nvme_dev *dev, bool writable);
@@ -423,13 +417,29 @@ static int get_dev(struct nvme_dev **dev, int argc, char **argv, int flags)
return ret;
devname = argv[optind];
+ errno = ENXIO;
if (!strncmp(devname, "mctp:", strlen("mctp:")))
ret = open_dev_mi_mctp(dev, devname);
else
ret = open_dev_direct(dev, devname, flags);
- return ret != 0 ? -errno : 0;
+ return ret ? -errno : 0;
+}
+
+static int parse_args(int argc, char *argv[], const char *desc,
+ struct argconfig_commandline_options *opts)
+{
+ int ret;
+
+ ret = argconfig_parse(argc, argv, desc, opts);
+ if (ret)
+ return ret;
+
+ log_level = map_log_level(nvme_cfg.verbose, false);
+ nvme_init_default_logging(stderr, log_level, false, false);
+
+ return 0;
}
int parse_and_open(struct nvme_dev **dev, int argc, char **argv,
@@ -438,15 +448,13 @@ int parse_and_open(struct nvme_dev **dev, int argc, char **argv,
{
int ret;
- ret = argconfig_parse(argc, argv, desc, opts);
+ ret = parse_args(argc, argv, desc, opts);
if (ret)
return ret;
ret = get_dev(dev, argc, argv, O_RDONLY);
if (ret < 0)
argconfig_print_help(desc, opts);
- else
- log_level = map_log_level(verbose_level, false);
return ret;
}
@@ -462,9 +470,9 @@ int open_exclusive(struct nvme_dev **dev, int argc, char **argv,
return get_dev(dev, argc, argv, flags);
}
-int validate_output_format(const char *format, enum nvme_print_flags *flags)
+int validate_output_format(const char *format, nvme_print_flags_t *flags)
{
- enum nvme_print_flags f;
+ nvme_print_flags_t f;
if (!format)
return -EINVAL;
@@ -485,9 +493,9 @@ int validate_output_format(const char *format, enum nvme_print_flags *flags)
bool nvme_is_output_format_json(void)
{
- enum nvme_print_flags flags;
+ nvme_print_flags_t flags;
- if (validate_output_format(output_format_val, &flags))
+ if (validate_output_format(nvme_cfg.output_format, &flags))
return false;
return flags == JSON;
@@ -516,7 +524,7 @@ static int get_smart_log(int argc, char **argv, struct command *cmd, struct plug
_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;
+ nvme_print_flags_t flags;
int err = -1;
struct config {
@@ -540,7 +548,7 @@ static int get_smart_log(int argc, char **argv, struct command *cmd, struct plug
if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
return err;
@@ -549,7 +557,7 @@ static int get_smart_log(int argc, char **argv, struct command *cmd, struct plug
if (cfg.raw_binary)
flags = BINARY;
- if (cfg.human_readable)
+ if (cfg.human_readable || argconfig_parse_seen(opts, "verbose"))
flags |= VERBOSE;
smart_log = nvme_alloc(sizeof(*smart_log));
@@ -578,10 +586,10 @@ static int get_ana_log(int argc, char **argv, struct command *cmd,
_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;
- enum nvme_print_flags flags;
- enum nvme_log_ana_lsp lsp;
+ _cleanup_free_ struct nvme_ana_log *ana_log = NULL;
+ size_t max_ana_log_len;
+ __u32 ana_log_len;
+ nvme_print_flags_t flags;
int err = -1;
struct config {
@@ -599,7 +607,7 @@ static int get_ana_log(int argc, char **argv, struct command *cmd,
if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
return err;
@@ -616,19 +624,19 @@ static int get_ana_log(int argc, char **argv, struct command *cmd,
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);
+ max_ana_log_len = nvme_get_ana_log_len_from_id_ctrl(ctrl, cfg.groups);
+ ana_log_len = max_ana_log_len;
+ if (ana_log_len < max_ana_log_len) {
+ nvme_show_error("ANA log length %zu too large", max_ana_log_len);
+ return -ENOMEM;
+ }
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);
+ err = nvme_cli_get_ana_log_atomic(dev, cfg.groups, true, 10,
+ ana_log, &ana_log_len);
if (!err)
nvme_show_ana_log(ana_log, dev->name, ana_log_len, flags);
else if (err > 0)
@@ -703,7 +711,10 @@ static int get_log_telemetry_ctrl(struct nvme_dev *dev, bool rae, size_t size,
err = nvme_cli_get_log_telemetry_ctrl(dev, rae, 0, size, log);
if (err) {
free(log);
- return -errno;
+ if (errno)
+ return -errno;
+ else
+ return err;
}
*buf = log;
@@ -723,7 +734,10 @@ static int get_log_telemetry_host(struct nvme_dev *dev, size_t size,
err = nvme_cli_get_log_telemetry_host(dev, 0, size, log);
if (err) {
free(log);
- return -errno;
+ if (errno)
+ return -errno;
+ else
+ return err;
}
*buf = log;
@@ -743,8 +757,12 @@ static int __create_telemetry_log_host(struct nvme_dev *dev,
return -ENOMEM;
err = nvme_cli_get_log_create_telemetry_host(dev, log);
- if (err)
- return -errno;
+ if (err) {
+ if (errno)
+ return -errno;
+ else
+ return err;
+ }
err = parse_telemetry_da(dev, da, log, size);
if (err)
@@ -838,7 +856,7 @@ static int get_telemetry_log(int argc, char **argv, struct command *cmd,
_cleanup_free_ struct nvme_telemetry_log *log = NULL;
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
- _cleanup_file_ int output = -1;
+ _cleanup_fd_ int output = -1;
int err = 0;
size_t total_size;
__u8 *data_ptr = NULL;
@@ -944,7 +962,7 @@ static int get_endurance_log(int argc, char **argv, struct command *cmd, struct
_cleanup_free_ struct nvme_endurance_group_log *endurance_log = NULL;
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
- enum nvme_print_flags flags;
+ nvme_print_flags_t flags;
int err;
struct config {
@@ -962,7 +980,7 @@ static int get_endurance_log(int argc, char **argv, struct command *cmd, struct
if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
return err;
@@ -1017,7 +1035,7 @@ static int get_effects_log(int argc, char **argv, struct command *cmd, struct pl
void *bar = NULL;
int err = -1;
- enum nvme_print_flags flags;
+ nvme_print_flags_t flags;
struct config {
bool human_readable;
@@ -1040,7 +1058,7 @@ static int get_effects_log(int argc, char **argv, struct command *cmd, struct pl
if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
return err;
@@ -1049,7 +1067,7 @@ static int get_effects_log(int argc, char **argv, struct command *cmd, struct pl
if (cfg.raw_binary)
flags = BINARY;
- if (cfg.human_readable)
+ if (cfg.human_readable || argconfig_parse_seen(opts, "verbose"))
flags |= VERBOSE;
list_head_init(&log_pages);
@@ -1068,7 +1086,7 @@ static int get_effects_log(int argc, char **argv, struct command *cmd, struct pl
.fd = dev_fd(dev),
.offset = NVME_REG_CAP,
.value = &cap,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .timeout = nvme_cfg.timeout,
};
err = nvme_get_property(&args);
if (err)
@@ -1107,7 +1125,7 @@ static int get_supported_log_pages(int argc, char **argv, struct command *cmd,
_cleanup_free_ struct nvme_supported_log_pages *supports = NULL;
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
- enum nvme_print_flags flags;
+ nvme_print_flags_t flags;
int err = -1;
NVME_ARGS(opts);
@@ -1116,7 +1134,7 @@ static int get_supported_log_pages(int argc, char **argv, struct command *cmd,
if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
return err;
@@ -1151,7 +1169,7 @@ static int get_error_log(int argc, char **argv, struct command *cmd, struct plug
_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;
+ nvme_print_flags_t flags;
int err = -1;
struct config {
@@ -1172,7 +1190,7 @@ static int get_error_log(int argc, char **argv, struct command *cmd, struct plug
if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
return err;
@@ -1219,7 +1237,7 @@ static int get_fw_log(int argc, char **argv, struct command *cmd, struct plugin
_cleanup_free_ struct nvme_firmware_slot *fw_log = NULL;
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
- enum nvme_print_flags flags;
+ nvme_print_flags_t flags;
int err;
struct config {
@@ -1237,7 +1255,7 @@ static int get_fw_log(int argc, char **argv, struct command *cmd, struct plugin
if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
return err;
@@ -1268,7 +1286,7 @@ static int get_changed_ns_list_log(int argc, char **argv, struct command *cmd, s
_cleanup_free_ struct nvme_ns_list *changed_ns_list_log = NULL;
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
- enum nvme_print_flags flags;
+ nvme_print_flags_t flags;
int err;
struct config {
@@ -1286,7 +1304,7 @@ static int get_changed_ns_list_log(int argc, char **argv, struct command *cmd, s
if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
return err;
@@ -1322,7 +1340,7 @@ static int get_pred_lat_per_nvmset_log(int argc, char **argv,
_cleanup_free_ struct nvme_nvmset_predictable_lat_log *plpns_log = NULL;
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
- enum nvme_print_flags flags;
+ nvme_print_flags_t flags;
int err;
struct config {
@@ -1343,7 +1361,7 @@ static int get_pred_lat_per_nvmset_log(int argc, char **argv,
if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
return err;
@@ -1380,7 +1398,7 @@ static int get_pred_lat_event_agg_log(int argc, char **argv,
_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;
+ nvme_print_flags_t flags;
__u32 log_size;
int err;
@@ -1405,7 +1423,7 @@ static int get_pred_lat_event_agg_log(int argc, char **argv,
if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
return err;
@@ -1462,11 +1480,11 @@ static int get_persistent_event_log(int argc, char **argv,
"processing this persistent log page command.";
const char *log_len = "number of bytes to retrieve";
- _cleanup_free_ struct nvme_persistent_event_log *pevent_collected = NULL;
_cleanup_free_ struct nvme_persistent_event_log *pevent = NULL;
+ struct nvme_persistent_event_log *pevent_collected = NULL;
_cleanup_huge_ struct nvme_mem_huge mh = { 0, };
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
- enum nvme_print_flags flags;
+ nvme_print_flags_t flags;
void *pevent_log_info;
int err;
@@ -1491,7 +1509,7 @@ static int get_persistent_event_log(int argc, char **argv,
if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
return err;
@@ -1582,7 +1600,7 @@ static int get_endurance_event_agg_log(int argc, char **argv,
_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;
+ nvme_print_flags_t flags;
__u32 log_size;
int err;
@@ -1607,7 +1625,7 @@ static int get_endurance_event_agg_log(int argc, char **argv,
if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
return err;
@@ -1663,7 +1681,7 @@ static int get_lba_status_log(int argc, char **argv,
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
_cleanup_free_ void *lba_status = NULL;
- enum nvme_print_flags flags;
+ nvme_print_flags_t flags;
__u32 lslplen;
int err;
@@ -1682,7 +1700,7 @@ static int get_lba_status_log(int argc, char **argv,
if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
return err;
@@ -1723,7 +1741,7 @@ static int get_resv_notif_log(int argc, char **argv,
_cleanup_free_ struct nvme_resv_notification_log *resv = NULL;
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
- enum nvme_print_flags flags;
+ nvme_print_flags_t flags;
int err;
NVME_ARGS(opts);
@@ -1732,7 +1750,7 @@ static int get_resv_notif_log(int argc, char **argv,
if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
return err;
@@ -1764,9 +1782,9 @@ static int get_boot_part_log(int argc, char **argv, struct command *cmd, struct
_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;
+ nvme_print_flags_t flags;
int err = -1;
- _cleanup_file_ int output = -1;
+ _cleanup_fd_ int output = -1;
__u32 bpsz = 0;
struct config {
@@ -1787,7 +1805,7 @@ static int get_boot_part_log(int argc, char **argv, struct command *cmd, struct
if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
return err;
@@ -1858,7 +1876,7 @@ static int get_phy_rx_eom_log(int argc, char **argv, struct command *cmd,
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;
+ nvme_print_flags_t flags;
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
int err = -1;
__u8 lsp_tmp;
@@ -1881,7 +1899,7 @@ static int get_phy_rx_eom_log(int argc, char **argv, struct command *cmd,
if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
return err;
@@ -1948,7 +1966,7 @@ static int get_media_unit_stat_log(int argc, char **argv, struct command *cmd,
_cleanup_free_ struct nvme_media_unit_stat_log *mus = NULL;
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
- enum nvme_print_flags flags;
+ nvme_print_flags_t flags;
int err = -1;
struct config {
@@ -1969,7 +1987,7 @@ static int get_media_unit_stat_log(int argc, char **argv, struct command *cmd,
if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
return err;
@@ -2000,7 +2018,7 @@ static int get_supp_cap_config_log(int argc, char **argv, struct command *cmd,
_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;
+ nvme_print_flags_t flags;
int err = -1;
struct config {
@@ -2021,7 +2039,7 @@ static int get_supp_cap_config_log(int argc, char **argv, struct command *cmd,
if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
return err;
@@ -2054,7 +2072,7 @@ static int io_mgmt_send(int argc, char **argv, struct command *cmd, struct plugi
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
_cleanup_free_ void *buf = NULL;
int err = -1;
- int dfd = STDIN_FILENO;
+ _cleanup_fd_ int dfd = STDIN_FILENO;
struct config {
__u16 mos;
@@ -2104,7 +2122,7 @@ static int io_mgmt_send(int argc, char **argv, struct command *cmd, struct plugi
err = read(dfd, buf, cfg.data_len);
if (err < 0) {
nvme_show_perror("read");
- goto close_fd;
+ return err;
}
struct nvme_io_mgmt_send_args args = {
@@ -2115,7 +2133,7 @@ static int io_mgmt_send(int argc, char **argv, struct command *cmd, struct plugi
.mo = cfg.mo,
.data_len = cfg.data_len,
.data = buf,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .timeout = nvme_cfg.timeout,
};
err = nvme_io_mgmt_send(&args);
@@ -2127,9 +2145,6 @@ static int io_mgmt_send(int argc, char **argv, struct command *cmd, struct plugi
else
nvme_show_perror("io-mgmt-send");
-close_fd:
- if (cfg.file)
- close(dfd);
return err;
}
@@ -2141,7 +2156,7 @@ static int io_mgmt_recv(int argc, char **argv, struct command *cmd, struct plugi
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
_cleanup_free_ void *buf = NULL;
int err = -1;
- _cleanup_file_ int dfd = -1;
+ _cleanup_fd_ int dfd = -1;
struct config {
__u16 mos;
@@ -2188,7 +2203,7 @@ static int io_mgmt_recv(int argc, char **argv, struct command *cmd, struct plugi
.mo = cfg.mo,
.data_len = cfg.data_len,
.data = buf,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .timeout = nvme_cfg.timeout,
};
err = nvme_io_mgmt_recv(&args);
@@ -2357,7 +2372,7 @@ static int sanitize_log(int argc, char **argv, struct command *command, struct p
_cleanup_free_ struct nvme_sanitize_log_page *sanitize_log = NULL;
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
- enum nvme_print_flags flags;
+ nvme_print_flags_t flags;
int err;
struct config {
@@ -2381,7 +2396,7 @@ static int sanitize_log(int argc, char **argv, struct command *command, struct p
if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
return err;
@@ -2390,7 +2405,7 @@ static int sanitize_log(int argc, char **argv, struct command *command, struct p
if (cfg.raw_binary)
flags = BINARY;
- if (cfg.human_readable)
+ if (cfg.human_readable || argconfig_parse_seen(opts, "verbose"))
flags |= VERBOSE;
sanitize_log = nvme_alloc(sizeof(*sanitize_log));
@@ -2415,7 +2430,7 @@ static int get_fid_support_effects_log(int argc, char **argv, struct command *cm
_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;
+ nvme_print_flags_t flags;
int err = -1;
struct config {
@@ -2433,13 +2448,13 @@ static int get_fid_support_effects_log(int argc, char **argv, struct command *cm
if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
return err;
}
- if (cfg.human_readable)
+ if (cfg.human_readable || argconfig_parse_seen(opts, "verbose"))
flags |= VERBOSE;
fid_support_log = nvme_alloc(sizeof(*fid_support_log));
@@ -2464,7 +2479,7 @@ static int get_mi_cmd_support_effects_log(int argc, char **argv, struct command
_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;
+ nvme_print_flags_t flags;
int err = -1;
struct config {
@@ -2482,13 +2497,13 @@ static int get_mi_cmd_support_effects_log(int argc, char **argv, struct command
if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
return err;
}
- if (cfg.human_readable)
+ if (cfg.human_readable || argconfig_parse_seen(opts, "verbose"))
flags |= VERBOSE;
mi_cmd_support_log = nvme_alloc(sizeof(*mi_cmd_support_log));
@@ -2514,7 +2529,7 @@ static int list_ctrl(int argc, char **argv, struct command *cmd, struct plugin *
_cleanup_free_ struct nvme_ctrl_list *cntlist = NULL;
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
- enum nvme_print_flags flags;
+ nvme_print_flags_t flags;
int err;
struct config {
@@ -2535,7 +2550,7 @@ static int list_ctrl(int argc, char **argv, struct command *cmd, struct plugin *
if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
return err;
@@ -2570,7 +2585,7 @@ static int list_ns(int argc, char **argv, struct command *cmd, struct plugin *pl
_cleanup_free_ struct nvme_ns_list *ns_list = NULL;
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
- enum nvme_print_flags flags;
+ nvme_print_flags_t flags;
int err;
struct config {
@@ -2594,7 +2609,7 @@ static int list_ns(int argc, char **argv, struct command *cmd, struct plugin *pl
if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0 || (flags != JSON && flags != NORMAL)) {
nvme_show_error("Invalid output format");
return -EINVAL;
@@ -2611,7 +2626,7 @@ static int list_ns(int argc, char **argv, struct command *cmd, struct plugin *pl
struct nvme_identify_args args = {
.args_size = sizeof(args),
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .timeout = nvme_cfg.timeout,
.data = ns_list,
.nsid = cfg.namespace_id - 1.
};
@@ -2643,7 +2658,7 @@ static int id_ns_lba_format(int argc, char **argv, struct command *cmd, struct p
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
_cleanup_free_ struct nvme_id_ns *ns = NULL;
- enum nvme_print_flags flags;
+ nvme_print_flags_t flags;
int err = -1;
struct config {
@@ -2664,7 +2679,7 @@ static int id_ns_lba_format(int argc, char **argv, struct command *cmd, struct p
if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
return err;
@@ -2698,7 +2713,7 @@ static int id_endurance_grp_list(int argc, char **argv, struct command *cmd,
_cleanup_free_ struct nvme_id_endurance_group_list *endgrp_list = NULL;
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
- enum nvme_print_flags flags;
+ nvme_print_flags_t flags;
int err = -1;
struct config {
@@ -2716,7 +2731,7 @@ static int id_endurance_grp_list(int argc, char **argv, struct command *cmd,
if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0 || (flags != JSON && flags != NORMAL)) {
nvme_show_error("invalid output format");
return -EINVAL;
@@ -2752,17 +2767,16 @@ static int delete_ns(int argc, char **argv, struct command *cmd, struct plugin *
struct config {
__u32 namespace_id;
- __u32 timeout;
};
struct config cfg = {
.namespace_id = 0,
- .timeout = 120000,
};
+ nvme_cfg.timeout = 120000;
+
NVME_ARGS(opts,
- OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id),
- OPT_UINT("timeout", 't', &cfg.timeout, timeout));
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
@@ -2776,7 +2790,7 @@ static int delete_ns(int argc, char **argv, struct command *cmd, struct plugin *
}
}
- err = nvme_cli_ns_mgmt_delete(dev, cfg.namespace_id);
+ err = nvme_cli_ns_mgmt_delete(dev, cfg.namespace_id, nvme_cfg.timeout);
if (!err)
printf("%s: Success, deleted nsid:%d\n", cmd->name, cfg.namespace_id);
else if (err > 0)
@@ -2790,9 +2804,9 @@ static int delete_ns(int argc, char **argv, struct command *cmd, struct plugin *
static int nvme_attach_ns(int argc, char **argv, int attach, const char *desc, struct command *cmd)
{
_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];
+ int err, num;
+ __u16 list[NVME_ID_CTRL_LIST_MAX];
const char *namespace_id = "namespace to attach";
const char *cont = "optional comma-sep controller id list";
@@ -2820,7 +2834,8 @@ static int nvme_attach_ns(int argc, char **argv, int attach, const char *desc, s
return -EINVAL;
}
- num = argconfig_parse_comma_sep_array(cfg.cntlist, list, 2047);
+ num = argconfig_parse_comma_sep_array_u16(cfg.cntlist,
+ list, ARRAY_SIZE(list));
if (!num)
fprintf(stderr, "warning: empty controller-id list will result in no actual change in namespace attachment\n");
@@ -2833,14 +2848,7 @@ static int nvme_attach_ns(int argc, char **argv, int attach, const char *desc, s
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, list);
if (attach)
err = nvme_cli_ns_attach_ctrls(dev, cfg.namespace_id,
@@ -2887,15 +2895,15 @@ static int parse_lba_num_si(struct nvme_dev *dev, const char *opt,
_cleanup_free_ struct nvme_id_ctrl *ctrl = NULL;
_cleanup_free_ struct nvme_id_ns *ns = NULL;
__u32 nsid = 1;
+ __u8 lbaf;
unsigned int remainder;
char *endptr;
int err = -EINVAL;
- int i;
int lbas;
struct nvme_identify_args args = {
.args_size = sizeof(args),
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .timeout = nvme_cfg.timeout,
.cns = NVME_IDENTIFY_CNS_NS_ACTIVE_LIST,
.nsid = nsid - 1.
};
@@ -2956,8 +2964,8 @@ static int parse_lba_num_si(struct nvme_dev *dev, const char *opt,
return err;
}
- i = flbas & NVME_NS_FLBAS_LOWER_MASK;
- lbas = (1 << ns->lbaf[i].ds) + ns->lbaf[i].ms;
+ nvme_id_ns_flbas_to_lbaf_inuse(flbas, &lbaf);
+ lbas = (1 << ns->lbaf[lbaf].ds) + ns->lbaf[lbaf].ms;
if (suffix_si_parse(val, &endptr, (uint64_t *)num)) {
nvme_show_error("Expected long suffixed integer argument for '%s-si' but got '%s'!",
@@ -3028,7 +3036,6 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin *
__u16 nvmsetid;
__u16 endgid;
__u64 bs;
- __u32 timeout;
__u8 csi;
__u64 lbstm;
__u16 nphndls;
@@ -3051,7 +3058,6 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin *
.nvmsetid = 0,
.endgid = 0,
.bs = 0x00,
- .timeout = 120000,
.csi = 0,
.lbstm = 0,
.nphndls = 0,
@@ -3064,6 +3070,8 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin *
.phndls = "",
};
+ nvme_cfg.timeout = 120000;
+
NVME_ARGS(opts,
OPT_SUFFIX("nsze", 's', &cfg.nsze, nsze),
OPT_SUFFIX("ncap", 'c', &cfg.ncap, ncap),
@@ -3074,7 +3082,6 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin *
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),
@@ -3220,7 +3227,7 @@ parse_lba:
for (i = 0; i < num_phandle; 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, nvme_cfg.timeout, cfg.csi);
if (!err)
printf("%s: Success, created nsid:%d\n", cmd->name, nsid);
else if (err > 0)
@@ -3269,8 +3276,8 @@ static bool nvme_match_device_filter(nvme_subsystem_t s,
static int list_subsys(int argc, char **argv, struct command *cmd,
struct plugin *plugin)
{
- nvme_root_t r = NULL;
- enum nvme_print_flags flags;
+ _cleanup_nvme_root_ nvme_root_t r = NULL;
+ nvme_print_flags_t flags;
const char *desc = "Retrieve information for subsystems";
nvme_scan_filter_t filter = NULL;
char *devname;
@@ -3279,15 +3286,15 @@ static int list_subsys(int argc, char **argv, struct command *cmd,
NVME_ARGS(opts);
- err = argconfig_parse(argc, argv, desc, opts);
- if (err < 0)
- goto ret;
+ err = parse_args(argc, argv, desc, opts);
+ if (err)
+ return err;
devname = NULL;
if (optind < argc)
devname = basename(argv[optind++]);
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0 || (flags != JSON && flags != NORMAL)) {
nvme_show_error("Invalid output format");
return -EINVAL;
@@ -3303,8 +3310,7 @@ static int list_subsys(int argc, char **argv, struct command *cmd,
nvme_show_error("Failed to scan nvme subsystem for %s", devname);
else
nvme_show_error("Failed to scan nvme subsystem");
- err = -errno;
- goto ret;
+ return -errno;
}
if (devname) {
@@ -3312,41 +3318,36 @@ static int list_subsys(int argc, char **argv, struct command *cmd,
if (sscanf(devname, "nvme%dn%d", &subsys_num, &nsid) != 2) {
nvme_show_error("Invalid device name %s", devname);
- err = -EINVAL;
- goto ret;
+ return -EINVAL;
}
filter = nvme_match_device_filter;
}
err = nvme_scan_topology(r, filter, (void *)devname);
if (err) {
- if (errno != ENOENT)
- nvme_show_error("Failed to scan topology: %s", nvme_strerror(errno));
- goto ret;
+ nvme_show_error("Failed to scan topology: %s", nvme_strerror(errno));
+ return -errno;
}
nvme_show_subsystem_list(r, nsid != NVME_NSID_ALL, flags);
-ret:
- if (r)
- nvme_free_tree(r);
- return err;
+ return 0;
}
static int list(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
const char *desc = "Retrieve basic information for all NVMe namespaces";
- enum nvme_print_flags flags;
- nvme_root_t r;
+ nvme_print_flags_t flags;
+ _cleanup_nvme_root_ nvme_root_t r = NULL;
int err = 0;
NVME_ARGS(opts);
- err = argconfig_parse(argc, argv, desc, opts);
- if (err < 0)
+ err = parse_args(argc, argv, desc, opts);
+ if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0 || (flags != JSON && flags != NORMAL)) {
nvme_show_error("Invalid output format");
return -EINVAL;
@@ -3362,14 +3363,11 @@ static int list(int argc, char **argv, struct command *cmd, struct plugin *plugi
}
err = nvme_scan_topology(r, NULL, NULL);
if (err < 0) {
- if (errno != ENOENT)
- nvme_show_error("Failed to scan topology: %s", nvme_strerror(errno));
- nvme_free_tree(r);
+ nvme_show_error("Failed to scan topology: %s", nvme_strerror(errno));
return err;
}
nvme_show_list_items(r, flags);
- nvme_free_tree(r);
return err;
}
@@ -3386,7 +3384,7 @@ int __id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *plugin,
_cleanup_free_ struct nvme_id_ctrl *ctrl = NULL;
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
- enum nvme_print_flags flags;
+ nvme_print_flags_t flags;
int err;
struct config {
@@ -3410,7 +3408,7 @@ int __id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *plugin,
if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
return err;
@@ -3422,7 +3420,7 @@ int __id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *plugin,
if (cfg.vendor_specific)
flags |= VS;
- if (cfg.human_readable)
+ if (cfg.human_readable || argconfig_parse_seen(opts, "verbose"))
flags |= VERBOSE;
ctrl = nvme_alloc(sizeof(*ctrl));
@@ -3454,7 +3452,7 @@ static int nvm_id_ctrl(int argc, char **argv, struct command *cmd,
_cleanup_free_ struct nvme_id_ctrl_nvm *ctrl_nvm = NULL;
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
- enum nvme_print_flags flags;
+ nvme_print_flags_t flags;
int err = -1;
NVME_ARGS(opts);
@@ -3463,7 +3461,7 @@ static int nvm_id_ctrl(int argc, char **argv, struct command *cmd,
if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
return err;
@@ -3494,7 +3492,7 @@ static int nvm_id_ns(int argc, char **argv, struct command *cmd,
_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;
+ nvme_print_flags_t flags;
int err = -1;
struct config {
@@ -3515,7 +3513,7 @@ static int nvm_id_ns(int argc, char **argv, struct command *cmd,
if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
return err;
@@ -3568,7 +3566,7 @@ static int nvm_id_ns_lba_format(int argc, char **argv, struct command *cmd, stru
_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;
+ nvme_print_flags_t flags;
int err = -1;
struct config {
@@ -3589,7 +3587,7 @@ static int nvm_id_ns_lba_format(int argc, char **argv, struct command *cmd, stru
if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
return err;
@@ -3633,7 +3631,7 @@ static int ns_descs(int argc, char **argv, struct command *cmd, struct plugin *p
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
_cleanup_free_ void *nsdescs = NULL;
- enum nvme_print_flags flags;
+ nvme_print_flags_t flags;
int err;
struct config {
@@ -3654,7 +3652,7 @@ static int ns_descs(int argc, char **argv, struct command *cmd, struct plugin *p
if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
return err;
@@ -3700,7 +3698,7 @@ static int id_ns(int argc, char **argv, struct command *cmd, struct plugin *plug
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
_cleanup_free_ struct nvme_id_ns *ns = NULL;
- enum nvme_print_flags flags;
+ nvme_print_flags_t flags;
int err;
struct config {
@@ -3730,7 +3728,7 @@ static int id_ns(int argc, char **argv, struct command *cmd, struct plugin *plug
if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
return err;
@@ -3742,7 +3740,7 @@ static int id_ns(int argc, char **argv, struct command *cmd, struct plugin *plug
if (cfg.vendor_specific)
flags |= VS;
- if (cfg.human_readable)
+ if (cfg.human_readable || argconfig_parse_seen(opts, "verbose"))
flags |= VERBOSE;
if (!cfg.namespace_id) {
@@ -3781,7 +3779,7 @@ static int cmd_set_independent_id_ns(int argc, char **argv, struct command *cmd,
_cleanup_free_ struct nvme_id_independent_id_ns *ns = NULL;
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
- enum nvme_print_flags flags;
+ nvme_print_flags_t flags;
int err = -1;
struct config {
@@ -3805,7 +3803,7 @@ static int cmd_set_independent_id_ns(int argc, char **argv, struct command *cmd,
if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
return err;
@@ -3814,7 +3812,7 @@ static int cmd_set_independent_id_ns(int argc, char **argv, struct command *cmd,
if (cfg.raw_binary)
flags = BINARY;
- if (cfg.human_readable)
+ if (cfg.human_readable || argconfig_parse_seen(opts, "verbose"))
flags |= VERBOSE;
if (!cfg.namespace_id) {
@@ -3849,7 +3847,7 @@ static int id_ns_granularity(int argc, char **argv, struct command *cmd, struct
_cleanup_free_ struct nvme_id_ns_granularity_list *granularity_list = NULL;
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
- enum nvme_print_flags flags;
+ nvme_print_flags_t flags;
int err;
NVME_ARGS(opts);
@@ -3858,7 +3856,7 @@ static int id_ns_granularity(int argc, char **argv, struct command *cmd, struct
if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
return err;
@@ -3889,7 +3887,7 @@ static int id_nvmset(int argc, char **argv, struct command *cmd, struct plugin *
_cleanup_free_ struct nvme_id_nvmset_list *nvmset = NULL;
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
- enum nvme_print_flags flags;
+ nvme_print_flags_t flags;
int err;
struct config {
@@ -3907,7 +3905,7 @@ static int id_nvmset(int argc, char **argv, struct command *cmd, struct plugin *
if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
return err;
@@ -3938,7 +3936,7 @@ static int id_uuid(int argc, char **argv, struct command *cmd, struct plugin *pl
_cleanup_free_ struct nvme_id_uuid_list *uuid_list = NULL;
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
- enum nvme_print_flags flags;
+ nvme_print_flags_t flags;
int err;
struct config {
@@ -3959,7 +3957,7 @@ static int id_uuid(int argc, char **argv, struct command *cmd, struct plugin *pl
if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
return err;
@@ -3968,7 +3966,7 @@ static int id_uuid(int argc, char **argv, struct command *cmd, struct plugin *pl
if (cfg.raw_binary)
flags = BINARY;
- if (cfg.human_readable)
+ if (cfg.human_readable || argconfig_parse_seen(opts, "verbose"))
flags |= VERBOSE;
uuid_list = nvme_alloc(sizeof(*uuid_list));
@@ -4038,7 +4036,7 @@ static int id_domain(int argc, char **argv, struct command *cmd, struct plugin *
_cleanup_free_ struct nvme_id_domain_list *id_domain = NULL;
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
- enum nvme_print_flags flags;
+ nvme_print_flags_t flags;
int err;
struct config {
@@ -4056,7 +4054,7 @@ static int id_domain(int argc, char **argv, struct command *cmd, struct plugin *
if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
return err;
@@ -4158,7 +4156,7 @@ static int virtual_mgmt(int argc, char **argv, struct command *cmd, struct plugi
.rt = cfg.rt,
.cntlid = cfg.cntlid,
.nr = cfg.nr,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .timeout = nvme_cfg.timeout,
.result = &result,
};
err = nvme_virtual_mgmt(&args);
@@ -4181,7 +4179,7 @@ static int primary_ctrl_caps(int argc, char **argv, struct command *cmd, struct
_cleanup_free_ struct nvme_primary_ctrl_cap *caps = NULL;
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
- enum nvme_print_flags flags;
+ nvme_print_flags_t flags;
int err;
struct config {
@@ -4202,13 +4200,13 @@ static int primary_ctrl_caps(int argc, char **argv, struct command *cmd, struct
if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
return err;
}
- if (cfg.human_readable)
+ if (cfg.human_readable || argconfig_parse_seen(opts, "verbose"))
flags |= VERBOSE;
caps = nvme_alloc(sizeof(*caps));
@@ -4236,7 +4234,7 @@ static int list_secondary_ctrl(int argc, char **argv, struct command *cmd, struc
_cleanup_free_ struct nvme_secondary_ctrl_list *sc_list = NULL;
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
- enum nvme_print_flags flags;
+ nvme_print_flags_t flags;
int err;
struct config {
@@ -4257,7 +4255,7 @@ static int list_secondary_ctrl(int argc, char **argv, struct command *cmd, struc
if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
return err;
@@ -4458,7 +4456,7 @@ static int device_self_test(int argc, char **argv, struct command *cmd, struct p
.fd = dev_fd(dev),
.nsid = cfg.namespace_id,
.stc = cfg.stc,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .timeout = nvme_cfg.timeout,
.result = NULL,
};
err = nvme_dev_self_test(&args);
@@ -4494,7 +4492,7 @@ static int self_test_log(int argc, char **argv, struct command *cmd, struct plug
_cleanup_free_ struct nvme_self_test_log *log = NULL;
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
- enum nvme_print_flags flags;
+ nvme_print_flags_t flags;
int err;
struct config {
@@ -4512,7 +4510,7 @@ static int self_test_log(int argc, char **argv, struct command *cmd, struct plug
if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
return err;
@@ -4570,7 +4568,7 @@ static int get_feature_id(struct nvme_dev *dev, struct feat_cfg *cfg,
.uuidx = cfg->uuid_index,
.data_len = cfg->data_len,
.data = *buf,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .timeout = nvme_cfg.timeout,
.result = result,
};
return nvme_cli_get_features(dev, &args);
@@ -4617,8 +4615,8 @@ static int get_feature_id_changed(struct nvme_dev *dev, struct feat_cfg cfg,
int err_def = 0;
__u32 result;
__u32 result_def;
- void *buf = NULL;
- void *buf_def = NULL;
+ _cleanup_free_ void *buf = NULL;
+ _cleanup_free_ void *buf_def = NULL;
if (changed)
cfg.sel = 0;
@@ -4637,9 +4635,6 @@ static int get_feature_id_changed(struct nvme_dev *dev, struct feat_cfg cfg,
(buf && buf_def && !strcmp(buf, buf_def)))
get_feature_id_print(cfg, err, result, buf);
- free(buf);
- free(buf_def);
-
return err;
}
@@ -4778,7 +4773,7 @@ static int fw_download_single(struct nvme_dev *dev, void *fw_buf,
.offset = offset,
.data_len = len,
.data = fw_buf,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .timeout = nvme_cfg.timeout,
.result = NULL,
};
@@ -4870,7 +4865,7 @@ static int fw_download(int argc, char **argv, struct command *cmd, struct plugin
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
_cleanup_huge_ struct nvme_mem_huge mh = { 0, };
- _cleanup_file_ int fw_fd = -1;
+ _cleanup_fd_ int fw_fd = -1;
unsigned int fw_size, pos;
int err;
struct stat sb;
@@ -5012,11 +5007,11 @@ static void fw_commit_print_mud(struct nvme_dev *dev, __u32 result)
if (result & 0x1)
printf("Detected an overlapping firmware/boot partition image update command\n"
- "sequence due to processing a command from a Management Endpoint");
+ "sequence due to processing a command from an Admin SQ on a controller\n");
if (result >> 1 & 0x1)
printf("Detected an overlapping firmware/boot partition image update command\n"
- "sequence due to processing a command from an Admin SQ on a controller");
+ "sequence due to processing a command from a Management Endpoint\n");
}
static int fw_commit(int argc, char **argv, struct command *cmd, struct plugin *plugin)
@@ -5073,7 +5068,7 @@ static int fw_commit(int argc, char **argv, struct command *cmd, struct plugin *
.slot = cfg.slot,
.action = cfg.action,
.bpid = cfg.bpid,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .timeout = nvme_cfg.timeout,
.result = &result,
};
err = nvme_cli_fw_commit(dev, &args);
@@ -5287,7 +5282,7 @@ static int nvme_get_single_property(int fd, struct get_reg_config *cfg, __u64 *v
.fd = fd,
.offset = cfg->offset,
.value = value,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .timeout = nvme_cfg.timeout,
};
err = nvme_get_property(&args);
@@ -5358,7 +5353,7 @@ static void *mmap_registers(struct nvme_dev *dev, bool writable)
sprintf(path, "/sys/class/nvme/%s/device/resource0", dev->name);
fd = open(path, writable ? O_RDWR : O_RDONLY);
if (fd < 0) {
- if (log_level >= LOG_DEBUG)
+ if (log_level >= LOG_INFO)
nvme_show_error("%s did not find a pci resource, open failed %s",
dev->name, strerror(errno));
return NULL;
@@ -5366,9 +5361,12 @@ static void *mmap_registers(struct nvme_dev *dev, bool writable)
membase = mmap(NULL, getpagesize(), prot, MAP_SHARED, fd, 0);
if (membase == MAP_FAILED) {
- if (log_level >= LOG_DEBUG) {
- fprintf(stderr, "%s failed to map. ", dev->name);
- fprintf(stderr, "Did your kernel enable CONFIG_IO_STRICT_DEVMEM?\n");
+ if (log_level >= LOG_INFO) {
+ fprintf(stderr, "Failed to map registers to userspace.\n\n"
+ "Did your kernel enable CONFIG_IO_STRICT_DEVMEM?\n"
+ "You can disable this feature with command line argument\n\n"
+ "\tio_memory=relaxed\n\n"
+ "Also ensure secure boot is disabled.\n\n");
}
membase = NULL;
}
@@ -5385,7 +5383,7 @@ static int show_registers(int argc, char **argv, struct command *cmd, struct plu
"show info in readable format in case of output_format == normal";
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
- enum nvme_print_flags flags;
+ nvme_print_flags_t flags;
bool fabrics = false;
void *bar;
int err;
@@ -5401,13 +5399,13 @@ static int show_registers(int argc, char **argv, struct command *cmd, struct plu
if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
return err;
}
- if (cfg.human_readable)
+ if (cfg.human_readable || argconfig_parse_seen(opts, "verbose"))
flags |= VERBOSE;
bar = mmap_registers(dev, false);
@@ -5509,7 +5507,7 @@ static int get_register_properties(int fd, void **pbar, struct get_reg_config *c
.args_size = sizeof(args),
.fd = fd,
.value = &value,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .timeout = nvme_cfg.timeout,
};
size = offset + get_reg_size(offset);
@@ -5585,7 +5583,7 @@ bool nvme_is_ctrl_reg(int offset)
}
static bool get_register_offset(void *bar, bool fabrics, struct get_reg_config *cfg,
- enum nvme_print_flags flags)
+ nvme_print_flags_t flags)
{
bool offset_matched = cfg->offset >= 0;
int offset;
@@ -5632,7 +5630,7 @@ static int get_register(int argc, char **argv, struct command *cmd, struct plugi
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
int err;
- enum nvme_print_flags flags;
+ nvme_print_flags_t flags;
bool fabrics = false;
void *bar;
@@ -5677,13 +5675,13 @@ static int get_register(int argc, char **argv, struct command *cmd, struct plugi
if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
return err;
}
- if (cfg.human_readable)
+ if (cfg.human_readable || argconfig_parse_seen(opts, "verbose"))
flags |= VERBOSE;
bar = mmap_registers(dev, false);
@@ -5718,7 +5716,7 @@ static int nvme_set_single_property(int fd, int offset, uint64_t value)
.fd = fd,
.offset = offset,
.value = value,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .timeout = nvme_cfg.timeout,
.result = NULL,
};
int err = nvme_set_property(&args);
@@ -6076,7 +6074,7 @@ static int format_cmd(int argc, char **argv, struct command *cmd, struct plugin
"Can also be used to change LBAF to change the namespaces reported physical block format.";
const char *lbaf = "LBA format to apply (required)";
const char *ses = "[0-2]: secure erase";
- const char *pil = "[0-1]: protection info location last/first 8 bytes of metadata";
+ const char *pil = "[0-1]: protection info location last/first bytes of metadata";
const char *pi = "[0-3]: protection info off/Type 1/Type 2/Type 3";
const char *ms = "[0-1]: extended format off/on";
const char *reset = "Automatically reset the controller after successful format";
@@ -6092,7 +6090,6 @@ static int format_cmd(int argc, char **argv, struct command *cmd, struct plugin
struct config {
__u32 namespace_id;
- __u32 timeout;
__u8 lbaf;
__u8 ses;
__u8 pi;
@@ -6105,7 +6102,6 @@ static int format_cmd(int argc, char **argv, struct command *cmd, struct plugin
struct config cfg = {
.namespace_id = 0,
- .timeout = 600000,
.lbaf = 0xff,
.ses = 0,
.pi = 0,
@@ -6116,9 +6112,10 @@ static int format_cmd(int argc, char **argv, struct command *cmd, struct plugin
.bs = 0,
};
+ nvme_cfg.timeout = 600000;
+
NVME_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),
@@ -6128,7 +6125,7 @@ static int format_cmd(int argc, char **argv, struct command *cmd, struct plugin
OPT_FLAG("force", 0, &cfg.force, force),
OPT_SUFFIX("block-size", 'b', &cfg.bs, bs));
- err = argconfig_parse(argc, argv, desc, opts);
+ err = parse_args(argc, argv, desc, opts);
if (err)
return err;
@@ -6269,13 +6266,13 @@ static int format_cmd(int argc, char **argv, struct command *cmd, struct plugin
struct nvme_format_nvm_args args = {
.args_size = sizeof(args),
.nsid = cfg.namespace_id,
- .lbafu = (cfg.lbaf & NVME_NS_FLBAS_HIGHER_MASK) >> 4,
- .lbaf = cfg.lbaf & NVME_NS_FLBAS_LOWER_MASK,
+ .lbafu = (cfg.lbaf >> 4) & 0x3,
+ .lbaf = cfg.lbaf & 0xf,
.mset = cfg.ms,
.pi = cfg.pi,
.pil = cfg.pil,
.ses = cfg.ses,
- .timeout = cfg.timeout,
+ .timeout = nvme_cfg.timeout,
.result = NULL,
};
err = nvme_cli_format_nvm(dev, &args);
@@ -6342,7 +6339,7 @@ static int set_feature(int argc, char **argv, struct command *cmd, struct plugin
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
_cleanup_free_ void *buf = NULL;
- _cleanup_file_ int ffd = STDIN_FILENO;
+ _cleanup_fd_ int ffd = STDIN_FILENO;
int err;
__u32 result;
@@ -6420,7 +6417,8 @@ static int set_feature(int argc, char **argv, struct command *cmd, struct plugin
* should use the buffer method if the value exceeds this
* length.
*/
- if (cfg.feature_id == NVME_FEAT_FID_TIMESTAMP && cfg.value) {
+ if (cfg.feature_id == NVME_FEAT_FID_TIMESTAMP &&
+ argconfig_parse_seen(opts, "value")) {
memcpy(buf, &cfg.value, NVME_FEAT_TIMESTAMP_DATA_SIZE);
} else {
if (strlen(cfg.file))
@@ -6453,7 +6451,7 @@ static int set_feature(int argc, char **argv, struct command *cmd, struct plugin
.cdw15 = 0,
.data_len = cfg.data_len,
.data = buf,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .timeout = nvme_cfg.timeout,
.result = &result,
};
err = nvme_set_features(&args);
@@ -6492,7 +6490,7 @@ static int sec_send(int argc, char **argv, struct command *cmd, struct plugin *p
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
_cleanup_free_ void *sec_buf = NULL;
- _cleanup_file_ int sec_fd = -1;
+ _cleanup_fd_ int sec_fd = -1;
unsigned int sec_size;
int err;
@@ -6574,7 +6572,7 @@ static int sec_send(int argc, char **argv, struct command *cmd, struct plugin *p
.tl = cfg.tl,
.data_len = cfg.tl,
.data = sec_buf,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .timeout = nvme_cfg.timeout,
.result = NULL,
};
@@ -6601,7 +6599,7 @@ static int dir_send(int argc, char **argv, struct command *cmd, struct plugin *p
_cleanup_free_ void *buf = NULL;
__u32 result;
__u32 dw12 = 0;
- _cleanup_file_ int ffd = STDIN_FILENO;
+ _cleanup_fd_ int ffd = STDIN_FILENO;
int err;
struct config {
@@ -6709,7 +6707,7 @@ static int dir_send(int argc, char **argv, struct command *cmd, struct plugin *p
.cdw12 = dw12,
.data_len = cfg.data_len,
.data = buf,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .timeout = nvme_cfg.timeout,
.result = &result,
};
err = nvme_directive_send(&args);
@@ -6789,7 +6787,7 @@ static int write_uncor(int argc, char **argv, struct command *cmd, struct plugin
.nlb = cfg.block_count,
.control = cfg.dtype << 4,
.dspec = cfg.dspec,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .timeout = nvme_cfg.timeout,
.result = NULL,
};
err = nvme_write_uncorrectable(&args);
@@ -6813,15 +6811,15 @@ static int invalid_tags(__u64 storage_tag, __u64 ref_tag, __u8 sts, __u8 pif)
}
switch (pif) {
- case 0:
+ case NVME_NVM_PIF_16B_GUARD:
if (ref_tag >= (1LL << (32 - sts)))
result = 1;
break;
- case 1:
+ case NVME_NVM_PIF_32B_GUARD:
if (sts > 16 && ref_tag >= (1LL << (80 - sts)))
result = 1;
break;
- case 2:
+ case NVME_NVM_PIF_64B_GUARD:
if (sts > 0 && ref_tag >= (1LL << (48 - sts)))
result = 1;
break;
@@ -6837,12 +6835,25 @@ static int invalid_tags(__u64 storage_tag, __u64 ref_tag, __u8 sts, __u8 pif)
return result;
}
+static void get_pif_sts(struct nvme_id_ns *ns, struct nvme_nvm_id_ns *nvm_ns, __u8 *pif, __u8 *sts)
+{
+ __u8 lba_index;
+ __u32 elbaf;
+
+ nvme_id_ns_flbas_to_lbaf_inuse(ns->flbas, &lba_index);
+ elbaf = le32_to_cpu(nvm_ns->elbaf[lba_index]);
+ *sts = elbaf & NVME_NVM_ELBAF_STS_MASK;
+ *pif = (elbaf & NVME_NVM_ELBAF_PIF_MASK) >> 7;
+ if (*pif == NVME_NVM_PIF_QTYPE && (nvm_ns->pic & 0x8))
+ *pif = (elbaf & NVME_NVM_ELBAF_QPIF_MASK) >> 9;
+}
+
static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
_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;
+ __u8 sts = 0, pif = 0;
__u16 control = 0;
int err;
@@ -6953,9 +6964,7 @@ static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugi
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;
+ get_pif_sts(ns, nvm_ns, &pif, &sts);
}
if (invalid_tags(cfg.storage_tag, cfg.ref_tag, sts, pif))
@@ -6975,7 +6984,7 @@ static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugi
.pif = pif,
.storage_tag = cfg.storage_tag,
.dspec = cfg.dspec,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .timeout = nvme_cfg.timeout,
.result = NULL,
};
err = nvme_write_zeros(&args);
@@ -7078,7 +7087,7 @@ static int dsm(int argc, char **argv, struct command *cmd, struct plugin *plugin
.attrs = cfg.cdw11,
.nr_ranges = nr,
.dsm = dsm,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .timeout = nvme_cfg.timeout,
.result = NULL,
};
err = nvme_dsm(&args);
@@ -7282,7 +7291,7 @@ static int copy_cmd(int argc, char **argv, struct command *cmd, struct plugin *p
.ilbrt_u64 = cfg.ilbrt,
.lbatm = cfg.lbatm,
.lbat = cfg.lbat,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .timeout = nvme_cfg.timeout,
.result = NULL,
};
err = nvme_copy(&args);
@@ -7405,7 +7414,7 @@ static int resv_acquire(int argc, char **argv, struct command *cmd, struct plugi
.iekey = !!cfg.iekey,
.crkey = cfg.crkey,
.nrkey = cfg.prkey,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .timeout = nvme_cfg.timeout,
.result = NULL,
};
err = nvme_resv_acquire(&args);
@@ -7486,7 +7495,7 @@ static int resv_register(int argc, char **argv, struct command *cmd, struct plug
.iekey = !!cfg.iekey,
.crkey = cfg.crkey,
.nrkey = cfg.nrkey,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .timeout = nvme_cfg.timeout,
.result = NULL,
};
err = nvme_resv_register(&args);
@@ -7562,7 +7571,7 @@ static int resv_release(int argc, char **argv, struct command *cmd, struct plugi
.rrela = cfg.rrela,
.iekey = !!cfg.iekey,
.crkey = cfg.crkey,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .timeout = nvme_cfg.timeout,
.result = NULL,
};
err = nvme_resv_release(&args);
@@ -7587,7 +7596,7 @@ static int resv_report(int argc, char **argv, struct command *cmd, struct plugin
_cleanup_free_ struct nvme_resv_status *status = NULL;
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
- enum nvme_print_flags flags;
+ nvme_print_flags_t flags;
int err, size;
struct config {
@@ -7614,7 +7623,7 @@ static int resv_report(int argc, char **argv, struct command *cmd, struct plugin
if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
return err;
@@ -7649,7 +7658,7 @@ static int resv_report(int argc, char **argv, struct command *cmd, struct plugin
.eds = cfg.eds,
.len = size,
.report = status,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .timeout = nvme_cfg.timeout,
.result = NULL,
};
err = nvme_resv_report(&args);
@@ -7677,8 +7686,8 @@ static int submit_io(int opcode, char *command, const char *desc, int argc, char
void *buffer;
_cleanup_free_ void *mbuffer = NULL;
int err = 0;
- _cleanup_file_ int dfd = -1, mfd = -1;
- int flags;
+ _cleanup_fd_ int dfd = -1, mfd = -1;
+ int flags, pi_size;
int mode = 0644;
__u16 control = 0, nblocks = 0;
__u32 dsmgmt = 0;
@@ -7783,7 +7792,7 @@ static int submit_io(int opcode, char *command, const char *desc, int argc, char
if (err)
return err;
} else {
- err = argconfig_parse(argc, argv, desc, opts);
+ err = parse_args(argc, argv, desc, opts);
if (err)
return err;
err = open_exclusive(&dev, argc, argv, cfg.force);
@@ -7874,13 +7883,23 @@ static int submit_io(int opcode, char *command, const char *desc, int argc, char
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;
+
+ 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)
+ get_pif_sts(ns, nvm_ns, &pif, &sts);
+
+ pi_size = (pif == NVME_NVM_PIF_16B_GUARD) ? 8 : 16;
if (NVME_FLBAS_META_EXT(ns->flbas)) {
/*
- * No meta data is transferred for PRACT=1 and MD=8:
+ * No meta data is transferred for PRACT=1 and MD=PI size:
* 5.2.2.1 Protection Information and Write Commands
* 5.2.2.2 Protection Information and Read Commands
*/
- if (!((cfg.prinfo & 0x8) != 0 && ms == 8))
+ if (!((cfg.prinfo & 0x8) != 0 && ms == pi_size))
logical_block_size += ms;
}
@@ -7905,17 +7924,7 @@ static int submit_io(int opcode, char *command, const char *desc, int argc, char
if (!buffer)
return -ENOMEM;
- nvm_ns = nvme_alloc(sizeof(*nvm_ns));
- if (!nvm_ns)
- return -ENOMEM;
-
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;
- }
-
mbuffer_size = ((unsigned long long)cfg.block_count + 1) * ms;
if (ms && cfg.metadata_size < mbuffer_size)
nvme_show_error("Rounding metadata size to fit block count (%lld bytes)",
@@ -7990,7 +7999,7 @@ static int submit_io(int opcode, char *command, const char *desc, int argc, char
.data = buffer,
.metadata_len = mbuffer_size,
.metadata = mbuffer,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .timeout = nvme_cfg.timeout,
.result = NULL,
};
gettimeofday(&start_time, NULL);
@@ -8048,11 +8057,11 @@ static int write_cmd(int argc, char **argv, struct command *cmd, struct plugin *
static int verify_cmd(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- __u16 control = 0;
- __u8 lba_index, sts = 0, pif = 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 sts = 0, pif = 0;
+ __u16 control = 0;
int err;
const char *desc = "Verify specified logical blocks on the given device.";
@@ -8145,9 +8154,7 @@ static int verify_cmd(int argc, char **argv, struct command *cmd, struct plugin
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;
+ get_pif_sts(ns, nvm_ns, &pif, &sts);
}
if (invalid_tags(cfg.storage_tag, cfg.ref_tag, sts, pif))
@@ -8166,7 +8173,7 @@ static int verify_cmd(int argc, char **argv, struct command *cmd, struct plugin
.sts = sts,
.pif = pif,
.storage_tag = cfg.storage_tag,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .timeout = nvme_cfg.timeout,
.result = NULL,
};
err = nvme_verify(&args);
@@ -8244,7 +8251,7 @@ static int sec_recv(int argc, char **argv, struct command *cmd, struct plugin *p
.al = cfg.al,
.data_len = cfg.size,
.data = sec_buf,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .timeout = nvme_cfg.timeout,
.result = NULL,
};
@@ -8279,7 +8286,7 @@ static int get_lba_status(int argc, char **argv, struct command *cmd,
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
_cleanup_free_ void *buf = NULL;
- enum nvme_print_flags flags;
+ nvme_print_flags_t flags;
unsigned long buf_len;
int err;
@@ -8289,7 +8296,6 @@ static int get_lba_status(int argc, char **argv, struct command *cmd,
__u32 mndw;
__u8 atype;
__u16 rl;
- __u32 timeout;
};
struct config cfg = {
@@ -8298,7 +8304,6 @@ static int get_lba_status(int argc, char **argv, struct command *cmd,
.mndw = 0,
.atype = 0,
.rl = 0,
- .timeout = 0,
};
NVME_ARGS(opts,
@@ -8306,14 +8311,13 @@ static int get_lba_status(int argc, char **argv, struct command *cmd,
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_SHRT("range-len", 'l', &cfg.rl, rl));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
return err;
@@ -8338,7 +8342,7 @@ static int get_lba_status(int argc, char **argv, struct command *cmd,
.rl = cfg.rl,
.atype = cfg.atype,
.lbas = buf,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .timeout = nvme_cfg.timeout,
.result = NULL,
};
err = nvme_get_lba_status(&args);
@@ -8405,7 +8409,7 @@ static int capacity_mgmt(int argc, char **argv, struct command *cmd, struct plug
.element_id = cfg.element_id,
.cdw11 = cfg.dw11,
.cdw12 = cfg.dw12,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .timeout = nvme_cfg.timeout,
.result = &result,
};
err = nvme_capacity_mgmt(&args);
@@ -8429,7 +8433,7 @@ static int dir_receive(int argc, char **argv, struct command *cmd, struct plugin
const char *desc = "Read directive parameters of the specified directive type.";
const char *nsr = "namespace stream requested";
- enum nvme_print_flags flags = NORMAL;
+ nvme_print_flags_t flags = NORMAL;
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
_cleanup_free_ void *buf = NULL;
__u32 result;
@@ -8472,7 +8476,7 @@ static int dir_receive(int argc, char **argv, struct command *cmd, struct plugin
if (err)
return err;
- if (cfg.human_readable)
+ if (cfg.human_readable || argconfig_parse_seen(opts, "verbose"))
flags |= VERBOSE;
if (cfg.raw_binary)
flags = BINARY;
@@ -8528,7 +8532,7 @@ static int dir_receive(int argc, char **argv, struct command *cmd, struct plugin
.cdw12 = dw12,
.data_len = cfg.data_len,
.data = buf,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .timeout = nvme_cfg.timeout,
.result = &result,
};
err = nvme_directive_recv(&args);
@@ -8627,7 +8631,7 @@ static int lockdown_cmd(int argc, char **argv, struct command *cmd, struct plugi
.ifc = cfg.ifc,
.ofi = cfg.ofi,
.uuidx = cfg.uuid,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .timeout = nvme_cfg.timeout,
.result = NULL,
};
err = nvme_lockdown(&args);
@@ -8691,7 +8695,7 @@ static int passthru(int argc, char **argv, bool admin,
_cleanup_huge_ struct nvme_mem_huge mh = { 0, };
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
- _cleanup_file_ int dfd = -1, mfd = -1;
+ _cleanup_fd_ int dfd = -1, mfd = -1;
int flags;
int mode = 0644;
void *data = NULL;
@@ -8709,7 +8713,6 @@ static int passthru(int argc, char **argv, bool admin,
.namespace_id = 0,
.data_len = 0,
.metadata_len = 0,
- .timeout = 0,
.cdw2 = 0,
.cdw3 = 0,
.cdw10 = 0,
@@ -8736,7 +8739,6 @@ static int passthru(int argc, char **argv, bool admin,
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),
@@ -8837,7 +8839,7 @@ static int passthru(int argc, char **argv, bool admin,
printf("cdw13 : %08x\n", cfg.cdw13);
printf("cdw14 : %08x\n", cfg.cdw14);
printf("cdw15 : %08x\n", cfg.cdw15);
- printf("timeout_ms : %08x\n", cfg.timeout);
+ printf("timeout_ms : %08x\n", nvme_cfg.timeout);
}
if (cfg.dry_run)
return 0;
@@ -8853,7 +8855,7 @@ static int passthru(int argc, char **argv, bool admin,
cfg.cdw14,
cfg.cdw15, cfg.data_len, data,
cfg.metadata_len,
- mdata, cfg.timeout, &result);
+ mdata, nvme_cfg.timeout, &result);
else
err = nvme_io_passthru(dev_fd(dev), cfg.opcode, cfg.flags,
cfg.rsvd,
@@ -8863,7 +8865,7 @@ static int passthru(int argc, char **argv, bool admin,
cfg.cdw14,
cfg.cdw15, cfg.data_len, data,
cfg.metadata_len,
- mdata, cfg.timeout, &result);
+ mdata, nvme_cfg.timeout, &result);
gettimeofday(&end_time, NULL);
cmd_name = nvme_cmd_to_string(admin, cfg.opcode);
@@ -8975,7 +8977,7 @@ static int gen_dhchap_key(int argc, char **argv, struct command *command, struct
OPT_STR("nqn", 'n', &cfg.nqn, nqn),
OPT_UINT("hmac", 'm', &cfg.hmac, hmac));
- err = argconfig_parse(argc, argv, desc, opts);
+ err = parse_args(argc, argv, desc, opts);
if (err)
return err;
@@ -9075,8 +9077,8 @@ static int check_dhchap_key(int argc, char **argv, struct command *command, stru
unsigned char decoded_key[128];
unsigned int decoded_len;
- u_int32_t crc = crc32(0L, NULL, 0);
- u_int32_t key_crc;
+ uint32_t crc = crc32(0L, NULL, 0);
+ uint32_t key_crc;
int err = 0, hmac;
struct config {
char *key;
@@ -9089,7 +9091,7 @@ static int check_dhchap_key(int argc, char **argv, struct command *command, stru
NVME_ARGS(opts,
OPT_STR("key", 'k', &cfg.key, key));
- err = argconfig_parse(argc, argv, desc, opts);
+ err = parse_args(argc, argv, desc, opts);
if (err)
return err;
@@ -9144,10 +9146,10 @@ static int check_dhchap_key(int argc, char **argv, struct command *command, stru
return -EINVAL;
}
crc = crc32(crc, decoded_key, decoded_len);
- key_crc = ((u_int32_t)decoded_key[decoded_len]) |
- ((u_int32_t)decoded_key[decoded_len + 1] << 8) |
- ((u_int32_t)decoded_key[decoded_len + 2] << 16) |
- ((u_int32_t)decoded_key[decoded_len + 3] << 24);
+ key_crc = ((uint32_t)decoded_key[decoded_len]) |
+ ((uint32_t)decoded_key[decoded_len + 1] << 8) |
+ ((uint32_t)decoded_key[decoded_len + 2] << 16) |
+ ((uint32_t)decoded_key[decoded_len + 3] << 24);
if (key_crc != crc) {
nvme_show_error("CRC mismatch (key %08x, crc %08x)", key_crc, crc);
return -EINVAL;
@@ -9208,7 +9210,7 @@ static int gen_tls_key(int argc, char **argv, struct command *command, struct pl
OPT_UINT("identity", 'I', &cfg.identity, identity),
OPT_FLAG("insert", 'i', &cfg.insert, insert));
- err = argconfig_parse(argc, argv, desc, opts);
+ err = parse_args(argc, argv, desc, opts);
if (err)
return err;
if (cfg.hmac < 1 || cfg.hmac > 2) {
@@ -9326,7 +9328,7 @@ static int check_tls_key(int argc, char **argv, struct command *command, struct
OPT_UINT("identity", 'I', &cfg.identity, identity),
OPT_FLAG("insert", 'i', &cfg.insert, insert));
- err = argconfig_parse(argc, argv, desc, opts);
+ err = parse_args(argc, argv, desc, opts);
if (err)
return err;
@@ -9402,6 +9404,47 @@ static void __scan_tls_key(long keyring_id, long key_id,
fprintf(fd, "%s %s\n", desc, encoded_key);
}
+static int import_key(const char *keyring, FILE *fd)
+{
+ long keyring_id;
+ char tls_str[512];
+ char *tls_key;
+ unsigned char *psk;
+ unsigned int hmac;
+ int linenum = -1, key_len;
+
+ keyring_id = nvme_lookup_keyring(keyring);
+ if (!keyring_id) {
+ nvme_show_error("Invalid keyring '%s'", keyring);
+ return -ENOKEY;
+ }
+
+ while (fgets(tls_str, 512, fd)) {
+ linenum++;
+ tls_key = strrchr(tls_str, ' ');
+ if (!tls_key) {
+ nvme_show_error("Parse error in line %d",
+ linenum);
+ continue;
+ }
+ *tls_key = '\0';
+ tls_key++;
+ tls_key[strcspn(tls_key, "\n")] = 0;
+ psk = nvme_import_tls_key(tls_key, &key_len, &hmac);
+ if (!psk) {
+ nvme_show_error("Failed to import key in line %d",
+ linenum);
+ continue;
+ }
+ nvme_update_key(keyring_id, "psk", tls_str,
+ psk, key_len);
+ free(psk);
+ }
+
+ return 0;
+}
+
+
static int tls_key(int argc, char **argv, struct command *command, struct plugin *plugin)
{
const char *desc = "Manipulation of TLS keys.\n";
@@ -9410,9 +9453,10 @@ static int tls_key(int argc, char **argv, struct command *command, struct plugin
const char *keyfile = "File for list of keys.";
const char *import = "Import all keys into the keyring.";
const char *export = "Export all keys from the keyring.";
+ const char *revoke = "Revoke key from the keyring.";
- FILE *fd;
- int err = 0;
+ _cleanup_file_ FILE *fd = NULL;
+ int cnt, err = 0;
struct config {
char *keyring;
@@ -9420,6 +9464,7 @@ static int tls_key(int argc, char **argv, struct command *command, struct plugin
char *keyfile;
bool import;
bool export;
+ char *revoke;
};
struct config cfg = {
@@ -9428,6 +9473,7 @@ static int tls_key(int argc, char **argv, struct command *command, struct plugin
.keyfile = NULL,
.import = false,
.export = false,
+ .revoke = NULL,
};
NVME_ARGS(opts,
@@ -9435,71 +9481,56 @@ static int tls_key(int argc, char **argv, struct command *command, struct plugin
OPT_STR("keytype", 't', &cfg.keytype, keytype),
OPT_STR("keyfile", 'f', &cfg.keyfile, keyfile),
OPT_FLAG("import", 'i', &cfg.import, import),
- OPT_FLAG("export", 'e', &cfg.export, export));
+ OPT_FLAG("export", 'e', &cfg.export, export),
+ OPT_STR("revoke", 'r', &cfg.revoke, revoke));
err = argconfig_parse(argc, argv, desc, opts);
if (err)
return err;
if (cfg.keyfile) {
- fd = fopen(cfg.keyfile, "r");
+ const char *mode;
+
+ if (cfg.import)
+ mode = "r";
+ else
+ mode = "w";
+
+ fd = fopen(cfg.keyfile, mode);
if (!fd) {
nvme_show_error("Cannot open keyfile %s, error %d\n",
cfg.keyfile, errno);
return -errno;
}
- } else
- fd = stdin;
+ } else {
+ if (cfg.import)
+ fd = freopen(NULL, "r", stdin);
+ else
+ fd = freopen(NULL, "w", stdout);
+ }
- if (cfg.export && cfg.import) {
- nvme_show_error("Cannot specify both --import and --export");
- err = -EINVAL;
+ cnt = 0;
+ if (cfg.export) cnt++;
+ if (cfg.import) cnt++;
+ if (cfg.revoke) cnt++;
+
+ if (cnt != 1) {
+ nvme_show_error("Must specify either --import, --export or --revoke");
+ return -EINVAL;
} else if (cfg.export) {
- nvme_scan_tls_keys(cfg.keyring, __scan_tls_key, fd);
+ err = nvme_scan_tls_keys(cfg.keyring, __scan_tls_key, fd);
+ if (err)
+ nvme_show_error("Export of TLS keys failed with '%s'",
+ nvme_strerror(errno));
} else if (cfg.import) {
- long keyring_id;
- char tls_str[512];
- char *tls_key;
- unsigned char *psk;
- unsigned int hmac;
- int linenum = -1, key_len;
-
- keyring_id = nvme_lookup_keyring(cfg.keyring);
- if (!keyring_id) {
- nvme_show_error("Invalid keyring '%s'", cfg.keyring);
- err = -ENOKEY;
- goto out;
- }
-
- while (fgets(tls_str, 512, fd)) {
- linenum++;
- tls_key = strrchr(tls_str, ' ');
- if (!tls_key) {
- nvme_show_error("Parse error in line %d",
- linenum);
- continue;
- }
- *tls_key = '\0';
- tls_key++;
- psk = nvme_import_tls_key(tls_key, &key_len, &hmac);
- if (!psk) {
- nvme_show_error("Failed to import key in line %d",
- linenum);
- continue;
- }
- nvme_update_key(keyring_id, "psk", tls_str,
- psk, key_len);
- free(psk);
- }
+ err = import_key(cfg.keyring, fd);
} else {
- nvme_show_error("Must specify either --import or --export");
- err = -EINVAL;
+ err = nvme_revoke_tls_key(cfg.keyring, cfg.keytype, cfg.revoke);
+ if (err)
+ nvme_show_error("Failed to revoke key '%s'",
+ nvme_strerror(errno));
}
-out:
- if (cfg.keyfile)
- fclose(fd);
-
return err;
}
@@ -9507,8 +9538,8 @@ static int show_topology_cmd(int argc, char **argv, struct command *command, str
{
const char *desc = "Show the topology\n";
const char *ranking = "Ranking order: namespace|ctrl";
- enum nvme_print_flags flags;
- nvme_root_t r;
+ nvme_print_flags_t flags;
+ _cleanup_nvme_root_ nvme_root_t r = NULL;
enum nvme_cli_topo_ranking rank;
int err;
@@ -9527,7 +9558,7 @@ static int show_topology_cmd(int argc, char **argv, struct command *command, str
if (err)
return err;
- err = validate_output_format(output_format_val, &flags);
+ err = validate_output_format(nvme_cfg.output_format, &flags);
if (err < 0) {
nvme_show_error("Invalid output format");
return err;
@@ -9553,14 +9584,11 @@ static int show_topology_cmd(int argc, char **argv, struct command *command, str
err = nvme_scan_topology(r, NULL, NULL);
if (err < 0) {
- if (errno != ENOENT)
- nvme_show_error("Failed to scan topology: %s", nvme_strerror(errno));
- nvme_free_tree(r);
+ nvme_show_error("Failed to scan topology: %s", nvme_strerror(errno));
return err;
}
nvme_show_topology(r, rank, flags);
- nvme_free_tree(r);
return err;
}
@@ -9629,7 +9657,7 @@ static int nvme_mi(int argc, char **argv, __u8 admin_opcode, const char *desc)
void *data = NULL;
int err = 0;
bool send;
- _cleanup_file_ int fd = -1;
+ _cleanup_fd_ int fd = -1;
int flags;
_cleanup_huge_ struct nvme_mem_huge mh = { 0, };
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;