553 lines
24 KiB
C
553 lines
24 KiB
C
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <inttypes.h>
|
|
#include <errno.h>
|
|
#include <limits.h>
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include <dirent.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include "common.h"
|
|
#include "nvme.h"
|
|
#include "libnvme.h"
|
|
#include "plugin.h"
|
|
#include "nvme-print.h"
|
|
|
|
#include "util/suffix.h"
|
|
|
|
#define CREATE_CMD
|
|
#include "dapustor-nvme.h"
|
|
|
|
struct __packed nvme_additional_smart_log_item {
|
|
__u8 key;
|
|
__u8 _kp[2];
|
|
__u8 norm;
|
|
__u8 _np;
|
|
union __packed {
|
|
__u8 raw[6];
|
|
struct __packed wear_level {
|
|
__le16 min;
|
|
__le16 max;
|
|
__le16 avg;
|
|
} wear_level;
|
|
struct __packed thermal_throttle {
|
|
__u8 pct;
|
|
__u32 count;
|
|
} thermal_throttle;
|
|
struct __packed temperature {
|
|
__le16 max;
|
|
__le16 min;
|
|
__le16 cur;
|
|
} temperature;
|
|
struct __packed power_consumption {
|
|
__le16 max;
|
|
__le16 min;
|
|
__le16 avg;
|
|
} power_consumption;
|
|
struct __packed thermal_throttle_time {
|
|
__u8 sts;
|
|
__u32 time;
|
|
__u8 rsv;
|
|
} thermal_throttle_time;
|
|
};
|
|
__u8 _rp;
|
|
};
|
|
|
|
struct nvme_additional_smart_log {
|
|
struct nvme_additional_smart_log_item program_fail_cnt;
|
|
struct nvme_additional_smart_log_item erase_fail_cnt;
|
|
struct nvme_additional_smart_log_item wear_leveling_cnt;
|
|
struct nvme_additional_smart_log_item e2e_err_cnt;
|
|
struct nvme_additional_smart_log_item crc_err_cnt;
|
|
struct nvme_additional_smart_log_item timed_workload_media_wear;
|
|
struct nvme_additional_smart_log_item timed_workload_host_reads;
|
|
struct nvme_additional_smart_log_item timed_workload_timer;
|
|
struct nvme_additional_smart_log_item thermal_throttle_status;
|
|
struct nvme_additional_smart_log_item retry_buffer_overflow_cnt;
|
|
struct nvme_additional_smart_log_item pll_lock_loss_cnt;
|
|
struct nvme_additional_smart_log_item nand_bytes_written;
|
|
struct nvme_additional_smart_log_item host_bytes_written;
|
|
};
|
|
|
|
struct nvme_extended_additional_smart_log {
|
|
struct nvme_additional_smart_log_item sys_area_life_remain;
|
|
struct nvme_additional_smart_log_item nand_bytes_read;
|
|
struct nvme_additional_smart_log_item temperature;
|
|
struct nvme_additional_smart_log_item power_consumption;
|
|
struct nvme_additional_smart_log_item power_on_temperature;
|
|
struct nvme_additional_smart_log_item power_loss_protection;
|
|
struct nvme_additional_smart_log_item read_fail_count;
|
|
struct nvme_additional_smart_log_item thermal_throttle_time;
|
|
struct nvme_additional_smart_log_item flash_error_media_count;
|
|
struct nvme_additional_smart_log_item lifetime_write_amplification;
|
|
struct nvme_additional_smart_log_item firmware_update_count;
|
|
struct nvme_additional_smart_log_item dram_cecc_count;
|
|
struct nvme_additional_smart_log_item dram_uecc_count;
|
|
struct nvme_additional_smart_log_item xor_pass_count;
|
|
struct nvme_additional_smart_log_item xor_fail_count;
|
|
struct nvme_additional_smart_log_item xor_invoked_count;
|
|
struct nvme_additional_smart_log_item inflight_read_io_cmd;
|
|
struct nvme_additional_smart_log_item temp_since_born;
|
|
struct nvme_additional_smart_log_item temp_since_bootup;
|
|
struct nvme_additional_smart_log_item inflight_write_io_cmd;
|
|
};
|
|
|
|
static void show_dapustor_add_smart_log_jsn(struct nvme_additional_smart_log *smart,
|
|
struct json_object *dev_stats)
|
|
{
|
|
struct json_object *entry_stats, *multi;
|
|
|
|
entry_stats = json_create_object();
|
|
json_object_add_value_int(entry_stats, "normalized", smart->program_fail_cnt.norm);
|
|
json_object_add_value_int(entry_stats, "raw", int48_to_long(smart->program_fail_cnt.raw));
|
|
json_object_add_value_object(dev_stats, "program_fail_count", entry_stats);
|
|
|
|
entry_stats = json_create_object();
|
|
json_object_add_value_int(entry_stats, "normalized", smart->erase_fail_cnt.norm);
|
|
json_object_add_value_int(entry_stats, "raw", int48_to_long(smart->erase_fail_cnt.raw));
|
|
json_object_add_value_object(dev_stats, "erase_fail_count", entry_stats);
|
|
|
|
entry_stats = json_create_object();
|
|
json_object_add_value_int(entry_stats, "normalized", smart->wear_leveling_cnt.norm);
|
|
multi = json_create_object();
|
|
json_object_add_value_int(multi, "min",
|
|
le16_to_cpu(smart->wear_leveling_cnt.wear_level.min));
|
|
json_object_add_value_int(multi, "max",
|
|
le16_to_cpu(smart->wear_leveling_cnt.wear_level.max));
|
|
json_object_add_value_int(multi, "avg",
|
|
le16_to_cpu(smart->wear_leveling_cnt.wear_level.avg));
|
|
json_object_add_value_object(entry_stats, "raw", multi);
|
|
json_object_add_value_object(dev_stats, "wear_leveling", entry_stats);
|
|
|
|
entry_stats = json_create_object();
|
|
json_object_add_value_int(entry_stats, "normalized", smart->e2e_err_cnt.norm);
|
|
json_object_add_value_int(entry_stats, "raw", int48_to_long(smart->e2e_err_cnt.raw));
|
|
json_object_add_value_object(dev_stats, "end_to_end_error_detection_count", entry_stats);
|
|
|
|
entry_stats = json_create_object();
|
|
json_object_add_value_int(entry_stats, "normalized", smart->crc_err_cnt.norm);
|
|
json_object_add_value_int(entry_stats, "raw", int48_to_long(smart->crc_err_cnt.raw));
|
|
json_object_add_value_object(dev_stats, "crc_error_count", entry_stats);
|
|
|
|
entry_stats = json_create_object();
|
|
json_object_add_value_int(entry_stats, "normalized", smart->timed_workload_media_wear.norm);
|
|
json_object_add_value_float(entry_stats, "raw",
|
|
((long double)int48_to_long(smart->timed_workload_media_wear.raw)) / 1024);
|
|
json_object_add_value_object(dev_stats, "timed_workload_media_wear", entry_stats);
|
|
|
|
entry_stats = json_create_object();
|
|
json_object_add_value_int(entry_stats, "normalized", smart->timed_workload_host_reads.norm);
|
|
json_object_add_value_int(entry_stats, "raw",
|
|
int48_to_long(smart->timed_workload_host_reads.raw));
|
|
json_object_add_value_object(dev_stats, "timed_workload_host_reads", entry_stats);
|
|
|
|
entry_stats = json_create_object();
|
|
json_object_add_value_int(entry_stats, "normalized", smart->timed_workload_timer.norm);
|
|
json_object_add_value_int(entry_stats, "raw",
|
|
int48_to_long(smart->timed_workload_timer.raw));
|
|
json_object_add_value_object(dev_stats, "timed_workload_timer", entry_stats);
|
|
|
|
entry_stats = json_create_object();
|
|
json_object_add_value_int(entry_stats, "normalized", smart->thermal_throttle_status.norm);
|
|
multi = json_create_object();
|
|
json_object_add_value_int(multi, "pct",
|
|
smart->thermal_throttle_status.thermal_throttle.pct);
|
|
json_object_add_value_int(multi, "cnt",
|
|
smart->thermal_throttle_status.thermal_throttle.count);
|
|
json_object_add_value_object(entry_stats, "raw", multi);
|
|
json_object_add_value_object(dev_stats, "thermal_throttle_status", entry_stats);
|
|
|
|
entry_stats = json_create_object();
|
|
json_object_add_value_int(entry_stats, "normalized", smart->retry_buffer_overflow_cnt.norm);
|
|
json_object_add_value_int(entry_stats, "raw",
|
|
int48_to_long(smart->retry_buffer_overflow_cnt.raw));
|
|
json_object_add_value_object(dev_stats, "retry_buffer_overflow_count", entry_stats);
|
|
|
|
entry_stats = json_create_object();
|
|
json_object_add_value_int(entry_stats, "normalized", smart->pll_lock_loss_cnt.norm);
|
|
json_object_add_value_int(entry_stats, "raw", int48_to_long(smart->pll_lock_loss_cnt.raw));
|
|
json_object_add_value_object(dev_stats, "pll_lock_loss_count", entry_stats);
|
|
|
|
entry_stats = json_create_object();
|
|
json_object_add_value_int(entry_stats, "normalized", smart->nand_bytes_written.norm);
|
|
json_object_add_value_int(entry_stats, "raw", int48_to_long(smart->nand_bytes_written.raw));
|
|
json_object_add_value_object(dev_stats, "nand_bytes_written", entry_stats);
|
|
|
|
entry_stats = json_create_object();
|
|
json_object_add_value_int(entry_stats, "normalized", smart->host_bytes_written.norm);
|
|
json_object_add_value_int(entry_stats, "raw", int48_to_long(smart->host_bytes_written.raw));
|
|
json_object_add_value_object(dev_stats, "host_bytes_written", entry_stats);
|
|
}
|
|
|
|
static void show_dapustor_ext_add_smart_log_jsn(struct nvme_extended_additional_smart_log *smart,
|
|
struct json_object *dev_stats)
|
|
{
|
|
struct json_object *entry_stats, *multi;
|
|
|
|
entry_stats = json_create_object();
|
|
json_object_add_value_int(entry_stats, "normalized", smart->sys_area_life_remain.norm);
|
|
json_object_add_value_int(entry_stats, "raw",
|
|
int48_to_long(smart->sys_area_life_remain.raw));
|
|
json_object_add_value_object(dev_stats, "system_area_life_remaining", entry_stats);
|
|
|
|
entry_stats = json_create_object();
|
|
json_object_add_value_int(entry_stats, "normalized", smart->nand_bytes_read.norm);
|
|
json_object_add_value_int(entry_stats, "raw", int48_to_long(smart->nand_bytes_read.raw));
|
|
json_object_add_value_object(dev_stats, "nand_bytes_read", entry_stats);
|
|
|
|
entry_stats = json_create_object();
|
|
json_object_add_value_int(entry_stats, "normalized", smart->temperature.norm);
|
|
multi = json_create_object();
|
|
json_object_add_value_int(multi, "min", le16_to_cpu(smart->temperature.temperature.min));
|
|
json_object_add_value_int(multi, "max", le16_to_cpu(smart->temperature.temperature.max));
|
|
json_object_add_value_int(multi, "cur", le16_to_cpu(smart->temperature.temperature.cur));
|
|
json_object_add_value_object(entry_stats, "raw", multi);
|
|
json_object_add_value_object(dev_stats, "temperature", entry_stats);
|
|
|
|
entry_stats = json_create_object();
|
|
json_object_add_value_int(entry_stats, "normalized", smart->power_consumption.norm);
|
|
multi = json_create_object();
|
|
json_object_add_value_int(multi, "min",
|
|
le16_to_cpu(smart->power_consumption.power_consumption.min));
|
|
json_object_add_value_int(multi, "max",
|
|
le16_to_cpu(smart->power_consumption.power_consumption.max));
|
|
json_object_add_value_int(multi, "avg",
|
|
le16_to_cpu(smart->power_consumption.power_consumption.avg));
|
|
json_object_add_value_object(entry_stats, "raw", multi);
|
|
json_object_add_value_object(dev_stats, "power_consumption", entry_stats);
|
|
|
|
entry_stats = json_create_object();
|
|
json_object_add_value_int(entry_stats, "normalized", smart->power_on_temperature.norm);
|
|
multi = json_create_object();
|
|
json_object_add_value_int(multi, "min",
|
|
le16_to_cpu(smart->power_on_temperature.temperature.min));
|
|
json_object_add_value_int(multi, "max",
|
|
le16_to_cpu(smart->power_on_temperature.temperature.max));
|
|
json_object_add_value_int(multi, "cur",
|
|
le16_to_cpu(smart->power_on_temperature.temperature.cur));
|
|
json_object_add_value_object(entry_stats, "raw", multi);
|
|
json_object_add_value_object(dev_stats, "power_on_temperature", entry_stats);
|
|
|
|
entry_stats = json_create_object();
|
|
json_object_add_value_int(entry_stats, "normalized", smart->power_loss_protection.norm);
|
|
json_object_add_value_int(entry_stats, "raw",
|
|
int48_to_long(smart->power_loss_protection.raw));
|
|
json_object_add_value_object(dev_stats, "power_loss_protection", entry_stats);
|
|
|
|
entry_stats = json_create_object();
|
|
json_object_add_value_int(entry_stats, "normalized", smart->read_fail_count.norm);
|
|
json_object_add_value_int(entry_stats, "raw", int48_to_long(smart->read_fail_count.raw));
|
|
json_object_add_value_object(dev_stats, "read_fail_count", entry_stats);
|
|
|
|
entry_stats = json_create_object();
|
|
json_object_add_value_int(entry_stats, "normalized", smart->thermal_throttle_time.norm);
|
|
json_object_add_value_int(entry_stats, "raw",
|
|
int48_to_long(smart->thermal_throttle_time.raw));
|
|
json_object_add_value_object(dev_stats, "thermal_throttle_time", entry_stats);
|
|
|
|
entry_stats = json_create_object();
|
|
json_object_add_value_int(entry_stats, "normalized", smart->flash_error_media_count.norm);
|
|
json_object_add_value_int(entry_stats, "raw",
|
|
int48_to_long(smart->flash_error_media_count.raw));
|
|
json_object_add_value_object(dev_stats, "flash_error_media_count", entry_stats);
|
|
|
|
entry_stats = json_create_object();
|
|
json_object_add_value_int(entry_stats, "normalized",
|
|
smart->lifetime_write_amplification.norm);
|
|
json_object_add_value_int(entry_stats, "raw",
|
|
int48_to_long(smart->lifetime_write_amplification.raw));
|
|
json_object_add_value_object(dev_stats, "lifetime_write_amplification", entry_stats);
|
|
|
|
entry_stats = json_create_object();
|
|
json_object_add_value_int(entry_stats, "normalized", smart->firmware_update_count.norm);
|
|
json_object_add_value_int(entry_stats, "raw",
|
|
int48_to_long(smart->firmware_update_count.raw));
|
|
json_object_add_value_object(dev_stats, "firmware_update_count", entry_stats);
|
|
|
|
entry_stats = json_create_object();
|
|
json_object_add_value_int(entry_stats, "normalized", smart->dram_cecc_count.norm);
|
|
json_object_add_value_int(entry_stats, "raw", int48_to_long(smart->dram_cecc_count.raw));
|
|
json_object_add_value_object(dev_stats, "dram_cecc_count", entry_stats);
|
|
|
|
entry_stats = json_create_object();
|
|
json_object_add_value_int(entry_stats, "normalized", smart->dram_uecc_count.norm);
|
|
json_object_add_value_int(entry_stats, "raw", int48_to_long(smart->dram_uecc_count.raw));
|
|
json_object_add_value_object(dev_stats, "dram_uecc_count", entry_stats);
|
|
|
|
entry_stats = json_create_object();
|
|
json_object_add_value_int(entry_stats, "normalized", smart->xor_pass_count.norm);
|
|
json_object_add_value_int(entry_stats, "raw", int48_to_long(smart->xor_pass_count.raw));
|
|
json_object_add_value_object(dev_stats, "xor_pass_count", entry_stats);
|
|
|
|
entry_stats = json_create_object();
|
|
json_object_add_value_int(entry_stats, "normalized", smart->xor_fail_count.norm);
|
|
json_object_add_value_int(entry_stats, "raw", int48_to_long(smart->xor_fail_count.raw));
|
|
json_object_add_value_object(dev_stats, "xor_fail_count", entry_stats);
|
|
|
|
entry_stats = json_create_object();
|
|
json_object_add_value_int(entry_stats, "normalized", smart->xor_invoked_count.norm);
|
|
json_object_add_value_int(entry_stats, "raw", int48_to_long(smart->xor_invoked_count.raw));
|
|
json_object_add_value_object(dev_stats, "xor_invoked_count", entry_stats);
|
|
|
|
entry_stats = json_create_object();
|
|
json_object_add_value_int(entry_stats, "normalized", smart->inflight_read_io_cmd.norm);
|
|
json_object_add_value_int(entry_stats, "raw",
|
|
int48_to_long(smart->inflight_read_io_cmd.raw));
|
|
json_object_add_value_object(dev_stats, "inflight_read_io_cmd", entry_stats);
|
|
|
|
entry_stats = json_create_object();
|
|
json_object_add_value_int(entry_stats, "normalized", smart->temp_since_born.norm);
|
|
multi = json_create_object();
|
|
json_object_add_value_int(multi, "min",
|
|
le16_to_cpu(smart->temp_since_born.temperature.min));
|
|
json_object_add_value_int(multi, "max",
|
|
le16_to_cpu(smart->temp_since_born.temperature.max));
|
|
json_object_add_value_int(multi, "cur",
|
|
le16_to_cpu(smart->temp_since_born.temperature.cur));
|
|
json_object_add_value_object(entry_stats, "raw", multi);
|
|
json_object_add_value_object(dev_stats, "temp_since_born", entry_stats);
|
|
|
|
entry_stats = json_create_object();
|
|
json_object_add_value_int(entry_stats, "normalized", smart->temp_since_bootup.norm);
|
|
multi = json_create_object();
|
|
json_object_add_value_int(multi, "min",
|
|
le16_to_cpu(smart->temp_since_bootup.temperature.min));
|
|
json_object_add_value_int(multi, "max",
|
|
le16_to_cpu(smart->temp_since_bootup.temperature.max));
|
|
json_object_add_value_int(multi, "cur",
|
|
le16_to_cpu(smart->temp_since_bootup.temperature.cur));
|
|
json_object_add_value_object(entry_stats, "raw", multi);
|
|
json_object_add_value_object(dev_stats, "temp_since_bootup", entry_stats);
|
|
|
|
entry_stats = json_create_object();
|
|
json_object_add_value_int(entry_stats, "normalized", smart->inflight_write_io_cmd.norm);
|
|
json_object_add_value_int(entry_stats, "raw",
|
|
int48_to_long(smart->inflight_write_io_cmd.raw));
|
|
json_object_add_value_object(dev_stats, "inflight_write_io_cmd", entry_stats);
|
|
}
|
|
|
|
static void show_dapustor_smart_log_jsn(struct nvme_additional_smart_log *smart,
|
|
struct nvme_extended_additional_smart_log *ext_smart,
|
|
unsigned int nsid, const char *devname, bool has_ext)
|
|
{
|
|
struct json_object *root, *dev_stats;
|
|
|
|
root = json_create_object();
|
|
json_object_add_value_string(root, "Intel Smart log", devname);
|
|
|
|
dev_stats = json_create_object();
|
|
show_dapustor_add_smart_log_jsn(smart, dev_stats);
|
|
if (has_ext)
|
|
show_dapustor_ext_add_smart_log_jsn(ext_smart, dev_stats);
|
|
json_object_add_value_object(root, "Device stats", dev_stats);
|
|
|
|
json_print_object(root, NULL);
|
|
json_free_object(root);
|
|
}
|
|
|
|
static void show_dapustor_add_smart_log(struct nvme_additional_smart_log *smart)
|
|
{
|
|
printf("program_fail_count : %3d%% %"PRIu64"\n",
|
|
smart->program_fail_cnt.norm,
|
|
int48_to_long(smart->program_fail_cnt.raw));
|
|
printf("erase_fail_count : %3d%% %"PRIu64"\n",
|
|
smart->erase_fail_cnt.norm,
|
|
int48_to_long(smart->erase_fail_cnt.raw));
|
|
printf("wear_leveling : %3d%% min: %u, max: %u, avg: %u\n",
|
|
smart->wear_leveling_cnt.norm,
|
|
le16_to_cpu(smart->wear_leveling_cnt.wear_level.min),
|
|
le16_to_cpu(smart->wear_leveling_cnt.wear_level.max),
|
|
le16_to_cpu(smart->wear_leveling_cnt.wear_level.avg));
|
|
printf("end_to_end_error_detection_count: %3d%% %"PRIu64"\n",
|
|
smart->e2e_err_cnt.norm,
|
|
int48_to_long(smart->e2e_err_cnt.raw));
|
|
printf("crc_error_count : %3d%% %"PRIu64"\n",
|
|
smart->crc_err_cnt.norm,
|
|
int48_to_long(smart->crc_err_cnt.raw));
|
|
printf("timed_workload_media_wear : %3d%% %.3f%%\n",
|
|
smart->timed_workload_media_wear.norm,
|
|
((float)int48_to_long(smart->timed_workload_media_wear.raw)) / 1024);
|
|
printf("timed_workload_host_reads : %3d%% %"PRIu64"%%\n",
|
|
smart->timed_workload_host_reads.norm,
|
|
int48_to_long(smart->timed_workload_host_reads.raw));
|
|
printf("timed_workload_timer : %3d%% %"PRIu64" min\n",
|
|
smart->timed_workload_timer.norm,
|
|
int48_to_long(smart->timed_workload_timer.raw));
|
|
printf("thermal_throttle_status : %3d%% %u%%, cnt: %u\n",
|
|
smart->thermal_throttle_status.norm,
|
|
smart->thermal_throttle_status.thermal_throttle.pct,
|
|
smart->thermal_throttle_status.thermal_throttle.count);
|
|
printf("retry_buffer_overflow_count : %3d%% %"PRIu64"\n",
|
|
smart->retry_buffer_overflow_cnt.norm,
|
|
int48_to_long(smart->retry_buffer_overflow_cnt.raw));
|
|
printf("pll_lock_loss_count : %3d%% %"PRIu64"\n",
|
|
smart->pll_lock_loss_cnt.norm,
|
|
int48_to_long(smart->pll_lock_loss_cnt.raw));
|
|
printf("nand_bytes_written : %3d%% sectors: %"PRIu64"\n",
|
|
smart->nand_bytes_written.norm,
|
|
int48_to_long(smart->nand_bytes_written.raw));
|
|
printf("host_bytes_written : %3d%% sectors: %"PRIu64"\n",
|
|
smart->host_bytes_written.norm,
|
|
int48_to_long(smart->host_bytes_written.raw));
|
|
}
|
|
|
|
static void show_dapustor_ext_add_smart_log(struct nvme_extended_additional_smart_log *smart)
|
|
{
|
|
printf("system_area_life_remaining : %3d%% %"PRIu64"\n",
|
|
smart->sys_area_life_remain.norm,
|
|
int48_to_long(smart->sys_area_life_remain.raw));
|
|
printf("nand_bytes_read : %3d%% %"PRIu64"\n",
|
|
smart->nand_bytes_read.norm,
|
|
int48_to_long(smart->nand_bytes_read.raw));
|
|
printf("temperature : %3d%% min: %u, max: %u, cur: %u\n",
|
|
smart->temperature.norm,
|
|
le16_to_cpu(smart->temperature.temperature.min),
|
|
le16_to_cpu(smart->temperature.temperature.max),
|
|
le16_to_cpu(smart->temperature.temperature.cur));
|
|
printf("power_consumption : %3d%% min: %u, max: %u, avg: %u\n",
|
|
smart->power_consumption.norm,
|
|
le16_to_cpu(smart->power_consumption.power_consumption.min),
|
|
le16_to_cpu(smart->power_consumption.power_consumption.max),
|
|
le16_to_cpu(smart->power_consumption.power_consumption.avg));
|
|
printf("power_on_temperature : %3d%% min: %u, max: %u, cur: %u\n",
|
|
smart->power_on_temperature.norm,
|
|
le16_to_cpu(smart->power_on_temperature.temperature.min),
|
|
le16_to_cpu(smart->power_on_temperature.temperature.max),
|
|
le16_to_cpu(smart->power_on_temperature.temperature.cur));
|
|
printf("power_loss_protection : %3d%% %"PRIu64"\n",
|
|
smart->power_loss_protection.norm,
|
|
int48_to_long(smart->power_loss_protection.raw));
|
|
printf("read_fail_count : %3d%% %"PRIu64"\n",
|
|
smart->read_fail_count.norm,
|
|
int48_to_long(smart->read_fail_count.raw));
|
|
printf("thermal_throttle_time : %3d%% %"PRIu64"\n",
|
|
smart->thermal_throttle_time.norm,
|
|
int48_to_long(smart->thermal_throttle_time.raw));
|
|
printf("flash_error_media_count : %3d%% %"PRIu64"\n",
|
|
smart->flash_error_media_count.norm,
|
|
int48_to_long(smart->flash_error_media_count.raw));
|
|
printf("lifetime_write_amplification : %3d%% %"PRIu64"\n",
|
|
smart->lifetime_write_amplification.norm,
|
|
int48_to_long(smart->lifetime_write_amplification.raw));
|
|
printf("firmware_update_count : %3d%% %"PRIu64"\n",
|
|
smart->firmware_update_count.norm,
|
|
int48_to_long(smart->firmware_update_count.raw));
|
|
printf("dram_cecc_count : %3d%% %"PRIu64"\n",
|
|
smart->dram_cecc_count.norm,
|
|
int48_to_long(smart->dram_cecc_count.raw));
|
|
printf("dram_uecc_count : %3d%% %"PRIu64"\n",
|
|
smart->dram_uecc_count.norm,
|
|
int48_to_long(smart->dram_uecc_count.raw));
|
|
printf("xor_pass_count : %3d%% %"PRIu64"\n",
|
|
smart->xor_pass_count.norm,
|
|
int48_to_long(smart->xor_pass_count.raw));
|
|
printf("xor_fail_count : %3d%% %"PRIu64"\n",
|
|
smart->xor_fail_count.norm,
|
|
int48_to_long(smart->xor_fail_count.raw));
|
|
printf("xor_invoked_count : %3d%% %"PRIu64"\n",
|
|
smart->xor_invoked_count.norm,
|
|
int48_to_long(smart->xor_invoked_count.raw));
|
|
printf("inflight_read_io_cmd : %3d%% %"PRIu64"\n",
|
|
smart->inflight_read_io_cmd.norm,
|
|
int48_to_long(smart->inflight_read_io_cmd.raw));
|
|
printf("temp_since_born : %3d%% min: %u, max: %u, cur: %u\n",
|
|
smart->temp_since_born.norm,
|
|
le16_to_cpu(smart->temp_since_born.temperature.min),
|
|
le16_to_cpu(smart->temp_since_born.temperature.max),
|
|
le16_to_cpu(smart->temp_since_born.temperature.cur));
|
|
printf("temp_since_bootup : %3d%% min: %u, max: %u, cur: %u\n",
|
|
smart->temp_since_bootup.norm,
|
|
le16_to_cpu(smart->temp_since_bootup.temperature.min),
|
|
le16_to_cpu(smart->temp_since_bootup.temperature.max),
|
|
le16_to_cpu(smart->temp_since_bootup.temperature.cur));
|
|
printf("inflight_write_io_cmd : %3d%% %"PRIu64"\n",
|
|
smart->inflight_write_io_cmd.norm,
|
|
int48_to_long(smart->inflight_write_io_cmd.raw));
|
|
}
|
|
|
|
static void show_dapustor_smart_log(struct nvme_additional_smart_log *smart,
|
|
struct nvme_extended_additional_smart_log *ext_smart,
|
|
unsigned int nsid, const char *devname, bool has_ext)
|
|
{
|
|
printf("Additional Smart Log for NVME device:%s namespace-id:%x\n",
|
|
devname, nsid);
|
|
printf("key normalized raw\n");
|
|
show_dapustor_add_smart_log(smart);
|
|
if (has_ext)
|
|
show_dapustor_ext_add_smart_log(ext_smart);
|
|
}
|
|
|
|
static int dapustor_additional_smart_log_data(
|
|
int dev_fd,
|
|
struct nvme_additional_smart_log *smart_log,
|
|
struct nvme_extended_additional_smart_log *ext_smart_log,
|
|
bool *has_ext)
|
|
{
|
|
int err;
|
|
|
|
err = nvme_get_log_simple(dev_fd, 0xca, sizeof(*smart_log), smart_log);
|
|
if (err) {
|
|
nvme_show_status(err);
|
|
return err;
|
|
}
|
|
err = nvme_get_log_simple(dev_fd, 0xcb, sizeof(*ext_smart_log), ext_smart_log);
|
|
*has_ext = !err;
|
|
return 0;
|
|
}
|
|
|
|
static int dapustor_additional_smart_log(int argc, char **argv, struct command *cmd,
|
|
struct plugin *plugin)
|
|
{
|
|
const char *desc = "Get DapuStor vendor specific additional smart log, and show it.";
|
|
const char *namespace = "(optional) desired namespace";
|
|
const char *raw = "Dump output in binary format";
|
|
const char *json = "Dump output in json format";
|
|
|
|
struct nvme_additional_smart_log smart_log;
|
|
struct nvme_extended_additional_smart_log ext_smart_log;
|
|
struct nvme_dev *dev;
|
|
int err;
|
|
bool has_ext = false;
|
|
|
|
struct config {
|
|
uint32_t namespace_id;
|
|
bool raw_binary;
|
|
bool json;
|
|
};
|
|
|
|
struct config cfg = {
|
|
.namespace_id = NVME_NSID_ALL,
|
|
};
|
|
|
|
OPT_ARGS(opts) = {
|
|
OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace),
|
|
OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw),
|
|
OPT_FLAG("json", 'j', &cfg.json, json),
|
|
OPT_END()
|
|
};
|
|
|
|
err = parse_and_open(&dev, argc, argv, desc, opts);
|
|
if (err)
|
|
return err;
|
|
|
|
err = dapustor_additional_smart_log_data(dev_fd(dev), &smart_log, &ext_smart_log, &has_ext);
|
|
if (!err) {
|
|
if (cfg.json)
|
|
show_dapustor_smart_log_jsn(&smart_log, &ext_smart_log,
|
|
cfg.namespace_id, dev->name, has_ext);
|
|
else if (!cfg.raw_binary)
|
|
show_dapustor_smart_log(&smart_log, &ext_smart_log,
|
|
cfg.namespace_id, dev->name, has_ext);
|
|
else {
|
|
d_raw((unsigned char *)&smart_log, sizeof(smart_log));
|
|
if (has_ext)
|
|
d_raw((unsigned char *)&ext_smart_log, sizeof(ext_smart_log));
|
|
}
|
|
}
|
|
dev_close(dev);
|
|
return err;
|
|
}
|