[multipathd] add "show maps stats" CLI command
authorChristophe Varoqui <root@xa-s05.(none)>
Mon, 28 Nov 2005 08:38:09 +0000 (09:38 +0100)
committerChristophe Varoqui <root@xa-s05.(none)>
Mon, 28 Nov 2005 08:38:09 +0000 (09:38 +0100)
xa-s05:~# multipathd -k"show maps stats"
name   sysfs path_fails switch_grp map_loads total_q_time q_tmo
mpath0 dm-0  1          4424       2         0            0
mpath1 dm-1  0          13717      2         0            0

libmultipath/configure.c
libmultipath/print.c
libmultipath/print.h
libmultipath/structs.h
multipathd/cli.c
multipathd/cli.h
multipathd/cli_handlers.c
multipathd/cli_handlers.h
multipathd/main.c
multipathd/main.h

index 14e0774..640d8d8 100644 (file)
@@ -358,6 +358,7 @@ domap (struct multipath * mpp)
                dm_switchgroup(mpp->alias, mpp->bestpg);
                print_mp(mpp, conf->verbosity);
 #else
+               mpp->stat_map_loads++;
                condlog(2, "%s: load table [0 %llu %s %s]", mpp->alias,
                         mpp->size, DEFAULT_TARGET, mpp->params);
 #endif
index 4207de3..3700bf0 100644 (file)
@@ -180,6 +180,26 @@ snprint_map_header (char * line, int len, char * format)
                        PRINT(c, TAIL, "dm-st");
                        PAD(7);
                        break;
+               case '0':
+                       PRINT(c, TAIL, "path_fails");
+                       PAD(10);
+                       break;
+               case '1':
+                       PRINT(c, TAIL, "switch_group");
+                       PAD(12);
+                       break;
+               case '2':
+                       PRINT(c, TAIL, "map_loads");
+                       PAD(9);
+                       break;
+               case '3':
+                       PRINT(c, TAIL, "total_queue_time");
+                       PAD(16);
+                       break;
+               case '4':
+                       PRINT(c, TAIL, "queueing_tmo");
+                       PAD(12);
+                       break;
                default:
                        break;
                }
@@ -269,6 +289,26 @@ snprint_map (char * line, int len, char * format,
                        }
                        PAD(7);
                        break;
+               case '0':
+                       PRINT(c, TAIL, "%i", mpp->stat_path_failures);
+                       PAD(10);
+                       break;
+               case '1':
+                       PRINT(c, TAIL, "%i", mpp->stat_switchgroup);
+                       PAD(12);
+                       break;
+               case '2':
+                       PRINT(c, TAIL, "%i", mpp->stat_map_loads);
+                       PAD(9);
+                       break;
+               case '3':
+                       PRINT(c, TAIL, "%i", mpp->stat_total_queueing_time);
+                       PAD(16);
+                       break;
+               case '4':
+                       PRINT(c, TAIL, "%i", mpp->stat_queueing_timeouts);
+                       PAD(12);
+                       break;
                default:
                        break;
                }
@@ -569,6 +609,15 @@ print_path (struct path * pp, char * style)
 }
 
 extern void
+print_multipath (struct multipath * mpp, char * style)
+{
+       char line[MAX_LINE_LEN];
+
+       snprint_map(&line[0], MAX_LINE_LEN, style, mpp);
+       printf("%s", line);
+}
+
+extern void
 print_map (struct multipath * mpp)
 {
        if (mpp->size && mpp->params)
index da69edc..479dfd3 100644 (file)
  * %Q : queueing policy changer countdown (no_path_retry)
  * %n : number of active paths
  * %t : device mapper map status
+ * %0 : stat_path_failures
+ * %1 : stat_switchgroup
+ * %2 : stat_map_loads
+ * %3 : stat_total_queueing_time
+ * %4 : stat_queueing_timeouts
  */
 #define PRINT_PATH_LONG      "%w %i %d %D %p %t%T %s"
 #define PRINT_PATH_INDENT    " \\_ %i %d %D %t%T"
 #define PRINT_PATH_CHECKER   "%i %d %D %p %t%T %C"
 #define PRINT_MAP_FAILBACK   "%w %d %F %Q %n %t"
+#define PRINT_MAP_STATS      "%w %d %0 %1 %2 %3 %4"
 
 #define MAX_LINE_LEN 80
 #define PROGRESS_LEN 10
@@ -54,5 +60,6 @@ int snprint_map (char *, int, char *,struct multipath *);
 
 void print_mp (struct multipath * mpp, int verbosity);
 void print_path (struct path * pp, char * style);
+void print_multipath (struct multipath * mpp, char * style);
 void print_map (struct multipath * mpp);
 void print_all_paths (vector pathvec, int banner);
index cd8946f..c04ba1a 100644 (file)
@@ -144,6 +144,13 @@ struct multipath {
 
        /* daemon store a data blob for DM event waiter threads */
        void * waiter;
+
+       /* stats */
+       unsigned int stat_switchgroup;
+       unsigned int stat_path_failures;
+       unsigned int stat_map_loads;
+       unsigned int stat_total_queueing_time;
+       unsigned int stat_queueing_timeouts;
 };
 
 struct pathgroup {
index f8cecd5..76e4dbb 100644 (file)
@@ -136,6 +136,7 @@ load_keys (void)
        r += add_key(keys, "dump", DUMP, 0);
        r += add_key(keys, "pathvec", PATHVEC, 0);
        r += add_key(keys, "reconfigure", RECONFIGURE, 0);
+       r += add_key(keys, "stats", STATS, 0);
 
        if (r) {
                free_keys(keys);
index 814af15..3ae53aa 100644 (file)
@@ -14,7 +14,8 @@ enum {
        __GROUP,
        __DUMP,
        __PATHVEC,
-       __RECONFIGURE
+       __RECONFIGURE,
+       __STATS,
 };
 
 #define LIST           (1 << __LIST)
@@ -33,6 +34,7 @@ enum {
 #define DUMP           (1 << __DUMP)
 #define PATHVEC                (1 << __PATHVEC)
 #define RECONFIGURE    (1 << __RECONFIGURE)
+#define STATS          (1 << __STATS)
 
 #define INITIAL_REPLY_LEN 1000
 
index 59bafb6..39e7207 100644 (file)
@@ -11,6 +11,7 @@
 #include <configure.h>
 #include <blacklist.h>
 #include <debug.h>
+#include <print.h>
 
 #include "main.h"
 #include "cli.h"
@@ -22,7 +23,7 @@ cli_list_paths (void * v, char ** reply, int * len, void * data)
 
        condlog(3, "list paths (operator)");
 
-       return show_paths(reply, len, vecs);
+       return show_paths(reply, len, vecs, PRINT_PATH_CHECKER);
 }
 
 int
@@ -32,7 +33,17 @@ cli_list_maps (void * v, char ** reply, int * len, void * data)
 
        condlog(3, "list maps (operator)");
 
-       return show_maps(reply, len, vecs);
+       return show_maps(reply, len, vecs, PRINT_MAP_FAILBACK);
+}
+
+int
+cli_list_maps_stats (void * v, char ** reply, int * len, void * data)
+{
+       struct vectors * vecs = (struct vectors *)data;
+
+       condlog(3, "list maps (operator)");
+
+       return show_maps(reply, len, vecs, PRINT_MAP_STATS);
 }
 
 int
index 5b9a66c..e76e68e 100644 (file)
@@ -1,5 +1,6 @@
 int cli_list_paths (void * v, char ** reply, int * len, void * data);
 int cli_list_maps (void * v, char ** reply, int * len, void * data);
+int cli_list_maps_stats (void * v, char ** reply, int * len, void * data);
 int cli_add_path (void * v, char ** reply, int * len, void * data);
 int cli_del_path (void * v, char ** reply, int * len, void * data);
 int cli_add_map (void * v, char ** reply, int * len, void * data);
index fa7478a..66f9751 100644 (file)
@@ -163,6 +163,7 @@ update_queue_mode_del_path(struct multipath *mpp)
                 * meaning of +1: retry_tick may be decremented in
                 *                checkerloop before starting retry.
                 */
+               mpp->stat_queueing_timeouts++;
                mpp->retry_tick = mpp->no_path_retry * conf->checkint + 1;
                condlog(1, "%s: Entering recovery mode: max_retries=%d",
                        mpp->alias, mpp->no_path_retry);
@@ -212,6 +213,7 @@ need_switch_pathgroup (struct multipath * mpp, int refresh)
 static void
 switch_pathgroup (struct multipath * mpp)
 {
+       mpp->stat_switchgroup++;
        dm_switchgroup(mpp->alias, mpp->bestpg);
        condlog(2, "%s: switch to path group #%i",
                 mpp->alias, mpp->bestpg);
@@ -289,6 +291,7 @@ update_multipath (struct vectors *vecs, char *mapname)
 
                        if (pp->state != PATH_DOWN) {
                                condlog(2, "%s: mark as failed", pp->dev_t);
+                               mpp->stat_path_failures++;
                                pp->state = PATH_DOWN;
                                update_queue_mode_del_path(mpp);
 
@@ -858,7 +861,7 @@ out:
 }
 
 int
-show_paths (char ** r, int * len, struct vectors * vecs)
+show_paths (char ** r, int * len, struct vectors * vecs, char * style)
 {
        int i;
        struct path * pp;
@@ -878,11 +881,11 @@ show_paths (char ** r, int * len, struct vectors * vecs)
 
                if (VECTOR_SIZE(vecs->pathvec) > 0)
                        c += snprint_path_header(c, reply + maxlen - c,
-                                                PRINT_PATH_CHECKER);
+                                                style);
 
                vector_foreach_slot(vecs->pathvec, pp, i)
                        c += snprint_path(c, reply + maxlen - c,
-                                         PRINT_PATH_CHECKER, pp);
+                                         style, pp);
 
                again = ((c - reply) == (maxlen - 1));
 
@@ -896,7 +899,7 @@ show_paths (char ** r, int * len, struct vectors * vecs)
 }
 
 int
-show_maps (char ** r, int *len, struct vectors * vecs)
+show_maps (char ** r, int *len, struct vectors * vecs, char * style)
 {
        int i;
        struct multipath * mpp;
@@ -915,11 +918,11 @@ show_maps (char ** r, int *len, struct vectors * vecs)
                c = reply;
                if (VECTOR_SIZE(vecs->mpvec) > 0)
                        c += snprint_map_header(c, reply + maxlen - c,
-                                               PRINT_MAP_FAILBACK);
+                                               style);
 
                vector_foreach_slot(vecs->mpvec, mpp, i)
                        c += snprint_map(c, reply + maxlen - c,
-                                        PRINT_MAP_FAILBACK, mpp);
+                                        style, mpp);
 
                again = ((c - reply) == (maxlen - 1));
 
@@ -1094,6 +1097,7 @@ uxlsnrloop (void * ap)
 
        add_handler(LIST+PATHS, cli_list_paths);
        add_handler(LIST+MAPS, cli_list_maps);
+       add_handler(LIST+MAPS+STATS, cli_list_maps_stats);
        add_handler(ADD+PATH, cli_add_path);
        add_handler(DEL+PATH, cli_del_path);
        add_handler(ADD+MAP, cli_add_map);
@@ -1222,6 +1226,7 @@ retry_count_tick(vector mpvec)
 
        vector_foreach_slot (mpvec, mpp, i) {
                if (mpp->retry_tick) {
+                       mpp->stat_total_queueing_time++;
                        condlog(4, "%s: Retrying.. No active path", mpp->alias);
                        if(--mpp->retry_tick == 0) {
                                dm_queue_if_no_path(mpp->alias, 0);
@@ -1314,6 +1319,7 @@ checkerloop (void *ap)
                                         */
                                        pp->mpp->failback_tick = 0;
 
+                                       pp->mpp->stat_path_failures++;
                                        continue;
                                }
 
index a60dff7..aa82bdc 100644 (file)
@@ -7,8 +7,8 @@
 #define MAX_CHECKINT CHECKINT << 2
 
 int reconfigure (struct vectors *);
-int show_paths (char **, int *, struct vectors *);
-int show_maps (char **, int *, struct vectors *);
+int show_paths (char **, int *, struct vectors *, char *);
+int show_maps (char **, int *, struct vectors *, char *);
 int dump_pathvec (char **, int *, struct vectors *);
 int ev_add_path (char *, struct vectors *);
 int ev_remove_path (char *, struct vectors *);