diff options
-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")) { |