From 69cb2d84466042ae5021740c04703c2cb92f6c1b Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Mon, 17 May 2010 14:04:27 -0500 Subject: [PATCH] multipath: add "count paths" multipathd command This adds a new multipathd command, "count paths". which returns information in the format Paths: Busy: 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 --- libmultipath/uevent.c | 8 ++++++++ libmultipath/uevent.h | 1 + multipathd/cli.c | 2 ++ multipathd/cli.h | 2 ++ multipathd/cli_handlers.c | 33 +++++++++++++++++++++++++++++++++ multipathd/cli_handlers.h | 1 + multipathd/main.c | 1 + multipathd/multipathd.8 | 4 ++++ 8 files changed, 52 insertions(+) diff --git a/libmultipath/uevent.c b/libmultipath/uevent.c index f18c20b..d8f3647 100644 --- a/libmultipath/uevent.c +++ b/libmultipath/uevent.c @@ -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(); diff --git a/libmultipath/uevent.h b/libmultipath/uevent.h index 55ce42c..e1a1254 100644 --- a/libmultipath/uevent.h +++ b/libmultipath/uevent.h @@ -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); diff --git a/multipathd/cli.c b/multipathd/cli.c index 208a0ad..741e3d6 100644 --- a/multipathd/cli.c +++ b/multipathd/cli.c @@ -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; diff --git a/multipathd/cli.h b/multipathd/cli.h index f22d459..05de4e3 100644 --- a/multipathd/cli.h +++ b/multipathd/cli.h @@ -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) diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c index 71a73ff..0542fde 100644 --- a/multipathd/cli_handlers.c +++ b/multipathd/cli_handlers.c @@ -18,6 +18,29 @@ #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) @@ -176,6 +199,16 @@ cli_list_config (void * v, char ** reply, int * len, void * data) } 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) { struct vectors * vecs = (struct vectors *)data; diff --git a/multipathd/cli_handlers.h b/multipathd/cli_handlers.h index b3ad377..71009b7 100644 --- a/multipathd/cli_handlers.h +++ b/multipathd/cli_handlers.h @@ -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); diff --git a/multipathd/main.c b/multipathd/main.c index c247c43..d2c2cc3 100644 --- a/multipathd/main.c +++ b/multipathd/main.c @@ -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); diff --git a/multipathd/multipathd.8 b/multipathd/multipathd.8 index a2d71d8..5ab7330 100644 --- a/multipathd/multipathd.8 +++ b/multipathd/multipathd.8 @@ -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 -- 2.7.4