multipath: add "count paths" multipathd command
authorBenjamin Marzinski <bmarzins@redhat.com>
Mon, 17 May 2010 19:04:27 +0000 (14:04 -0500)
committerChristophe Varoqui <christophe.varoqui@opensvc.com>
Thu, 20 May 2010 04:49:38 +0000 (06:49 +0200)
This adds a new multipathd command, "count paths". which returns information in
the format

Paths: <nr_of_paths>
Busy: <True|False>

where "Paths" is the number of monitored paths, and "Busy" is set when
multipathd is currently handling uevents.  With this, it is possible to quickly
get the number of paths being monitored, as well as an idea if more paths may
be showing up shortly.

Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
libmultipath/uevent.c
libmultipath/uevent.h
multipathd/cli.c
multipathd/cli.h
multipathd/cli_handlers.c
multipathd/cli_handlers.h
multipathd/main.c
multipathd/multipathd.8

index f18c20b..d8f3647 100644 (file)
@@ -52,6 +52,12 @@ pthread_mutex_t uevc_lock, *uevc_lockp = &uevc_lock;
 pthread_cond_t  uev_cond,  *uev_condp  = &uev_cond;
 uev_trigger *my_uev_trigger;
 void * my_trigger_data;
+int servicing_uev;
+
+int is_uevent_busy(void)
+{
+       return (uevqhp != NULL || servicing_uev);
+}
 
 static struct uevent * alloc_uevent (void)
 {
@@ -96,7 +102,9 @@ uevq_thread(void * et)
 
        while (1) {
                pthread_mutex_lock(uevc_lockp);
+               servicing_uev = 0;
                pthread_cond_wait(uev_condp, uevc_lockp);
+               servicing_uev = 1;
                pthread_mutex_unlock(uevc_lockp);
 
                service_uevq();
index 55ce42c..e1a1254 100644 (file)
@@ -17,3 +17,4 @@ struct uevent {
 
 int uevent_listen(int (*store_uev)(struct uevent *, void * trigger_data),
                  void * trigger_data);
+int is_uevent_busy(void);
index 208a0ad..741e3d6 100644 (file)
@@ -174,6 +174,7 @@ load_keys (void)
        r += add_key(keys, "devices", DEVICES, 0);
        r += add_key(keys, "format", FMT, 1);
        r += add_key(keys, "wildcards", WILDCARDS, 0);
+       r += add_key(keys, "count", COUNT, 0);
        r += add_key(keys, "quit", QUIT, 0);
        r += add_key(keys, "exit", QUIT, 0);
 
@@ -443,6 +444,7 @@ cli_init (void) {
        add_handler(RESTOREQ+MAPS, NULL);
        add_handler(REINSTATE+PATH, NULL);
        add_handler(FAIL+PATH, NULL);
+       add_handler(COUNT+PATHS, NULL);
        add_handler(QUIT, NULL);
 
        return 0;
index f22d459..05de4e3 100644 (file)
@@ -23,6 +23,7 @@ enum {
        __BLACKLIST,
        __DEVICES,
        __FMT,
+       __COUNT,
        __WILDCARDS,
        __QUIT,
 };
@@ -51,6 +52,7 @@ enum {
 #define BLACKLIST      (1 << __BLACKLIST)
 #define DEVICES        (1 << __DEVICES)
 #define FMT            (1 << __FMT)
+#define COUNT          (1 << __COUNT)
 #define WILDCARDS      (1 << __WILDCARDS)
 #define QUIT           (1 << __QUIT)
 
index 71a73ff..0542fde 100644 (file)
 
 #include "main.h"
 #include "cli.h"
+#include "uevent.h"
+
+int
+count_paths(char  **r, int *l, struct vectors *vecs)
+{
+       int i, len;
+       struct path *pp;
+       char * reply;
+       unsigned int maxlen = INITIAL_REPLY_LEN;
+       int monitored_count = 0;
+
+       reply = MALLOC(maxlen);
+       if (!reply)
+               return 1;
+       vector_foreach_slot(vecs->pathvec, pp, i)
+               if (pp->fd != -1)
+                       monitored_count++;
+       len = sprintf(reply, "Paths: %d\nBusy: %s\n", monitored_count,
+                   is_uevent_busy()? "True" : "False");
+       *r = reply;
+       *l = len + 1;
+       return 0;
+}
 
 int
 show_paths (char ** r, int * len, struct vectors * vecs, char * style)
@@ -175,6 +198,16 @@ cli_list_config (void * v, char ** reply, int * len, void * data)
        return show_config(reply, len);
 }
 
+int
+cli_count_paths (void * v, char ** reply, int * len, void * data)
+{
+       struct vectors * vecs = (struct vectors *)data;
+
+       condlog(3, "count paths (operator)");
+
+       return count_paths(reply, len, vecs);
+}
+
 int
 cli_list_paths (void * v, char ** reply, int * len, void * data)
 {
index b3ad377..71009b7 100644 (file)
@@ -25,5 +25,6 @@ int cli_restore_all_queueing(void * v, char ** reply, int * len, void * data);
 int cli_suspend(void * v, char ** reply, int * len, void * data);
 int cli_resume(void * v, char ** reply, int * len, void * data);
 int cli_reinstate(void * v, char ** reply, int * len, void * data);
+int cli_count_paths(void * v, char ** reply, int * len, void * data);
 int cli_fail(void * v, char ** reply, int * len, void * data);
 int cli_quit(void * v, char ** reply, int * len, void * data);
index c247c43..d2c2cc3 100644 (file)
@@ -783,6 +783,7 @@ uxlsnrloop (void * ap)
        set_handler_callback(RESTOREQ+MAP, cli_restore_queueing);
        set_handler_callback(DISABLEQ+MAPS, cli_disable_all_queueing);
        set_handler_callback(RESTOREQ+MAPS, cli_restore_all_queueing);
+       set_handler_callback(COUNT+PATHS, cli_count_paths);
        set_handler_callback(QUIT, cli_quit);
 
        umask(077);
index a2d71d8..5ab7330 100644 (file)
@@ -69,6 +69,10 @@ Add a path to the list of monitored paths. $path is as listed in /sys/block (e.g
 .B remove|del path $path
 Stop monitoring a path. $path is as listed in /sys/block (e.g. sda).
 .TP
+.B count paths
+Show the number of monitored paths, and whether multipathd is currently
+handling a uevent.
+.TP
 .B add map $map
 Add a multipath device to the list of monitored devices. $map can either be a device-mapper device as listed in /sys/block (e.g. dm-0) or it can be the alias for the multipath device (e.g. mpath1) or the uid of the multipath device (e.g. 36005076303ffc56200000000000010aa). 
 .TP