summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPranith K <pranithk@gluster.com>2011-03-10 02:20:39 +0000
committerVijay Bellur <vijay@dev.gluster.com>2011-03-10 08:09:58 -0800
commita0aafa365dd355864d24232bd6d7f399ef38f9ef (patch)
tree5911492054085849f13f7a8a58983ee599c242db
parent496a04f3b2d46893635f93e5a33032969a826cd2 (diff)
cli: gluster profile CLI
Signed-off-by: Pranith Kumar K <pranithk@gluster.com> Signed-off-by: Vijay Bellur <vijay@dev.gluster.com> BUG: 1965 (need a cmd to get io-stat details) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=1965
-rw-r--r--cli/src/cli-cmd-parser.c326
-rw-r--r--cli/src/cli-cmd-volume.c48
-rw-r--r--cli/src/cli-cmd.h9
-rw-r--r--cli/src/cli-rpc-ops.c319
-rw-r--r--cli/src/cli.c9
-rw-r--r--cli/src/cli.h3
6 files changed, 534 insertions, 180 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c
index 8cfdc808a..b38cf24fa 100644
--- a/cli/src/cli-cmd-parser.c
+++ b/cli/src/cli-cmd-parser.c
@@ -37,28 +37,115 @@
#include "cli1-xdr.h"
int32_t
+cli_cmd_bricks_parse (const char **words, int wordcount, int brick_index,
+ char **bricks, int *brick_count)
+{
+ int ret = 0;
+ char *tmp_list = NULL;
+ char brick_list[120000] = {0,};
+ char *space = " ";
+ char *delimiter = NULL;
+ char *host_name = NULL;
+ char *tmp = NULL;
+ char *free_list_ptr = NULL;
+ char *tmpptr = NULL;
+ int j = 0;
+ int brick_list_len = 0;
+
+ GF_ASSERT (words);
+ GF_ASSERT (wordcount);
+ GF_ASSERT (bricks);
+ GF_ASSERT (brick_index > 0);
+ GF_ASSERT (brick_index < wordcount);
+
+ strncpy (brick_list, space, strlen (space));
+ brick_list_len++;
+ while (brick_index < wordcount) {
+ delimiter = strchr (words[brick_index], ':');
+ if (!delimiter || delimiter == words[brick_index]
+ || *(delimiter+1) != '/') {
+ cli_out ("wrong brick type: %s, use <HOSTNAME>:"
+ "<export-dir-abs-path>", words[brick_index]);
+ ret = -1;
+ goto out;
+ } else {
+ cli_path_strip_trailing_slashes (delimiter + 1);
+ }
+
+ if ((brick_list_len + strlen (words[brick_index]) + 1) > sizeof (brick_list)) {
+ gf_log ("cli", GF_LOG_ERROR,
+ "total brick list is larger than a request "
+ "can take (brick_count %d)", *brick_count);
+ ret = -1;
+ goto out;
+ }
+
+ host_name = gf_strdup (words[brick_index]);
+ if (!host_name) {
+ ret = -1;
+ gf_log("cli",GF_LOG_ERROR, "Unable to allocate "
+ "memory");
+ goto out;
+ }
+
+ strtok_r (host_name, ":", &tmp);
+ if (!(strcmp (host_name, "localhost") &&
+ strcmp (host_name, "127.0.0.1"))) {
+ cli_out ("Please provide a valid hostname/ip other "
+ "than localhost or 127.0.0.1");
+ ret = -1;
+ GF_FREE (host_name);
+ goto out;
+ }
+ GF_FREE (host_name);
+ tmp_list = gf_strdup (brick_list + 1);
+ if (free_list_ptr) {
+ GF_FREE (free_list_ptr);
+ free_list_ptr = NULL;
+ }
+ free_list_ptr = tmp_list;
+ j = 0;
+ while(j < *brick_count) {
+ strtok_r (tmp_list, " ", &tmpptr);
+ if (!(strcmp (tmp_list, words[brick_index]))) {
+ ret = -1;
+ cli_out ("Found duplicate"
+ " exports %s",words[brick_index]);
+ goto out;
+ }
+ tmp_list = tmpptr;
+ j++;
+ }
+ strcat (brick_list, words[brick_index]);
+ strcat (brick_list, " ");
+ brick_list_len += (strlen (words[brick_index]) + 1);
+ ++(*brick_count);
+ ++brick_index;
+ }
+
+ *bricks = gf_strdup (brick_list);
+ if (!*bricks)
+ ret = -1;
+out:
+ if (free_list_ptr)
+ GF_FREE (free_list_ptr);
+ return ret;
+}
+
+int32_t
cli_cmd_volume_create_parse (const char **words, int wordcount, dict_t **options)
{
dict_t *dict = NULL;
char *volname = NULL;
- char *delimiter = NULL;
int ret = -1;
gf1_cluster_type type = GF_CLUSTER_TYPE_NONE;
int count = 1;
- int brick_count = 0, brick_index = 0;
- int brick_list_size = 1;
- char brick_list[120000] = {0,};
+ int brick_index = 0;
int i = 0;
- char *tmp_list = NULL;
- char *tmpptr = NULL;
- int j = 0;
- char *host_name = NULL;
- char *tmp = NULL;
- char *freeptr = NULL;
char *trans_type = NULL;
int32_t index = 0;
- char *free_list_ptr = NULL;
char *bricks = NULL;
+ int32_t brick_count = 0;
GF_ASSERT (words);
GF_ASSERT (options);
@@ -187,77 +274,10 @@ cli_cmd_volume_create_parse (const char **words, int wordcount, dict_t **options
if (ret)
goto out;
- strcpy (brick_list, " ");
- while (brick_index < wordcount) {
- delimiter = strchr (words[brick_index], ':');
- if (!delimiter || delimiter == words[brick_index]
- || *(delimiter+1) != '/') {
- cli_out ("wrong brick type: %s, use <HOSTNAME>:"
- "<export-dir-abs-path>", words[brick_index]);
- ret = -1;
- goto out;
- } else {
- cli_path_strip_trailing_slashes (delimiter + 1);
- }
- if ((brick_list_size + strlen (words[brick_index]) + 1) > 120000) {
- gf_log ("cli", GF_LOG_ERROR,
- "total brick list is larger than a request "
- "can take (brick_count %d)", brick_count);
- ret = -1;
- goto out;
- }
-
- host_name = gf_strdup(words[brick_index]);
- if (!host_name) {
- ret = -1;
- gf_log("cli",GF_LOG_ERROR, "Unable to allocate "
- "memory");
- goto out;
- }
- freeptr = host_name;
-
- strtok_r(host_name, ":", &tmp);
- if (!(strcmp(host_name, "localhost") &&
- strcmp (host_name, "127.0.0.1"))) {
- cli_out ("Please provide a valid hostname/ip other "
- "than localhost or 127.0.0.1");
- ret = -1;
- GF_FREE(freeptr);
- goto out;
- }
- GF_FREE (freeptr);
- tmp_list = strdup(brick_list+1);
- free_list_ptr = tmp_list;
- j = 0;
- while(( brick_count != 0) && (j < brick_count)) {
- strtok_r (tmp_list, " ", &tmpptr);
- if (!(strcmp (tmp_list, words[brick_index]))) {
- ret = -1;
- cli_out ("Found duplicate"
- " exports %s",words[brick_index]);
- if (free_list_ptr)
- free (free_list_ptr);
- goto out;
- }
- tmp_list = tmpptr;
- j++;
- }
- strcat (brick_list, words[brick_index]);
- strcat (brick_list, " ");
- brick_list_size += (strlen (words[brick_index]) + 1);
- ++brick_count;
- ++brick_index;
- /*
- char key[50];
- snprintf (key, 50, "brick%d", ++brick_count);
- ret = dict_set_str (dict, key, (char *)words[brick_index++]);
-
- if (ret)
- goto out;
- */
- if (free_list_ptr)
- free (free_list_ptr);
- }
+ ret = cli_cmd_bricks_parse (words, wordcount, brick_index, &bricks,
+ &brick_count);
+ if (ret)
+ goto out;
/* If brick-count is not valid when replica or stripe is
given, exit here */
@@ -278,12 +298,6 @@ cli_cmd_volume_create_parse (const char **words, int wordcount, dict_t **options
goto out;
}
- bricks = gf_strdup (brick_list);
- if (!bricks) {
- ret = -1;
- goto out;
- }
-
ret = dict_set_dynstr (dict, "bricks", bricks);
if (ret)
goto out;
@@ -429,18 +443,8 @@ cli_cmd_volume_add_brick_parse (const char **words, int wordcount,
{
dict_t *dict = NULL;
char *volname = NULL;
- char *delimiter = NULL;
int ret = -1;
int brick_count = 0, brick_index = 0;
- int brick_list_size = 1;
- char brick_list[120000] = {0,};
- int j = 0;
- char *tmp_list = NULL;
- char *tmpptr = NULL;
- char *host_name = NULL;
- char *tmp = NULL;
- char *freeptr = NULL;
- char *free_list_ptr = NULL;
char *bricks = NULL;
GF_ASSERT (words);
@@ -472,85 +476,10 @@ cli_cmd_volume_add_brick_parse (const char **words, int wordcount,
}
brick_index = 3;
- strcpy (brick_list, " ");
- while (brick_index < wordcount) {
- delimiter = strchr (words[brick_index], ':');
- if (!delimiter || delimiter == words[brick_index]
- || *(delimiter+1) != '/') {
- cli_out ("wrong brick type: %s, use <HOSTNAME>:"
- "<export-dir-abs-path>", words[brick_index]);
- ret = -1;
- goto out;
- } else {
- cli_path_strip_trailing_slashes (delimiter + 1);
- }
-
- if ((brick_list_size + strlen (words[brick_index]) + 1) > 120000) {
- gf_log ("cli", GF_LOG_ERROR,
- "total brick list is larger than a request "
- "can take (brick_count %d)", brick_count);
- ret = -1;
- goto out;
- }
-
- host_name = gf_strdup(words[brick_index]);
- if (!host_name) {
- ret = -1;
- gf_log ("cli", GF_LOG_ERROR, "unable to allocate "
- "memory");
- goto out;
- }
- freeptr = host_name;
- strtok_r(host_name, ":", &tmp);
- if (!(strcmp(host_name, "localhost") &&
- strcmp (host_name, "127.0.0.1"))) {
- cli_out ("Please provide a valid hostname/ip other "
- "localhost or 127.0.0.1");
- ret = -1;
- GF_FREE (freeptr);
- goto out;
- }
- GF_FREE (freeptr);
-
- tmp_list = strdup(brick_list+1);
- free_list_ptr = tmp_list;
- j = 0;
- while(( brick_count != 0) && (j < brick_count)) {
- strtok_r (tmp_list, " ", &tmpptr);
- if (!(strcmp (tmp_list, words[brick_index]))) {
- ret = -1;
- cli_out ("Found duplicate"
- " exports %s",words[brick_index]);
- if (free_list_ptr)
- free (free_list_ptr);
- goto out;
- }
- tmp_list = tmpptr;
- j++;
- }
-
- strcat (brick_list, words[brick_index]);
- strcat (brick_list, " ");
- brick_list_size += (strlen (words[brick_index]) + 1);
- ++brick_count;
- ++brick_index;
- /*
- char key[50];
- snprintf (key, 50, "brick%d", ++brick_count);
- ret = dict_set_str (dict, key, (char *)words[brick_index++]);
-
- if (ret)
- goto out;
- */
- if (free_list_ptr)
- free (free_list_ptr);
- }
-
- bricks = gf_strdup (brick_list);
- if (!bricks) {
- ret = -1;
+ ret = cli_cmd_bricks_parse (words, wordcount, brick_index, &bricks,
+ &brick_count);
+ if (ret)
goto out;
- }
ret = dict_set_dynstr (dict, "bricks", bricks);
if (ret)
@@ -1097,3 +1026,48 @@ out:
return ret;
}
+int32_t
+cli_cmd_volume_profile_parse (const char **words, int wordcount,
+ dict_t **options)
+{
+ dict_t *dict = NULL;
+ char *volname = NULL;
+ int ret = -1;
+ gf1_cli_stats_op op = GF_CLI_STATS_NONE;
+
+ GF_ASSERT (words);
+ GF_ASSERT (options);
+
+ GF_ASSERT ((strcmp (words[0], "volume")) == 0);
+ GF_ASSERT ((strcmp (words[1], "profile")) == 0);
+
+ dict = dict_new ();
+ if (!dict)
+ goto out;
+
+ if (wordcount != 4)
+ goto out;
+
+ volname = (char *)words[2];
+
+ ret = dict_set_str (dict, "volname", volname);
+ if (ret)
+ goto out;
+
+ if (strcmp (words[3], "start") == 0) {
+ op = GF_CLI_STATS_START;
+ } else if (strcmp (words[3], "stop") == 0) {
+ op = GF_CLI_STATS_STOP;
+ } else if (strcmp (words[3], "info") == 0) {
+ op = GF_CLI_STATS_INFO;
+ } else {
+ ret = -1;
+ goto out;
+ }
+ ret = dict_set_int32 (dict, "op", (int32_t)op);
+ *options = dict;
+out:
+ if (ret && dict)
+ dict_destroy (dict);
+ return ret;
+}
diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c
index 8414a50b6..f53db3d80 100644
--- a/cli/src/cli-cmd-volume.c
+++ b/cli/src/cli-cmd-volume.c
@@ -570,6 +570,49 @@ out:
}
+int
+cli_cmd_volume_profile_cbk (struct cli_state *state, struct cli_cmd_word *word,
+ const char **words, int wordcount)
+{
+ int sent = 0;
+ int parse_error = 0;
+
+ int ret = -1;
+ rpc_clnt_procedure_t *proc = NULL;
+ call_frame_t *frame = NULL;
+ dict_t *options = NULL;
+
+ ret = cli_cmd_volume_profile_parse (words, wordcount, &options);
+
+ if (ret) {
+ cli_usage_out (word->pattern);
+ parse_error = 1;
+ goto out;
+ }
+
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_PROFILE_VOLUME];
+
+ frame = create_frame (THIS, THIS->ctx->pool);
+ if (!frame)
+ goto out;
+
+ if (proc->fn) {
+ ret = proc->fn (frame, THIS, options);
+ }
+
+out:
+ if (options)
+ dict_unref (options);
+
+ if (ret) {
+ cli_cmd_sent_status_get (&sent);
+ if ((sent == 0) && (parse_error == 0))
+ cli_out ("Volume profile failed");
+ }
+
+ return ret;
+
+}
int
cli_cmd_volume_set_cbk (struct cli_state *state, struct cli_cmd_word *word,
@@ -1024,6 +1067,11 @@ struct cli_cmd volume_cmds[] = {
cli_cmd_volume_gsync_set_cbk,
"Geo-sync operations"},
#endif
+
+ { "volume profile <VOLNAME> {start|info|stop}",
+ cli_cmd_volume_profile_cbk,
+ "volume profile operations"},
+
{ NULL, NULL, NULL }
};
diff --git a/cli/src/cli-cmd.h b/cli/src/cli-cmd.h
index 4daf7fae3..ee784f0e9 100644
--- a/cli/src/cli-cmd.h
+++ b/cli/src/cli-cmd.h
@@ -43,6 +43,15 @@ struct cli_cmd_volume_get_ctx_ {
int flags;
};
+typedef struct cli_profile_info_ {
+ uint64_t fop_hits;
+ double min_latency;
+ double max_latency;
+ double avg_latency;
+ char *fop_name;
+ double percentage_avg_latency;
+} cli_profile_info_t;
+
typedef struct cli_cmd_volume_get_ctx_ cli_cmd_volume_get_ctx_t;
int cli_cmd_volume_register (struct cli_state *state);
diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c
index 1082a908f..31adfb332 100644
--- a/cli/src/cli-rpc-ops.c
+++ b/cli/src/cli-rpc-ops.c
@@ -2646,6 +2646,324 @@ out:
return ret;
}
+void*
+cli_profile_info_elem (void *a, int index)
+{
+ return ((cli_profile_info_t *)a) + index;
+}
+
+int
+cli_profile_info_percentage_cmp (void *a, void *b)
+{
+ cli_profile_info_t *ia = NULL;
+ cli_profile_info_t *ib = NULL;
+ int ret = 0;
+
+ ia = a;
+ ib = b;
+ if (ia->percentage_avg_latency < ib->percentage_avg_latency)
+ ret = -1;
+ else if (ia->percentage_avg_latency > ib->percentage_avg_latency)
+ ret = 1;
+ else
+ ret = 0;
+ return ret;
+}
+
+void
+cli_profile_info_swap (void *a, void *b)
+{
+ cli_profile_info_t *ia = NULL;
+ cli_profile_info_t *ib = NULL;
+ cli_profile_info_t tmp = {0};
+
+ ia = a;
+ ib = b;
+ tmp = *ia;
+ *ia = *ib;
+ *ib = tmp;
+}
+
+void
+cmd_profile_volume_brick_out (dict_t *dict, int count, int interval)
+{
+ char key[256] = {0};
+ int i = 0;
+ uint64_t sec = 0;
+ uint64_t r_count = 0;
+ uint64_t w_count = 0;
+ char *brick = NULL;
+ uint64_t rb_counts[32] = {0};
+ uint64_t wb_counts[32] = {0};
+ cli_profile_info_t profile_info[GF_FOP_MAXVALUE] = {{0}};
+ char output[128] = {0};
+ int per_line = 0;
+ char read_blocks[128] = {0};
+ char write_blocks[128] = {0};
+ int index = 0;
+ int is_header_printed = 0;
+ int ret = 0;
+ uint64_t total_fop_hits = 0;
+ double total_avg_latency = 0;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%d-brick", count);
+ ret = dict_get_str (dict, key, &brick);
+ for (i = 0; i < 32; i++) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%d-%d-read-%d", count,
+ interval, (1 << i));
+ ret = dict_get_uint64 (dict, key, &rb_counts[i]);
+ }
+
+ for (i = 0; i < 32; i++) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%d-%d-write-%d", count, interval,
+ (1<<i));
+ ret = dict_get_uint64 (dict, key, &wb_counts[i]);
+ }
+
+ for (i = 0; i < GF_FOP_MAXVALUE; i++) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%d-%d-%d-hits", count,
+ interval, i);
+ ret = dict_get_uint64 (dict, key, &profile_info[i].fop_hits);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%d-%d-%d-avglatency", count,
+ interval, i);
+ ret = dict_get_double (dict, key, &profile_info[i].avg_latency);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%d-%d-%d-minlatency", count,
+ interval, i);
+ ret = dict_get_double (dict, key, &profile_info[i].min_latency);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%d-%d-%d-maxlatency", count,
+ interval, i);
+ ret = dict_get_double (dict, key, &profile_info[i].max_latency);
+ profile_info[i].fop_name = gf_fop_list[i];
+
+ total_fop_hits += profile_info[i].fop_hits;
+ total_avg_latency += profile_info[i].avg_latency;
+ }
+ if (total_fop_hits && total_avg_latency) {
+ for (i = 0; i < GF_FOP_MAXVALUE; i++) {
+ profile_info[i].percentage_avg_latency = 100 * (
+ (profile_info[i].avg_latency* profile_info[i].fop_hits) /
+ (total_avg_latency * total_fop_hits));
+ }
+ gf_array_insertionsort (profile_info, 1, GF_FOP_MAXVALUE - 1,
+ sizeof (cli_profile_info_t),
+ cli_profile_info_percentage_cmp);
+ }
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%d-%d-duration", count, interval);
+ ret = dict_get_uint64 (dict, key, &sec);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%d-%d-total-read", count, interval);
+ ret = dict_get_uint64 (dict, key, &r_count);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%d-%d-total-write", count, interval);
+ ret = dict_get_uint64 (dict, key, &w_count);
+
+ if (ret == 0) {
+ cli_out ("Brick: %s", brick);
+ }
+
+ if (interval == -1)
+ cli_out ("Cumulative Stats:");
+ else
+ cli_out ("Interval %d Stats:", interval);
+ snprintf (output, sizeof (output), "%12s", "Block Size: ");
+ snprintf (read_blocks, sizeof (read_blocks), "%12s", "Read: ");
+ snprintf (write_blocks, sizeof (write_blocks), "%12s", "Write: ");
+ index = 12;
+ for (i = 0; i < 32; i++) {
+ if ((rb_counts[i] == 0) && (wb_counts[i] == 0))
+ continue;
+ per_line++;
+ snprintf (output+index, sizeof (output)-index, "%19db+ ", (1<<i));
+ if (rb_counts[i]) {
+ snprintf (read_blocks+index, sizeof (read_blocks)-index,
+ "%21"PRId64" ", rb_counts[i]);
+ } else {
+ snprintf (read_blocks+index, sizeof (read_blocks)-index,
+ "%21s ", "0");
+ }
+ if (wb_counts[i]) {
+ snprintf (write_blocks+index, sizeof (write_blocks)-index,
+ "%21"PRId64" ", wb_counts[i]);
+ } else {
+ snprintf (write_blocks+index, sizeof (write_blocks)-index,
+ "%21s ", "0");
+ }
+ index += 22;
+ if (per_line == 3) {
+ cli_out (output);
+ cli_out (read_blocks);
+ cli_out (write_blocks);
+ cli_out ("");
+ per_line = 0;
+ memset (output, 0, sizeof (output));
+ memset (read_blocks, 0, sizeof (read_blocks));
+ memset (write_blocks, 0, sizeof (write_blocks));
+ snprintf (output, sizeof (output), "%12s", "Block Size: ");
+ snprintf (read_blocks, sizeof (read_blocks), "%12s",
+ "Read: ");
+ snprintf (write_blocks, sizeof (write_blocks), "%12s",
+ "Write: ");
+ index = 12;
+ }
+ }
+
+ if (per_line != 0) {
+ cli_out (output);
+ cli_out (read_blocks);
+ cli_out (write_blocks);
+ }
+ for (i = 0; i < GF_FOP_MAXVALUE; i++) {
+ if (profile_info[i].fop_hits == 0)
+ continue;
+ if (is_header_printed == 0) {
+ cli_out ("%11s %11s %11s %11s %20s %10s", "%-latency", "Avg-latency", "Min-Latency", "Max-Latency", "calls", "Fop");
+ cli_out ("%11s %11s %11s %11s %20s %10s", "---------", "-----------", "-----------", "-----------", "-----", "----");
+ is_header_printed = 1;
+ }
+ if (profile_info[i].fop_hits) {
+ cli_out ("%11lf %11lf %11lf %11lf %20"PRId64" %10s",
+ profile_info[i].percentage_avg_latency,
+ profile_info[i].avg_latency,
+ profile_info[i].min_latency,
+ profile_info[i].max_latency,
+ profile_info[i].fop_hits,
+ profile_info[i].fop_name);
+ }
+ }
+ cli_out ("");
+ cli_out ("%12s : %"PRId64, "Duration", sec);
+ cli_out ("%12s : %"PRId64, "BytesRead", r_count);
+ cli_out ("%12s : %"PRId64, "BytesWritten", w_count);
+ cli_out ("");
+}
+
+int32_t
+gf_cli3_1_profile_volume_cbk (struct rpc_req *req, struct iovec *iov,
+ int count, void *myframe)
+{
+ gf1_cli_stats_volume_rsp rsp = {0,};
+ int ret = -1;
+ dict_t *dict = NULL;
+ gf1_cli_stats_op op = GF_CLI_STATS_NONE;
+ char key[256] = {0};
+ int interval = 0;
+ int i = 1;
+ int32_t brick_count = 0;
+ if (-1 == req->rpc_status) {
+ goto out;
+ }
+
+ gf_log ("cli", GF_LOG_DEBUG, "Received resp to profile");
+ ret = gf_xdr_to_cli_stats_volume_rsp (*iov, &rsp);
+ if (ret < 0) {
+ gf_log ("", GF_LOG_ERROR, "error");
+ goto out;
+ }
+
+ if (rsp.op_ret && strcmp (rsp.op_errstr, "")) {
+ cli_out (rsp.op_errstr);
+ } else {
+ cli_out ("volume profile %s ",
+ (rsp.op_ret) ? "unsuccessful": "successful");
+ }
+
+ if (rsp.op_ret) {
+ ret = rsp.op_ret;
+ goto out;
+ }
+
+ dict = dict_new ();
+
+ if (!dict) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = dict_unserialize (rsp.stats_info.stats_info_val,
+ rsp.stats_info.stats_info_len,
+ &dict);
+
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR,
+ "Unable to allocate memory");
+ goto out;
+ }
+
+ ret = dict_get_int32 (dict, "op", (int32_t*)&op);
+
+ if (op != GF_CLI_STATS_INFO) {
+ ret = 0;
+ goto out;
+ }
+
+ ret = dict_get_int32 (dict, "count", &brick_count);
+ if (ret)
+ goto out;
+ while (i <= brick_count) {
+ snprintf (key, sizeof (key), "%d-cumulative", i);
+ ret = dict_get_int32 (dict, key, &interval);
+ if (ret == 0) {
+ cmd_profile_volume_brick_out (dict, i, interval);
+ }
+ snprintf (key, sizeof (key), "%d-interval", i);
+ ret = dict_get_int32 (dict, key, &interval);
+ if (ret == 0) {
+ cmd_profile_volume_brick_out (dict, i, interval);
+ }
+ i++;
+ }
+ ret = rsp.op_ret;
+
+out:
+ cli_cmd_broadcast_response (ret);
+ return ret;
+}
+
+int32_t
+gf_cli3_1_profile_volume (call_frame_t *frame, xlator_t *this, void *data)
+{
+ int ret = -1;
+ gf1_cli_stats_volume_req req = {0,};
+ dict_t *dict = NULL;
+
+ GF_ASSERT (frame);
+ GF_ASSERT (this);
+ GF_ASSERT (data);
+
+ if (!frame || !this || !data)
+ goto out;
+ dict = data;
+ ret = dict_get_str (dict, "volname", &req.volname);
+ if (ret)
+ goto out;
+
+ ret = dict_get_int32 (dict, "op", (int32_t*)&req.op);
+ if (ret)
+ goto out;
+
+ ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
+ GLUSTER_CLI_PROFILE_VOLUME, NULL,
+ gf_xdr_from_cli_stats_volume_req,
+ this, gf_cli3_1_profile_volume_cbk);
+
+out:
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
struct rpc_clnt_procedure gluster_cli_actors[GLUSTER_CLI_MAXVALUE] = {
[GLUSTER_CLI_NULL] = {"NULL", NULL },
@@ -2673,6 +2991,7 @@ struct rpc_clnt_procedure gluster_cli_actors[GLUSTER_CLI_MAXVALUE] = {
[GLUSTER_CLI_RESET_VOLUME] = {"RESET_VOLUME", gf_cli3_1_reset_volume},
[GLUSTER_CLI_FSM_LOG] = {"FSM_LOG", gf_cli3_1_fsm_log},
[GLUSTER_CLI_GSYNC_SET] = {"GSYNC_SET", gf_cli3_1_gsync_set},
+ [GLUSTER_CLI_PROFILE_VOLUME] = {"PROFILE_VOLUME", gf_cli3_1_profile_volume}
};
struct rpc_clnt_program cli_prog = {
diff --git a/cli/src/cli.c b/cli/src/cli.c
index 00faffe42..ef88d0420 100644
--- a/cli/src/cli.c
+++ b/cli/src/cli.c
@@ -491,7 +491,6 @@ struct rpc_clnt *
cli_rpc_init (struct cli_state *state)
{
struct rpc_clnt *rpc = NULL;
- struct rpc_clnt_config rpc_cfg = {0,};
dict_t *options = NULL;
int ret = -1;
int port = CLI_GLUSTERD_PORT;
@@ -511,9 +510,6 @@ cli_rpc_init (struct cli_state *state)
if (state->remote_port)
port = state->remote_port;
- rpc_cfg.remote_host = state->remote_host;
- rpc_cfg.remote_port = port;
-
ret = dict_set_int32 (options, "remote-port", port);
if (ret)
goto out;
@@ -535,6 +531,11 @@ cli_rpc_init (struct cli_state *state)
rpc_clnt_start (rpc);
out:
+ if (ret) {
+ if (rpc)
+ rpc_clnt_unref (rpc);
+ rpc = NULL;
+ }
return rpc;
}
diff --git a/cli/src/cli.h b/cli/src/cli.h
index 77bc249d9..acfd5b539 100644
--- a/cli/src/cli.h
+++ b/cli/src/cli.h
@@ -217,4 +217,7 @@ cli_rpc_notify (struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event,
void *data);
void
cli_path_strip_trailing_slashes (char *path);
+int32_t
+cli_cmd_volume_profile_parse (const char **words, int wordcount,
+ dict_t **options);
#endif /* __CLI_H__ */