[PATCH 3/4] nvme-cli : add support for retrieving sanitize log.

Chaitanya Kulkarni chaitanya.kulkarni at hgst.com
Wed Jun 28 19:19:27 PDT 2017


This adds support for retrieving and printing NVMe sanitize log
page. For more details please look into NVM Express 1.3
specification.

Signed-off-by: Chaitanya Kulkarni <chaitanya.kulkarni at hgst.com>
---
 linux/nvme.h   | 23 +++++++++++++++++++++-
 nvme-builtin.h |  1 +
 nvme.c         | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 85 insertions(+), 1 deletion(-)

diff --git a/linux/nvme.h b/linux/nvme.h
index 28ab9b8..19354a5 100644
--- a/linux/nvme.h
+++ b/linux/nvme.h
@@ -693,13 +693,15 @@ enum {
 	NVME_LOG_FW_SLOT	= 0x03,
 	NVME_LOG_DISC		= 0x70,
 	NVME_LOG_RESERVATION	= 0x80,
+	NVME_LOG_SANITIZE	= 0x81,
 	NVME_FWACT_REPL		= (0 << 3),
 	NVME_FWACT_REPL_ACTV	= (1 << 3),
 	NVME_FWACT_ACTV		= (2 << 3),
 };
 
-/* Sanitize */
+/* Sanitize and Sanitize Monitor/Log */
 enum {
+	/* Sanitize */
 	NVME_SANITIZE_NO_DEALLOC		= 0x00000200,
 	NVME_SANITIZE_OIPBP				= 0x00000100,
 	NVME_SANITIZE_OWPASS_SHIFT		= 0x00000004,
@@ -708,6 +710,15 @@ enum {
 	NVME_SANITIZE_ACT_OVERWRITE		= 0x00000003,
 	NVME_SANITIZE_ACT_BLOCK_ERASE	= 0x00000002,
 	NVME_SANITIZE_ACT_EXIT			= 0x00000001,
+
+	/* Sanitize Monitor/Log */
+	NVME_SANITIZE_LOG_DATA_LEN				= 0x0014,
+	NVME_SANITIZE_LOG_GLOBAL_DATA_ERASED	= 0x0100,
+	NVME_SANITIZE_LOG_STATUS_MASK			= 0x0007,
+	NVME_SANITIZE_LOG_NEVER_SANITIZED		= 0x0000,
+	NVME_SANITIZE_LOG_COMPLETED_SUCCESS		= 0x0001,
+	NVME_SANITIZE_LOG_IN_PROGESS			= 0x0002,
+	NVME_SANITIZE_LOG_COMPLETED_FAILED		= 0x0003,
 };
 
 struct nvme_identify {
@@ -832,6 +843,16 @@ struct nvme_get_log_page_command {
 	__u32			rsvd14[2];
 };
 
+/* Sanitize Log Page */
+struct nvme_sanitize_log_page {
+	__le16			progress;
+	__le16			status;
+	__le32			cdw10_info;
+	__le32			est_ovrwrt_time;
+	__le32			est_blk_erase_time;
+	__le32			est_crypto_erase_time;
+};
+
 /*
  * Fabrics subcommands.
  */
diff --git a/nvme-builtin.h b/nvme-builtin.h
index b4cd3ba..2143ffd 100644
--- a/nvme-builtin.h
+++ b/nvme-builtin.h
@@ -43,6 +43,7 @@ COMMAND_LIST(
 	ENTRY("write-zeroes", "Submit a write zeroes command, return results", write_zeroes)
 	ENTRY("write-uncor", "Submit a write uncorrectable command, return results", write_uncor)
 	ENTRY("sanitize", "Submit a sanitize command", sanitize)
+	ENTRY("sanitize-log", "Retrive sanitize log, show it", sanitize_log)
 	ENTRY("reset", "Resets the controller", reset)
 	ENTRY("subsystem-reset", "Resets the controller", subsystem_reset)
 	ENTRY("show-regs", "Shows the controller registers. Requires admin character device", show_registers)
diff --git a/nvme.c b/nvme.c
index 8507cd3..40fb3df 100644
--- a/nvme.c
+++ b/nvme.c
@@ -422,6 +422,68 @@ static int get_log(int argc, char **argv, struct command *cmd, struct plugin *pl
 	}
 }
 
+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)
+{
+	char *desc = "Retrieve sanitize log and show it.";
+	int fd;
+	int ret;
+	__u8 output[NVME_SANITIZE_LOG_DATA_LEN] = {0};
+	struct nvme_sanitize_log_page *slp;
+	double progress_percent;
+	const struct argconfig_commandline_options command_line_options[] = {
+		{ NULL, '\0', NULL, CFG_NONE, NULL, no_argument, desc},
+		{NULL}
+	};
+
+	fd = parse_and_open(argc, argv, desc, command_line_options, NULL, 0);
+	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;
+
+	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 ((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");
+		else
+			printf("Global Data Erased Cleared\n");
+	}
+	return ret;
+}
+
 static int list_ctrl(int argc, char **argv, struct command *cmd, struct plugin *plugin)
 {
 	const char *desc = "Show controller list information for the subsystem the "\
-- 
2.7.4




More information about the Linux-nvme mailing list