summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVijay Bellur <vijay@gluster.com>2011-08-18 23:19:22 +0530
committerAnand Avati <avati@gluster.com>2011-08-19 01:29:18 -0700
commit0143a2ef653d0f7a337c8220f127655dadbca942 (patch)
tree61896872f41f8ccb39b692a521a62569516bab2d
parentd2849bd349081b332540713cfeaa561f57356b2a (diff)
mgmt/glusterd, cli: Introduce gluster volume status <volname>
Change-Id: Iea835b9e448e736016da2e44e3c9bfff93f2fa78 BUG: 3439 Reviewed-on: http://review.gluster.com/259 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Anand Avati <avati@gluster.com>
-rw-r--r--cli/src/cli-cmd-parser.c34
-rw-r--r--cli/src/cli-cmd-volume.c72
-rw-r--r--cli/src/cli-rpc-ops.c127
-rw-r--r--cli/src/cli.c11
-rw-r--r--cli/src/cli.h13
-rw-r--r--rpc/rpc-lib/src/protocol-common.h2
-rw-r--r--rpc/xdr/src/cli1-xdr.c129
-rw-r--r--rpc/xdr/src/cli1-xdr.h120
-rw-r--r--rpc/xdr/src/cli1-xdr.x24
-rw-r--r--rpc/xdr/src/cli1.c36
-rw-r--r--rpc/xdr/src/cli1.h16
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-handler.c61
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-op-sm.c113
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-op-sm.h5
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-rpc-ops.c84
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.c87
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.h4
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.h1
18 files changed, 828 insertions, 111 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c
index a442b3aee85..9f35cc47e5b 100644
--- a/cli/src/cli-cmd-parser.c
+++ b/cli/src/cli-cmd-parser.c
@@ -1646,3 +1646,37 @@ out:
dict_destroy (dict);
return ret;
}
+
+int32_t
+cli_cmd_volume_status_parse (const char **words, int wordcount,
+ dict_t **options)
+{
+ dict_t *dict = NULL;
+ int ret = -1;
+
+ GF_ASSERT (words);
+ GF_ASSERT (options);
+
+
+ GF_ASSERT ((strncmp(words[0], "volume", 6) == 0));
+ GF_ASSERT ((strncmp(words[1], "status", 5) == 0));
+
+
+ dict = dict_new ();
+ if (!dict)
+ goto out;
+
+ GF_ASSERT(words[2]);
+
+ ret = dict_set_str (dict, "volname", (char *)words[2]);
+ if (ret)
+ goto out;
+
+ *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 ab7f1ddc7b3..b61eb31c0bc 100644
--- a/cli/src/cli-cmd-volume.c
+++ b/cli/src/cli-cmd-volume.c
@@ -1211,6 +1211,74 @@ cli_cmd_log_level_cbk (struct cli_state *state, struct cli_cmd_word *word,
return ret;
}
+int
+cli_cmd_volume_status_cbk (struct cli_state *state,
+ struct cli_cmd_word *word,
+ const char **words, int wordcount)
+{
+ int ret = -1;
+ rpc_clnt_procedure_t *proc = NULL;
+ call_frame_t *frame = NULL;
+ dict_t *dict = NULL;
+ int parse_error = 0;
+
+ if (wordcount != 3) {
+ cli_usage_out (word->pattern);
+ parse_error = 1;
+ goto out;
+ }
+
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_STATUS_VOLUME];
+
+ frame = create_frame (THIS, THIS->ctx->pool);
+ if (!frame)
+ goto out;
+
+ ret = cli_cmd_volume_status_parse (words, wordcount, &dict);
+ if (ret)
+ goto out;
+
+ if (proc->fn)
+ ret = proc->fn (frame, THIS, dict);
+
+ out:
+ return ret;
+}
+
+
+int
+cli_print_brick_status (char *brick, int port, int online, int pid)
+{
+ int fieldlen = CLI_VOL_STATUS_BRICK_LEN;
+ char buf[80] = {0,};
+ int bricklen = 0;
+ int i = 0;
+ char *p = NULL;
+ int num_tabs = 0;
+
+ bricklen = strlen (brick);
+ p = brick;
+ while (bricklen > 0) {
+ if (bricklen > fieldlen) {
+ i++;
+ strncpy (buf, p, fieldlen);
+ buf[strlen(buf) + 1] = '\0';
+ cli_out ("%s", buf);
+ p = brick + i * fieldlen;
+ bricklen -= fieldlen;
+ } else {
+ num_tabs = (fieldlen - bricklen) / CLI_TAB_LENGTH + 1;
+ printf ("%s", p);
+ while (num_tabs-- != 0)
+ printf ("\t");
+ cli_out ("%d\t%c\t%d", port, online?'Y':'N', pid);
+ bricklen = 0;
+ }
+ }
+
+ return 0;
+}
+
struct cli_cmd volume_cmds[] = {
{ "volume info [all|<VOLNAME>]",
cli_cmd_volume_info_cbk,
@@ -1309,6 +1377,10 @@ struct cli_cmd volume_cmds[] = {
cli_cmd_log_level_cbk,
"log level for translator"},
+ { "volume status <VOLNAME>",
+ cli_cmd_volume_status_cbk,
+ "display status of specified volume"},
+
{ NULL, NULL, NULL }
};
diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c
index b6fbf3f05fc..498cdbf74e2 100644
--- a/cli/src/cli-rpc-ops.c
+++ b/cli/src/cli-rpc-ops.c
@@ -3562,6 +3562,130 @@ out:
return ret;
}
+static int
+gf_cli3_1_status_cbk (struct rpc_req *req, struct iovec *iov,
+ int count, void *myframe)
+{
+ gf1_cli_status_volume_rsp rsp = {0,};
+ int ret = -1;
+ dict_t *dict = NULL;
+ char *hostname = NULL;
+ char *path = NULL;
+ int i = 0;
+ int port = 0;
+ int online = 0;
+ char key[1024] = {0,};
+ int pid = 0;
+ char brick[8192] = {0,};
+ char *volname = NULL;
+
+
+ if (req->rpc_status == -1)
+ goto out;
+
+ ret = gf_xdr_to_cli_status_volume_rsp (*iov, &rsp);
+ if (ret < 0) {
+ gf_log ("cli", GF_LOG_ERROR, "Volume status response error");
+ goto out;
+ }
+
+ gf_log ("cli", GF_LOG_DEBUG, "Received response to status cmd");
+
+ if (rsp.op_ret && strcmp (rsp.op_errstr, ""))
+ cli_out ("%s", rsp.op_errstr);
+ else if (rsp.op_ret)
+ cli_out ("Unable to obtain volume status information.");
+
+ dict = dict_new ();
+ if (!dict)
+ goto out;
+
+ ret = dict_unserialize (rsp.dict.dict_val,
+ rsp.dict.dict_len,
+ &dict);
+ if (ret)
+ goto out;
+
+
+ ret = dict_get_int32 (dict, "count", &count);
+ if (ret)
+ goto out;
+
+ ret = dict_get_str (dict, "volname", &volname);
+
+ cli_out ("Brick status for volume: %s", volname);
+ cli_out ("Brick\t\t\t\t\t\t\tPort\tOnline\tPID");
+ for (i = 0; i < count; i++) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.hostname", i);
+ ret = dict_get_str (dict, key, &hostname);
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.path", i);
+ ret = dict_get_str (dict, key, &path);
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.port", i);
+ ret = dict_get_int32 (dict, key, &port);
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.status", i);
+ ret = dict_get_int32 (dict, key, &online);
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.pid", i);
+ ret = dict_get_int32 (dict, key, &pid);
+
+ snprintf (brick, sizeof (brick) -1, "%s:%s", hostname, path);
+
+ cli_print_line (CLI_BRICK_STATUS_LINE_LEN);
+ cli_print_brick_status (brick, port, online, pid);
+ }
+
+ ret = rsp.op_ret;
+
+ out:
+ cli_cmd_broadcast_response (ret);
+ return ret;
+}
+
+int32_t
+gf_cli3_1_status_volume (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ gf1_cli_status_volume_req req = {0,};
+ int ret = 0;
+ dict_t *dict = NULL;
+
+ if (!frame || !this || !data) {
+ ret = -1;
+ goto out;
+ }
+
+ dict = data;
+
+ ret = dict_get_str (dict, "volname", &req.volname);
+ if (ret)
+ goto out;
+
+ ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
+ GLUSTER_CLI_STATUS_VOLUME, NULL,
+ gf_xdr_from_cli_status_volume_req,
+ this, gf_cli3_1_status_cbk,
+ (xdrproc_t)xdr_gf1_cli_status_volume_req);
+
+ 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 },
@@ -3593,7 +3717,8 @@ struct rpc_clnt_procedure gluster_cli_actors[GLUSTER_CLI_MAXVALUE] = {
[GLUSTER_CLI_QUOTA] = {"QUOTA", gf_cli3_1_quota},
[GLUSTER_CLI_TOP_VOLUME] = {"TOP_VOLUME", gf_cli3_1_top_volume},
[GLUSTER_CLI_LOG_LEVEL] = {"VOLUME_LOGLEVEL", gf_cli3_1_log_level},
- [GLUSTER_CLI_GETWD] = {"GETWD", gf_cli3_1_getwd}
+ [GLUSTER_CLI_GETWD] = {"GETWD", gf_cli3_1_getwd},
+ [GLUSTER_CLI_STATUS_VOLUME] = {"STATUS_VOLUME", gf_cli3_1_status_volume},
};
struct rpc_clnt_program cli_prog = {
diff --git a/cli/src/cli.c b/cli/src/cli.c
index 1703c0ca63b..eec14d6fad0 100644
--- a/cli/src/cli.c
+++ b/cli/src/cli.c
@@ -698,3 +698,14 @@ out:
return ret;
}
+
+void
+cli_print_line (int len)
+{
+ GF_ASSERT (len > 0);
+
+ while (len--)
+ printf ("-");
+
+ printf ("\n");
+}
diff --git a/cli/src/cli.h b/cli/src/cli.h
index 91fca102ea1..55d0d89f1d0 100644
--- a/cli/src/cli.h
+++ b/cli/src/cli.h
@@ -34,6 +34,9 @@
#define CLI_DEFAULT_CONN_TIMEOUT 120
#define CLI_DEFAULT_CMD_TIMEOUT 120
#define DEFAULT_CLI_LOG_FILE_DIRECTORY DATADIR "/log/glusterfs"
+#define CLI_VOL_STATUS_BRICK_LEN 55
+#define CLI_TAB_LENGTH 8
+#define CLI_BRICK_STATUS_LINE_LEN 75
enum argp_option_keys {
ARGP_DEBUG_KEY = 133,
@@ -248,4 +251,14 @@ cli_cmd_volume_top_parse (const char **words, int wordcount,
int32_t
cli_cmd_log_level_parse (const char **words, int wordcount,
dict_t **options);
+
+int32_t
+cli_cmd_volume_status_parse (const char **words, int wordcount,
+ dict_t **options);
+
+int
+cli_print_brick_status (char *brick, int port, int online, int pid);
+
+void
+cli_print_line (int len);
#endif /* __CLI_H__ */
diff --git a/rpc/rpc-lib/src/protocol-common.h b/rpc/rpc-lib/src/protocol-common.h
index a456fb727b4..216429e79a6 100644
--- a/rpc/rpc-lib/src/protocol-common.h
+++ b/rpc/rpc-lib/src/protocol-common.h
@@ -109,6 +109,7 @@ enum gf_mgmt_procnum_ {
GD_MGMT_CLI_PROFILE_VOLUME,
GD_MGMT_BRICK_OP,
GD_MGMT_CLI_LOG_LEVEL,
+ GD_MGMT_CLI_STATUS_VOLUME,
GD_MGMT_MAXVALUE,
};
@@ -201,6 +202,7 @@ enum gluster_cli_procnum {
GLUSTER_CLI_TOP_VOLUME,
GLUSTER_CLI_GETWD,
GLUSTER_CLI_LOG_LEVEL,
+ GLUSTER_CLI_STATUS_VOLUME,
GLUSTER_CLI_MAXVALUE,
};
diff --git a/rpc/xdr/src/cli1-xdr.c b/rpc/xdr/src/cli1-xdr.c
index d4523c359f0..a37e4cd21af 100644
--- a/rpc/xdr/src/cli1-xdr.c
+++ b/rpc/xdr/src/cli1-xdr.c
@@ -17,7 +17,6 @@
<http://www.gnu.org/licenses/>.
*/
-
/*
* Please do not edit this file.
* It was generated using rpcgen.
@@ -112,9 +111,9 @@ bool_t
xdr_gf1_cli_top_op (XDR *xdrs, gf1_cli_top_op *objp)
{
- if (!xdr_enum (xdrs, (enum_t *) objp))
- return FALSE;
- return TRUE;
+ if (!xdr_enum (xdrs, (enum_t *) objp))
+ return FALSE;
+ return TRUE;
}
bool_t
@@ -131,6 +130,7 @@ xdr_gf1_cli_probe_req (XDR *xdrs, gf1_cli_probe_req *objp)
bool_t
xdr_gf1_cli_probe_rsp (XDR *xdrs, gf1_cli_probe_rsp *objp)
{
+
register int32_t *buf;
if (xdrs->x_op == XDR_ENCODE) {
@@ -548,36 +548,6 @@ xdr_gf1_cli_reset_vol_rsp (XDR *xdrs, gf1_cli_reset_vol_rsp *objp)
}
bool_t
-xdr_gf1_cli_quota_req (XDR *xdrs, gf1_cli_quota_req *objp)
-{
-
- if (!xdr_string (xdrs, &objp->volname, ~0))
- return FALSE;
- if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val, (u_int *) &objp->dict.dict_len, ~0))
- return FALSE;
- return TRUE;
-}
-
-bool_t
-xdr_gf1_cli_quota_rsp (XDR *xdrs, gf1_cli_quota_rsp *objp)
-{
-
- if (!xdr_int (xdrs, &objp->op_ret))
- return FALSE;
- if (!xdr_int (xdrs, &objp->op_errno))
- return FALSE;
- if (!xdr_string (xdrs, &objp->volname, ~0))
- return FALSE;
- if (!xdr_string (xdrs, &objp->op_errstr, ~0))
- return FALSE;
- if (!xdr_string (xdrs, &objp->limit_list, ~0))
- return FALSE;
- if (!xdr_gf_quota_type (xdrs, &objp->type))
- return FALSE;
- return TRUE;
-}
-
-bool_t
xdr_gf1_cli_set_vol_req (XDR *xdrs, gf1_cli_set_vol_req *objp)
{
@@ -750,10 +720,8 @@ xdr_gf1_cli_gsync_set_rsp (XDR *xdrs, gf1_cli_gsync_set_rsp *objp)
return FALSE;
if (!xdr_int (xdrs, &objp->type))
return FALSE;
- if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val,
- (u_int *) &objp->dict.dict_len, ~0))
- return FALSE;
-
+ if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val, (u_int *) &objp->dict.dict_len, ~0))
+ return FALSE;
return TRUE;
}
@@ -767,7 +735,6 @@ xdr_gf1_cli_stats_volume_req (XDR *xdrs, gf1_cli_stats_volume_req *objp)
return FALSE;
if (!xdr_bytes (xdrs, (char **)&objp->dict_req.dict_req_val, (u_int *) &objp->dict_req.dict_req_len, ~0))
return FALSE;
-
return TRUE;
}
@@ -787,8 +754,39 @@ xdr_gf1_cli_stats_volume_rsp (XDR *xdrs, gf1_cli_stats_volume_rsp *objp)
}
bool_t
+xdr_gf1_cli_quota_req (XDR *xdrs, gf1_cli_quota_req *objp)
+{
+
+ if (!xdr_string (xdrs, &objp->volname, ~0))
+ return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val, (u_int *) &objp->dict.dict_len, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_gf1_cli_quota_rsp (XDR *xdrs, gf1_cli_quota_rsp *objp)
+{
+
+ if (!xdr_int (xdrs, &objp->op_ret))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->op_errno))
+ return FALSE;
+ if (!xdr_string (xdrs, &objp->volname, ~0))
+ return FALSE;
+ if (!xdr_string (xdrs, &objp->op_errstr, ~0))
+ return FALSE;
+ if (!xdr_string (xdrs, &objp->limit_list, ~0))
+ return FALSE;
+ if (!xdr_gf_quota_type (xdrs, &objp->type))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
xdr_gf1_cli_getwd_req (XDR *xdrs, gf1_cli_getwd_req *objp)
{
+
if (!xdr_int (xdrs, &objp->unused))
return FALSE;
return TRUE;
@@ -797,6 +795,7 @@ xdr_gf1_cli_getwd_req (XDR *xdrs, gf1_cli_getwd_req *objp)
bool_t
xdr_gf1_cli_getwd_rsp (XDR *xdrs, gf1_cli_getwd_rsp *objp)
{
+
if (!xdr_int (xdrs, &objp->op_ret))
return FALSE;
if (!xdr_int (xdrs, &objp->op_errno))
@@ -809,29 +808,51 @@ xdr_gf1_cli_getwd_rsp (XDR *xdrs, gf1_cli_getwd_rsp *objp)
bool_t
xdr_gf1_cli_log_level_req (XDR *xdrs, gf1_cli_log_level_req *objp)
{
- if (!xdr_string (xdrs, &objp->volname, ~0))
- return FALSE;
- if (!xdr_string (xdrs, &objp->xlator, ~0))
- return FALSE;
+ if (!xdr_string (xdrs, &objp->volname, ~0))
+ return FALSE;
+ if (!xdr_string (xdrs, &objp->xlator, ~0))
+ return FALSE;
+ if (!xdr_string (xdrs, &objp->loglevel, ~0))
+ return FALSE;
+ return TRUE;
+}
- if (!xdr_string (xdrs, &objp->loglevel, ~0))
- return FALSE;
+bool_t
+xdr_gf1_cli_log_level_rsp (XDR *xdrs, gf1_cli_log_level_rsp *objp)
+{
- return TRUE;
+ if (!xdr_int (xdrs, &objp->op_ret))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->op_errno))
+ return FALSE;
+ if (!xdr_string (xdrs, &objp->op_errstr, ~0))
+ return FALSE;
+ return TRUE;
}
bool_t
-xdr_gf1_cli_log_level_rsp (XDR *xdrs, gf1_cli_log_level_rsp *objp)
+xdr_gf1_cli_status_volume_req (XDR *xdrs, gf1_cli_status_volume_req *objp)
{
- if (!xdr_int (xdrs, &objp->op_ret))
- return FALSE;
- if (!xdr_int (xdrs, &objp->op_errno))
- return FALSE;
+ if (!xdr_string (xdrs, &objp->volname, ~0))
+ return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val, (u_int *) &objp->dict.dict_len, ~0))
+ return FALSE;
+ return TRUE;
+}
- if (!xdr_string (xdrs, &objp->op_errstr, ~0))
- return FALSE;
+bool_t
+xdr_gf1_cli_status_volume_rsp (XDR *xdrs, gf1_cli_status_volume_rsp *objp)
+{
- return TRUE;
+ if (!xdr_int (xdrs, &objp->op_ret))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->op_errno))
+ return FALSE;
+ if (!xdr_string (xdrs, &objp->op_errstr, ~0))
+ return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val, (u_int *) &objp->dict.dict_len, ~0))
+ return FALSE;
+ return TRUE;
}
diff --git a/rpc/xdr/src/cli1-xdr.h b/rpc/xdr/src/cli1-xdr.h
index 81319c2906c..cce3ecbe89a 100644
--- a/rpc/xdr/src/cli1-xdr.h
+++ b/rpc/xdr/src/cli1-xdr.h
@@ -26,7 +26,6 @@
#include <rpc/rpc.h>
-#include "xdr-common.h"
#ifdef __cplusplus
extern "C" {
@@ -90,8 +89,7 @@ enum gf1_cli_gsync_set {
GF_GSYNC_OPTION_TYPE_START = 1,
GF_GSYNC_OPTION_TYPE_STOP = 2,
GF_GSYNC_OPTION_TYPE_CONFIG = 3,
- GF_GSYNC_OPTION_TYPE_STATUS = 4,
-
+ GF_GSYNC_OPTION_TYPE_STATUS = 4,
};
typedef enum gf1_cli_gsync_set gf1_cli_gsync_set;
@@ -100,19 +98,19 @@ 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_TOP = 4,
};
typedef enum gf1_cli_stats_op gf1_cli_stats_op;
enum gf1_cli_top_op {
- GF_CLI_TOP_NONE = 0,
- GF_CLI_TOP_OPEN = 0 + 1,
- GF_CLI_TOP_READ = 0 + 2,
- GF_CLI_TOP_WRITE = 0 + 3,
- GF_CLI_TOP_OPENDIR = 0 + 4,
- GF_CLI_TOP_READDIR = 0 + 5,
- GF_CLI_TOP_READ_PERF = 0 + 6,
- GF_CLI_TOP_WRITE_PERF = 0 + 7,
+ GF_CLI_TOP_NONE = 0,
+ GF_CLI_TOP_OPEN = 0 + 1,
+ GF_CLI_TOP_READ = 0 + 2,
+ GF_CLI_TOP_WRITE = 0 + 3,
+ GF_CLI_TOP_OPENDIR = 0 + 4,
+ GF_CLI_TOP_READDIR = 0 + 5,
+ GF_CLI_TOP_READ_PERF = 0 + 6,
+ GF_CLI_TOP_WRITE_PERF = 0 + 7,
};
typedef enum gf1_cli_top_op gf1_cli_top_op;
@@ -353,25 +351,6 @@ struct gf1_cli_reset_vol_rsp {
};
typedef struct gf1_cli_reset_vol_rsp gf1_cli_reset_vol_rsp;
-struct gf1_cli_quota_req {
- char *volname;
- struct {
- u_int dict_len;
- char *dict_val;
- } dict;
-};
-typedef struct gf1_cli_quota_req gf1_cli_quota_req;
-
-struct gf1_cli_quota_rsp {
- int op_ret;
- int op_errno;
- char *volname;
- char *op_errstr;
- char *limit_list;
- gf_quota_type type;
-};
-typedef struct gf1_cli_quota_rsp gf1_cli_quota_rsp;
-
struct gf1_cli_set_vol_req {
char *volname;
struct {
@@ -488,7 +467,7 @@ struct gf1_cli_stats_volume_req {
gf1_cli_stats_op op;
struct {
u_int dict_req_len;
- char* dict_req_val;
+ char *dict_req_val;
} dict_req;
};
typedef struct gf1_cli_stats_volume_req gf1_cli_stats_volume_req;
@@ -504,6 +483,25 @@ struct gf1_cli_stats_volume_rsp {
};
typedef struct gf1_cli_stats_volume_rsp gf1_cli_stats_volume_rsp;
+struct gf1_cli_quota_req {
+ char *volname;
+ struct {
+ u_int dict_len;
+ char *dict_val;
+ } dict;
+};
+typedef struct gf1_cli_quota_req gf1_cli_quota_req;
+
+struct gf1_cli_quota_rsp {
+ int op_ret;
+ int op_errno;
+ char *volname;
+ char *op_errstr;
+ char *limit_list;
+ gf_quota_type type;
+};
+typedef struct gf1_cli_quota_rsp gf1_cli_quota_rsp;
+
struct gf1_cli_getwd_req {
int unused;
};
@@ -517,32 +515,52 @@ struct gf1_cli_getwd_rsp {
typedef struct gf1_cli_getwd_rsp gf1_cli_getwd_rsp;
struct gf1_cli_log_level_req {
- char *volname;
- char *xlator;
- char *loglevel;
+ char *volname;
+ char *xlator;
+ char *loglevel;
};
typedef struct gf1_cli_log_level_req gf1_cli_log_level_req;
struct gf1_cli_log_level_rsp {
- int op_ret;
- int op_errno;
- char *op_errstr;
+ int op_ret;
+ int op_errno;
+ char *op_errstr;
};
typedef struct gf1_cli_log_level_rsp gf1_cli_log_level_rsp;
+struct gf1_cli_status_volume_req {
+ char *volname;
+ struct {
+ u_int dict_len;
+ char *dict_val;
+ } dict;
+};
+typedef struct gf1_cli_status_volume_req gf1_cli_status_volume_req;
+
+struct gf1_cli_status_volume_rsp {
+ int op_ret;
+ int op_errno;
+ char *op_errstr;
+ struct {
+ u_int dict_len;
+ char *dict_val;
+ } dict;
+};
+typedef struct gf1_cli_status_volume_rsp gf1_cli_status_volume_rsp;
+
/* the xdr functions */
#if defined(__STDC__) || defined(__cplusplus)
extern bool_t xdr_gf1_cluster_type (XDR *, gf1_cluster_type*);
extern bool_t xdr_gf1_cli_replace_op (XDR *, gf1_cli_replace_op*);
+extern bool_t xdr_gf_quota_type (XDR *, gf_quota_type*);
extern bool_t xdr_gf1_cli_friends_list (XDR *, gf1_cli_friends_list*);
extern bool_t xdr_gf1_cli_get_volume (XDR *, gf1_cli_get_volume*);
extern bool_t xdr_gf1_cli_sync_volume (XDR *, gf1_cli_sync_volume*);
extern bool_t xdr_gf1_cli_op_flags (XDR *, gf1_cli_op_flags*);
extern bool_t xdr_gf1_cli_gsync_set (XDR *, gf1_cli_gsync_set*);
-extern bool_t xdr_gf1_cli_top_op (XDR *, gf1_cli_top_op*);
extern bool_t xdr_gf1_cli_stats_op (XDR *, gf1_cli_stats_op*);
-extern bool_t xdr_gf_quota_type (XDR *, gf_quota_type*);
+extern bool_t xdr_gf1_cli_top_op (XDR *, gf1_cli_top_op*);
extern bool_t xdr_gf1_cli_probe_req (XDR *, gf1_cli_probe_req*);
extern bool_t xdr_gf1_cli_probe_rsp (XDR *, gf1_cli_probe_rsp*);
extern bool_t xdr_gf1_cli_deprobe_req (XDR *, gf1_cli_deprobe_req*);
@@ -572,8 +590,6 @@ extern bool_t xdr_gf1_cli_replace_brick_req (XDR *, gf1_cli_replace_brick_req*)
extern bool_t xdr_gf1_cli_replace_brick_rsp (XDR *, gf1_cli_replace_brick_rsp*);
extern bool_t xdr_gf1_cli_reset_vol_req (XDR *, gf1_cli_reset_vol_req*);
extern bool_t xdr_gf1_cli_reset_vol_rsp (XDR *, gf1_cli_reset_vol_rsp*);
-extern bool_t xdr_gf1_cli_quota_req (XDR *, gf1_cli_quota_req*);
-extern bool_t xdr_gf1_cli_quota_rsp (XDR *, gf1_cli_quota_rsp*);
extern bool_t xdr_gf1_cli_set_vol_req (XDR *, gf1_cli_set_vol_req*);
extern bool_t xdr_gf1_cli_set_vol_rsp (XDR *, gf1_cli_set_vol_rsp*);
extern bool_t xdr_gf1_cli_log_filename_req (XDR *, gf1_cli_log_filename_req*);
@@ -590,14 +606,19 @@ extern bool_t xdr_gf1_cli_gsync_set_req (XDR *, gf1_cli_gsync_set_req*);
extern bool_t xdr_gf1_cli_gsync_set_rsp (XDR *, gf1_cli_gsync_set_rsp*);
extern bool_t xdr_gf1_cli_stats_volume_req (XDR *, gf1_cli_stats_volume_req*);
extern bool_t xdr_gf1_cli_stats_volume_rsp (XDR *, gf1_cli_stats_volume_rsp*);
-extern bool_t xdr_gf1_cli_log_level_req (XDR *, gf1_cli_log_level_req *);
-extern bool_t xdr_gf1_cli_log_level_rsp (XDR *, gf1_cli_log_level_rsp *);
+extern bool_t xdr_gf1_cli_quota_req (XDR *, gf1_cli_quota_req*);
+extern bool_t xdr_gf1_cli_quota_rsp (XDR *, gf1_cli_quota_rsp*);
extern bool_t xdr_gf1_cli_getwd_req (XDR *, gf1_cli_getwd_req*);
extern bool_t xdr_gf1_cli_getwd_rsp (XDR *, gf1_cli_getwd_rsp*);
+extern bool_t xdr_gf1_cli_log_level_req (XDR *, gf1_cli_log_level_req*);
+extern bool_t xdr_gf1_cli_log_level_rsp (XDR *, gf1_cli_log_level_rsp*);
+extern bool_t xdr_gf1_cli_status_volume_req (XDR *, gf1_cli_status_volume_req*);
+extern bool_t xdr_gf1_cli_status_volume_rsp (XDR *, gf1_cli_status_volume_rsp*);
#else /* K&R C */
extern bool_t xdr_gf1_cluster_type ();
extern bool_t xdr_gf1_cli_replace_op ();
+extern bool_t xdr_gf_quota_type ();
extern bool_t xdr_gf1_cli_friends_list ();
extern bool_t xdr_gf1_cli_get_volume ();
extern bool_t xdr_gf1_cli_sync_volume ();
@@ -605,7 +626,6 @@ extern bool_t xdr_gf1_cli_op_flags ();
extern bool_t xdr_gf1_cli_gsync_set ();
extern bool_t xdr_gf1_cli_stats_op ();
extern bool_t xdr_gf1_cli_top_op ();
-extern bool_t xdr_gf_quota_type ();
extern bool_t xdr_gf1_cli_probe_req ();
extern bool_t xdr_gf1_cli_probe_rsp ();
extern bool_t xdr_gf1_cli_deprobe_req ();
@@ -635,8 +655,6 @@ extern bool_t xdr_gf1_cli_replace_brick_req ();
extern bool_t xdr_gf1_cli_replace_brick_rsp ();
extern bool_t xdr_gf1_cli_reset_vol_req ();
extern bool_t xdr_gf1_cli_reset_vol_rsp ();
-extern bool_t xdr_gf1_cli_quota_req ();
-extern bool_t xdr_gf1_cli_quota_rsp ();
extern bool_t xdr_gf1_cli_set_vol_req ();
extern bool_t xdr_gf1_cli_set_vol_rsp ();
extern bool_t xdr_gf1_cli_log_filename_req ();
@@ -653,10 +671,14 @@ extern bool_t xdr_gf1_cli_gsync_set_req ();
extern bool_t xdr_gf1_cli_gsync_set_rsp ();
extern bool_t xdr_gf1_cli_stats_volume_req ();
extern bool_t xdr_gf1_cli_stats_volume_rsp ();
-extern bool_t xdr_gf1_cli_log_level_req ();
-extern bool_t xdr_gf1_cli_log_level_rsp ();
+extern bool_t xdr_gf1_cli_quota_req ();
+extern bool_t xdr_gf1_cli_quota_rsp ();
extern bool_t xdr_gf1_cli_getwd_req ();
extern bool_t xdr_gf1_cli_getwd_rsp ();
+extern bool_t xdr_gf1_cli_log_level_req ();
+extern bool_t xdr_gf1_cli_log_level_rsp ();
+extern bool_t xdr_gf1_cli_status_volume_req ();
+extern bool_t xdr_gf1_cli_status_volume_rsp ();
#endif /* K&R C */
diff --git a/rpc/xdr/src/cli1-xdr.x b/rpc/xdr/src/cli1-xdr.x
index ee21d4bb3d8..db15b822a8f 100644
--- a/rpc/xdr/src/cli1-xdr.x
+++ b/rpc/xdr/src/cli1-xdr.x
@@ -1,7 +1,8 @@
enum gf1_cluster_type {
GF_CLUSTER_TYPE_NONE = 0,
GF_CLUSTER_TYPE_STRIPE,
- GF_CLUSTER_TYPE_REPLICATE
+ GF_CLUSTER_TYPE_REPLICATE,
+ GF_CLUSTER_TYPE_STRIPE_REPLICATE
} ;
enum gf1_cli_replace_op {
@@ -344,6 +345,7 @@ struct gf1_cli_gsync_set_rsp {
struct gf1_cli_stats_volume_req {
string volname<>;
gf1_cli_stats_op op;
+ opaque dict_req<>;
};
struct gf1_cli_stats_volume_rsp {
@@ -378,13 +380,25 @@ struct gf1_cli_getwd_rsp {
};
struct gf1_cli_log_level_req {
- char *volname;
- char *xlator;
- char *loglevel;
+ string volname<>;
+ string xlator<>;
+ string loglevel<>;
};
struct gf1_cli_log_level_rsp {
int op_ret;
int op_errno;
- char *op_errstr;
+ string op_errstr<>;
+};
+
+struct gf1_cli_status_volume_req {
+ string volname<>;
+ opaque dict<>;
+};
+
+struct gf1_cli_status_volume_rsp {
+ int op_ret;
+ int op_errno;
+ string op_errstr<>;
+ opaque dict<>;
};
diff --git a/rpc/xdr/src/cli1.c b/rpc/xdr/src/cli1.c
index 56d59bea6f0..b69aa612027 100644
--- a/rpc/xdr/src/cli1.c
+++ b/rpc/xdr/src/cli1.c
@@ -776,3 +776,39 @@ gf_xdr_from_cli_log_level_rsp (struct iovec outmsg, void *args)
return xdr_serialize_generic (outmsg, (void *)args,
(xdrproc_t)xdr_gf1_cli_log_level_rsp);
}
+
+ssize_t
+gf_xdr_serialize_cli_status_volume_rsp (struct iovec outmsg, void *rsp)
+{
+ return xdr_serialize_generic (outmsg, (void *)rsp,
+ (xdrproc_t)xdr_gf1_cli_status_volume_rsp);
+
+}
+
+ssize_t
+gf_xdr_to_cli_status_volume_req (struct iovec inmsg, void *args)
+{
+ return xdr_to_generic (inmsg, (void *)args,
+ (xdrproc_t)xdr_gf1_cli_status_volume_req);
+}
+
+ssize_t
+gf_xdr_from_cli_status_volume_req (struct iovec outmsg, void *args)
+{
+ return xdr_serialize_generic (outmsg, (void*)args,
+ (xdrproc_t)xdr_gf1_cli_status_volume_req);
+}
+
+ssize_t
+gf_xdr_to_cli_status_volume_rsp (struct iovec inmsg, void *args)
+{
+ return xdr_to_generic (inmsg, (void *)args,
+ (xdrproc_t)xdr_gf1_cli_status_volume_rsp);
+}
+
+ssize_t
+gf_xdr_from_cli_status_volume_rsp (struct iovec outmsg, void *args)
+{
+ return xdr_serialize_generic (outmsg, (void *)args,
+ (xdrproc_t)xdr_gf1_cli_status_volume_rsp);
+}
diff --git a/rpc/xdr/src/cli1.h b/rpc/xdr/src/cli1.h
index 22c16862ef3..9da385cbb21 100644
--- a/rpc/xdr/src/cli1.h
+++ b/rpc/xdr/src/cli1.h
@@ -343,4 +343,20 @@ gf_xdr_to_cli_getwd_rsp (struct iovec inmsg, void *args);
ssize_t
gf_xdr_from_cli_getwd_rsp (struct iovec outmsg, void *args);
+
+ssize_t
+gf_xdr_serialize_cli_status_volume_rsp (struct iovec outmsg, void *rsp);
+
+ssize_t
+gf_xdr_to_cli_status_volume_req (struct iovec inmsg, void *args);
+
+ssize_t
+gf_xdr_to_cli_status_volume_rsp (struct iovec inmsg, void *args);
+
+ssize_t
+gf_xdr_from_cli_status_volume_req (struct iovec outmsg, void *req);
+
+ssize_t
+gf_xdr_serialize_cli_status_volume_rsp (struct iovec outmsg, void *rsp);
+
#endif /* !_CLI1_H */
diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c
index 39f8976e833..09ed6ae2ce2 100644
--- a/xlators/mgmt/glusterd/src/glusterd-handler.c
+++ b/xlators/mgmt/glusterd/src/glusterd-handler.c
@@ -3875,6 +3875,63 @@ out:
}
int
+glusterd_handle_status_volume (rpcsvc_request_t *req)
+{
+ int32_t ret = -1;
+ gf1_cli_status_volume_req cli_req = {0,};
+ dict_t *dict = NULL;
+ int lock_fail = 0;
+ glusterd_op_t cli_op = GD_OP_STATUS_VOLUME;
+
+ GF_ASSERT (req);
+
+ ret = glusterd_op_set_cli_op (cli_op);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to set cli op: %d",
+ ret);
+ lock_fail = 1;
+ goto out;
+ }
+
+ ret = -1;
+ if (!gf_xdr_to_cli_status_volume_req (req->msg[0], &cli_req)) {
+ //failed to decode msg;
+ req->rpc_err = GARBAGE_ARGS;
+ goto out;
+ }
+
+ gf_log ("glusterd", GF_LOG_INFO, "Received status volume req "
+ "for volume %s", cli_req.volname);
+
+ dict = dict_new ();
+ if (!dict)
+ goto out;
+
+ ret = dict_set_dynmstr (dict, "volname", cli_req.volname);
+ if (ret)
+ goto out;
+
+ ret = glusterd_op_begin (req, GD_OP_STATUS_VOLUME, dict, _gf_true);
+
+out:
+ if (ret && dict)
+ dict_unref (dict);
+
+ glusterd_friend_sm ();
+ glusterd_op_sm ();
+
+ if (ret) {
+ ret = glusterd_op_send_cli_response (cli_op, ret, 0, req,
+ NULL, "operation failed");
+ if (!lock_fail)
+ (void) glusterd_opinfo_unlock ();
+
+ }
+
+ return ret;
+}
+
+int
glusterd_brick_rpc_notify (struct rpc_clnt *rpc, void *mydata,
rpc_clnt_event_t event,
void *data)
@@ -4020,6 +4077,7 @@ rpcsvc_actor_t gd_svc_cli_actors[] = {
[GLUSTER_CLI_QUOTA] = { "QUOTA", GLUSTER_CLI_QUOTA, glusterd_handle_quota, NULL, NULL},
[GLUSTER_CLI_LOG_LEVEL] = {"LOG_LEVEL", GLUSTER_CLI_LOG_LEVEL, glusterd_handle_log_level, NULL, NULL},
[GLUSTER_CLI_GETWD] = { "GETWD", GLUSTER_CLI_GETWD, glusterd_handle_getwd, NULL, NULL},
+ [GLUSTER_CLI_STATUS_VOLUME] = {"STATUS_VOLUME", GLUSTER_CLI_STATUS_VOLUME, glusterd_handle_status_volume, NULL, NULL},
};
@@ -4064,7 +4122,8 @@ rpcsvc_actor_t glusterd1_mgmt_actors[] = {
[GD_MGMT_CLI_FSM_LOG] = { "FSM_LOG", GD_MGMT_CLI_FSM_LOG, glusterd_handle_fsm_log, NULL, NULL},
[GD_MGMT_CLI_GSYNC_SET] = {"GSYNC_SET", GD_MGMT_CLI_GSYNC_SET, glusterd_handle_gsync_set, NULL, NULL},
[GD_MGMT_CLI_PROFILE_VOLUME] = { "STATS_VOLUME", GD_MGMT_CLI_PROFILE_VOLUME, glusterd_handle_cli_profile_volume, NULL, NULL},
- [GD_MGMT_CLI_LOG_LEVEL] = {"LOG_LEVEL", GD_MGMT_CLI_LOG_LEVEL, glusterd_handle_log_level, NULL, NULL}
+ [GD_MGMT_CLI_LOG_LEVEL] = {"LOG_LEVEL", GD_MGMT_CLI_LOG_LEVEL, glusterd_handle_log_level, NULL, NULL},
+ [GD_MGMT_CLI_STATUS_VOLUME] = {"STATUS_VOLUME", GD_MGMT_CLI_STATUS_VOLUME, glusterd_handle_status_volume, NULL, NULL}
};
struct rpcsvc_program glusterd1_mop_prog = {
diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
index 0875ec97ae3..a99c9fa1372 100644
--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c
+++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
@@ -1856,6 +1856,48 @@ out:
return ret;
}
+static int
+glusterd_op_stage_status_volume (dict_t *dict, char **op_errstr)
+{
+ int ret = -1;
+ gf_boolean_t exists = _gf_false;
+ char *volname = NULL;
+ glusterd_conf_t *priv = NULL;
+ xlator_t *this = NULL;
+ char msg[2048] = {0,};
+
+ GF_ASSERT (dict);
+ this = THIS;
+ GF_ASSERT (this);
+ priv = this->private;
+ GF_ASSERT(priv);
+
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret) {
+ gf_log ("glusterd", GF_LOG_ERROR, "Unable to get volume name");
+ goto out;
+ }
+
+ exists = glusterd_check_volume_exists (volname);
+ if (!exists) {
+ snprintf (msg, sizeof(msg), "Volume %s does not exist", volname);
+ gf_log ("glusterd", GF_LOG_ERROR, "%s", msg);
+
+ *op_errstr = gf_strdup(msg);
+ ret = -1;
+ goto out;
+ }
+
+ ret = 0;
+
+ out:
+ if (ret && !(*op_errstr))
+ *op_errstr = gf_strdup ("Validation Failed for Status");
+
+ gf_log ("glusterd", GF_LOG_DEBUG, "Returning: %d", ret);
+ return ret;
+}
int
glusterd_query_extutil (char *resbuf, runner_t *runner)
@@ -6440,6 +6482,67 @@ out:
}
static int
+glusterd_op_status_volume (dict_t *dict, char **op_errstr,
+ dict_t *rsp_dict)
+{
+ int ret = -1;
+ char *volname = NULL;
+ int count = 0;
+ int brick_count = 0;
+ glusterd_volinfo_t *volinfo = NULL;
+ glusterd_brickinfo_t *brickinfo = NULL;
+ glusterd_conf_t *priv = NULL;
+ xlator_t *this = NULL;
+ int32_t brick_index = 0;
+
+ this = THIS;
+ GF_ASSERT (this);
+ priv = this->private;
+
+ GF_ASSERT (priv);
+
+ GF_ASSERT (dict);
+
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (!ret) {
+ ret = glusterd_volinfo_find (volname, &volinfo);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Volume with name: %s "
+ "does not exist", volname);
+ goto out;
+ }
+ }
+
+ if (!rsp_dict) {
+ //this should happen only on source
+ ret = 0;
+ rsp_dict = glusterd_op_get_ctx (GD_OP_STATUS_VOLUME);
+ }
+
+ if (volname) {
+ list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
+ if (!uuid_compare (brickinfo->uuid, priv->uuid)) {
+ ret = glusterd_add_brick_to_dict (volinfo,
+ brickinfo,
+ rsp_dict,
+ brick_index);
+ count++;
+ brick_count = count;
+ }
+ brick_index++;
+ }
+ }
+
+ ret = dict_set_int32 (rsp_dict, "count", brick_count);
+
+out:
+ gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+
+ return ret;
+}
+
+static int
glusterd_op_ac_none (glusterd_op_sm_event_t *event, void *ctx)
{
int ret = 0;
@@ -6664,6 +6767,7 @@ glusterd_op_build_payload (glusterd_op_t op, dict_t **req)
case GD_OP_GSYNC_SET:
case GD_OP_PROFILE_VOLUME:
case GD_OP_LOG_LEVEL:
+ case GD_OP_STATUS_VOLUME:
{
dict_t *dict = ctx;
dict_copy (dict, req_dict);
@@ -7628,6 +7732,10 @@ glusterd_op_stage_validate (glusterd_op_t op, dict_t *dict, char **op_errstr,
ret = glusterd_op_stage_log_level (dict, op_errstr);
break;
+ case GD_OP_STATUS_VOLUME:
+ ret = glusterd_op_stage_status_volume (dict, op_errstr);
+ break;
+
default:
gf_log ("", GF_LOG_ERROR, "Unknown op %d",
op);
@@ -7711,6 +7819,10 @@ glusterd_op_commit_perform (glusterd_op_t op, dict_t *dict, char **op_errstr,
ret = glusterd_op_log_level (dict);
break;
+ case GD_OP_STATUS_VOLUME:
+ ret = glusterd_op_status_volume (dict, op_errstr, rsp_dict);
+ break;
+
default:
gf_log ("", GF_LOG_ERROR, "Unknown op %d",
op);
@@ -8733,6 +8845,7 @@ glusterd_op_free_ctx (glusterd_op_t op, void *ctx, gf_boolean_t ctx_free)
case GD_OP_QUOTA:
case GD_OP_PROFILE_VOLUME:
case GD_OP_LOG_LEVEL:
+ case GD_OP_STATUS_VOLUME:
dict_unref (ctx);
break;
case GD_OP_DELETE_VOLUME:
diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.h b/xlators/mgmt/glusterd/src/glusterd-op-sm.h
index 5dc1a56372a..b95d584aca6 100644
--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.h
+++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.h
@@ -163,6 +163,11 @@ typedef struct glusterd_pr_brick_rsp_conv_t {
dict_t *dict;
} glusterd_pr_brick_rsp_conv_t;
+typedef struct glusterd_status_rsp_conv_ {
+ int count;
+ dict_t *dict;
+} glusterd_status_rsp_conv_t;
+
typedef struct glusterd_gsync_slaves {
char *slave;
char *host_uuid;
diff --git a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c
index fa60430da91..36868d3ce3c 100644
--- a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c
+++ b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c
@@ -57,7 +57,7 @@ glusterd_op_send_cli_response (glusterd_op_t op, int32_t op_ret,
dict_t *ctx = NULL;
char *free_ptr = NULL;
glusterd_conf_t *conf = NULL;
- xdrproc_t xdrproc;
+ xdrproc_t xdrproc = NULL;
GF_ASSERT (THIS);
@@ -407,6 +407,26 @@ glusterd_op_send_cli_response (glusterd_op_t op, int32_t op_ret,
break;
}
+
+ case GD_OP_STATUS_VOLUME:
+ {
+ gf1_cli_status_volume_rsp rsp = {0,};
+ rsp.op_ret = op_ret;
+ rsp.op_errno = op_errno;
+ if (op_errstr)
+ rsp.op_errstr = op_errstr;
+ else
+ rsp.op_errstr = "";
+ ctx = op_ctx;
+ dict_allocate_and_serialize (ctx,
+ &rsp.dict.dict_val,
+ (size_t*)&rsp.dict.dict_len);
+ free_ptr = rsp.dict.dict_val;
+ cli_rsp = &rsp;
+ sfunc = gf_xdr_serialize_cli_status_volume_rsp;
+ xdrproc = (xdrproc_t) xdr_gf1_cli_status_volume_rsp;
+ break;
+ }
case GD_OP_NONE:
case GD_OP_MAX:
{
@@ -1219,6 +1239,62 @@ out:
return ret;
}
+void
+glusterd_volume_status_add_peer_rsp (dict_t *this, char *key, data_t *value,
+ void *data)
+{
+ glusterd_status_rsp_conv_t *rsp_ctx = NULL;
+ data_t *new_value = NULL;
+ int32_t ret = 0;
+
+ if (strcmp (key, "count") == 0)
+ return;
+
+ rsp_ctx = data;
+ new_value = data_copy (value);
+ GF_ASSERT (new_value);
+
+ ret = dict_set (rsp_ctx->dict, key, new_value);
+ if (ret)
+ gf_log ("", GF_LOG_ERROR, "Unable to set key: %s in dict",
+ key);
+
+ return;
+}
+
+int
+glusterd_volume_status_use_rsp_dict (dict_t *rsp_dict)
+{
+ int ret = 0;
+ glusterd_status_rsp_conv_t rsp_ctx = {0};
+ int32_t brick_count = 0;
+ int32_t count = 0;
+ dict_t *ctx_dict = NULL;
+ glusterd_op_t op = GD_OP_NONE;
+
+ GF_ASSERT (rsp_dict);
+
+ ret = dict_get_int32 (rsp_dict, "count", &brick_count);
+ if (ret) {
+ ret = 0; //no bricks in the rsp
+ goto out;
+ }
+
+ op = glusterd_op_get_op ();
+ GF_ASSERT (GD_OP_STATUS_VOLUME == op);
+ ctx_dict = glusterd_op_get_ctx (op);
+
+ ret = dict_get_int32 (ctx_dict, "count", &count);
+ rsp_ctx.count = count;
+ rsp_ctx.dict = ctx_dict;
+ dict_foreach (rsp_dict, glusterd_volume_status_add_peer_rsp, &rsp_ctx);
+ dict_del (ctx_dict, "count");
+ ret = dict_get_int32 (ctx_dict, "count", &brick_count);
+ ret = dict_set_int32 (ctx_dict, "count", count + brick_count);
+out:
+ return ret;
+}
+
int32_t
glusterd3_1_commit_op_cbk (struct rpc_req *req, struct iovec *iov,
int count, void *myframe)
@@ -1330,6 +1406,12 @@ glusterd3_1_commit_op_cbk (struct rpc_req *req, struct iovec *iov,
goto out;
break;
+ case GD_OP_STATUS_VOLUME:
+ ret = glusterd_volume_status_use_rsp_dict (dict);
+ if (ret)
+ goto out;
+ break;
+
default:
break;
}
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
index fb7f75c523b..278b25c954a 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
@@ -2538,6 +2538,93 @@ out:
return -1;
}
+int32_t
+glusterd_add_brick_to_dict (glusterd_volinfo_t *volinfo,
+ glusterd_brickinfo_t *brickinfo,
+ dict_t *dict, int32_t count)
+{
+
+ int ret = -1;
+ char key[8192] = {0,};
+ char base_key[8192] = {0};
+ char pidfile[PATH_MAX] = {0};
+ char path[PATH_MAX] = {0};
+ FILE *file = NULL;
+ int32_t pid = -1;
+ xlator_t *this = NULL;
+ glusterd_conf_t *priv = NULL;
+
+ GF_ASSERT (volinfo);
+ GF_ASSERT (brickinfo);
+ GF_ASSERT (dict);
+
+ this = THIS;
+ GF_ASSERT (this);
+
+ priv = this->private;
+
+ snprintf (base_key, sizeof (base_key), "brick%d", count);
+ snprintf (key, sizeof (key), "%s.hostname", base_key);
+ ret = dict_set_str (dict, key, brickinfo->hostname);
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.path", base_key);
+ ret = dict_set_str (dict, key, brickinfo->path);
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.port", base_key);
+ ret = dict_set_int32 (dict, key, brickinfo->port);
+ if (ret)
+ goto out;
+
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.status", base_key);
+ ret = dict_set_int32 (dict, key, brickinfo->signed_in);
+ if (ret)
+ goto out;
+
+ if (!brickinfo->signed_in)
+ goto out;
+
+
+ GLUSTERD_GET_VOLUME_DIR (path, volinfo, priv);
+ GLUSTERD_GET_BRICK_PIDFILE (pidfile, path, brickinfo->hostname,
+ brickinfo->path);
+
+ file = fopen (pidfile, "r+");
+ if (!file) {
+ gf_log ("", GF_LOG_ERROR, "Unable to open pidfile: %s",
+ pidfile);
+ ret = -1;
+ goto out;
+ }
+
+ ret = fscanf (file, "%d", &pid);
+ if (ret <= 0) {
+ gf_log ("", GF_LOG_ERROR, "Unable to read pidfile: %s",
+ pidfile);
+ ret = -1;
+ goto out;
+ }
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.pid", base_key);
+ ret = dict_set_int32 (dict, key, pid);
+ if (ret)
+ goto out;
+
+out:
+ if (ret)
+ gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+
+ return ret;
+}
+
int
glusterd_all_volume_cond_check (glusterd_condition_func func, int status,
void *ctx)
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h
index 1f5223fefc1..93e2cb92d22 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.h
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.h
@@ -282,4 +282,8 @@ glusterd_recreate_bricks (glusterd_conf_t *conf);
int32_t
glusterd_handle_upgrade_downgrade (dict_t *options, glusterd_conf_t *conf);
+int32_t
+glusterd_add_brick_to_dict (glusterd_volinfo_t *volinfo,
+ glusterd_brickinfo_t *brickinfo,
+ dict_t *dict, int32_t count);
#endif
diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h
index ab4049d0ba5..4362984fef4 100644
--- a/xlators/mgmt/glusterd/src/glusterd.h
+++ b/xlators/mgmt/glusterd/src/glusterd.h
@@ -77,6 +77,7 @@ typedef enum glusterd_op_ {
GD_OP_PROFILE_VOLUME,
GD_OP_QUOTA,
GD_OP_LOG_LEVEL,
+ GD_OP_STATUS_VOLUME,
GD_OP_MAX,
} glusterd_op_t;