[PATCH nvme-cli 2/3] show fault devices in command "nvme huawei list"

chengjike chengjike.cheng at huawei.com
Tue Aug 17 08:07:14 PDT 2021


If there are some fault nvme devices, when execute the "nvme huawei list" command, it doesn't show nvme devices
(the program will exit when the context of fault device can not be obtained from NVMe Subsystem).
In this situation, the displaying content of fault devices can be obtained from
the device attribute files(such as "nsid" can be obtained from the file "/sys/block/nvme0n1/nsid").

Signed-off-by: chengjike <chengjike.cheng at huawei.com>
---
 plugins/huawei/huawei-nvme.c | 132 +++++++++++++++++++++++++----------
 1 file changed, 96 insertions(+), 36 deletions(-)

diff --git a/plugins/huawei/huawei-nvme.c b/plugins/huawei/huawei-nvme.c
index f36c7a5..40aab5d 100644
--- a/plugins/huawei/huawei-nvme.c
+++ b/plugins/huawei/huawei-nvme.c
@@ -43,6 +43,7 @@
 #define HW_SSD_PCI_VENDOR_ID 0x19E5
 #define ARRAY_NAME_LEN 80
 #define NS_NAME_LEN    40
+#define NS_EGUID_LEN   33
 
 #define MIN_ARRAY_NAME_LEN 16
 #define MIN_NS_NAME_LEN 16
@@ -55,6 +56,7 @@ struct huawei_list_item {
 	unsigned            block;
 	char                ns_name[NS_NAME_LEN];
 	char                array_name[ARRAY_NAME_LEN];
+	char                eguid[NS_EGUID_LEN];
 	bool                huawei_device;
 };
 
@@ -67,56 +69,114 @@ struct huawei_list_element_len {
 	unsigned int array_name;
 };
 
-static int huawei_get_nvme_info(int fd, struct huawei_list_item *item, const char *node)
+void huawei_get_attr_data(const char *name, struct huawei_list_item *item)
 {
+	char *wwid = NULL;
+	char *nsid = NULL;
+	char *eguid = NULL;
+	char path[280];
+
+	sprintf(path, "/sys/block/%s", name);
+	wwid = nvme_get_ctrl_attr(path, "wwid");
+	if (wwid == NULL) 
+		return;
+
+	eguid = strrchr(wwid, '.');
+	if (eguid)
+		sprintf(item->eguid, "%s", &eguid[1]);;
+	free(wwid);
+
+	nsid = nvme_get_ctrl_attr(path, "nsid");
+	if (nsid == NULL) 
+		return;
+	item->nsid = atoi(nsid);
+	free(nsid);
+	return;
+}
+
+int huawei_get_device_data(const char *name, struct huawei_list_item *item)
+{
+	int fd;
 	int err;
-	int len;
+	char path[280];
 	struct stat nvme_stat_info;
 
-	memset(item, 0, sizeof(*item));
-
+	sprintf(path, "/dev/%s", name);
+	fd = open(path, O_RDONLY);
+	if (fd < 0)
+		goto out_get_attr;
+	
 	err = nvme_identify_ctrl(fd, &item->ctrl);
 	if (err)
-		return err;
+		goto out_close;
 
-	/*identify huawei device*/
-	if (strstr(item->ctrl.mn, "Huawei") == NULL &&
-	    le16_to_cpu(item->ctrl.vid) != HW_SSD_PCI_VENDOR_ID) {
-		item->huawei_device = false;
-		return 0;
-	}
+	err = fstat(fd, &nvme_stat_info);
+	if (err < 0)
+		goto out_close;
 
-	item->huawei_device = true;
 	item->nsid = nvme_get_nsid(fd);
+	item->block = S_ISBLK(nvme_stat_info.st_mode);
 	err = nvme_identify_ns(fd, item->nsid, 0, &item->ns);
 	if (err)
-		return err;
+		goto out_close;
+	close(fd);
+	return 0;
+out_close:
+	close(fd);
+out_get_attr:
+ 	huawei_get_attr_data(name, item);
+	return 0;
+}
 
-	err = fstat(fd, &nvme_stat_info);
-	if (err < 0)
-		return err;
+bool huawei_check_device(const char *name, struct huawei_list_item *item)
+{	 
+	char path[280];
+	char *model = NULL;
+	bool flag = false;
 
-	strcpy(item->node, node);
-	item->block = S_ISBLK(nvme_stat_info.st_mode);
-
-	if (item->ns.vs[0] == 0) {
+	/*identify huawei device*/
+	if (strstr(item->ctrl.mn, "Huawei") != NULL ||
+		le16_to_cpu(item->ctrl.vid) == HW_SSD_PCI_VENDOR_ID) {
+		return true;
+	}
 
-		len = snprintf(item->ns_name, NS_NAME_LEN, "%s", "----");
-		if (len < 0)
-			return -EINVAL;
+	sprintf(path, "/sys/block/%s/device", name);
+	model = nvme_get_ctrl_attr(path, "model");
+	if (model != NULL) {
+		if(strstr(model, "Huawei") != NULL)
+			flag = true;
+		free(model);
 	}
-	else {
+	return flag;
+}
+
+void huawei_init_item(struct huawei_list_item *item)
+{
+	memset(item, 0, sizeof(*item));
+	item->huawei_device = false;
+	sprintf(item->ns_name, "%s", "----");
+	sprintf(item->array_name, "%s", "----");	 
+}
+
+static int huawei_get_nvme_info(const char *name, struct huawei_list_item *item, const char *node)
+{
+	bool flag;
+	
+	huawei_init_item(item);
+	huawei_get_device_data(name, item);
+	flag = huawei_check_device(name, item);
+	if (flag == false)
+		return -EINVAL;
+
+	item->huawei_device = true;
+	sprintf(item->node, "/dev/%s", name);
+	
+	if (item->ns.vs[0] != 0) {
 		memcpy(item->ns_name, item->ns.vs, NS_NAME_LEN);
 		item->ns_name[NS_NAME_LEN - 1] = '\0';
 	}
 
-	if (item->ctrl.vs[0] == 0) {
-
-		len = snprintf(item->array_name, ARRAY_NAME_LEN, "%s", "----");
-	if (len < 0)
-			return -EINVAL;
-	}
-	else {
+	if (item->ctrl.vs[0] != 0) {
 		memcpy(item->array_name, item->ctrl.vs, ARRAY_NAME_LEN);
 		item->array_name[ARRAY_NAME_LEN - 1] = '\0';
 	}
@@ -230,6 +290,8 @@ static void huawei_print_list_item(struct huawei_list_item list_item,
 	for (i = 0; i < sizeof(list_item.ns.nguid); i++)
 		nguid += sprintf(nguid, "%02x", list_item.ns.nguid[i]);
 
+	if (!strlen((char *)list_item.ns.nguid))
+		sprintf(nguid_buf, "%s", list_item.eguid);
 	printf("%-*.*s %-*.*s %-*.*s %-*d %-*.*s %-*.*s\n",
 		element_len.node, element_len.node, list_item.node,
 		element_len.ns_name, element_len.ns_name, list_item.ns_name,
@@ -298,7 +360,7 @@ static int huawei_list(int argc, char **argv, struct command *command,
 	char path[264];
 	struct dirent **devices;
 	struct huawei_list_item *list_items;
-	unsigned int i, n, fd, ret;
+	unsigned int i, n, ret;
 	unsigned int huawei_num = 0;
 	int fmt;
 	int ctrl, ns, part;
@@ -334,11 +396,9 @@ static int huawei_list(int argc, char **argv, struct command *command,
 	for (i = 0; i < n; i++) {
 		if (sscanf(devices[i]->d_name, "nvme%dn%dp%d", &ctrl, &ns, &part) == 3) 
 			continue;
-		snprintf(path, sizeof(path), "/dev/%s", devices[i]->d_name);
-		fd = open(path, O_RDONLY);
-		ret = huawei_get_nvme_info(fd, &list_items[huawei_num], path);
+		ret = huawei_get_nvme_info(devices[i]->d_name, &list_items[huawei_num], path);
 		if (ret)
-			return ret;
+			continue;
 		if (list_items[huawei_num].huawei_device == true) {
 			huawei_num++;
 		}
-- 
2.24.0.windows.2




More information about the Linux-nvme mailing list