Skip to contentSkip to conversation

Print out controller and ANA state for list-subsys

PATCH New Hannes Reinecke 2 participants 5 messages Nov 16, 2018

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

cover Print out controller and ANA state for list-subsys

Hi all,

this patchset implements the ability to check the path / controller state on each namespace. It does so by enhancing the 'list-subsys' command to optionally accept a device name for the namespace to check; with that we are able to print out the controller and the ANA state per controller leading up to that namespace.

As usual, comments and reviews are welcome.

Hannes Reinecke (3):
nvme: introduce get_nvme_ctrl_attr()
nvme: print out controller state for 'list-subsys'
nvme-list-subsys: Add device name argument and print out ANA state

 Documentation/nvme-list-subsys.txt |   4 +-
 fabrics.c                          |   2 +-
 nvme-print.c                       |  13 ++-
 nvme.c                             | 226 ++++++++++++++++++++++++++-----------
 nvme.h                             |   4 +-
 5 files changed, 175 insertions(+), 74 deletions(-)
Signature · 1 line
2.13.7
#1 lore raw

PATCH 1/3 nvme: introduce get_nvme_ctrl_attr()

Use a generic function 'get_nvme_ctrl_attr()' instead of coding the same function for each sysfs attribute.

Signed-off-by Hannes Reinecke <hare at suse.com>
---
 nvme.c | 98 ++++++++++++++++++------------------------------------------------
 1 file changed, 27 insertions(+), 71 deletions(-)
nvme.c +27 -71
index 1df3a10..f15d372 100644
@@ -1290,103 +1290,58 @@ close_fd:
 	return subsysnqn;
 }
 
-static char *get_nvme_ctrl_transport(char *path)
+static char *get_nvme_ctrl_attr(char *path, const char *attr)
 {
-	char *trpath;
-	char *transport;
-	int fd;
-	ssize_t ret;
-
-	ret = asprintf(&trpath, "%s/transport", path);
-	if (ret < 0)
-		return NULL;
-
-	transport = calloc(1, 1024);
-	if (!transport)
-		goto err_free_trpath;
-
-	fd = open(trpath, O_RDONLY);
-	if (fd < 0) {
-		fprintf(stderr, "Failed to open %s: %s\n",
-				trpath, strerror(errno));
-		goto err_free_tr;
-	}
-
-	ret = read(fd, transport, 1024);
-	if (ret < 0) {
-		fprintf(stderr, "read :%s :%s\n", trpath, strerror(errno));
-		goto err_close_fd;
-	}
-
-	if (transport[strlen(transport) - 1] == '\n')
-		transport[strlen(transport) - 1] = '\0';
-
-	close(fd);
-	free(trpath);
-
-	return transport;
-
-err_close_fd:
-	close(fd);
-err_free_tr:
-	free(transport);
-err_free_trpath:
-	free(trpath);
-
-	return NULL;
-}
-
-static char *get_nvme_ctrl_address(char *path)
-{
-	char *addrpath;
-	char *address;
+	char *attrpath;
+	char *value;
 	int fd;
 	ssize_t ret;
 	int i;
 
-	ret = asprintf(&addrpath, "%s/address", path);
+	ret = asprintf(&attrpath, "%s/%s", path, attr);
 	if (ret < 0)
 		return NULL;
 
-	address = calloc(1, 1024);
-	if (!address)
-		goto err_free_addrpath;
+	value = calloc(1, 1024);
+	if (!value)
+		goto err_free_path;
 
-	fd = open(addrpath, O_RDONLY);
+	fd = open(attrpath, O_RDONLY);
 	if (fd < 0) {
 		fprintf(stderr, "Failed to open %s: %s\n",
-				addrpath, strerror(errno));
-		goto err_free_addr;
+				attrpath, strerror(errno));
+		goto err_free_value;
 	}
 
-	ret = read(fd, address, 1024);
+	ret = read(fd, value, 1024);
 	if (ret < 0) {
-		fprintf(stderr, "read :%s :%s\n", addrpath, strerror(errno));
+		fprintf(stderr, "read :%s :%s\n", attrpath, strerror(errno));
 		goto err_close_fd;
 	}
 
-	if (address[strlen(address) - 1] == '\n')
-		address[strlen(address) - 1] = '\0';
+	if (value[strlen(value) - 1] == '\n')
+		value[strlen(value) - 1] = '\0';
 
-	for (i = 0; i < strlen(address); i++) {
-		if (address[i] == ',' )
-			address[i] = ' ';
+	for (i = 0; i < strlen(value); i++) {
+		if (value[i] == ',' )
+			value[i] = ' ';
 	}
 
 	close(fd);
-	free(addrpath);
+	free(attrpath);
 
-	return address;
+	return value;
 
 err_close_fd:
 	close(fd);
-err_free_addr:
-	free(address);
-err_free_addrpath:
-	free(addrpath);
+err_free_value:
+	free(value);
+err_free_path:
+	free(attrpath);
 
 	return NULL;
 }
+
 static int scan_ctrls_filter(const struct dirent *d)
 {
 	int id, nsid;
@@ -1445,7 +1400,8 @@ static int get_nvme_subsystem_info(char *name, char *path,
 		snprintf(ctrl_path, sizeof(ctrl_path), "%s/%s", path,
 			 item->ctrls[ccnt].name);
 
-		item->ctrls[ccnt].address = get_nvme_ctrl_address(ctrl_path);
+		item->ctrls[ccnt].address =
+				get_nvme_ctrl_attr(ctrl_path, "address");
 		if (!item->ctrls[ccnt].address) {
 			fprintf(stderr, "failed to get controller[%d] address.\n", i);
 			free_ctrl_list_item(&item->ctrls[ccnt]);
@@ -1453,7 +1409,7 @@ static int get_nvme_subsystem_info(char *name, char *path,
 		}
 
 		item->ctrls[ccnt].transport =
-				get_nvme_ctrl_transport(ctrl_path);
+				get_nvme_ctrl_attr(ctrl_path, "transport");
 		if (!item->ctrls[ccnt].transport) {
 			fprintf(stderr, "failed to get controller[%d] transport.\n", i);
 			free_ctrl_list_item(&item->ctrls[ccnt]);
Signature · 1 line
2.13.7
#3 lore raw

PATCH 2/3 nvme: print out controller state for 'list-subsys'

In reply to Hannes Reinecke
Signed-off-by Hannes Reinecke <hare at suse.com>
---
 nvme-print.c | 7 +++++--
 nvme.c       | 9 +++++++++
 nvme.h       | 1 +
 3 files changed, 15 insertions(+), 2 deletions(-)
nvme-print.c +5 -2
index b728975..5cdfabe 100644
@@ -2772,9 +2772,10 @@ static void show_nvme_subsystem(struct subsys_list_item *item)
 	printf("\\\n");
 
 	for (i = 0; i < item->nctrls; i++) {
-		printf(" +- %s %s %s\n", item->ctrls[i].name,
+		printf(" +- %s %s %s %s\n", item->ctrls[i].name,
 				item->ctrls[i].transport,
-				item->ctrls[i].address);
+				item->ctrls[i].address,
+				item->ctrls[i].state);
 	}
 
 }
@@ -2820,6 +2821,8 @@ void json_print_nvme_subsystem_list(struct subsys_list_item *slist, int n)
 					slist[i].ctrls[j].transport);
 			json_object_add_value_string(path_attrs, "Address",
 					slist[i].ctrls[j].address);
+			json_object_add_value_string(path_attrs, "State",
+					slist[i].ctrls[j].state);
 			json_array_add_value_object(paths, path_attrs);
 		}
 		if (j) {
nvme.c +9 -0
index f15d372..c3295c5 100644
@@ -1363,6 +1363,7 @@ static void free_ctrl_list_item(struct ctrl_list_item *ctrls)
 	free(ctrls->name);
 	free(ctrls->transport);
 	free(ctrls->address);
+	free(ctrls->state);
 }
 
 static int get_nvme_subsystem_info(char *name, char *path,
@@ -1416,6 +1417,14 @@ static int get_nvme_subsystem_info(char *name, char *path,
 			continue;
 		}
 
+		item->ctrls[ccnt].state =
+				get_nvme_ctrl_attr(ctrl_path, "state");
+		if (!item->ctrls[ccnt].state) {
+			fprintf(stderr, "failed to get controller[%d] state.\n", i);
+			free_ctrl_list_item(&item->ctrls[ccnt]);
+			continue;
+		}
+
 		ccnt++;
 	}
 
nvme.h +1 -0
index 32ac96d..668c6fd 100644
@@ -129,6 +129,7 @@ struct ctrl_list_item {
 	char *name;
 	char *address;
 	char *transport;
+	char *state;
 };
 
 struct subsys_list_item {
Signature · 1 line
2.13.7
#4 lore raw

PATCH 3/3 nvme-list-subsys: Add device name argument and print out ANA state

In reply to Hannes Reinecke

Update the 'nvme list-subsys' command to accept a device name and print out the ANA state for all paths to that device.

Signed-off-by Hannes Reinecke <hare at suse.com>
---
 Documentation/nvme-list-subsys.txt |   4 +-
 fabrics.c                          |   2 +-
 nvme-print.c                       |  10 ++-
 nvme.c                             | 135 +++++++++++++++++++++++++++++++++++--
 nvme.h                             |   3 +-
 5 files changed, 143 insertions(+), 11 deletions(-)
Documentation/nvme-list-subsys.txt +3 -1
index c7de7ef..c40b708 100644
@@ -8,12 +8,14 @@ nvme-list-subsys - List all NVMe subsystems
 SYNOPSIS
 --------
 [verse]
-'nvme list-subsys' [-o <fmt> | --output-format=<fmt>]
+'nvme list-subsys' [-o <fmt> | --output-format=<fmt>] <device>
 
 DESCRIPTION
 -----------
 Scan the sysfs tree for NVM Express subsystems and return the controllers
 for those subsystems as well as some pertinent information about them.
+If a device is given, print out only the values for the controllers
+and subsystems leading to the device.
 
 OPTIONS
 -------
fabrics.c +1 -1
index 711a755..f2bbd92 100644
@@ -1102,7 +1102,7 @@ int disconnect_all(const char *desc, int argc, char **argv)
 	if (ret)
 		return ret;
 
-	slist = get_subsys_list(&subcnt);
+	slist = get_subsys_list(&subcnt, NULL, NVME_NSID_ALL);
 	for (i = 0; i < subcnt; i++) {
 		struct subsys_list_item *subsys = &slist[i];
 
nvme-print.c +8 -2
index 5cdfabe..ee3ceb3 100644
@@ -2772,10 +2772,12 @@ static void show_nvme_subsystem(struct subsys_list_item *item)
 	printf("\\\n");
 
 	for (i = 0; i < item->nctrls; i++) {
-		printf(" +- %s %s %s %s\n", item->ctrls[i].name,
+		printf(" +- %s %s %s %s %s\n", item->ctrls[i].name,
 				item->ctrls[i].transport,
 				item->ctrls[i].address,
-				item->ctrls[i].state);
+				item->ctrls[i].state,
+				item->ctrls[i].ana_state ?
+					item->ctrls[i].ana_state : "");
 	}
 
 }
@@ -2823,6 +2825,10 @@ void json_print_nvme_subsystem_list(struct subsys_list_item *slist, int n)
 					slist[i].ctrls[j].address);
 			json_object_add_value_string(path_attrs, "State",
 					slist[i].ctrls[j].state);
+			if (slist[i].ctrls[j].ana_state)
+				json_object_add_value_string(path_attrs,
+						"ANAState",
+						slist[i].ctrls[j].ana_state);
 			json_array_add_value_object(paths, path_attrs);
 		}
 		if (j) {
nvme.c +129 -6

200 lines not on this page · raw message

nvme.h +2 -1
index 668c6fd..685d179 100644
@@ -130,6 +130,7 @@ struct ctrl_list_item {
 	char *address;
 	char *transport;
 	char *state;
+	char *ana_state;
 };
 
 struct subsys_list_item {
@@ -156,7 +157,7 @@ extern const char *devicename;
 int __id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *plugin, void (*vs)(__u8 *vs, struct json_object *root));
 int	validate_output_format(char *format);
 
-struct subsys_list_item *get_subsys_list(int *subcnt);
+struct subsys_list_item *get_subsys_list(int *subcnt, char *subsysnqn, __u32 nsid);
 void free_subsys_list(struct subsys_list_item *slist, int n);
 char *nvme_char_from_block(char *block);
 #endif /* _NVME_H */
Signature · 1 line
2.13.7
#2 lore raw

PATCH 1/3 nvme: introduce get_nvme_ctrl_attr()

In reply to Hannes Reinecke

Looks good, I've applied all three. I also fixed some unrelated documentation format for the list-subsys manpage and regenerated all the documentation.