[multipathd] add "show status" cli command
authorChristophe Varoqui <christophe.varoqui@free.fr>
Wed, 10 Sep 2008 22:17:37 +0000 (00:17 +0200)
committerChristophe Varoqui <christophe.varoqui@free.fr>
Wed, 10 Sep 2008 22:17:37 +0000 (00:17 +0200)
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
libmultipath/checkers.h
libmultipath/print.c
libmultipath/print.h
libmultipath/structs.c
multipathd/cli.c
multipathd/cli_handlers.c
multipathd/cli_handlers.h
multipathd/main.c

index 5889ad7..5132081 100644 (file)
@@ -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);
index a65aaf9..e735250 100644 (file)
  * - 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 *);
index 08ebd51..459b973 100644 (file)
@@ -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;
index 5c7023c..1718c94 100644 (file)
@@ -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);
index 50f66f4..bb0d9f7 100644 (file)
@@ -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;
index 7eaac73..051624a 100644 (file)
@@ -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);
index c84805a..415f865 100644 (file)
@@ -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;
index a688481..cfc4b12 100644 (file)
@@ -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);
index 8d74cb9..e57a3e4 100644 (file)
@@ -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);