summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cli/src/cli-cmd-parser.c4
-rw-r--r--cli/src/cli-cmd-volume.c2
-rw-r--r--cli/src/cli-rpc-ops.c139
-rw-r--r--glusterfsd/src/glusterfsd-mgmt.c1
-rw-r--r--rpc/xdr/src/cli1-xdr.x1
-rw-r--r--tests/basic/volume-status.t6
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-handler.c10
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-op-sm.c1
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-syncop.c12
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.c210
-rw-r--r--xlators/protocol/server/src/server.c8
11 files changed, 388 insertions, 6 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c
index 984ce5bbad0..ae4f78c522d 100644
--- a/cli/src/cli-cmd-parser.c
+++ b/cli/src/cli-cmd-parser.c
@@ -3249,7 +3249,8 @@ cli_cmd_get_statusop (const char *arg)
uint32_t ret = GF_CLI_STATUS_NONE;
char *w = NULL;
char *opwords[] = {"detail", "mem", "clients", "fd",
- "inode", "callpool", "tasks", NULL};
+ "inode", "callpool", "tasks", "client-list",
+ NULL};
struct {
char *opname;
uint32_t opcode;
@@ -3261,6 +3262,7 @@ cli_cmd_get_statusop (const char *arg)
{ "inode", GF_CLI_STATUS_INODE },
{ "callpool", GF_CLI_STATUS_CALLPOOL },
{ "tasks", GF_CLI_STATUS_TASKS },
+ { "client-list", GF_CLI_STATUS_CLIENT_LIST },
{ NULL }
};
diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c
index e6d168d3d8f..7bf99eb5e12 100644
--- a/cli/src/cli-cmd-volume.c
+++ b/cli/src/cli-cmd-volume.c
@@ -3289,7 +3289,7 @@ struct cli_cmd volume_cmds[] = {
"volume top operations"},
{ "volume status [all | <VOLNAME> [nfs|shd|<BRICK>|quotad|tierd]]"
- " [detail|clients|mem|inode|fd|callpool|tasks]",
+ " [detail|clients|mem|inode|fd|callpool|tasks|client-list]",
cli_cmd_volume_status_cbk,
"display status of all or specified volume(s)/brick"},
diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c
index 03071dd9e45..1840b208431 100644
--- a/cli/src/cli-rpc-ops.c
+++ b/cli/src/cli-rpc-ops.c
@@ -7299,6 +7299,141 @@ out:
}
void
+cli_print_volume_status_client_list (dict_t *dict, gf_boolean_t notbrick)
+{
+ int ret = -1;
+ char *volname = NULL;
+ int client_count = 0;
+ int current_count = 0;
+ char key[1024] = {0,};
+ int i = 0;
+ int total = 0;
+ char *name = NULL;
+ gf_boolean_t is_fuse_done = _gf_false;
+ gf_boolean_t is_gfapi_done = _gf_false;
+ gf_boolean_t is_tierd_done = _gf_false;
+ gf_boolean_t is_rebalance_done = _gf_false;
+ gf_boolean_t is_glustershd_done = _gf_false;
+ gf_boolean_t is_quotad_done = _gf_false;
+ gf_boolean_t is_snapd_done = _gf_false;
+
+ GF_ASSERT (dict);
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret)
+ goto out;
+ cli_out ("Client connections for volume %s", volname);
+
+ ret = dict_get_int32 (dict, "client-count", &client_count);
+ if (ret)
+ goto out;
+
+ cli_out ("%-48s %15s", "Name", "count");
+ cli_out ("%-48s %15s", "-----", "------");
+ for (i = 0; i < client_count; i++) {
+ name = NULL;
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key),
+ "client%d.name", i);
+ ret = dict_get_str (dict, key, &name);
+
+ if (!strncmp (name, "fuse", 4)) {
+ if (!is_fuse_done) {
+ is_fuse_done = _gf_true;
+ ret = dict_get_int32 (dict,
+ "fuse-count",
+ &current_count);
+ if (ret)
+ goto out;
+ total = total + current_count;
+ goto print;
+ }
+ continue;
+ } else if (!strncmp (name, "gfapi", 5)) {
+ if (!is_gfapi_done) {
+ is_gfapi_done = _gf_true;
+ ret = dict_get_int32 (dict,
+ "gfapi-count",
+ &current_count);
+ if (ret)
+ goto out;
+ total = total + current_count;
+ goto print;
+ }
+ continue;
+ } else if (!strcmp(name, "tierd")) {
+ if (!is_tierd_done) {
+ is_tierd_done = _gf_true;
+ ret = dict_get_int32 (dict,
+ "tierd-count",
+ &current_count);
+ if (ret)
+ goto out;
+ total = total + current_count;
+ goto print;
+ }
+ continue;
+ } else if (!strcmp(name, "rebalance")) {
+ if (!is_rebalance_done) {
+ is_rebalance_done = _gf_true;
+ ret = dict_get_int32 (dict,
+ "rebalance-count",
+ &current_count);
+ if (ret)
+ goto out;
+ total = total + current_count;
+ goto print;
+ }
+ continue;
+ } else if (!strcmp(name, "glustershd")) {
+ if (!is_glustershd_done) {
+ is_glustershd_done = _gf_true;
+ ret = dict_get_int32 (dict,
+ "glustershd-count",
+ &current_count);
+ if (ret)
+ goto out;
+ total = total + current_count;
+ goto print;
+ }
+ continue;
+ } else if (!strcmp(name, "quotad")) {
+ if (!is_quotad_done) {
+ is_quotad_done = _gf_true;
+ ret = dict_get_int32 (dict,
+ "quotad-count",
+ &current_count);
+ if (ret)
+ goto out;
+ total = total + current_count;
+ goto print;
+ }
+ continue;
+ } else if (!strcmp(name, "snapd")) {
+ if (!is_snapd_done) {
+ is_snapd_done = _gf_true;
+ ret = dict_get_int32 (dict,
+ "snapd-count",
+ &current_count);
+ if (ret)
+ goto out;
+ total = total + current_count;
+ goto print;
+ }
+ continue;
+ }
+
+print:
+ cli_out ("%-48s %15d", name, current_count);
+
+ }
+out:
+ cli_out ("\ntotal clients for volume %s : %d ", volname, total);
+ cli_out ("-----------------------------------------------------------------\n");
+ return;
+}
+
+void
cli_print_volume_status_clients (dict_t *dict, gf_boolean_t notbrick)
{
int ret = -1;
@@ -8293,6 +8428,10 @@ xml_end:
cli_print_volume_status_clients (dict, notbrick);
goto cont;
break;
+ case GF_CLI_STATUS_CLIENT_LIST:
+ cli_print_volume_status_client_list (dict, notbrick);
+ goto cont;
+ break;
case GF_CLI_STATUS_INODE:
cli_print_volume_status_inode (dict, notbrick);
goto cont;
diff --git a/glusterfsd/src/glusterfsd-mgmt.c b/glusterfsd/src/glusterfsd-mgmt.c
index ca706d1020d..46d4e918bc6 100644
--- a/glusterfsd/src/glusterfsd-mgmt.c
+++ b/glusterfsd/src/glusterfsd-mgmt.c
@@ -1050,6 +1050,7 @@ glusterfs_handle_brick_status (rpcsvc_request_t *req)
break;
case GF_CLI_STATUS_CLIENTS:
+ case GF_CLI_STATUS_CLIENT_LIST:
ret = xlator->dumpops->priv_to_dict (xlator, output);
break;
diff --git a/rpc/xdr/src/cli1-xdr.x b/rpc/xdr/src/cli1-xdr.x
index f62248396ca..6f5fd256954 100644
--- a/rpc/xdr/src/cli1-xdr.x
+++ b/rpc/xdr/src/cli1-xdr.x
@@ -180,6 +180,7 @@ enum gf_cli_status_type {
GF_CLI_STATUS_CALLPOOL = 0x000010, /*000000000010000*/
GF_CLI_STATUS_DETAIL = 0x000020, /*000000000100000*/
GF_CLI_STATUS_TASKS = 0x000040, /*00000001000000*/
+ GF_CLI_STATUS_CLIENT_LIST = 0x000080, /*00000010000000*/
GF_CLI_STATUS_MASK = 0x0000FF, /*000000011111111 Used to get the op*/
GF_CLI_STATUS_VOL = 0x000100, /*00000000100000000*/
GF_CLI_STATUS_ALL = 0x000200, /*00000001000000000*/
diff --git a/tests/basic/volume-status.t b/tests/basic/volume-status.t
index f87b0a93edf..0899344cba9 100644
--- a/tests/basic/volume-status.t
+++ b/tests/basic/volume-status.t
@@ -6,6 +6,10 @@
cleanup;
+function gluster_client_list_status () {
+ gluster volume status $V0 client-list | sed -n '/Name/','/total/'p | wc -l
+}
+
TEST glusterd
TEST pidof glusterd
TEST $CLI volume info;
@@ -21,6 +25,8 @@ EXPECT_WITHIN $PROCESS_UP_TIMEOUT "Y" nfs_up_status
## Mount FUSE
TEST $GFS -s $H0 --volfile-id $V0 $M0;
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "7" gluster_client_list_status
+
##Wait for connection establishment between nfs server and brick process
EXPECT_WITHIN $NFS_EXPORT_TIMEOUT "1" is_nfs_export_available;
diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c
index c0929fa8192..a3ff49de173 100644
--- a/xlators/mgmt/glusterd/src/glusterd-handler.c
+++ b/xlators/mgmt/glusterd/src/glusterd-handler.c
@@ -4303,6 +4303,16 @@ __glusterd_handle_status_volume (rpcsvc_request_t *req)
"Received status volume req for volume %s", volname);
}
+ if ((cmd & GF_CLI_STATUS_CLIENT_LIST) &&
+ (conf->op_version < GD_OP_VERSION_4_0_0)) {
+ snprintf (err_str, sizeof (err_str), "The cluster is operating "
+ "at version less than %d. Getting the client-list "
+ "is not allowed in this state.",
+ GD_OP_VERSION_4_0_0);
+ ret = -1;
+ goto out;
+ }
+
if ((cmd & GF_CLI_STATUS_QUOTAD) &&
(conf->op_version == GD_OP_VERSION_MIN)) {
snprintf (err_str, sizeof (err_str), "The cluster is operating "
diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
index b461edba106..28f36d7c268 100644
--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c
+++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
@@ -7281,6 +7281,7 @@ glusterd_bricks_select_status_volume (dict_t *dict, char **op_errstr,
case GF_CLI_STATUS_TIERD:
case GF_CLI_STATUS_BITD:
case GF_CLI_STATUS_SCRUB:
+ case GF_CLI_STATUS_CLIENT_LIST:
break;
default:
goto out;
diff --git a/xlators/mgmt/glusterd/src/glusterd-syncop.c b/xlators/mgmt/glusterd/src/glusterd-syncop.c
index e327c168d20..aa47517c356 100644
--- a/xlators/mgmt/glusterd/src/glusterd-syncop.c
+++ b/xlators/mgmt/glusterd/src/glusterd-syncop.c
@@ -987,7 +987,6 @@ gd_syncop_mgmt_brick_op (struct rpc_clnt *rpc, glusterd_pending_node_t *pnode,
else
GF_FREE (args.errstr);
}
-
if (op == GD_OP_STOP_VOLUME || op == GD_OP_REMOVE_BRICK) {
if (args.op_ret == 0) {
brickinfo = pnode->node;
@@ -1758,7 +1757,16 @@ gd_brick_op_phase (glusterd_op_t op, dict_t *op_ctx, dict_t *req_dict,
}
ret = gd_syncop_mgmt_brick_op (rpc, pending_node, op, req_dict,
op_ctx, op_errstr);
- if (cmd == GF_OP_CMD_DETACH_START) {
+ if (op == GD_OP_STATUS_VOLUME) {
+ /* for client-list its enough to quit the loop
+ * once we get the value from one brick
+ * */
+ ret = dict_get_int32 (req_dict, "cmd", &cmd);
+ if (!ret && (cmd & GF_CLI_STATUS_CLIENT_LIST)) {
+ if (dict_get (op_ctx, "client-count"))
+ break;
+ }
+ } else if (cmd == GF_OP_CMD_DETACH_START) {
op = GD_OP_REMOVE_BRICK;
dict_del (req_dict, "rebalance-command");
} else if (cmd == GF_DEFRAG_CMD_DETACH_START) {
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
index fbf192ebdb7..b861edf4a20 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
@@ -11378,6 +11378,206 @@ out:
}
int
+glusterd_status_volume_client_list (dict_t *rsp_dict, dict_t *op_ctx,
+ char **op_errstr)
+{
+ int ret = 0;
+ char *process = 0;
+ int32_t count = 0;
+ int32_t fuse_count = 0;
+ int32_t gfapi_count = 0;
+ int32_t tierd_count = 0;
+ int32_t rebalance_count = 0;
+ int32_t glustershd_count = 0;
+ int32_t quotad_count = 0;
+ int32_t snapd_count = 0;
+ int32_t client_count = 0;
+ int i = 0;
+ char key[256] = {0,};
+
+ GF_ASSERT (rsp_dict);
+ GF_ASSERT (op_ctx);
+ GF_ASSERT (op_errstr);
+
+ ret = dict_get_int32 (rsp_dict, "clientcount", &client_count);
+ if (ret) {
+ gf_msg (THIS->name, GF_LOG_INFO, 0,
+ GD_MSG_DICT_GET_FAILED,
+ "Couldn't get node index");
+ }
+ ret = dict_set_int32 (op_ctx, "client-count", client_count);
+ if (ret) {
+ gf_msg (THIS->name, GF_LOG_ERROR, 0,
+ GD_MSG_DICT_GET_FAILED,
+ "Couldn't get node index");
+ goto out;
+ }
+ for (i = 0; i < client_count; i++) {
+ count = 0;
+ snprintf (key, sizeof (key), "client%d.name", i);
+ ret = dict_get_str (rsp_dict, key, &process);
+ if (ret) {
+ gf_msg (THIS->name, GF_LOG_INFO, 0,
+ GD_MSG_DICT_GET_FAILED,
+ "Couldn't get client name");
+ goto out;
+ }
+ ret = dict_add_dynstr_with_alloc (op_ctx, key, process);
+ if (ret) {
+ gf_msg (THIS->name, GF_LOG_INFO, 0,
+ GD_MSG_DICT_SET_FAILED,
+ "Couldn't set client name");
+ }
+ if (!strncmp(process, "fuse", 4)) {
+ ret = dict_get_int32 (op_ctx, "fuse-count",
+ &count);
+ if (ret) {
+ gf_msg (THIS->name, GF_LOG_INFO, 0,
+ GD_MSG_DICT_GET_FAILED,
+ "Couldn't get fuse-count");
+ }
+ fuse_count++;
+ continue;
+ } else if (!strncmp(process, "gfapi", 5)) {
+ ret = dict_get_int32 (op_ctx, "gfapi-count",
+ &count);
+ if (ret) {
+ gf_msg (THIS->name, GF_LOG_INFO, 0,
+ GD_MSG_DICT_GET_FAILED,
+ "Couldn't get gfapi-count");
+ }
+ gfapi_count++;
+ continue;
+
+ } else if (!strcmp(process, "tierd")) {
+ ret = dict_get_int32 (op_ctx, "tierd-count",
+ &count);
+ if (ret) {
+ gf_msg (THIS->name, GF_LOG_INFO, 0,
+ GD_MSG_DICT_GET_FAILED,
+ "Couldn't get tierd-count");
+ }
+ tierd_count++;
+ continue;
+ } else if (!strcmp(process, "rebalance")) {
+ ret = dict_get_int32 (op_ctx, "rebalance-count",
+ &count);
+ if (ret) {
+ gf_msg (THIS->name, GF_LOG_INFO, 0,
+ GD_MSG_DICT_GET_FAILED,
+ "Couldn't get rebalance-count");
+ }
+ rebalance_count++;
+ continue;
+ } else if (!strcmp(process, "glustershd")) {
+ ret = dict_get_int32 (op_ctx,
+ "glustershd-count", &count);
+ if (ret) {
+ gf_msg (THIS->name, GF_LOG_INFO, 0,
+ GD_MSG_DICT_GET_FAILED,
+ "Couldn't get glustershd-count");
+ }
+ glustershd_count++;
+ continue;
+ } else if (!strcmp(process, "quotad")) {
+ ret = dict_get_int32 (op_ctx, "quotad-count",
+ &count);
+ if (ret) {
+ gf_msg (THIS->name, GF_LOG_INFO, 0,
+ GD_MSG_DICT_GET_FAILED,
+ "Couldn't get quotad-count");
+ }
+ quotad_count++;
+ continue;
+ } else if (!strcmp(process, "snapd")) {
+ ret = dict_get_int32 (op_ctx, "snapd-count",
+ &count);
+ if (ret) {
+ gf_msg (THIS->name, GF_LOG_INFO, 0,
+ GD_MSG_DICT_GET_FAILED,
+ "Couldn't get snapd-count");
+ }
+ snapd_count++;
+
+ }
+ }
+
+ if (fuse_count) {
+ ret = dict_set_int32 (op_ctx, "fuse-count",
+ fuse_count);
+ if (ret) {
+ gf_msg (THIS->name, GF_LOG_ERROR, 0,
+ GD_MSG_DICT_SET_FAILED,
+ "Couldn't set fuse-count");
+ goto out;
+ }
+ }
+ if (gfapi_count) {
+ ret = dict_set_int32 (op_ctx, "gfapi-count",
+ gfapi_count);
+ if (ret) {
+ gf_msg (THIS->name, GF_LOG_ERROR, 0,
+ GD_MSG_DICT_SET_FAILED,
+ "Couldn't set gfapi-count");
+ goto out;
+ }
+ }
+ if (tierd_count) {
+ ret = dict_set_int32 (op_ctx, "tierd-count",
+ tierd_count);
+ if (ret) {
+ gf_msg (THIS->name, GF_LOG_ERROR, 0,
+ GD_MSG_DICT_SET_FAILED,
+ "Couldn't set tierd-count");
+ goto out;
+ }
+ }
+ if (rebalance_count) {
+ ret = dict_set_int32 (op_ctx, "rebalance-count",
+ rebalance_count);
+ if (ret) {
+ gf_msg (THIS->name, GF_LOG_ERROR, 0,
+ GD_MSG_DICT_SET_FAILED,
+ "Couldn't set rebalance-count");
+ goto out;
+ }
+ }
+ if (glustershd_count) {
+ ret = dict_set_int32 (op_ctx, "glustershd-count",
+ glustershd_count);
+ if (ret) {
+ gf_msg (THIS->name, GF_LOG_ERROR, 0,
+ GD_MSG_DICT_SET_FAILED,
+ "Couldn't set glustershd-count");
+ goto out;
+ }
+ }
+ if (quotad_count) {
+ ret = dict_set_int32 (op_ctx, "quotad-count",
+ quotad_count);
+ if (ret) {
+ gf_msg (THIS->name, GF_LOG_ERROR, 0,
+ GD_MSG_DICT_SET_FAILED,
+ "Couldn't set quotad-count");
+ goto out;
+ }
+ }
+ if (snapd_count) {
+ ret = dict_set_int32 (op_ctx, "snapd-count",
+ snapd_count);
+ if (ret) {
+ gf_msg (THIS->name, GF_LOG_ERROR, 0,
+ GD_MSG_DICT_SET_FAILED,
+ "Couldn't set snapd-count");
+ goto out;
+ }
+ }
+
+out:
+ return ret;
+}
+
+int
glusterd_tier_or_rebalance_rsp (dict_t *op_ctx, glusterd_rebalance_t *index, int32_t i)
{
int ret = 0;
@@ -11542,6 +11742,7 @@ glusterd_handle_node_rsp (dict_t *req_dict, void *pending_entry,
char **op_errstr, gd_node_type type)
{
int ret = 0;
+ int32_t cmd = GF_OP_CMD_NONE;
GF_ASSERT (op_errstr);
@@ -11552,8 +11753,13 @@ glusterd_handle_node_rsp (dict_t *req_dict, void *pending_entry,
op_errstr, type);
break;
case GD_OP_STATUS_VOLUME:
- ret = glusterd_status_volume_brick_rsp (rsp_dict, op_ctx,
- op_errstr);
+ ret = dict_get_int32 (req_dict, "cmd", &cmd);
+ if (!ret && (cmd & GF_CLI_STATUS_CLIENT_LIST)) {
+ ret = glusterd_status_volume_client_list (rsp_dict,
+ op_ctx, op_errstr);
+ } else
+ ret = glusterd_status_volume_brick_rsp (rsp_dict,
+ op_ctx, op_errstr);
break;
case GD_OP_TIER_STATUS:
case GD_OP_DETACH_TIER_STATUS:
diff --git a/xlators/protocol/server/src/server.c b/xlators/protocol/server/src/server.c
index e47acb28637..95bffa095d8 100644
--- a/xlators/protocol/server/src/server.c
+++ b/xlators/protocol/server/src/server.c
@@ -277,6 +277,14 @@ server_priv_to_dict (xlator_t *this, dict_t *dict)
if (ret)
goto unlock;
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "client%d.name",
+ count);
+ ret = dict_set_str (dict, key,
+ xprt->xl_private->client_name);
+ if (ret)
+ goto unlock;
+
count++;
}
}