summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cli/src/cli-cmd-parser.c30
-rw-r--r--cli/src/cli-cmd-volume.c2
-rw-r--r--cli/src/cli-rpc-ops.c4
-rw-r--r--cli/src/cli-xml-output.c2
-rw-r--r--rpc/xdr/src/cli1-xdr.h4
-rw-r--r--tests/bugs/bug-1030580.t56
-rw-r--r--xlators/debug/io-stats/src/Makefile.am4
-rw-r--r--xlators/debug/io-stats/src/io-stats.c55
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-op-sm.c10
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")) {