Skip to contentSkip to conversation

nvme-cli: Implemented primary and secondary controller

PATCH New Revanth Rajashekar 2 participants 2 messages Jun 18, 2018 NVMe

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 nvme-cli: Implemented primary and secondary controller

Signed-off-by Revanth Rajashekar <revanth.rajashekar at intel.com>
---
 linux/nvme.h   |   3 ++
 nvme-builtin.h |   2 +
 nvme-ioctl.c   |  24 +++++++++
 nvme-ioctl.h   |   3 ++
 nvme-print.c   | 118 ++++++++++++++++++++++++++++++++++++++++++++
 nvme-print.h   |   7 +++
 nvme.c         | 129 +++++++++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 286 insertions(+)
linux/nvme.h +3 -0
index 97204f3..3db25ad 100644
@@ -377,6 +377,8 @@ enum {
 	NVME_ID_CNS_NS_PRESENT		= 0x11,
 	NVME_ID_CNS_CTRL_NS_LIST	= 0x12,
 	NVME_ID_CNS_CTRL_LIST		= 0x13,
+	NVME_ID_CNS_PIMARY_CNTRLR_CAP 		= 0x14,
+	NVME_ID_CNS_SECONDARY_CNTRLR_LIST 	= 0x15,
 };
 
 enum {
@@ -974,6 +976,7 @@ struct nvme_identify {
 };
 
 #define NVME_IDENTIFY_DATA_SIZE 4096
+#define NVME_VIRTUAL_CNTRLR_DATA_SIZE 4096
 
 struct nvme_features {
 	__u8			opcode;
nvme-builtin.h +2 -0
index 86b0fff..ccb3d16 100644
@@ -63,6 +63,8 @@ COMMAND_LIST(
 	ENTRY("gen-hostnqn", "Generate NVMeoF host NQN", gen_hostnqn_cmd)
 	ENTRY("dir-receive", "Submit a Directive Receive command, return results", dir_receive)
 	ENTRY("dir-send", "Submit a Directive Send command, return results", dir_send)
+	ENTRY("primary-cntrlr", "Obtain the primary controller capabilities structure", primary_cntrlr)
+	ENTRY("secondary-cntrlr", "Obtain a Secondary Controller list associated with the primary controller", secondary_cntrlr)
 );
 
 #endif
nvme-ioctl.c +24 -0
index 63ff8fb..4bc6154 100644
@@ -393,6 +393,30 @@ int nvme_identify_nvmset(int fd, __u16 nvmset_id, void *data)
 	return nvme_identify13(fd, 0, NVME_ID_CNS_NVMSET_LIST, nvmset_id, data);
 }
 
+int nvme_cntrlr13(int fd, __u32 cdw10, __u32 cdw11, void *data)
+{
+	struct nvme_admin_cmd cmd = {
+		.opcode 	= nvme_admin_virtual_mgmt,
+		.nsid		= 0,
+		.addr 		= (__u64)(uintptr_t) data,
+		.data_len	= NVME_VIRTUAL_CNTRLR_DATA_SIZE,
+		.cdw10 		= cdw10,
+		.cdw11 		= cdw11,
+	};
+
+	return nvme_submit_admin_passthru(fd, &cmd);
+}
+
+int nvme_primary_cntrlr(int fd, void *data)
+{
+	return nvme_cntrlr13(fd, NVME_ID_CNS_PIMARY_CNTRLR_CAP, 0, data);
+}
+
+int nvme_secondary_cntrlr(int fd, void *data)
+{
+	return nvme_cntrlr13(fd, NVME_ID_CNS_SECONDARY_CNTRLR_LIST, 0, data);
+}
+
 int nvme_get_log13(int fd, __u32 nsid, __u8 log_id, __u8 lsp, __u64 lpo,
                  __u16 lsi, __u32 data_len, void *data)
 {
nvme-ioctl.h +3 -0
index 6d4ac95..e6385eb 100644
@@ -138,4 +138,7 @@ int nvme_sanitize(int fd, __u8 sanact, __u8 ause, __u8 owpass, __u8 oipbp,
 		  __u8 no_dealloc, __u32 ovrpat);
 int nvme_self_test_start(int fd, __u32 nsid, __u32 cdw10);
 int nvme_self_test_log(int fd, struct nvme_self_test_log *self_test_log);
+int nvme_cntrlr13(int fd, __u32 cdw10, __u32 cdw11, void *data);
+int nvme_primary_cntrlr(int fd, void *data);
+int nvme_secondary_cntrlr(int fd, void *data);
 #endif				/* _NVME_LIB_H */
nvme-print.c +118 -0

130 lines not on this page · raw message

nvme-print.h +7 -0
index 7dd5f34..bdef9b2 100644
@@ -58,6 +58,13 @@ void json_nvme_id_ns_descs(void *data);
 void json_print_nvme_subsystem_list(struct subsys_list_item *slist, int n);
 void json_self_test_log(struct nvme_self_test_log *self_test, const char *devname);
 void json_nvme_id_nvmset(struct nvme_id_nvmset *nvmset, const char *devname);
+void show_nvme_primary_cntrlr_crt(__u8 crt);
+void show_nvme_primary_cntrlr(struct nvme_id_primary_cntrlr *ctrl);
+void show_nvme_secondary_cntrlr_entry_scs(__u8 scs);
+void show_nvme_secondary_cntrlr_entry(struct nvme_secondary_cntrlr_entry *ctrl);
+void show_nvme_secondary_cntrlr_list(struct nvme_secondary_cntrlr_list *ctrl);
+void json_nvme_primary_cntrlr(struct nvme_id_primary_cntrlr *ctrl);
+void json_nvme_secondary_cntrlr(struct nvme_secondary_cntrlr_list *ctrl);
 
 
 #endif
nvme.c +129 -0

135 lines not on this page · raw message

Signature · 1 line
2.17.1
#1 lore raw

PATCH 1/1 nvme-cli: Implemented primary and secondary controller

linux/nvme.h enum { · line 381

Quoted 5 lines · Revanth Rajashekar
linux/nvme.h +2 -0
 	NVME_ID_CNS_NS_PRESENT		= 0x11,
 	NVME_ID_CNS_CTRL_NS_LIST	= 0x12,
 	NVME_ID_CNS_CTRL_LIST		= 0x13,
+	NVME_ID_CNS_PIMARY_CNTRLR_CAP 		= 0x14,
+	NVME_ID_CNS_SECONDARY_CNTRLR_LIST 	= 0x15,

Let's stick with the existing convention of "CTRL" as the abbreviation for controller.

nvme-builtin.h COMMAND_LIST( · line 67

Quoted 2 lines
nvme-builtin.h +2 -0
+	ENTRY("primary-cntrlr", "Obtain the primary controller capabilities structure", primary_cntrlr)
+	ENTRY("secondary-cntrlr", "Obtain a Secondary Controller list associated with the primary controller", secondary_cntrlr)

Similarly, controller is abbreviated as "ctrl" by existing convention, and different types of identify commands are prefixed with "id-".

nvme-ioctl.c int nvme_identify_nvmset(int fd, __u16 nvmset_id, void *data) · line 408

Quoted 13 lines
nvme-ioctl.c +13 -0
+int nvme_cntrlr13(int fd, __u32 cdw10, __u32 cdw11, void *data)
+{
+	struct nvme_admin_cmd cmd = {
+		.opcode 	= nvme_admin_virtual_mgmt,
+		.nsid		= 0,
+		.addr 		= (__u64)(uintptr_t) data,
+		.data_len	= NVME_VIRTUAL_CNTRLR_DATA_SIZE,
+		.cdw10 		= cdw10,
+		.cdw11 		= cdw11,
+	};
+
+	return nvme_submit_admin_passthru(fd, &cmd);
+}

I can't tell what this function is for or why it's named with a "13" suffix. Also CDW11 isn't used for identify commands.

nvme-print.c void show_nvme_id_ctrl(struct nvme_id_ctrl *ctrl, unsigned int mode) · line 966

Quoted 13 lines
nvme-print.c +13 -0
+void show_nvme_primary_cntrlr_crt(__u8 crt)
+{
+	__u8 rsvd = (crt & 0xFC) >> 2;
+	__u8 vir  = (crt & 0x2) >> 1;
+	__u8 vqr  = crt & 0x1;
+	if (rsvd)
+		printf("  [7:2] : %#x\tReserved\n", rsvd);
+	printf("  [1:1] : %#x\t VI Resources are %s\n",
+		vir, vir ? "Supported" : "NOT Supported");
+	printf("  [0:0] : %#x\t VQ Resources are %s\n", vqr,
+		vqr ? "Supported" : "NOT Supported");
+	printf("\n");
+}

I don't think you want to call this without the "human readable" option, right?

nvme-print.c void show_nvme_id_ctrl(struct nvme_id_ctrl *ctrl, unsigned int mode) · line 975

Quoted 8 lines
nvme-print.c +8 -0
+void show_nvme_primary_cntrlr(struct nvme_id_primary_cntrlr *ctrl)
+{
+	printf("cntlid     : %#x\n", le16_to_cpu(ctrl->cntlid));
+	printf("portid     : %#x\n", le16_to_cpu(ctrl->portid));
+	printf("crt        : %#x\n", ctrl->crt);
+	show_nvme_primary_cntrlr_crt(ctrl->crt);
+	printf("vqfrt      : %d\n", ctrl->vqfrt);
+	printf("vqrfa      : %d\n", ctrl->vqrfa);

le32_to_cpu on the above two prints.

nvme-print.c void show_nvme_id_ctrl(struct nvme_id_ctrl *ctrl, unsigned int mode) · line 998

Quoted 11 lines
nvme-print.c +11 -0
+void show_nvme_secondary_cntrlr_entry_scs(__u8 scs)
+{
+	__u8 rsvd = (scs & 0xFE) >> 1;
+	__u8 os  = scs & 0x1;
+
+	if (rsvd)
+		printf("  [7:1] : %#x\tReserved\n", rsvd);
+	printf("  [0:0] : %#x\t Controller is in %s state\n", os,
+		os ? "Online" : "Offline");
+
+}

Another function that looks like it should not be called without the "human readable" option.

Quoted 9 lines
nvme-print.c +9 -0
+void show_nvme_secondary_cntrlr_entry(struct nvme_secondary_cntrlr_entry *ctrl)
+{
+	printf("scid     : %#x\n", le16_to_cpu(ctrl->scid));
+	printf("pcid     : %#x\n", le16_to_cpu(ctrl->pcid));
+	printf("scs 	 : %#x\n",ctrl->scs);
+	show_nvme_secondary_cntrlr_entry_scs(ctrl->scs);
+	printf("vfn	     : %d\n", le16_to_cpu(ctrl->vfn));
+	printf("nvq	     : %d\n", le16_to_cpu(ctrl->nvq));
+	printf("nvi	     : %d\n", le16_to_cpu(ctrl->nvi));

nvme-print.c void show_nvme_id_ctrl(struct nvme_id_ctrl *ctrl, unsigned int mode) · line 1018

Quoted 10 lines
nvme-print.c +10 -0
+}
+
+void show_nvme_secondary_cntrlr_list(struct nvme_secondary_cntrlr_list *ctrl)
+{
+	int i;
+
+	printf("num_of_identifiers  : %d\n", ctrl->num_of_identifiers);
+	for(i = 0; i < ctrl->num_of_identifiers; i++)
+		show_nvme_secondary_cntrlr_entry(&ctrl->sc[i]);
+}

We need a print here to break up different controllers in this list.

nvme-print.c void json_nvme_id_ctrl(struct nvme_id_ctrl *ctrl, unsigned int mode, void (*vs)( · line 2219

Quoted 10 lines
nvme-print.c +10 -0
+void json_nvme_primary_cntrlr(struct nvme_id_primary_cntrlr *ctrl)
+{
+	struct json_object *root;
+	root = json_create_object();
+
+	json_object_add_value_int(root, "cntlid", le16_to_cpu(ctrl->cntlid));
+	json_object_add_value_int(root, "portid", le16_to_cpu(ctrl->portid));
+	json_object_add_value_int(root, "crt", ctrl->crt);
+	json_object_add_value_int(root, "vqfrt", ctrl->vqfrt);
+	json_object_add_value_int(root, "vqrfa", ctrl->vqrfa);

le32_to_cpu on the above two.

Quoted 15 lines
nvme.c +15 -0
+int primary_cntrlr(int argc, char **argv, struct command *cmd, struct plugin *plugin)
+{
+	const char *desc = "Send an Primary Controller command to "\
+		"the given device and report information about the specified "\
+		"primary controller in human-readable or binary format.";
+	const char *raw_binary = "show infos in binary format";
+	const char *human_readable = "show infos in readable format";
+	int err, fmt, fd;
+	struct nvme_id_primary_cntrlr ctrl;
+
+	struct config {
+		int raw_binary;
+		int human_readable;
+		char *output_format;
+	};

nvme.c static int id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *pl · line 1660

Quoted 10 lines
nvme.c +10 -0
+
+	struct config cfg = {
+		.output_format = "normal",
+	};
+
+	const struct argconfig_commandline_options command_line_options[] = {
+		{"raw-binary",      'b', "",    CFG_NONE,   &cfg.raw_binary,      no_argument,       raw_binary},
+		{"human-readable",  'H', "",    CFG_NONE,   &cfg.human_readable,  no_argument,       human_readable},
+		{"output-format",   'o', "FMT", CFG_STRING, &cfg.output_format,   required_argument, output_format },
+		{NULL}

Let's not use the binary option when we have the "output-format" option. That binary option is really a legacy carry-over from when we only had the two possible options.

Also, I don't think the "human-readable" option is particularly well named anymore. The "normal" output option already is human readable, but the additional "human-readable" option really just means to be more "verbose", so I would favor seeing any new commands that have such potential for additional verbosity in its decoding use a "--verbose" or "-v" option instead.