/* Sanitize Monitor/Log */
NVME_SANITIZE_LOG_DATA_LEN = 0x0014,
NVME_SANITIZE_LOG_GLOBAL_DATA_ERASED = 0x0100,
+ NVME_SANITIZE_LOG_NUM_CMPLTED_PASS_MASK = 0x00F8,
NVME_SANITIZE_LOG_STATUS_MASK = 0x0007,
NVME_SANITIZE_LOG_NEVER_SANITIZED = 0x0000,
NVME_SANITIZE_LOG_COMPLETED_SUCCESS = 0x0001,
return nvme_get_log(fd, 0, NVME_LOG_DISC, size, log);
}
+int nvme_sanitize_log(int fd, struct nvme_sanitize_log_page *sanitize_log)
+{
+ return nvme_get_log(fd, 0, NVME_LOG_SANITIZE, sizeof(*sanitize_log), sanitize_log);
+}
+
int nvme_feature(int fd, __u8 opcode, __u32 nsid, __u32 cdw10, __u32 cdw11,
__u32 data_len, void *data, __u32 *result)
{
struct nvme_error_log_page *err_log);
int nvme_smart_log(int fd, __u32 nsid, struct nvme_smart_log *smart_log);
int nvme_discovery_log(int fd, struct nvmf_disc_rsp_page_hdr *log, __u32 size);
+int nvme_sanitize_log(int fd, struct nvme_sanitize_log_page *sanitize_log);
int nvme_feature(int fd, __u8 opcode, __u32 nsid, __u32 cdw10,
__u32 cdw11, __u32 data_len, void *data, __u32 *result);
printf("Thermal Management T2 Total Time : %u\n", le32_to_cpu(smart->thm_temp2_total_time));
}
+static void show_sanitize_log_sprog(__u32 sprog)
+{
+ double percent;
+
+ percent = (((double)sprog * 100) / 0x10000);
+ printf("\t(%f%%)\n", percent);
+}
+
+static void show_sanitize_log_sstat(__u16 status)
+{
+ const char * str;
+
+ switch (status & NVME_SANITIZE_LOG_STATUS_MASK) {
+ case NVME_SANITIZE_LOG_NEVER_SANITIZED:
+ str = "NVM Subsystem has never been sanitized.";
+ break;
+ case NVME_SANITIZE_LOG_COMPLETED_SUCCESS:
+ str = "Most Recent Sanitize Command Completed Successfully.";
+ break;
+ case NVME_SANITIZE_LOG_IN_PROGESS:
+ str = "Sanitize in Progress.";
+ break;
+ case NVME_SANITIZE_LOG_COMPLETED_FAILED:
+ str = "Most Recent Sanitize Command Failed.";
+ break;
+ default:
+ str = "Unknown.";
+ }
+
+ printf("\t[2:0]\t%s\n", str);
+ str = "Number of completed passes if most recent operation was overwrite";
+ printf("\t[7:3]\t%s:\t%u\n", str, (status & NVME_SANITIZE_LOG_NUM_CMPLTED_PASS_MASK) >> 3);
+
+ printf("\t [8]\t");
+ if (status & NVME_SANITIZE_LOG_GLOBAL_DATA_ERASED)
+ str = "Global Data Erased set: NVM storage has not been written";
+ else
+ str = "Global Data Erased cleared: NVM storage has been written";
+ printf("%s\n", str);
+}
+
+void show_sanitize_log(struct nvme_sanitize_log_page *sanitize, unsigned int mode, const char *devname)
+{
+ int human = mode & HUMAN;
+
+ printf("Sanitize Progress (SPROG) : %u", le32_to_cpu(sanitize->progress));
+ if (human && (sanitize->status & NVME_SANITIZE_LOG_STATUS_MASK) == NVME_SANITIZE_LOG_IN_PROGESS)
+ show_sanitize_log_sprog(le32_to_cpu(sanitize->progress));
+ else
+ printf("\n");
+
+ printf("Sanitize Status (SSTAT) : %#x\n", le16_to_cpu(sanitize->status));
+ if (human)
+ show_sanitize_log_sstat(le16_to_cpu(sanitize->status));
+
+ printf("Sanitize Command Dword 10 Information (SCDW10): %#x\n", le32_to_cpu(sanitize->cdw10_info));
+ printf("Estimated Time For Overwrite : %u\n", le32_to_cpu(sanitize->est_ovrwrt_time));
+ printf("Estimated Time For Block Erase : %u\n", le32_to_cpu(sanitize->est_blk_erase_time));
+ printf("Estimated Time For Crypto Erase : %u\n", le32_to_cpu(sanitize->est_crypto_erase_time));
+}
+
char *nvme_feature_to_string(int feature)
{
switch (feature) {
void show_smart_log(struct nvme_smart_log *smart, unsigned int nsid, const char *devname);
void show_fw_log(struct nvme_firmware_log_page *fw_log, const char *devname);
void show_effects_log(struct nvme_effects_log_page *effects);
+void show_sanitize_log(struct nvme_sanitize_log_page *sanitize, unsigned int mode, const char *devname);
void show_ctrl_registers(void *bar, unsigned int mode, bool fabrics);
void show_nvme_id_ns_descs(void *data);
}
}
-static const char * sanitize_mon_status_to_string(__u16 status)
-{
- const char * str;
-
- switch (status & NVME_SANITIZE_LOG_STATUS_MASK) {
- case NVME_SANITIZE_LOG_NEVER_SANITIZED:
- str = "NVM Subsystem has never been sanitized.";
- break;
- case NVME_SANITIZE_LOG_COMPLETED_SUCCESS:
- str = "Most Recent Sanitize Command Completed Successfully.";
- break;
- case NVME_SANITIZE_LOG_IN_PROGESS:
- str = "Sanitize in Progress.";
- break;
- case NVME_SANITIZE_LOG_COMPLETED_FAILED:
- str = "Most Recent Sanitize Command Failed.";
- break;
- default:
- str = "Unknown.";
- }
-
- return str;
-}
-
static int sanitize_log(int argc, char **argv, struct command *command, struct plugin *plugin)
{
const char *desc = "Retrieve sanitize log and show it.";
+ const char *raw_binary = "show infos in binary format";
+ const char *human_readable = "show infos in readable format";
int fd;
int ret;
- __u8 output[NVME_SANITIZE_LOG_DATA_LEN] = {0};
- struct nvme_sanitize_log_page *slp;
- double progress_percent;
+ int fmt;
+ unsigned int flags = 0;
+ struct nvme_sanitize_log_page sanitize_log;
+
+ struct config {
+ int raw_binary;
+ int human_readable;
+ char *output_format;
+ };
+
+ struct config cfg = {
+ .output_format = "normal",
+ };
+
const struct argconfig_commandline_options command_line_options[] = {
- { NULL, '\0', NULL, CFG_NONE, NULL, no_argument, desc},
+ {"output-format", 'o', "FMT", CFG_STRING, &cfg.output_format, required_argument, output_format},
+ {"human-readable",'H', "", CFG_NONE, &cfg.human_readable,no_argument, human_readable},
+ {"raw-binary", 'b', "", CFG_NONE, &cfg.raw_binary, no_argument, raw_binary},
{NULL}
};
- fd = parse_and_open(argc, argv, desc, command_line_options, NULL, 0);
+ fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
if (fd < 0)
return fd;
- ret = nvme_get_log(fd, 0x01, NVME_LOG_SANITIZE, NVME_SANITIZE_LOG_DATA_LEN, output);
- fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
- if (ret != 0)
- return ret;
+ fmt = validate_output_format(cfg.output_format);
+ if (fmt < 0)
+ return fmt;
+ if (cfg.raw_binary)
+ fmt = BINARY;
- slp = (struct nvme_sanitize_log_page *) output;
- printf("Sanitize status = 0x%0x\n", slp->status);
- printf("%s\n", sanitize_mon_status_to_string(slp->status));
+ if (cfg.human_readable)
+ flags |= HUMAN;
- if ((slp->status & NVME_SANITIZE_LOG_STATUS_MASK) == NVME_SANITIZE_LOG_IN_PROGESS) {
- progress_percent = (((double)le32_to_cpu(slp->progress) * 100) / 0x10000);
- printf("Sanitize Progress (percentage) = %f%%\n", progress_percent);
- } else {
- if (slp->status & NVME_SANITIZE_LOG_GLOBAL_DATA_ERASED)
- printf("Global Data Erased Set\n");
+ ret = nvme_sanitize_log(fd, &sanitize_log);
+ if (!ret) {
+ if (fmt == BINARY)
+ d_raw((unsigned char *)&sanitize_log, sizeof(sanitize_log));
+ else if (fmt == JSON)
+ return -EINVAL;
else
- printf("Global Data Erased Cleared\n");
+ show_sanitize_log(&sanitize_log, flags, devicename);
}
+ else if (ret > 0)
+ fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ else
+ perror("sanitize status log");
+
return ret;
}