[PATCH nvme-cli 3/3] add "Status" field in command "nvme huawei list"

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


When execute the "nvme huawei list" command, it is more intuitive and easy to understand displaying the status of each nvme device.
The "status" of each nvme device is derived from the belonging controller.
Specially, in a multipath environment, when all paths are not live, the device status is "fault". Otherwise, the device status is "live".

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

diff --git a/plugins/huawei/huawei-nvme.c b/plugins/huawei/huawei-nvme.c
index 40aab5d..65d4c40 100644
--- a/plugins/huawei/huawei-nvme.c
+++ b/plugins/huawei/huawei-nvme.c
@@ -44,6 +44,7 @@
 #define ARRAY_NAME_LEN 80
 #define NS_NAME_LEN    40
 #define NS_EGUID_LEN   33
+#define NS_STATUS_LEN  10
 
 #define MIN_ARRAY_NAME_LEN 16
 #define MIN_NS_NAME_LEN 16
@@ -58,6 +59,7 @@ struct huawei_list_item {
 	char                array_name[ARRAY_NAME_LEN];
 	char                eguid[NS_EGUID_LEN];
 	bool                huawei_device;
+	char                status[NS_STATUS_LEN];
 };
 
 struct huawei_list_element_len {
@@ -67,6 +69,7 @@ struct huawei_list_element_len {
 	unsigned int ns_id;
 	unsigned int usage;
 	unsigned int array_name;
+	unsigned int status;
 };
 
 void huawei_get_attr_data(const char *name, struct huawei_list_item *item)
@@ -154,10 +157,82 @@ void huawei_init_item(struct huawei_list_item *item)
 {
 	memset(item, 0, sizeof(*item));
 	item->huawei_device = false;
+	sprintf(item->status, "%s", "failed");
 	sprintf(item->ns_name, "%s", "----");
 	sprintf(item->array_name, "%s", "----");	 
 }
 
+bool huawei_check_multipath_device(const char *name)
+{
+	int sub_instance , head_instance;
+	char path[280];
+
+	if (sscanf(name, "/dev/nvme%dn%d", &sub_instance, &head_instance) != 2)
+		return false;
+		
+	sprintf(path, "/sys/class/nvme-subsystem/nvme-subsys%d/nvme%dn%d", 
+		sub_instance, sub_instance, head_instance);
+	if (access(path, F_OK) != -1) 
+		return true;
+	return false;
+}
+
+void huawei_get_multipath_device_status(struct huawei_list_item *item)
+{
+	int i, nr_ctrls, subsys_num, ctrl_num, head_num;
+	char path[280];
+	struct dirent **ctrls = NULL;
+	char *temp = NULL;
+
+	sscanf(item->node, "/dev/nvme%dn%d", &subsys_num, &head_num);
+	sprintf(path, "/sys/class/nvme-subsystem/nvme-subsys%d", subsys_num);
+	nr_ctrls = scandir(path, &ctrls, scan_ctrls_filter, alphasort);
+	if (nr_ctrls < 0) 
+		return;
+  
+	for (i = 0; i < nr_ctrls; i++) {
+		sscanf(ctrls[i]->d_name, "nvme%d", &ctrl_num);
+		sprintf(path, "/sys/class/nvme-subsystem/nvme-subsys%d/nvme%d", 
+			subsys_num, ctrl_num);
+		temp = nvme_get_ctrl_attr(path, "state");
+		if (temp == NULL)
+			continue;
+		if (strcmp(temp, "live"))
+			continue;
+		sprintf(item->status, "%s", "active");
+		free(temp);
+	}
+	
+	while (i--)
+		free(ctrls[i]);
+	free(ctrls); 
+	return;
+}
+
+void huawei_get_device_status(struct huawei_list_item *item)
+{
+	bool flag;
+	int m, n;
+	char path[280];
+	char *temp = NULL;
+	
+	sscanf(item->node, "/dev/nvme%dn%d", &m, &n);
+	flag = huawei_check_multipath_device(item->node);
+	if (flag == true) {
+		huawei_get_multipath_device_status(item);
+		return;
+	}
+	
+	sprintf(path, "/sys/class/nvme/nvme%d", m);
+	temp = nvme_get_ctrl_attr(path, "state");
+	if (temp == NULL) 
+		return; 
+	if (!strcmp(temp, "live")) 
+		sprintf(item->status, "%s", "active");
+	free(temp);
+	return;
+}
+
 static int huawei_get_nvme_info(const char *name, struct huawei_list_item *item, const char *node)
 {
 	bool flag;
@@ -170,6 +245,7 @@ static int huawei_get_nvme_info(const char *name, struct huawei_list_item *item,
 
 	item->huawei_device = true;
 	sprintf(item->node, "/dev/%s", name);
+	huawei_get_device_status(item);
 	
 	if (item->ns.vs[0] != 0) {
 		memcpy(item->ns_name, item->ns.vs, NS_NAME_LEN);
@@ -237,6 +313,14 @@ static void huawei_json_print_list_items(struct huawei_list_item *list_items,
 					     "Array Name",
 					     formatter);
 
+		format(formatter, sizeof(formatter),
+			   list_items[i].status,
+			   sizeof(list_items[i].status));
+
+		json_object_add_value_string(device_attrs,
+						"Status",
+						formatter);
+
 		json_array_add_value_object(devices, device_attrs);
 	}
 	json_object_add_value_array(root, "Devices", devices);
@@ -254,18 +338,20 @@ static void huawei_print_list_head(struct huawei_list_element_len element_len)
 		dash[i] = '-';
 	dash[127] = '\0';
 
-	printf("%-*.*s %-*.*s %-*.*s %-*.*s %-*.*s %-*.*s\n",
+	printf("%-*.*s %-*.*s %-*.*s %-*.*s %-*.*s %-*.*s %-*.*s\n",
 		element_len.node, element_len.node, "Node",
 		element_len.ns_name, element_len.ns_name, "NS Name",
 		element_len.nguid, element_len.nguid, "Nguid",
 		element_len.ns_id, element_len.ns_id, "NS ID",
 		element_len.usage, element_len.usage, "Usage",
-		element_len.array_name, element_len.array_name, "Array Name");
+		element_len.array_name, element_len.array_name, "Array Name",
+		element_len.status, element_len.status, "Status");
 
-	printf("%-.*s %-.*s %-.*s %-.*s %-.*s %-.*s\n",
+	printf("%-.*s %-.*s %-.*s %-.*s %-.*s %-.*s %-.*s\n",
 		element_len.node, dash, element_len.ns_name, dash,
 		element_len.nguid, dash, element_len.ns_id, dash,
-		element_len.usage, dash, element_len.array_name, dash);
+		element_len.usage, dash, element_len.array_name, dash,
+		element_len.status, dash);
 }
 
 static void huawei_print_list_item(struct huawei_list_item list_item,
@@ -292,13 +378,14 @@ static void huawei_print_list_item(struct huawei_list_item list_item,
 
 	if (!strlen((char *)list_item.ns.nguid))
 		sprintf(nguid_buf, "%s", list_item.eguid);
-	printf("%-*.*s %-*.*s %-*.*s %-*d %-*.*s %-*.*s\n",
+	printf("%-*.*s %-*.*s %-*.*s %-*d %-*.*s %-*.*s %-*.*s\n",
 		element_len.node, element_len.node, list_item.node,
 		element_len.ns_name, element_len.ns_name, list_item.ns_name,
 		element_len.nguid, element_len.nguid, nguid_buf,
 		element_len.ns_id, list_item.nsid,
 		element_len.usage, element_len.usage, usage,
-		element_len.array_name, element_len.array_name, list_item.array_name);
+		element_len.array_name, element_len.array_name, list_item.array_name,
+		element_len.status, element_len.status, list_item.status);
 
 }
 
@@ -347,6 +434,7 @@ static void huawei_print_list_items(struct huawei_list_item *list_items, unsigne
 	element_len.usage = 26;
 	element_len.ns_name = huawei_get_ns_len(list_items, len, MIN_NS_NAME_LEN);
 	element_len.array_name = huawei_get_array_len(list_items, len, MIN_ARRAY_NAME_LEN);
+	element_len.status= NS_STATUS_LEN;
 
 	huawei_print_list_head(element_len);
 
-- 
2.24.0.windows.2




More information about the Linux-nvme mailing list