File multipath-tools-add-show-status-cmd of Package multipath-tools

From 88eb616ae1a673127ef4fd995d703a8b46a63822 Mon Sep 17 00:00:00 2001
From: Christophe Varoqui <christophe.varoqui@free.fr>
Date: Thu, 11 Sep 2008 00:17:37 +0200
Subject: [PATCH] [multipathd] add "show status" cli command

For now just print the number of paths in each path checker state,
if not zero. For example :

path checker states:
up                  2
down                1
ghost               1
---
 libmultipath/checkers.c   |   15 +++++++++++++++
 libmultipath/checkers.h   |   18 +++++++++++-------
 libmultipath/print.c      |   24 ++++++++++++++++++++++++
 libmultipath/print.h      |    1 +
 libmultipath/structs.c    |    2 +-
 multipathd/cli.c          |    1 +
 multipathd/cli_handlers.c |   30 ++++++++++++++++++++++++++++++
 multipathd/cli_handlers.h |    1 +
 multipathd/main.c         |    4 +++-
 9 files changed, 87 insertions(+), 9 deletions(-)

diff --git a/libmultipath/checkers.c b/libmultipath/checkers.c
index 5889ad7..5132081 100644
--- a/libmultipath/checkers.c
+++ b/libmultipath/checkers.c
@@ -8,8 +8,23 @@
 #include "vector.h"
 #include "config.h"
 
+char *checker_state_names[] = {
+      "wild",
+      "unchecked",
+      "down",
+      "up",
+      "shaky",
+      "ghost",
+      "pending"
+};
+
 static LIST_HEAD(checkers);
 
+char * checker_state_name (int i)
+{
+	return checker_state_names[i];
+}
+
 int init_checkers (void)
 {
 	INIT_LIST_HEAD(&checkers);
diff --git a/libmultipath/checkers.h b/libmultipath/checkers.h
index a65aaf9..e735250 100644
--- a/libmultipath/checkers.h
+++ b/libmultipath/checkers.h
@@ -47,13 +47,16 @@
  * - Use: All async checkers
  * - Description: Indicates a check IO is in flight.
  */
-#define PATH_WILD	-1
-#define PATH_UNCHECKED	0
-#define PATH_DOWN	1
-#define PATH_UP		2
-#define PATH_SHAKY	3
-#define PATH_GHOST	4
-#define PATH_PENDING	5
+enum path_check_state {
+	PATH_WILD,
+	PATH_UNCHECKED,
+	PATH_DOWN,
+	PATH_UP,
+	PATH_SHAKY,
+	PATH_GHOST,
+	PATH_PENDING,
+	PATH_MAX_STATE
+};
 
 #define DIRECTIO     "directio"
 #define TUR          "tur"
@@ -106,6 +109,7 @@ struct checker {
 
 #define MSG(c, fmt, args...) snprintf((c)->message, CHECKER_MSG_LEN, fmt, ##args);
 
+char * checker_state_name (int);
 int init_checkers (void);
 struct checker * add_checker (char *);
 struct checker * checker_lookup (char *);
diff --git a/libmultipath/print.c b/libmultipath/print.c
index 08ebd51..459b973 100644
--- a/libmultipath/print.c
+++ b/libmultipath/print.c
@@ -1133,6 +1133,30 @@ snprint_blacklist_except (char * buff, int len)
 }
 
 extern int
+snprint_status (char * buff, int len, struct vectors *vecs)
+{
+	int fwd = 0;
+	int i;
+	unsigned int count[PATH_MAX_STATE] = {0};
+	struct path * pp;
+
+	vector_foreach_slot (vecs->pathvec, pp, i) {
+		count[pp->state]++;
+	}
+	fwd += snprintf(buff + fwd, len - fwd, "path checker states:\n");
+	for (i=0; i<PATH_MAX_STATE; i++) {
+		if (!count[i])
+			continue;
+		fwd += snprintf(buff + fwd, len - fwd, "%-20s%u\n",
+				checker_state_name(i), count[i]);
+	}
+
+	if (fwd > len)
+		return len;
+	return fwd;
+}
+
+extern int
 snprint_devices (char * buff, int len, struct vectors *vecs)
 {
 	DIR *blkdir;
diff --git a/libmultipath/print.h b/libmultipath/print.h
index 5c7023c..1718c94 100644
--- a/libmultipath/print.h
+++ b/libmultipath/print.h
@@ -44,6 +44,7 @@ int snprint_defaults (char *, int);
 int snprint_blacklist (char *, int);
 int snprint_blacklist_except (char *, int);
 int snprint_blacklist_report (char *, int);
+int snprint_status (char *, int, struct vectors *);
 int snprint_devices (char *, int, struct vectors *);
 int snprint_hwtable (char *, int, vector);
 int snprint_mptable (char *, int, vector);
diff --git a/libmultipath/structs.c b/libmultipath/structs.c
index 50f66f4..bb0d9f7 100644
--- a/libmultipath/structs.c
+++ b/libmultipath/structs.c
@@ -349,7 +349,7 @@ pathcountgr (struct pathgroup * pgp, int state)
 	int i;
 
 	vector_foreach_slot (pgp->paths, pp, i)
-		if ((pp->state == state) || (state < 0))
+		if ((pp->state == state) || (state == PATH_WILD))
 			count++;
 
 	return count;
diff --git a/multipathd/cli.c b/multipathd/cli.c
index 7eaac73..051624a 100644
--- a/multipathd/cli.c
+++ b/multipathd/cli.c
@@ -406,6 +406,7 @@ cli_init (void) {
 
 	add_handler(LIST+PATHS, NULL);
 	add_handler(LIST+PATHS+FMT, NULL);
+	add_handler(LIST+STATUS, NULL);
 	add_handler(LIST+MAPS, NULL);
 	add_handler(LIST+MAPS+STATUS, NULL);
 	add_handler(LIST+MAPS+STATS, NULL);
diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c
index c84805a..415f865 100644
--- a/multipathd/cli_handlers.c
+++ b/multipathd/cli_handlers.c
@@ -224,6 +224,26 @@ cli_list_maps_topology (void * v, char ** reply, int * len, void * data)
 }
 
 int
+show_status (char ** r, int *len, struct vectors * vecs)
+{
+	char * c;
+	char * reply;
+
+	unsigned int maxlen = INITIAL_REPLY_LEN;
+	reply = MALLOC(maxlen);
+
+	if (!reply)
+		return 1;
+
+	c = reply;
+	c += snprint_status(c, reply + maxlen - c, vecs);
+
+	*r = reply;
+	*len = (int)(c - reply + 1);
+	return 0;
+}
+
+int
 show_maps (char ** r, int *len, struct vectors * vecs, char * style)
 {
 	int i;
@@ -270,6 +290,16 @@ cli_list_maps (void * v, char ** reply, int * len, void * data)
 }
 
 int
+cli_list_status (void * v, char ** reply, int * len, void * data)
+{
+	struct vectors * vecs = (struct vectors *)data;
+
+	condlog(3, "list status (operator)");
+
+	return show_status(reply, len, vecs);
+}
+
+int
 cli_list_maps_status (void * v, char ** reply, int * len, void * data)
 {
 	struct vectors * vecs = (struct vectors *)data;
diff --git a/multipathd/cli_handlers.h b/multipathd/cli_handlers.h
index a688481..cfc4b12 100644
--- a/multipathd/cli_handlers.h
+++ b/multipathd/cli_handlers.h
@@ -1,5 +1,6 @@
 int cli_list_paths (void * v, char ** reply, int * len, void * data);
 int cli_list_paths_fmt (void * v, char ** reply, int * len, void * data);
+int cli_list_status (void * v, char ** reply, int * len, void * data);
 int cli_list_maps (void * v, char ** reply, int * len, void * data);
 int cli_list_maps_status (void * v, char ** reply, int * len, void * data);
 int cli_list_maps_stats (void * v, char ** reply, int * len, void * data);
diff --git a/multipathd/main.c b/multipathd/main.c
index 8d74cb9..e57a3e4 100644
--- a/multipathd/main.c
+++ b/multipathd/main.c
@@ -159,7 +159,8 @@ sync_map_state(struct multipath *mpp)
 
 	vector_foreach_slot (mpp->pg, pgp, i){
 		vector_foreach_slot (pgp->paths, pp, j){
-			if (pp->state <= PATH_UNCHECKED)
+			if (pp->state == PATH_UNCHECKED || 
+			    pp->state == PATH_WILD)
 				continue;
 			if ((pp->dmstate == PSTATE_FAILED ||
 			     pp->dmstate == PSTATE_UNDEF) &&
@@ -693,6 +694,7 @@ uxlsnrloop (void * ap)
 	set_handler_callback(LIST+PATHS, cli_list_paths);
 	set_handler_callback(LIST+PATHS+FMT, cli_list_paths_fmt);
 	set_handler_callback(LIST+MAPS, cli_list_maps);
+	set_handler_callback(LIST+STATUS, cli_list_status);
 	set_handler_callback(LIST+MAPS+STATUS, cli_list_maps_status);
 	set_handler_callback(LIST+MAPS+STATS, cli_list_maps_stats);
 	set_handler_callback(LIST+MAPS+TOPOLOGY, cli_list_maps_topology);
-- 
1.5.2.4

openSUSE Build Service is sponsored by