diff options
author | Dawit Alemu <dalemu@redhat.com> | 2013-11-14 12:52:14 -0500 |
---|---|---|
committer | Anand Avati <avati@redhat.com> | 2013-12-03 18:09:29 -0800 |
commit | 133c370ec5e2688b6734acb087fe3769cb900a74 (patch) | |
tree | 14e72f63bcfc8612c3f07166465e95614457b6db | |
parent | e4b9a74f46bca3894d686ce87042168c4304f07b (diff) |
cli: Add an option to fetch just incremental or cumulative I/0
information
'volume profile info' fetches both cumulative and incremental
I/O statistics. There isn't a way to fetch just cumulative or
incremental statistics.
This change introduces two optional arguments, namely "incremental"
and "cumulative", that can be tacked on to 'volume profile info'.
In other words, the new command format is
volume profile <VOLNAME> {start | info [incremental | cumulative]
| stop} [nfs]
'volume profile info incremental' - fetches incremental stats
'volume profile info cumulative' - fetches cumulative stats
'volume profile info' - fetches incremental and cumulative stats
Change-Id: I5ddb45d990542ea611d23d251efebfec46f472d0
BUG: 1030580
Signed-off-by: Dawit Alemu <dalemu@redhat.com>
Reviewed-on: http://review.gluster.org/6264
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Krishnan Parthasarathi <kparthas@redhat.com>
-rw-r--r-- | cli/src/cli-cmd-parser.c | 30 | ||||
-rw-r--r-- | cli/src/cli-cmd-volume.c | 2 | ||||
-rw-r--r-- | cli/src/cli-rpc-ops.c | 4 | ||||
-rw-r--r-- | cli/src/cli-xml-output.c | 2 | ||||
-rw-r--r-- | rpc/xdr/src/cli1-xdr.h | 4 | ||||
-rw-r--r-- | tests/bugs/bug-1030580.t | 56 | ||||
-rw-r--r-- | xlators/debug/io-stats/src/Makefile.am | 4 | ||||
-rw-r--r-- | xlators/debug/io-stats/src/io-stats.c | 55 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-op-sm.c | 10 |
9 files changed, 135 insertions, 32 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index 88fbf96ff9c..de980b27988 100644 --- a/cli/src/cli-cmd-parser.c +++ b/cli/src/cli-cmd-parser.c @@ -1988,7 +1988,7 @@ cli_cmd_volume_profile_parse (const char **words, int wordcount, if (!dict) goto out; - if (wordcount < 4 || wordcount >5) + if (wordcount < 4) goto out; volname = (char *)words[2]; @@ -2002,12 +2002,30 @@ cli_cmd_volume_profile_parse (const char **words, int wordcount, ret = -1; goto out; } + + if ((strcmp (w, "start") == 0 || strcmp (w, "stop") == 0) && + wordcount > 5) + goto out; + + if (strcmp (w, "info") == 0 && wordcount > 6) + goto out; + if (strcmp (w, "start") == 0) { op = GF_CLI_STATS_START; } else if (strcmp (w, "stop") == 0) { op = GF_CLI_STATS_STOP; } else if (strcmp (w, "info") == 0) { op = GF_CLI_STATS_INFO; + if (wordcount > 4) { + if (strcmp (words[4], "incremental") == 0) { + op = GF_CLI_STATS_INFO_INCREMENTAL; + } else if (strcmp (words[4], "cumulative") == 0) { + op = GF_CLI_STATS_INFO_CUMULATIVE; + } + } + ret = dict_set_int32 (dict, "info-op", op); + if (ret) + goto out; } else GF_ASSERT (!"opword mismatch"); @@ -2015,12 +2033,10 @@ cli_cmd_volume_profile_parse (const char **words, int wordcount, if (ret) goto out; - if (wordcount == 5) { - if (!strcmp (words[4], "nfs")) { - ret = dict_set_int32 (dict, "nfs", _gf_true); - if (ret) - goto out; - } + if (!strcmp (words[wordcount - 1], "nfs")) { + ret = dict_set_int32 (dict, "nfs", _gf_true); + if (ret) + goto out; } *options = dict; diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c index 22bf66b4fb5..f11fa21db96 100644 --- a/cli/src/cli-cmd-volume.c +++ b/cli/src/cli-cmd-volume.c @@ -2299,7 +2299,7 @@ struct cli_cmd volume_cmds[] = { cli_cmd_check_gsync_exists_cbk}, #endif - { "volume profile <VOLNAME> {start|stop|info [nfs]}", + { "volume profile <VOLNAME> {start | info [incremental | cumulative] | stop} [nfs]", cli_cmd_volume_profile_cbk, "volume profile operations"}, diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c index 3d2f90c0436..2cb0ba3d470 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -4976,6 +4976,8 @@ gf_cli_profile_volume_cbk (struct rpc_req *req, struct iovec *iov, (rsp.op_ret) ? "unsuccessful": "successful"); break; case GF_CLI_STATS_INFO: + case GF_CLI_STATS_INFO_INCREMENTAL: + case GF_CLI_STATS_INFO_CUMULATIVE: break; default: cli_out ("volume profile on %s has been %s ", @@ -4990,7 +4992,7 @@ gf_cli_profile_volume_cbk (struct rpc_req *req, struct iovec *iov, goto out; } - if (op != GF_CLI_STATS_INFO) { + if (op < GF_CLI_STATS_INFO || GF_CLI_STATS_INFO_CUMULATIVE < op) { ret = 0; goto out; } diff --git a/cli/src/cli-xml-output.c b/cli/src/cli-xml-output.c index 68d69111410..2927ab1e4fd 100644 --- a/cli/src/cli-xml-output.c +++ b/cli/src/cli-xml-output.c @@ -2260,7 +2260,7 @@ cli_xml_output_vol_profile (dict_t *dict, int op_ret, int op_errno, "%d", op); XML_RET_CHECK_AND_GOTO (ret, out); - if (op != GF_CLI_STATS_INFO) + if (op < GF_CLI_STATS_INFO || GF_CLI_STATS_INFO_CUMULATIVE < op) goto cont; ret = dict_get_int32 (dict, "count", &brick_count); diff --git a/rpc/xdr/src/cli1-xdr.h b/rpc/xdr/src/cli1-xdr.h index e1cb34dc96f..815384e808d 100644 --- a/rpc/xdr/src/cli1-xdr.h +++ b/rpc/xdr/src/cli1-xdr.h @@ -140,7 +140,9 @@ enum gf1_cli_stats_op { GF_CLI_STATS_START = 1, GF_CLI_STATS_STOP = 2, GF_CLI_STATS_INFO = 3, - GF_CLI_STATS_TOP = 4, + GF_CLI_STATS_INFO_INCREMENTAL = 4, + GF_CLI_STATS_INFO_CUMULATIVE = 5, + GF_CLI_STATS_TOP = 6 }; typedef enum gf1_cli_stats_op gf1_cli_stats_op; diff --git a/tests/bugs/bug-1030580.t b/tests/bugs/bug-1030580.t new file mode 100644 index 00000000000..ed1cdb864c8 --- /dev/null +++ b/tests/bugs/bug-1030580.t @@ -0,0 +1,56 @@ +#!/bin/bash + +. $(dirname $0)/../include.rc +. $(dirname $0)/../volume.rc + +cleanup; + +function write_to_file { + dd of=$M0/1 if=/dev/zero bs=1M count=128 oflag=append 2>&1 >/dev/null +} + +function cumulative_stat_count { + echo "$1" | grep "Cumulative Stats:" | wc -l +} + +function incremental_stat_count { + echo "$1" | grep "Interval$2Stats:" | wc -l +} + +TEST glusterd +TEST pidof glusterd +TEST $CLI volume create $V0 replica 2 $H0:$B0/${V0}0 $H0:$B0/${V0}1 +TEST $CLI volume start $V0 +TEST $CLI volume profile $V0 start +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --attribute-timeout=0 --entry-timeout=0 + +# Verify 'volume profile info' prints both cumulative and incremental stats +write_to_file & +wait +output=$($CLI volume profile $V0 info) +EXPECT 2 cumulative_stat_count "$output" +EXPECT 2 incremental_stat_count "$output" ' 0 ' + +# Verify 'volume profile info incremental' prints incremental stats only +write_to_file & +wait +output=$($CLI volume profile $V0 info incremental) +EXPECT 0 cumulative_stat_count "$output" +EXPECT 2 incremental_stat_count "$output" ' 1 ' + +# Verify 'volume profile info cumulative' prints cumulative stats only +write_to_file & +wait +output=$($CLI volume profile $V0 info cumulative) +EXPECT 2 cumulative_stat_count "$output" +EXPECT 0 incremental_stat_count "$output" '.*' + +# Verify the 'volume profile info cumulative' command above didn't alter +# the interval id +write_to_file & +wait +output=$($CLI volume profile $V0 info incremental) +EXPECT 0 cumulative_stat_count "$output" +EXPECT 2 incremental_stat_count "$output" ' 2 ' + +cleanup; diff --git a/xlators/debug/io-stats/src/Makefile.am b/xlators/debug/io-stats/src/Makefile.am index 332d79015e9..dff294cd84e 100644 --- a/xlators/debug/io-stats/src/Makefile.am +++ b/xlators/debug/io-stats/src/Makefile.am @@ -9,7 +9,9 @@ io_stats_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = io-stats-mem-types.h -AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src +AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ + -I$(top_srcdir)/rpc/xdr/src \ + -I$(top_srcdir)/rpc/rpc-lib/src AM_CFLAGS = -Wall $(GF_CFLAGS) diff --git a/xlators/debug/io-stats/src/io-stats.c b/xlators/debug/io-stats/src/io-stats.c index 3ca57753c56..65aeee52bfb 100644 --- a/xlators/debug/io-stats/src/io-stats.c +++ b/xlators/debug/io-stats/src/io-stats.c @@ -36,6 +36,7 @@ #include <stdarg.h> #include "defaults.h" #include "logging.h" +#include "cli1-xdr.h" #define MAX_LIST_MEMBERS 100 @@ -917,7 +918,8 @@ ios_dump_args_init (struct ios_dump_args *args, ios_dump_type_t type, } int -io_stats_dump (xlator_t *this, struct ios_dump_args *args) +io_stats_dump (xlator_t *this, struct ios_dump_args *args, + gf1_cli_stats_op op) { struct ios_conf *conf = NULL; struct ios_global_stats cumulative = {0, }; @@ -935,18 +937,30 @@ io_stats_dump (xlator_t *this, struct ios_dump_args *args) gettimeofday (&now, NULL); LOCK (&conf->lock); { - cumulative = conf->cumulative; - incremental = conf->incremental; + if (op == GF_CLI_STATS_INFO || + op == GF_CLI_STATS_INFO_CUMULATIVE) + cumulative = conf->cumulative; - increment = conf->increment++; + if (op == GF_CLI_STATS_INFO || + op == GF_CLI_STATS_INFO_INCREMENTAL) { + incremental = conf->incremental; - memset (&conf->incremental, 0, sizeof (conf->incremental)); - conf->incremental.started_at = now; + increment = conf->increment++; + + memset (&conf->incremental, 0, + sizeof (conf->incremental)); + conf->incremental.started_at = now; + } } UNLOCK (&conf->lock); - io_stats_dump_global (this, &cumulative, &now, -1, args); - io_stats_dump_global (this, &incremental, &now, increment, args); + if (op == GF_CLI_STATS_INFO || + op == GF_CLI_STATS_INFO_CUMULATIVE) + io_stats_dump_global (this, &cumulative, &now, -1, args); + + if (op == GF_CLI_STATS_INFO || + op == GF_CLI_STATS_INFO_INCREMENTAL) + io_stats_dump_global (this, &incremental, &now, increment, args); return 0; } @@ -2207,7 +2221,7 @@ conditional_dump (dict_t *dict, char *key, data_t *value, void *data) } (void) ios_dump_args_init (&args, IOS_DUMP_TYPE_FILE, logfp); - io_stats_dump (this, &args); + io_stats_dump (this, &args, GF_CLI_STATS_INFO); fclose (logfp); } return 0; @@ -2773,7 +2787,7 @@ notify (xlator_t *this, int32_t event, void *data, ...) struct ios_dump_args args = {0}; dict_t *output = NULL; dict_t *dict = NULL; - int32_t top_op = 0; + int32_t op = 0; int32_t list_cnt = 0; double throughput = 0; double time = 0; @@ -2787,7 +2801,7 @@ notify (xlator_t *this, int32_t event, void *data, ...) case GF_EVENT_TRANSLATOR_INFO: ret = dict_get_str_boolean (dict, "clear-stats", _gf_false); if (ret) { - ret = dict_set_int32 (output, "top-op", top_op); + ret = dict_set_int32 (output, "top-op", op); if (ret) { gf_log (this->name, GF_LOG_ERROR, "Failed to set top-op in dict"); @@ -2807,15 +2821,15 @@ notify (xlator_t *this, int32_t event, void *data, ...) goto out; } - ret = dict_get_int32 (dict, "top-op", &top_op); + ret = dict_get_int32 (dict, "top-op", &op); if (!ret) { ret = dict_get_int32 (dict, "list-cnt", &list_cnt); - if (top_op > IOS_STATS_TYPE_NONE && - top_op < IOS_STATS_TYPE_MAX) + if (op > IOS_STATS_TYPE_NONE && + op < IOS_STATS_TYPE_MAX) ret = io_stats_dump_stats_to_dict (this, output, - top_op, list_cnt); - if (top_op == IOS_STATS_TYPE_READ_THROUGHPUT || - top_op == IOS_STATS_TYPE_WRITE_THROUGHPUT) { + op, list_cnt); + if (op == IOS_STATS_TYPE_READ_THROUGHPUT || + op == IOS_STATS_TYPE_WRITE_THROUGHPUT) { ret = dict_get_double (dict, "throughput", &throughput); if (!ret) { @@ -2836,9 +2850,14 @@ notify (xlator_t *this, int32_t event, void *data, ...) } } else { + ret = dict_get_int32 (dict, "info-op", &op); + if (ret || op < GF_CLI_STATS_INFO || + GF_CLI_STATS_INFO_CUMULATIVE < op) + op = GF_CLI_STATS_INFO; + (void) ios_dump_args_init (&args, IOS_DUMP_TYPE_DICT, output); - ret = io_stats_dump (this, &args); + ret = io_stats_dump (this, &args, op); } break; default: diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c index e9437057aa2..add3b64f3c8 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c @@ -1056,7 +1056,8 @@ glusterd_op_stage_stats_volume (dict_t *dict, char **op_errstr) } if ((GF_CLI_STATS_STOP == stats_op) || - (GF_CLI_STATS_INFO == stats_op)) { + (GF_CLI_STATS_INFO <= stats_op && + stats_op <= GF_CLI_STATS_INFO_CUMULATIVE)) { if (_gf_false == glusterd_is_profile_on (volinfo)) { snprintf (msg, sizeof (msg), "Profile on Volume %s is" " not started", volinfo->volname); @@ -1066,7 +1067,8 @@ glusterd_op_stage_stats_volume (dict_t *dict, char **op_errstr) } } if ((GF_CLI_STATS_TOP == stats_op) || - (GF_CLI_STATS_INFO == stats_op)) { + (GF_CLI_STATS_INFO <= stats_op && + stats_op <= GF_CLI_STATS_INFO_CUMULATIVE)) { if (_gf_false == glusterd_is_volume_started (volinfo)) { snprintf (msg, sizeof (msg), "Volume %s is not started.", volinfo->volname); @@ -1868,6 +1870,8 @@ glusterd_op_stats_volume (dict_t *dict, char **op_errstr, glusterd_remove_profile_volume_options (volinfo); break; case GF_CLI_STATS_INFO: + case GF_CLI_STATS_INFO_INCREMENTAL: + case GF_CLI_STATS_INFO_CUMULATIVE: case GF_CLI_STATS_TOP: //info is already collected in brick op. //just goto out; @@ -4440,6 +4444,8 @@ glusterd_bricks_select_profile_volume (dict_t *dict, char **op_errstr, goto out; break; case GF_CLI_STATS_INFO: + case GF_CLI_STATS_INFO_INCREMENTAL: + case GF_CLI_STATS_INFO_CUMULATIVE: ret = dict_get_str_boolean (dict, "nfs", _gf_false); if (ret) { if (!glusterd_is_nodesvc_online ("nfs")) { |