summaryrefslogtreecommitdiffstats
path: root/nvme-print.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--nvme-print.c714
1 files changed, 479 insertions, 235 deletions
diff --git a/nvme-print.c b/nvme-print.c
index e92ba82..c27f087 100644
--- a/nvme-print.c
+++ b/nvme-print.c
@@ -6,22 +6,15 @@
#include <stdlib.h>
#include <time.h>
#include <sys/stat.h>
-#include <uuid/uuid.h>
#include "nvme.h"
#include "libnvme.h"
#include "nvme-print.h"
#include "nvme-models.h"
#include "util/suffix.h"
+#include "util/types.h"
#include "common.h"
-#define ABSOLUTE_ZERO_CELSIUS -273
-
-static inline long kelvin_to_celsius(long t)
-{
- return t + ABSOLUTE_ZERO_CELSIUS;
-}
-
static const uint8_t zero_uuid[16] = { 0 };
static const uint8_t invalid_uuid[16] = {[0 ... 15] = 0xff };
static const char dash[100] = {[0 ... 99] = '-'};
@@ -35,18 +28,6 @@ struct nvme_bar_cap {
__u8 rsvd_crms_nsss_cmbs_pmrs;
};
-static long double int128_to_double(__u8 *data)
-{
- int i;
- long double result = 0;
-
- for (i = 0; i < 16; i++) {
- result *= 256;
- result += data[15 - i];
- }
- return result;
-}
-
static const char *nvme_ana_state_to_string(enum nvme_ana_state state)
{
switch (state) {
@@ -120,17 +101,6 @@ const char *nvme_cmd_to_string(int admin, __u8 opcode)
return "Unknown";
}
-static const char *fw_to_string(char *c)
-{
- static char ret[9];
- int i;
-
- for (i = 0; i < 8; i++)
- ret[i] = c[i] >= '!' && c[i] <= '~' ? c[i] : '.';
- ret[i] = '\0';
- return ret;
-}
-
static const char *get_sanitize_log_sstat_status_str(__u16 status)
{
switch (status & NVME_SANITIZE_SSTAT_STATUS_MASK) {
@@ -158,7 +128,7 @@ static void json_nvme_id_ns(struct nvme_id_ns *ns, bool cap_only)
struct json_object *lbafs;
int i;
- long double nvmcap = int128_to_double(ns->nvmcap);
+ nvme_uint128_t nvmcap = le128_to_cpu(ns->nvmcap);
root = json_create_object();
@@ -186,7 +156,7 @@ static void json_nvme_id_ns(struct nvme_id_ns *ns, bool cap_only)
json_object_add_value_int(root, "nabo", le16_to_cpu(ns->nabo));
json_object_add_value_int(root, "nabspf", le16_to_cpu(ns->nabspf));
json_object_add_value_int(root, "noiob", le16_to_cpu(ns->noiob));
- json_object_add_value_double(root, "nvmcap", nvmcap);
+ json_object_add_value_uint128(root, "nvmcap", nvmcap);
json_object_add_value_int(root, "nsattr", ns->nsattr);
json_object_add_value_int(root, "nvmsetid", le16_to_cpu(ns->nvmsetid));
@@ -245,10 +215,10 @@ static void json_nvme_id_ctrl(struct nvme_id_ctrl *ctrl,
struct json_object *root;
struct json_object *psds;
- long double tnvmcap = int128_to_double(ctrl->tnvmcap);
- long double unvmcap = int128_to_double(ctrl->unvmcap);
- long double megcap = int128_to_double(ctrl->megcap);
- long double maxdna = int128_to_double(ctrl->maxdna);
+ nvme_uint128_t tnvmcap = le128_to_cpu(ctrl->tnvmcap);
+ nvme_uint128_t unvmcap = le128_to_cpu(ctrl->unvmcap);
+ nvme_uint128_t megcap = le128_to_cpu(ctrl->megcap);
+ nvme_uint128_t maxdna = le128_to_cpu(ctrl->maxdna);
char sn[sizeof(ctrl->sn) + 1], mn[sizeof(ctrl->mn) + 1],
fr[sizeof(ctrl->fr) + 1], subnqn[sizeof(ctrl->subnqn) + 1];
@@ -279,6 +249,8 @@ static void json_nvme_id_ctrl(struct nvme_id_ctrl *ctrl,
json_object_add_value_uint(root, "oaes", le32_to_cpu(ctrl->oaes));
json_object_add_value_int(root, "ctratt", le32_to_cpu(ctrl->ctratt));
json_object_add_value_int(root, "rrls", le16_to_cpu(ctrl->rrls));
+ json_object_add_value_int(root, "cntrltype", ctrl->cntrltype);
+ json_object_add_value_string(root, "fguid", util_uuid_to_string(ctrl->fguid));
json_object_add_value_int(root, "crdt1", le16_to_cpu(ctrl->crdt1));
json_object_add_value_int(root, "crdt2", le16_to_cpu(ctrl->crdt2));
json_object_add_value_int(root, "crdt3", le16_to_cpu(ctrl->crdt3));
@@ -299,8 +271,8 @@ static void json_nvme_id_ctrl(struct nvme_id_ctrl *ctrl,
json_object_add_value_int(root, "mtfa", le16_to_cpu(ctrl->mtfa));
json_object_add_value_uint(root, "hmpre", le32_to_cpu(ctrl->hmpre));
json_object_add_value_uint(root, "hmmin", le32_to_cpu(ctrl->hmmin));
- json_object_add_value_double(root, "tnvmcap", tnvmcap);
- json_object_add_value_double(root, "unvmcap", unvmcap);
+ json_object_add_value_uint128(root, "tnvmcap", tnvmcap);
+ json_object_add_value_uint128(root, "unvmcap", unvmcap);
json_object_add_value_uint(root, "rpmbs", le32_to_cpu(ctrl->rpmbs));
json_object_add_value_int(root, "edstt", le16_to_cpu(ctrl->edstt));
json_object_add_value_int(root, "dsto", ctrl->dsto);
@@ -314,15 +286,16 @@ static void json_nvme_id_ctrl(struct nvme_id_ctrl *ctrl,
json_object_add_value_int(root, "hmmaxd", le16_to_cpu(ctrl->hmmaxd));
json_object_add_value_int(root, "nsetidmax",
le16_to_cpu(ctrl->nsetidmax));
-
+ json_object_add_value_int(root, "endgidmax", le16_to_cpu(ctrl->endgidmax));
json_object_add_value_int(root, "anatt",ctrl->anatt);
json_object_add_value_int(root, "anacap", ctrl->anacap);
json_object_add_value_int(root, "anagrpmax",
le32_to_cpu(ctrl->anagrpmax));
json_object_add_value_int(root, "nanagrpid",
le32_to_cpu(ctrl->nanagrpid));
+ json_object_add_value_int(root, "pels", le32_to_cpu(ctrl->pels));
json_object_add_value_int(root, "domainid", le16_to_cpu(ctrl->domainid));
- json_object_add_value_double(root, "megcap", megcap);
+ json_object_add_value_uint128(root, "megcap", megcap);
json_object_add_value_int(root, "sqes", ctrl->sqes);
json_object_add_value_int(root, "cqes", ctrl->cqes);
json_object_add_value_int(root, "maxcmd", le16_to_cpu(ctrl->maxcmd));
@@ -338,7 +311,8 @@ static void json_nvme_id_ctrl(struct nvme_id_ctrl *ctrl,
json_object_add_value_int(root, "acwu", le16_to_cpu(ctrl->acwu));
json_object_add_value_int(root, "ocfs", le16_to_cpu(ctrl->ocfs));
json_object_add_value_int(root, "sgls", le32_to_cpu(ctrl->sgls));
- json_object_add_value_double(root, "maxdna", maxdna);
+ json_object_add_value_int(root, "mnan", le32_to_cpu(ctrl->mnan));
+ json_object_add_value_uint128(root, "maxdna", maxdna);
json_object_add_value_int(root, "maxcna", le32_to_cpu(ctrl->maxcna));
if (strlen(subnqn))
@@ -532,7 +506,7 @@ static void json_fw_log(struct nvme_firmware_slot *fw_log, const char *devname)
frs = (__le64 *)&fw_log->frs[i];
snprintf(str, sizeof(str), "%"PRIu64" (%s)",
le64_to_cpu(*frs),
- fw_to_string(fw_log->frs[i]));
+ util_fw_to_string(fw_log->frs[i]));
json_object_add_value_string(fwsi, fmt, str);
}
}
@@ -585,22 +559,22 @@ static void json_endurance_log(struct nvme_endurance_group_log *endurance_group,
{
struct json_object *root;
- long double endurance_estimate =
- int128_to_double(endurance_group->endurance_estimate);
- long double data_units_read =
- int128_to_double(endurance_group->data_units_read);
- long double data_units_written =
- int128_to_double(endurance_group->data_units_written);
- long double media_units_written =
- int128_to_double(endurance_group->media_units_written);
- long double host_read_cmds =
- int128_to_double(endurance_group->host_read_cmds);
- long double host_write_cmds =
- int128_to_double(endurance_group->host_write_cmds);
- long double media_data_integrity_err =
- int128_to_double(endurance_group->media_data_integrity_err);
- long double num_err_info_log_entries =
- int128_to_double(endurance_group->num_err_info_log_entries);
+ nvme_uint128_t endurance_estimate =
+ le128_to_cpu(endurance_group->endurance_estimate);
+ nvme_uint128_t data_units_read =
+ le128_to_cpu(endurance_group->data_units_read);
+ nvme_uint128_t data_units_written =
+ le128_to_cpu(endurance_group->data_units_written);
+ nvme_uint128_t media_units_written =
+ le128_to_cpu(endurance_group->media_units_written);
+ nvme_uint128_t host_read_cmds =
+ le128_to_cpu(endurance_group->host_read_cmds);
+ nvme_uint128_t host_write_cmds =
+ le128_to_cpu(endurance_group->host_write_cmds);
+ nvme_uint128_t media_data_integrity_err =
+ le128_to_cpu(endurance_group->media_data_integrity_err);
+ nvme_uint128_t num_err_info_log_entries =
+ le128_to_cpu(endurance_group->num_err_info_log_entries);
root = json_create_object();
@@ -612,18 +586,18 @@ static void json_endurance_log(struct nvme_endurance_group_log *endurance_group,
endurance_group->avl_spare_threshold);
json_object_add_value_int(root, "percent_used",
endurance_group->percent_used);
- json_object_add_value_double(root, "endurance_estimate",
+ json_object_add_value_uint128(root, "endurance_estimate",
endurance_estimate);
- json_object_add_value_double(root, "data_units_read", data_units_read);
- json_object_add_value_double(root, "data_units_written",
+ json_object_add_value_uint128(root, "data_units_read", data_units_read);
+ json_object_add_value_uint128(root, "data_units_written",
data_units_written);
- json_object_add_value_double(root, "mediate_write_commands",
+ json_object_add_value_uint128(root, "media_units_written",
media_units_written);
- json_object_add_value_double(root, "host_read_cmds", host_read_cmds);
- json_object_add_value_double(root, "host_write_cmds", host_write_cmds);
- json_object_add_value_double(root, "media_data_integrity_err",
+ json_object_add_value_uint128(root, "host_read_cmds", host_read_cmds);
+ json_object_add_value_uint128(root, "host_write_cmds", host_write_cmds);
+ json_object_add_value_uint128(root, "media_data_integrity_err",
media_data_integrity_err);
- json_object_add_value_double(root, "num_err_info_log_entries",
+ json_object_add_value_uint128(root, "num_err_info_log_entries",
num_err_info_log_entries);
json_print_object(root, NULL);
@@ -641,16 +615,16 @@ static void json_smart_log(struct nvme_smart_log *smart, unsigned int nsid,
unsigned int temperature = ((smart->temperature[1] << 8) |
smart->temperature[0]);
- long double data_units_read = int128_to_double(smart->data_units_read);
- long double data_units_written = int128_to_double(smart->data_units_written);
- long double host_read_commands = int128_to_double(smart->host_reads);
- long double host_write_commands = int128_to_double(smart->host_writes);
- long double controller_busy_time = int128_to_double(smart->ctrl_busy_time);
- long double power_cycles = int128_to_double(smart->power_cycles);
- long double power_on_hours = int128_to_double(smart->power_on_hours);
- long double unsafe_shutdowns = int128_to_double(smart->unsafe_shutdowns);
- long double media_errors = int128_to_double(smart->media_errors);
- long double num_err_log_entries = int128_to_double(smart->num_err_log_entries);
+ nvme_uint128_t data_units_read = le128_to_cpu(smart->data_units_read);
+ nvme_uint128_t data_units_written = le128_to_cpu(smart->data_units_written);
+ nvme_uint128_t host_read_commands = le128_to_cpu(smart->host_reads);
+ nvme_uint128_t host_write_commands = le128_to_cpu(smart->host_writes);
+ nvme_uint128_t controller_busy_time = le128_to_cpu(smart->ctrl_busy_time);
+ nvme_uint128_t power_cycles = le128_to_cpu(smart->power_cycles);
+ nvme_uint128_t power_on_hours = le128_to_cpu(smart->power_on_hours);
+ nvme_uint128_t unsafe_shutdowns = le128_to_cpu(smart->unsafe_shutdowns);
+ nvme_uint128_t media_errors = le128_to_cpu(smart->media_errors);
+ nvme_uint128_t num_err_log_entries = le128_to_cpu(smart->num_err_log_entries);
root = json_create_object();
@@ -676,20 +650,20 @@ static void json_smart_log(struct nvme_smart_log *smart, unsigned int nsid,
json_object_add_value_int(root, "percent_used", smart->percent_used);
json_object_add_value_int(root, "endurance_grp_critical_warning_summary",
smart->endu_grp_crit_warn_sumry);
- json_object_add_value_double(root, "data_units_read", data_units_read);
- json_object_add_value_double(root, "data_units_written",
+ json_object_add_value_uint128(root, "data_units_read", data_units_read);
+ json_object_add_value_uint128(root, "data_units_written",
data_units_written);
- json_object_add_value_double(root, "host_read_commands",
+ json_object_add_value_uint128(root, "host_read_commands",
host_read_commands);
- json_object_add_value_double(root, "host_write_commands",
+ json_object_add_value_uint128(root, "host_write_commands",
host_write_commands);
- json_object_add_value_double(root, "controller_busy_time",
+ json_object_add_value_uint128(root, "controller_busy_time",
controller_busy_time);
- json_object_add_value_double(root, "power_cycles", power_cycles);
- json_object_add_value_double(root, "power_on_hours", power_on_hours);
- json_object_add_value_double(root, "unsafe_shutdowns", unsafe_shutdowns);
- json_object_add_value_double(root, "media_errors", media_errors);
- json_object_add_value_double(root, "num_err_log_entries",
+ json_object_add_value_uint128(root, "power_cycles", power_cycles);
+ json_object_add_value_uint128(root, "power_on_hours", power_on_hours);
+ json_object_add_value_uint128(root, "unsafe_shutdowns", unsafe_shutdowns);
+ json_object_add_value_uint128(root, "media_errors", media_errors);
+ json_object_add_value_uint128(root, "num_err_log_entries",
num_err_log_entries);
json_object_add_value_uint(root, "warning_temp_time",
le32_to_cpu(smart->warning_temp_time));
@@ -1110,6 +1084,8 @@ static const char *nvme_show_nss_hw_error(__u16 error_code)
return "Controller Fatal Status";
case 0xA:
return "Media and Data Integrity Status";
+ case 0xB:
+ return "Controller Ready Timeout Exceeded";
default:
return "Reserved";
}
@@ -1191,8 +1167,8 @@ static void json_persistent_event_log(void *pevent_log_info, __u32 size)
le16_to_cpu(pevent_log_head->lhl));
json_object_add_value_uint64(root, "timestamp",
le64_to_cpu(pevent_log_head->ts));
- json_object_add_value_double(root, "power_on_hours",
- int128_to_double(pevent_log_head->poh));
+ json_object_add_value_uint128(root, "power_on_hours",
+ le128_to_cpu(pevent_log_head->poh));
json_object_add_value_uint64(root, "power_cycle_count",
le64_to_cpu(pevent_log_head->pcc));
json_object_add_value_uint(root, "pci_vid",
@@ -1256,16 +1232,16 @@ static void json_persistent_event_log(void *pevent_log_info, __u32 size)
unsigned int temperature = ((smart_event->temperature[1] << 8) |
smart_event->temperature[0]);
- long double data_units_read = int128_to_double(smart_event->data_units_read);
- long double data_units_written = int128_to_double(smart_event->data_units_written);
- long double host_read_commands = int128_to_double(smart_event->host_reads);
- long double host_write_commands = int128_to_double(smart_event->host_writes);
- long double controller_busy_time = int128_to_double(smart_event->ctrl_busy_time);
- long double power_cycles = int128_to_double(smart_event->power_cycles);
- long double power_on_hours = int128_to_double(smart_event->power_on_hours);
- long double unsafe_shutdowns = int128_to_double(smart_event->unsafe_shutdowns);
- long double media_errors = int128_to_double(smart_event->media_errors);
- long double num_err_log_entries = int128_to_double(smart_event->num_err_log_entries);
+ nvme_uint128_t data_units_read = le128_to_cpu(smart_event->data_units_read);
+ nvme_uint128_t data_units_written = le128_to_cpu(smart_event->data_units_written);
+ nvme_uint128_t host_read_commands = le128_to_cpu(smart_event->host_reads);
+ nvme_uint128_t host_write_commands = le128_to_cpu(smart_event->host_writes);
+ nvme_uint128_t controller_busy_time = le128_to_cpu(smart_event->ctrl_busy_time);
+ nvme_uint128_t power_cycles = le128_to_cpu(smart_event->power_cycles);
+ nvme_uint128_t power_on_hours = le128_to_cpu(smart_event->power_on_hours);
+ nvme_uint128_t unsafe_shutdowns = le128_to_cpu(smart_event->unsafe_shutdowns);
+ nvme_uint128_t media_errors = le128_to_cpu(smart_event->media_errors);
+ nvme_uint128_t num_err_log_entries = le128_to_cpu(smart_event->num_err_log_entries);
json_object_add_value_int(valid_attrs, "critical_warning",
smart_event->critical_warning);
@@ -1280,25 +1256,25 @@ static void json_persistent_event_log(void *pevent_log_info, __u32 size)
json_object_add_value_int(valid_attrs,
"endurance_grp_critical_warning_summary",
smart_event->endu_grp_crit_warn_sumry);
- json_object_add_value_double(valid_attrs, "data_units_read",
+ json_object_add_value_uint128(valid_attrs, "data_units_read",
data_units_read);
- json_object_add_value_double(valid_attrs, "data_units_written",
+ json_object_add_value_uint128(valid_attrs, "data_units_written",
data_units_written);
- json_object_add_value_double(valid_attrs, "host_read_commands",
+ json_object_add_value_uint128(valid_attrs, "host_read_commands",
host_read_commands);
- json_object_add_value_double(valid_attrs, "host_write_commands",
+ json_object_add_value_uint128(valid_attrs, "host_write_commands",
host_write_commands);
- json_object_add_value_double(valid_attrs, "controller_busy_time",
+ json_object_add_value_uint128(valid_attrs, "controller_busy_time",
controller_busy_time);
- json_object_add_value_double(valid_attrs, "power_cycles",
+ json_object_add_value_uint128(valid_attrs, "power_cycles",
power_cycles);
- json_object_add_value_double(valid_attrs, "power_on_hours",
+ json_object_add_value_uint128(valid_attrs, "power_on_hours",
power_on_hours);
- json_object_add_value_double(valid_attrs, "unsafe_shutdowns",
+ json_object_add_value_uint128(valid_attrs, "unsafe_shutdowns",
unsafe_shutdowns);
- json_object_add_value_double(valid_attrs, "media_errors",
+ json_object_add_value_uint128(valid_attrs, "media_errors",
media_errors);
- json_object_add_value_double(valid_attrs, "num_err_log_entries",
+ json_object_add_value_uint128(valid_attrs, "num_err_log_entries",
num_err_log_entries);
json_object_add_value_uint(valid_attrs, "warning_temp_time",
le32_to_cpu(smart_event->warning_temp_time));
@@ -1326,11 +1302,11 @@ static void json_persistent_event_log(void *pevent_log_info, __u32 size)
fw_commit_event = pevent_log_info + offset;
snprintf(fw_str, sizeof(fw_str), "%"PRIu64" (%s)",
le64_to_cpu(fw_commit_event->old_fw_rev),
- fw_to_string((char *)&fw_commit_event->old_fw_rev));
+ util_fw_to_string((char *)&fw_commit_event->old_fw_rev));
json_object_add_value_string(valid_attrs, "old_fw_rev", fw_str);
snprintf(fw_str, sizeof(fw_str), "%"PRIu64" (%s)",
le64_to_cpu(fw_commit_event->new_fw_rev),
- fw_to_string((char *)&fw_commit_event->new_fw_rev));
+ util_fw_to_string((char *)&fw_commit_event->new_fw_rev));
json_object_add_value_string(valid_attrs, "new_fw_rev", fw_str);
json_object_add_value_uint(valid_attrs, "fw_commit_action",
fw_commit_event->fw_commit_action);
@@ -1361,7 +1337,7 @@ static void json_persistent_event_log(void *pevent_log_info, __u32 size)
fw_rev = pevent_log_info + offset;
snprintf(fw_str, sizeof(fw_str), "%"PRIu64" (%s)",
le64_to_cpu(*fw_rev),
- fw_to_string((char *)fw_rev));
+ util_fw_to_string((char *)fw_rev));
json_object_add_value_string(valid_attrs, "fw_rev", fw_str);
for (int i = 0; i < por_info_list; i++) {
por_event = pevent_log_info + offset +
@@ -1541,8 +1517,8 @@ void nvme_show_persistent_event_log(void *pevent_log_info,
printf("Log Header Length: %u\n", pevent_log_head->lhl);
printf("Timestamp: %"PRIu64"\n",
le64_to_cpu(pevent_log_head->ts));
- printf("Power On Hours (POH): %'.0Lf\n",
- int128_to_double(pevent_log_head->poh));
+ printf("Power On Hours (POH): %s",
+ uint128_t_to_string(le128_to_cpu(pevent_log_head->poh)));
printf("Power Cycle Count: %"PRIu64"\n",
le64_to_cpu(pevent_log_head->pcc));
printf("PCI Vendor ID (VID): %u\n",
@@ -1615,10 +1591,10 @@ void nvme_show_persistent_event_log(void *pevent_log_info,
printf("FW Commit Event Entry: \n");
printf("Old Firmware Revision: %"PRIu64" (%s)\n",
le64_to_cpu(fw_commit_event->old_fw_rev),
- fw_to_string((char *)&fw_commit_event->old_fw_rev));
+ util_fw_to_string((char *)&fw_commit_event->old_fw_rev));
printf("New Firmware Revision: %"PRIu64" (%s)\n",
le64_to_cpu(fw_commit_event->new_fw_rev),
- fw_to_string((char *)&fw_commit_event->new_fw_rev));
+ util_fw_to_string((char *)&fw_commit_event->new_fw_rev));
printf("FW Commit Action: %u\n",
fw_commit_event->fw_commit_action);
printf("FW Slot: %u\n", fw_commit_event->fw_slot);
@@ -1646,7 +1622,7 @@ void nvme_show_persistent_event_log(void *pevent_log_info,
printf("Power On Reset Event Entry: \n");
fw_rev = pevent_log_info + offset;
printf("Firmware Revision: %"PRIu64" (%s)\n", le64_to_cpu(*fw_rev),
- fw_to_string((char *)fw_rev));
+ util_fw_to_string((char *)fw_rev));
printf("Reset Information List: \n");
for (int i = 0; i < por_info_list; i++) {
@@ -2263,10 +2239,10 @@ static void json_supported_cap_config_log(
le16_to_cpu(cap_log->cap_config_desc[i].egcd[j].endgid));
json_object_add_value_uint(endurance, "cap_adj_factor",
le16_to_cpu(cap_log->cap_config_desc[i].egcd[j].cap_adj_factor));
- json_object_add_value_double(endurance, "tegcap",
- int128_to_double(cap_log->cap_config_desc[i].egcd[j].tegcap));
- json_object_add_value_double(endurance, "segcap",
- int128_to_double(cap_log->cap_config_desc[i].egcd[j].segcap));
+ json_object_add_value_uint128(endurance, "tegcap",
+ le128_to_cpu(cap_log->cap_config_desc[i].egcd[j].tegcap));
+ json_object_add_value_uint128(endurance, "segcap",
+ le128_to_cpu(cap_log->cap_config_desc[i].egcd[j].segcap));
json_object_add_value_uint(endurance, "egsets",
le16_to_cpu(cap_log->cap_config_desc[i].egcd[j].egsets));
egsets = le16_to_cpu(cap_log->cap_config_desc[i].egcd[j].egsets);
@@ -2343,12 +2319,15 @@ void nvme_show_supported_cap_config_log(
le16_to_cpu(cap->cap_config_desc[i].egcd[j].endgid));
printf("Capacity Adjustment Factor: %u\n",
le16_to_cpu(cap->cap_config_desc[i].egcd[j].cap_adj_factor));
- printf("Total Endurance Group Capacity: %'.0Lf\n",
- int128_to_double(cap->cap_config_desc[i].egcd[j].tegcap));
- printf("Spare Endurance Group Capacity: %'.0Lf\n",
- int128_to_double(cap->cap_config_desc[i].egcd[j].segcap));
- printf("Endurance Estimate: %'.0Lf\n",
- int128_to_double(cap->cap_config_desc[i].egcd[j].end_est));
+ printf("Total Endurance Group Capacity: %s\n",
+ uint128_t_to_string(le128_to_cpu(
+ cap->cap_config_desc[i].egcd[j].tegcap)));
+ printf("Spare Endurance Group Capacity: %s\n",
+ uint128_t_to_string(le128_to_cpu(
+ cap->cap_config_desc[i].egcd[j].segcap)));
+ printf("Endurance Estimate: %s\n",
+ uint128_t_to_string(le128_to_cpu(
+ cap->cap_config_desc[i].egcd[j].end_est)));
egsets = le16_to_cpu(cap->cap_config_desc[i].egcd[j].egsets);
printf("Number of NVM Sets: %u\n", egsets);
for(k = 0; k < egsets; k++) {
@@ -2503,12 +2482,14 @@ static void json_print_nvme_subsystem_list(nvme_root_t r, bool show_ana)
nvme_for_each_host(r, h) {
nvme_subsystem_t s;
+ const char *hostid;
host_attrs = json_create_object();
json_object_add_value_string(host_attrs, "HostNQN",
nvme_host_get_hostnqn(h));
- json_object_add_value_string(host_attrs, "HostID",
- nvme_host_get_hostid(h));
+ hostid = nvme_host_get_hostid(h);
+ if (hostid)
+ json_object_add_value_string(host_attrs, "HostID", hostid);
subsystems = json_create_array();
nvme_for_each_subsystem(h, s) {
subsystem_attrs = json_create_object();
@@ -3274,20 +3255,32 @@ void d_raw(unsigned char *buf, unsigned len)
putchar(*(buf+i));
}
-void nvme_show_status(__u16 status)
-{
- fprintf(stderr, "NVMe status: %s(%#x)\n",
- nvme_status_to_string(status, false), status);
-}
-
-static const char *nvme_uuid_to_string(uuid_t uuid)
+void nvme_show_status(int status)
{
- /* large enough to hold uuid str (37) + null-termination byte */
- static char uuid_str[40];
+ int val = nvme_status_get_value(status);
+ int type = nvme_status_get_type(status);
- uuid_unparse_lower(uuid, uuid_str);
+ /* Callers should be checking for negative values first, but provide a
+ * sensible fallback anyway
+ */
+ if (status < 0) {
+ fprintf(stderr, "Error: %s\n", nvme_strerror(errno));
+ return;
+ }
- return uuid_str;
+ switch (type) {
+ case NVME_STATUS_TYPE_NVME:
+ fprintf(stderr, "NVMe status: %s(%#x)\n",
+ nvme_status_to_string(val, false), val);
+ break;
+ case NVME_STATUS_TYPE_MI:
+ fprintf(stderr, "NVMe-MI status: %s(%#x)\n",
+ nvme_mi_status_to_string(val), val);
+ break;
+ default:
+ fprintf(stderr, "Unknown status type %d, value %#x\n",
+ type, val);
+ }
}
static void nvme_show_id_ctrl_cmic(__u8 cmic)
@@ -3618,16 +3611,14 @@ static void nvme_show_id_ctrl_cctemp(__le16 cctemp)
static void nvme_show_id_ctrl_tnvmcap(__u8 *tnvmcap)
{
- printf("[127:0] : %.0Lf\tTotal NVM Capacity (TNVMCAP)\n",
- int128_to_double(tnvmcap));
- printf("\n");
+ printf("[127:0] : %s\n", uint128_t_to_string(le128_to_cpu(tnvmcap)));
+ printf("\tTotal NVM Capacity (TNVMCAP)\n\n");
}
static void nvme_show_id_ctrl_unvmcap(__u8 *unvmcap)
{
- printf("[127:0] : %.0Lf\tUnallocated NVM Capacity (UNVMCAP)\n",
- int128_to_double(unvmcap));
- printf("\n");
+ printf("[127:0] : %s\n", uint128_t_to_string(le128_to_cpu(unvmcap)));
+ printf("\tUnallocated NVM Capacity (UNVMCAP)\n\n");
}
void nvme_show_id_ctrl_rpmbs(__le32 ctrl_rpmbs)
@@ -4208,7 +4199,8 @@ void nvme_show_id_ns(struct nvme_id_ns *ns, unsigned int nsid,
printf("nabo : %d\n", le16_to_cpu(ns->nabo));
printf("nabspf : %d\n", le16_to_cpu(ns->nabspf));
printf("noiob : %d\n", le16_to_cpu(ns->noiob));
- printf("nvmcap : %.0Lf\n", int128_to_double(ns->nvmcap));
+ printf("nvmcap : %s\n",
+ uint128_t_to_string(le128_to_cpu(ns->nvmcap)));
if (ns->nsfeat & 0x10) {
printf("npwg : %u\n", le16_to_cpu(ns->npwg));
printf("npwa : %u\n", le16_to_cpu(ns->npwa));
@@ -4355,7 +4347,7 @@ static void json_nvme_id_ns_descs(void *data)
union {
__u8 eui64[NVME_NIDT_EUI64_LEN];
__u8 nguid[NVME_NIDT_NGUID_LEN];
- uuid_t uuid;
+ __u8 uuid[NVME_UUID_LEN];
__u8 csi;
} desc;
@@ -4396,7 +4388,7 @@ static void json_nvme_id_ns_descs(void *data)
case NVME_NIDT_UUID:
memcpy(desc.uuid, data + off, sizeof(desc.uuid));
- uuid_unparse_lower(desc.uuid, json_str);
+ nvme_uuid_to_string(desc.uuid, json_str);
len = sizeof(desc.uuid);
nidt_name = "uuid";
break;
@@ -4446,8 +4438,8 @@ void nvme_show_id_ns_descs(void *data, unsigned nsid, enum nvme_print_flags flag
{
int pos, len = 0;
int i;
- uuid_t uuid;
- char uuid_str[37];
+ __u8 uuid[NVME_UUID_LEN];
+ char uuid_str[NVME_UUID_LEN_STRING];
__u8 eui64[8];
__u8 nguid[16];
__u8 csi;
@@ -4483,7 +4475,7 @@ void nvme_show_id_ns_descs(void *data, unsigned nsid, enum nvme_print_flags flag
break;
case NVME_NIDT_UUID:
memcpy(uuid, data + pos + sizeof(*cur), 16);
- uuid_unparse_lower(uuid, uuid_str);
+ nvme_uuid_to_string(uuid, uuid_str);
printf("uuid : %s\n", uuid_str);
len = sizeof(uuid);
break;
@@ -4622,7 +4614,7 @@ void nvme_show_id_ctrl(struct nvme_id_ctrl *ctrl, enum nvme_print_flags flags,
printf("cntrltype : %d\n", ctrl->cntrltype);
if (human)
nvme_show_id_ctrl_cntrltype(ctrl->cntrltype);
- printf("fguid : %-.*s\n", (int)sizeof(ctrl->fguid), ctrl->fguid);
+ printf("fguid : %s\n", util_uuid_to_string(ctrl->fguid));
printf("crdt1 : %u\n", le16_to_cpu(ctrl->crdt1));
printf("crdt2 : %u\n", le16_to_cpu(ctrl->crdt2));
printf("crdt3 : %u\n", le16_to_cpu(ctrl->crdt3));
@@ -4668,10 +4660,12 @@ void nvme_show_id_ctrl(struct nvme_id_ctrl *ctrl, enum nvme_print_flags flags,
printf("mtfa : %d\n", le16_to_cpu(ctrl->mtfa));
printf("hmpre : %d\n", le32_to_cpu(ctrl->hmpre));
printf("hmmin : %d\n", le32_to_cpu(ctrl->hmmin));
- printf("tnvmcap : %.0Lf\n", int128_to_double(ctrl->tnvmcap));
+ printf("tnvmcap : %s\n",
+ uint128_t_to_string(le128_to_cpu(ctrl->tnvmcap)));
if (human)
nvme_show_id_ctrl_tnvmcap(ctrl->tnvmcap);
- printf("unvmcap : %.0Lf\n", int128_to_double(ctrl->unvmcap));
+ printf("unvmcap : %s\n",
+ uint128_t_to_string(le128_to_cpu(ctrl->unvmcap)));
if (human)
nvme_show_id_ctrl_unvmcap(ctrl->unvmcap);
printf("rpmbs : %#x\n", le32_to_cpu(ctrl->rpmbs));
@@ -4705,7 +4699,8 @@ void nvme_show_id_ctrl(struct nvme_id_ctrl *ctrl, enum nvme_print_flags flags,
printf("nanagrpid : %d\n", le32_to_cpu(ctrl->nanagrpid));
printf("pels : %d\n", le32_to_cpu(ctrl->pels));
printf("domainid : %d\n", le16_to_cpu(ctrl->domainid));
- printf("megcap : %.0Lf\n", int128_to_double(ctrl->megcap));
+ printf("megcap : %s\n",
+ uint128_t_to_string(le128_to_cpu(ctrl->megcap)));
printf("sqes : %#x\n", ctrl->sqes);
if (human)
nvme_show_id_ctrl_sqes(ctrl->sqes);
@@ -4742,7 +4737,8 @@ void nvme_show_id_ctrl(struct nvme_id_ctrl *ctrl, enum nvme_print_flags flags,
if (human)
nvme_show_id_ctrl_sgls(ctrl->sgls);
printf("mnan : %d\n", le32_to_cpu(ctrl->mnan));
- printf("maxdna : %.0Lf\n", int128_to_double(ctrl->maxdna));
+ printf("maxdna : %s\n",
+ uint128_t_to_string(le128_to_cpu(ctrl->maxdna)));
printf("maxcna : %d\n", le32_to_cpu(ctrl->maxcna));
printf("subnqn : %-.*s\n", (int)sizeof(ctrl->subnqn), ctrl->subnqn);
printf("ioccsz : %d\n", le32_to_cpu(ctrl->ioccsz));
@@ -5366,10 +5362,10 @@ static void json_nvme_id_nvmset(struct nvme_id_nvmset_list *nvmset)
le32_to_cpu(nvmset->ent[i].rr4kt));
json_object_add_value_int(entry, "optimal_write_size",
le32_to_cpu(nvmset->ent[i].ows));
- json_object_add_value_double(entry, "total_nvmset_cap",
- int128_to_double(nvmset->ent[i].tnvmsetcap));
- json_object_add_value_double(entry, "unalloc_nvmset_cap",
- int128_to_double(nvmset->ent[i].unvmsetcap));
+ json_object_add_value_uint128(entry, "total_nvmset_cap",
+ le128_to_cpu(nvmset->ent[i].tnvmsetcap));
+ json_object_add_value_uint128(entry, "unalloc_nvmset_cap",
+ le128_to_cpu(nvmset->ent[i].unvmsetcap));
json_array_add_value_object(entries, entry);
}
@@ -5403,10 +5399,12 @@ void nvme_show_id_nvmset(struct nvme_id_nvmset_list *nvmset, unsigned nvmset_id,
le32_to_cpu(nvmset->ent[i].rr4kt));
printf("optimal_write_size : %u\n",
le32_to_cpu(nvmset->ent[i].ows));
- printf("total_nvmset_cap : %.0Lf\n",
- int128_to_double(nvmset->ent[i].tnvmsetcap));
- printf("unalloc_nvmset_cap : %.0Lf\n",
- int128_to_double(nvmset->ent[i].unvmsetcap));
+ printf("total_nvmset_cap : %s\n",
+ uint128_t_to_string(
+ le128_to_cpu(nvmset->ent[i].tnvmsetcap)));
+ printf("unalloc_nvmset_cap : %s\n",
+ uint128_t_to_string(
+ le128_to_cpu(nvmset->ent[i].unvmsetcap)));
printf(".................\n");
}
}
@@ -5630,7 +5628,7 @@ static void json_nvme_id_uuid_list(const struct nvme_id_uuid_list *uuid_list)
entries = json_create_array();
/* The 0th entry is reserved */
for (i = 1; i < NVME_ID_UUID_LIST_MAX; i++) {
- uuid_t uuid;
+ __u8 uuid[NVME_UUID_LEN];
struct json_object *entry = json_create_object();
/* The list is terminated by a zero UUID value */
@@ -5640,7 +5638,7 @@ static void json_nvme_id_uuid_list(const struct nvme_id_uuid_list *uuid_list)
json_object_add_value_int(entry, "association",
uuid_list->entry[i].header & 0x3);
json_object_add_value_string(entry, "uuid",
- nvme_uuid_to_string(uuid));
+ util_uuid_to_string(uuid));
json_array_add_value_object(entries, entry);
}
json_object_add_value_array(root, "UUID-list", entries);
@@ -5662,13 +5660,13 @@ void nvme_show_id_uuid_list(const struct nvme_id_uuid_list *uuid_list,
/* The 0th entry is reserved */
printf("NVME Identify UUID:\n");
for (i = 0; i < NVME_ID_UUID_LIST_MAX; i++) {
- uuid_t uuid;
+ __u8 uuid[NVME_UUID_LEN];
char *association = "";
uint8_t identifier_association = uuid_list->entry[i].header & 0x3;
/* The list is terminated by a zero UUID value */
- if (memcmp(uuid_list->entry[i].uuid, zero_uuid, sizeof(zero_uuid)) == 0)
+ if (memcmp(uuid_list->entry[i].uuid, zero_uuid, NVME_UUID_LEN) == 0)
break;
- memcpy(&uuid, uuid_list->entry[i].uuid, sizeof(uuid));
+ memcpy(&uuid, uuid_list->entry[i].uuid, NVME_UUID_LEN);
if (human) {
switch (identifier_association) {
case 0x0:
@@ -5688,7 +5686,7 @@ void nvme_show_id_uuid_list(const struct nvme_id_uuid_list *uuid_list,
printf(" Entry[%3d]\n", i+1);
printf(".................\n");
printf("association : 0x%x %s\n", identifier_association, association);
- printf("UUID : %s", nvme_uuid_to_string(uuid));
+ printf("UUID : %s", util_uuid_to_string(uuid));
if (memcmp(uuid_list->entry[i].uuid, invalid_uuid,
sizeof(zero_uuid)) == 0)
printf(" (Invalid UUID)");
@@ -5702,7 +5700,7 @@ static void json_id_domain_list(struct nvme_id_domain_list *id_dom)
struct json_object *entries;
struct json_object *entry;
int i;
- long double dom_cap, unalloc_dom_cap, max_egrp_dom_cap;
+ nvme_uint128_t dom_cap, unalloc_dom_cap, max_egrp_dom_cap;
root = json_create_object();
entries = json_create_array();
@@ -5711,14 +5709,14 @@ static void json_id_domain_list(struct nvme_id_domain_list *id_dom)
for (i = 0; i < id_dom->num; i++) {
entry = json_create_object();
- dom_cap = int128_to_double(id_dom->domain_attr[i].dom_cap);
- unalloc_dom_cap = int128_to_double(id_dom->domain_attr[i].unalloc_dom_cap);
- max_egrp_dom_cap = int128_to_double(id_dom->domain_attr[i].max_egrp_dom_cap);
+ dom_cap = le128_to_cpu(id_dom->domain_attr[i].dom_cap);
+ unalloc_dom_cap = le128_to_cpu(id_dom->domain_attr[i].unalloc_dom_cap);
+ max_egrp_dom_cap = le128_to_cpu(id_dom->domain_attr[i].max_egrp_dom_cap);
json_object_add_value_uint(entry, "dom_id", le16_to_cpu(id_dom->domain_attr[i].dom_id));
- json_object_add_value_double(entry, "dom_cap", dom_cap);
- json_object_add_value_double(entry, "unalloc_dom_cap", unalloc_dom_cap);
- json_object_add_value_double(entry, "max_egrp_dom_cap", max_egrp_dom_cap);
+ json_object_add_value_uint128(entry, "dom_cap", dom_cap);
+ json_object_add_value_uint128(entry, "unalloc_dom_cap", unalloc_dom_cap);
+ json_object_add_value_uint128(entry, "max_egrp_dom_cap", max_egrp_dom_cap);
json_array_add_value_object(entries, entry);
}
@@ -5742,12 +5740,15 @@ void nvme_show_id_domain_list(struct nvme_id_domain_list *id_dom,
for (i = 0; i < id_dom->num; i++) {
printf("Domain Id for Attr Entry[%u]: %u\n", i,
le16_to_cpu(id_dom->domain_attr[i].dom_id));
- printf("Domain Capacity for Attr Entry[%u]: %.0Lf\\n", i,
- int128_to_double(id_dom->domain_attr[i].dom_cap));
- printf("Unallocated Domain Capacity for Attr Entry[%u]: %.0Lf\n", i,
- int128_to_double(id_dom->domain_attr[i].unalloc_dom_cap));
- printf("Max Endurance Group Domain Capacity for Attr Entry[%u]: %.0Lf\n", i,
- int128_to_double(id_dom->domain_attr[i].max_egrp_dom_cap));
+ printf("Domain Capacity for Attr Entry[%u]: %s\n", i,
+ uint128_t_to_string(
+ le128_to_cpu(id_dom->domain_attr[i].dom_cap)));
+ printf("Unallocated Domain Capacity for Attr Entry[%u]: %s\n", i,
+ uint128_t_to_string(
+ le128_to_cpu(id_dom->domain_attr[i].unalloc_dom_cap)));
+ printf("Max Endurance Group Domain Capacity for Attr Entry[%u]: %s\n", i,
+ uint128_t_to_string(
+ le128_to_cpu(id_dom->domain_attr[i].max_egrp_dom_cap)));
}
}
@@ -5938,7 +5939,7 @@ void nvme_show_fw_log(struct nvme_firmware_slot *fw_log,
frs = (__le64 *)&fw_log->frs[i];
printf("frs%d : %#016"PRIx64" (%s)\n", i + 1,
le64_to_cpu(*frs),
- fw_to_string(fw_log->frs[i]));
+ util_fw_to_string(fw_log->frs[i]));
}
}
}
@@ -6175,18 +6176,6 @@ void nvme_show_supported_log(struct nvme_supported_log_pages *support_log,
}
}
-uint64_t int48_to_long(__u8 *data)
-{
- int i;
- uint64_t result = 0;
-
- for (i = 0; i < 6; i++) {
- result *= 256;
- result += data[5 - i];
- }
- return result;
-}
-
void nvme_show_endurance_log(struct nvme_endurance_group_log *endurance_log,
__u16 group_id, const char *devname,
enum nvme_print_flags flags)
@@ -6205,22 +6194,30 @@ void nvme_show_endurance_log(struct nvme_endurance_group_log *endurance_log,
printf("avl_spare_threshold : %u\n",
endurance_log->avl_spare_threshold);
printf("percent_used : %u%%\n", endurance_log->percent_used);
- printf("endurance_estimate : %'.0Lf\n",
- int128_to_double(endurance_log->endurance_estimate));
- printf("data_units_read : %'.0Lf\n",
- int128_to_double(endurance_log->data_units_read));
- printf("data_units_written : %'.0Lf\n",
- int128_to_double(endurance_log->data_units_written));
- printf("media_units_written : %'.0Lf\n",
- int128_to_double(endurance_log->media_units_written));
- printf("host_read_cmds : %'.0Lf\n",
- int128_to_double(endurance_log->host_read_cmds));
- printf("host_write_cmds : %'.0Lf\n",
- int128_to_double(endurance_log->host_write_cmds));
- printf("media_data_integrity_err: %'.0Lf\n",
- int128_to_double(endurance_log->media_data_integrity_err));
- printf("num_err_info_log_entries: %'.0Lf\n",
- int128_to_double(endurance_log->num_err_info_log_entries));
+ printf("endurance_estimate : %s\n",
+ uint128_t_to_string(
+ le128_to_cpu(endurance_log->endurance_estimate)));
+ printf("data_units_read : %s\n",
+ uint128_t_to_string(
+ le128_to_cpu(endurance_log->data_units_read)));
+ printf("data_units_written : %s\n",
+ uint128_t_to_string(
+ le128_to_cpu(endurance_log->data_units_written)));
+ printf("media_units_written : %s\n",
+ uint128_t_to_string(
+ le128_to_cpu(endurance_log->media_units_written)));
+ printf("host_read_cmds : %s\n",
+ uint128_t_to_string(
+ le128_to_cpu(endurance_log->host_read_cmds)));
+ printf("host_write_cmds : %s\n",
+ uint128_t_to_string(
+ le128_to_cpu(endurance_log->host_write_cmds)));
+ printf("media_data_integrity_err: %s\n",
+ uint128_t_to_string(
+ le128_to_cpu(endurance_log->media_data_integrity_err)));
+ printf("num_err_info_log_entries: %s\n",
+ uint128_t_to_string(
+ le128_to_cpu(endurance_log->num_err_info_log_entries)));
}
void nvme_show_smart_log(struct nvme_smart_log *smart, unsigned int nsid,
@@ -6258,26 +6255,26 @@ void nvme_show_smart_log(struct nvme_smart_log *smart, unsigned int nsid,
smart->percent_used);
printf("endurance group critical warning summary: %#x\n",
smart->endu_grp_crit_warn_sumry);
- printf("data_units_read : %'.0Lf\n",
- int128_to_double(smart->data_units_read));
- printf("data_units_written : %'.0Lf\n",
- int128_to_double(smart->data_units_written));
- printf("host_read_commands : %'.0Lf\n",
- int128_to_double(smart->host_reads));
- printf("host_write_commands : %'.0Lf\n",
- int128_to_double(smart->host_writes));
- printf("controller_busy_time : %'.0Lf\n",
- int128_to_double(smart->ctrl_busy_time));
- printf("power_cycles : %'.0Lf\n",
- int128_to_double(smart->power_cycles));
- printf("power_on_hours : %'.0Lf\n",
- int128_to_double(smart->power_on_hours));
- printf("unsafe_shutdowns : %'.0Lf\n",
- int128_to_double(smart->unsafe_shutdowns));
- printf("media_errors : %'.0Lf\n",
- int128_to_double(smart->media_errors));
- printf("num_err_log_entries : %'.0Lf\n",
- int128_to_double(smart->num_err_log_entries));
+ printf("data_units_read : %s\n",
+ uint128_t_to_string(le128_to_cpu(smart->data_units_read)));
+ printf("data_units_written : %s\n",
+ uint128_t_to_string(le128_to_cpu(smart->data_units_written)));
+ printf("host_read_commands : %s\n",
+ uint128_t_to_string(le128_to_cpu(smart->host_reads)));
+ printf("host_write_commands : %s\n",
+ uint128_t_to_string(le128_to_cpu(smart->host_writes)));
+ printf("controller_busy_time : %s\n",
+ uint128_t_to_string(le128_to_cpu(smart->ctrl_busy_time)));
+ printf("power_cycles : %s\n",
+ uint128_t_to_string(le128_to_cpu(smart->power_cycles)));
+ printf("power_on_hours : %s\n",
+ uint128_t_to_string(le128_to_cpu(smart->power_on_hours)));
+ printf("unsafe_shutdowns : %s\n",
+ uint128_t_to_string(le128_to_cpu(smart->unsafe_shutdowns)));
+ printf("media_errors : %s\n",
+ uint128_t_to_string(le128_to_cpu(smart->media_errors)));
+ printf("num_err_log_entries : %s\n",
+ uint128_t_to_string(le128_to_cpu(smart->num_err_log_entries)));
printf("Warning Temperature Time : %u\n",
le32_to_cpu(smart->warning_temp_time));
printf("Critical Composite Temperature Time : %u\n",
@@ -6500,7 +6497,7 @@ void nvme_show_sanitize_log(struct nvme_sanitize_log_page *sanitize,
printf("\n");
printf("Sanitize Status (SSTAT) : %#x\n",
- le16_to_cpu(sanitize->sstat));
+ le16_to_cpu(sanitize->sstat) & NVME_SANITIZE_SSTAT_STATUS_MASK);
if (human)
nvme_show_sanitize_log_sstat(le16_to_cpu(sanitize->sstat));
@@ -7385,9 +7382,12 @@ static void json_detail_list(nvme_root_t r)
nvme_for_each_host(r, h) {
struct json_object *hss = json_create_object();
struct json_object *jsslist = json_create_array();
+ const char *hostid;
json_object_add_value_string(hss, "HostNQN", nvme_host_get_hostnqn(h));
- json_object_add_value_string(hss, "HostID", nvme_host_get_hostid(h));
+ hostid = nvme_host_get_hostid(h);
+ if (hostid)
+ json_object_add_value_string(hss, "HostID", hostid);
nvme_for_each_subsystem(h , s) {
struct json_object *jss = json_create_object();
@@ -7540,3 +7540,247 @@ void nvme_show_list_items(nvme_root_t r, enum nvme_print_flags flags)
else
nvme_show_simple_list(r);
}
+
+static unsigned int json_subsystem_topology_multipath(nvme_subsystem_t s,
+ json_object *namespaces)
+{
+ nvme_ns_t n;
+ nvme_path_t p;
+ unsigned int i = 0;
+
+ nvme_subsystem_for_each_ns(s, n) {
+ struct json_object *ns_attrs;
+ struct json_object *paths;
+
+ ns_attrs = json_create_object();
+ json_object_add_value_int(ns_attrs, "NSID",
+ nvme_ns_get_nsid(n));
+
+ paths = json_create_array();
+ nvme_namespace_for_each_path(n, p) {
+ struct json_object *path_attrs;
+
+ nvme_ctrl_t c = nvme_path_get_ctrl(p);
+
+ path_attrs = json_create_object();
+ json_object_add_value_string(path_attrs, "Name",
+ nvme_ctrl_get_name(c));
+ json_object_add_value_string(path_attrs, "Transport",
+ nvme_ctrl_get_transport(c));
+ json_object_add_value_string(path_attrs, "Address",
+ nvme_ctrl_get_address(c));
+ json_object_add_value_string(path_attrs, "State",
+ nvme_ctrl_get_state(c));
+ json_object_add_value_string(path_attrs, "ANAState",
+ nvme_path_get_ana_state(p));
+ json_array_add_value_object(paths, path_attrs);
+ }
+ json_object_add_value_array(ns_attrs, "Paths", paths);
+ json_array_add_value_object(namespaces, ns_attrs);
+ i++;
+ }
+
+ return i;
+}
+
+static void json_print_nvme_subsystem_topology(nvme_subsystem_t s,
+ json_object *namespaces)
+{
+ nvme_ctrl_t c;
+ nvme_ns_t n;
+
+ nvme_subsystem_for_each_ctrl(s, c) {
+ nvme_ctrl_for_each_ns(c, n) {
+ struct json_object *ctrl_attrs;
+ struct json_object *ns_attrs;
+ struct json_object *ctrl;
+
+ ns_attrs = json_create_object();
+ json_object_add_value_int(ns_attrs, "NSID",
+ nvme_ns_get_nsid(n));
+
+ ctrl = json_create_array();
+ ctrl_attrs = json_create_object();
+ json_object_add_value_string(ctrl_attrs, "Name",
+ nvme_ctrl_get_name(c));
+ json_object_add_value_string(ctrl_attrs, "Transport",
+ nvme_ctrl_get_transport(c));
+ json_object_add_value_string(ctrl_attrs, "Address",
+ nvme_ctrl_get_address(c));
+ json_object_add_value_string(ctrl_attrs, "State",
+ nvme_ctrl_get_state(c));
+
+ json_array_add_value_object(ctrl, ctrl_attrs);
+ json_object_add_value_array(ns_attrs, "Controller", ctrl);
+ json_array_add_value_object(namespaces, ns_attrs);
+ }
+ }
+}
+
+static void json_simple_topology(nvme_root_t r)
+{
+ struct json_object *host_attrs, *subsystem_attrs;
+ struct json_object *subsystems, *namespaces;
+ struct json_object *root;
+ nvme_host_t h;
+
+ root = json_create_array();
+
+ nvme_for_each_host(r, h) {
+ nvme_subsystem_t s;
+ const char *hostid;
+
+ host_attrs = json_create_object();
+ json_object_add_value_string(host_attrs, "HostNQN",
+ nvme_host_get_hostnqn(h));
+ hostid = nvme_host_get_hostid(h);
+ if (hostid)
+ json_object_add_value_string(host_attrs, "HostID", hostid);
+ subsystems = json_create_array();
+ nvme_for_each_subsystem(h, s) {
+ subsystem_attrs = json_create_object();
+ json_object_add_value_string(subsystem_attrs, "Name",
+ nvme_subsystem_get_name(s));
+ json_object_add_value_string(subsystem_attrs, "NQN",
+ nvme_subsystem_get_nqn(s));
+
+ json_array_add_value_object(subsystems, subsystem_attrs);
+ namespaces = json_create_array();
+
+ if (!json_subsystem_topology_multipath(s, namespaces))
+ json_print_nvme_subsystem_topology(s, namespaces);
+
+ json_object_add_value_array(subsystem_attrs, "Namespaces",
+ namespaces);
+ }
+ json_object_add_value_array(host_attrs, "Subsystems", subsystems);
+ json_array_add_value_object(root, host_attrs);
+ }
+ json_print_object(root, NULL);
+ printf("\n");
+ json_free_object(root);
+}
+
+static bool nvme_is_multipath(nvme_subsystem_t s)
+{
+ nvme_ns_t n;
+ nvme_path_t p;
+
+ nvme_subsystem_for_each_ns(s, n)
+ nvme_namespace_for_each_path(n, p)
+ return true;
+
+ return false;
+}
+
+static void nvme_show_subsystem_topology_multipath(nvme_subsystem_t s,
+ enum nvme_cli_topo_ranking ranking)
+{
+ nvme_ns_t n;
+ nvme_path_t p;
+ nvme_ctrl_t c;
+
+ if (ranking == NVME_CLI_TOPO_NAMESPACE) {
+ nvme_subsystem_for_each_ns(s, n) {
+ printf(" +- ns %d\n", nvme_ns_get_nsid(n));
+ printf(" \\\n");
+
+ nvme_namespace_for_each_path(n, p) {
+ c = nvme_path_get_ctrl(p);
+
+ printf(" +- %s %s %s %s %s\n",
+ nvme_ctrl_get_name(c),
+ nvme_ctrl_get_transport(c),
+ nvme_ctrl_get_address(c),
+ nvme_ctrl_get_state(c),
+ nvme_path_get_ana_state(p));
+ }
+ }
+ } else {
+ /* NVME_CLI_TOPO_CTRL */
+ nvme_subsystem_for_each_ctrl(s, c) {
+ printf(" +- %s %s %s\n",
+ nvme_ctrl_get_name(c),
+ nvme_ctrl_get_transport(c),
+ nvme_ctrl_get_address(c));
+ printf(" \\\n");
+
+ nvme_subsystem_for_each_ns(s, n) {
+ nvme_namespace_for_each_path(n, p) {
+ if (nvme_path_get_ctrl(p) != c)
+ continue;
+
+ printf(" +- ns %d %s %s\n",
+ nvme_ns_get_nsid(n),
+ nvme_ctrl_get_state(c),
+ nvme_path_get_ana_state(p));
+ }
+ }
+ }
+ }
+}
+
+static void nvme_show_subsystem_topology(nvme_subsystem_t s,
+ enum nvme_cli_topo_ranking ranking)
+{
+ nvme_ctrl_t c;
+ nvme_ns_t n;
+
+ if (ranking == NVME_CLI_TOPO_NAMESPACE) {
+ nvme_subsystem_for_each_ctrl(s, c) {
+ nvme_ctrl_for_each_ns(c, n) {
+ printf(" +- ns %d\n", nvme_ns_get_nsid(n));
+ printf(" \\\n");
+ printf(" +- %s %s %s %s\n",
+ nvme_ctrl_get_name(c),
+ nvme_ctrl_get_transport(c),
+ nvme_ctrl_get_address(c),
+ nvme_ctrl_get_state(c));
+ }
+ }
+ } else {
+ /* NVME_CLI_TOPO_CTRL */
+ nvme_subsystem_for_each_ctrl(s, c) {
+ printf(" +- %s %s %s\n",
+ nvme_ctrl_get_name(c),
+ nvme_ctrl_get_transport(c),
+ nvme_ctrl_get_address(c));
+ printf(" \\\n");
+ nvme_ctrl_for_each_ns(c, n) {
+ printf(" +- ns %d %s\n",
+ nvme_ns_get_nsid(n),
+ nvme_ctrl_get_state(c));
+ }
+ }
+ }
+}
+
+static void nvme_show_simple_topology(nvme_root_t r,
+ enum nvme_cli_topo_ranking ranking)
+{
+ nvme_host_t h;
+ nvme_subsystem_t s;
+
+ nvme_for_each_host(r, h) {
+ nvme_for_each_subsystem(h, s) {
+
+ printf("%s - NQN=%s\n", nvme_subsystem_get_name(s),
+ nvme_subsystem_get_nqn(s));
+ printf("\\\n");
+
+ if (nvme_is_multipath(s))
+ nvme_show_subsystem_topology_multipath(s, ranking);
+ else
+ nvme_show_subsystem_topology(s, ranking);
+ }
+ }
+}
+
+void nvme_show_topology(nvme_root_t r, enum nvme_print_flags flags,
+ enum nvme_cli_topo_ranking ranking)
+{
+ if (flags & JSON)
+ json_simple_topology(r);
+ else
+ nvme_show_simple_topology(r, ranking);
+}