summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaushal M <kaushal@redhat.com>2012-02-27 12:41:24 +0530
committerVijay Bellur <vijay@gluster.com>2012-03-14 02:27:42 -0700
commita476aba5b0368c3bc649db319ee748ae410144d9 (patch)
treeac6ea7e9ac361f3516ae2a2867f3c2d5aa86e047
parentfcb5ebde1e84da871a7f43df9ecbce7d1d1de435 (diff)
cli, glusterd, nfs: "volume status|profile|top" for nfs servers
Enables usage of volume monitoring operations "volume status", "volume top" and "volume profile" for nfs servers. These operations can be performed on nfs-servers by passing "nfs" as an option in cli. The output is similar to the normal brick outputs for these commands. The new syntaxes for the changed commands are as below, #gluster volume profile <VOLNAME> {start|info|stop} [nfs] #gluster volume top <VOLNAME> {[open|read|write|opendir|readdir [nfs]] |[read-perf|write-perf [nfs|{bs <size> count <count>}]]} [brick <brick>] [list-cnt <count>] #gluster volume status [all | <VOLNAME> [nfs|<BRICK>]] [detail|clients|mem|inode|fd|callpool] Change-Id: Ia6eb50c60aecacf9b413d3ea993f4cdd90ec0e07 BUG: 795267 Signed-off-by: Kaushal M <kaushal@redhat.com> Reviewed-on: http://review.gluster.com/2820 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Krishnan Parthasarathi <kp@gluster.com>
-rw-r--r--cli/src/cli-cmd-parser.c56
-rw-r--r--cli/src/cli-cmd-volume.c8
-rw-r--r--cli/src/cli-rpc-ops.c85
-rw-r--r--glusterfsd/src/glusterfsd-mgmt.c247
-rw-r--r--rpc/rpc-lib/src/protocol-common.h2
-rw-r--r--rpc/xdr/src/cli1-xdr.h1
-rw-r--r--rpc/xdr/src/cli1-xdr.x3
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-handler.c15
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-op-sm.c354
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-op-sm.h10
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-rpc-ops.c38
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.c188
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.h20
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volume-ops.c2
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.c5
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.h6
-rw-r--r--xlators/nfs/server/src/nfs.c89
17 files changed, 975 insertions, 154 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c
index 24310cac5..0f13928bb 100644
--- a/cli/src/cli-cmd-parser.c
+++ b/cli/src/cli-cmd-parser.c
@@ -1648,7 +1648,7 @@ cli_cmd_volume_profile_parse (const char **words, int wordcount,
if (!dict)
goto out;
- if (wordcount != 4)
+ if (wordcount < 4 || wordcount >5)
goto out;
volname = (char *)words[2];
@@ -1670,7 +1670,19 @@ cli_cmd_volume_profile_parse (const char **words, int wordcount,
op = GF_CLI_STATS_INFO;
} else
GF_ASSERT (!"opword mismatch");
+
ret = dict_set_int32 (dict, "op", (int32_t)op);
+ if (ret)
+ goto out;
+
+ if (wordcount == 5) {
+ if (!strcmp (words[4], "nfs")) {
+ ret = dict_set_int32 (dict, "nfs", _gf_true);
+ if (ret)
+ goto out;
+ }
+ }
+
*options = dict;
out:
if (ret && dict)
@@ -1694,6 +1706,7 @@ cli_cmd_volume_top_parse (const char **words, int wordcount,
int perf = 0;
uint32_t blk_size = 0;
uint32_t count = 0;
+ gf_boolean_t nfs = _gf_false;
char *delimiter = NULL;
char *opwords[] = { "open", "read", "write", "opendir",
"readdir", "read-perf", "write-perf",
@@ -1748,7 +1761,17 @@ cli_cmd_volume_top_parse (const char **words, int wordcount,
if (ret)
goto out;
- for (index = 4; index < wordcount; index+=2) {
+ if ((wordcount > 4) && !strcmp (words[4], "nfs")) {
+ nfs = _gf_true;
+ ret = dict_set_int32 (dict, "nfs", nfs);
+ if (ret)
+ goto out;
+ index = 5;
+ } else {
+ index = 4;
+ }
+
+ for (; index < wordcount; index+=2) {
key = (char *) words[index];
value = (char *) words[index+1];
@@ -1781,7 +1804,7 @@ cli_cmd_volume_top_parse (const char **words, int wordcount,
ret = -1;
goto out;
}
- } else if (perf && !strcmp (key, "bs")) {
+ } else if (perf && !nfs && !strcmp (key, "bs")) {
ret = gf_is_str_int (value);
if (!ret)
blk_size = atoi (value);
@@ -1795,7 +1818,7 @@ cli_cmd_volume_top_parse (const char **words, int wordcount,
goto out;
}
ret = dict_set_uint32 (dict, "blk-size", blk_size);
- } else if (perf && !strcmp (key, "count")) {
+ } else if (perf && !nfs && !strcmp (key, "count")) {
ret = gf_is_str_int (value);
if (!ret)
count = atoi(value);
@@ -1931,9 +1954,13 @@ cli_cmd_volume_status_parse (const char **words, int wordcount,
goto out;
if (cmd == GF_CLI_STATUS_NONE) {
- cmd = GF_CLI_STATUS_BRICK;
- ret = dict_set_str (dict, "brick",
- (char *)words[3]);
+ if (!strcmp (words[3], "nfs")) {
+ cmd |= GF_CLI_STATUS_NFS;
+ } else {
+ cmd = GF_CLI_STATUS_BRICK;
+ ret = dict_set_str (dict, "brick",
+ (char *)words[3]);
+ }
} else {
cmd |= GF_CLI_STATUS_VOL;
@@ -1945,7 +1972,7 @@ cli_cmd_volume_status_parse (const char **words, int wordcount,
case 5:
if (!strcmp (words[2], "all")) {
- cli_out ("Cannot specify brick for \"all\"");
+ cli_out ("Cannot specify brick/nfs for \"all\"");
ret = -1;
goto out;
}
@@ -1958,13 +1985,22 @@ cli_cmd_volume_status_parse (const char **words, int wordcount,
goto out;
}
- cmd |= GF_CLI_STATUS_BRICK;
ret = dict_set_str (dict, "volname", (char *)words[2]);
if (ret)
goto out;
- ret = dict_set_str (dict, "brick", (char *)words[3]);
+ if (!strcmp (words[3], "nfs")) {
+ if (cmd == GF_CLI_STATUS_FD) {
+ cli_out ("FD status not available for NFS");
+ ret = -1;
+ goto out;
+ }
+ cmd |= GF_CLI_STATUS_NFS;
+ } else {
+ cmd |= GF_CLI_STATUS_BRICK;
+ ret = dict_set_str (dict, "brick", (char *)words[3]);
+ }
break;
default:
diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c
index 6b9c0b03f..9546831ab 100644
--- a/cli/src/cli-cmd-volume.c
+++ b/cli/src/cli-cmd-volume.c
@@ -1804,7 +1804,7 @@ struct cli_cmd volume_cmds[] = {
cli_cmd_check_gsync_exists_cbk},
#endif
- { "volume profile <VOLNAME> {start|info|stop}",
+ { "volume profile <VOLNAME> {start|info|stop} [nfs]",
cli_cmd_volume_profile_cbk,
"volume profile operations"},
@@ -1812,13 +1812,13 @@ struct cli_cmd volume_cmds[] = {
cli_cmd_quota_cbk,
"quota translator specific operations"},
- { "volume top <VOLNAME> {[open|read|write|opendir|readdir] "
- "|[read-perf|write-perf bs <size> count <count>]} "
+ { "volume top <VOLNAME> {[open|read|write|opendir|readdir [nfs]] "
+ "|[read-perf|write-perf [nfs|{bs <size> count <count>}]]} "
" [brick <brick>] [list-cnt <count>]",
cli_cmd_volume_top_cbk,
"volume top operations"},
- { "volume status [all | <VOLNAME> [<BRICK>]]"
+ { "volume status [all | <VOLNAME> [nfs|<BRICK>]]"
" [detail|clients|mem|inode|fd|callpool]",
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 20688b096..dbef04a99 100644
--- a/cli/src/cli-rpc-ops.c
+++ b/cli/src/cli-rpc-ops.c
@@ -3506,7 +3506,6 @@ cmd_profile_volume_brick_out (dict_t *dict, int count, int interval)
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}};
@@ -3519,9 +3518,6 @@ cmd_profile_volume_brick_out (dict_t *dict, int count, int interval)
int ret = 0;
double total_percentage_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,
@@ -3584,7 +3580,6 @@ cmd_profile_volume_brick_out (dict_t *dict, int count, int interval)
ret = dict_get_uint64 (dict, key, &w_count);
if (ret == 0) {
- cli_out ("Brick: %s", brick);
}
if (interval == -1)
@@ -3681,6 +3676,9 @@ gf_cli3_1_profile_volume_cbk (struct rpc_req *req, struct iovec *iov,
int i = 1;
int32_t brick_count = 0;
char *volname = NULL;
+ char *brick = NULL;
+ char str[1024] = {0,};
+
if (-1 == req->rpc_status) {
goto out;
}
@@ -3775,6 +3773,23 @@ gf_cli3_1_profile_volume_cbk (struct rpc_req *req, struct iovec *iov,
}
while (i <= brick_count) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%d-brick", i);
+ ret = dict_get_str (dict, key, &brick);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Couldn't get brick name");
+ goto out;
+ }
+
+ ret = dict_get_str_boolean (dict, "nfs", _gf_false);
+ if (ret)
+ snprintf (str, sizeof (str), "NFS Server : %s", brick);
+ else
+ snprintf (str, sizeof (str), "Brick: %s", brick);
+ cli_out (str);
+ memset (str, '-', strlen (str));
+ cli_out (str);
+
snprintf (key, sizeof (key), "%d-cumulative", i);
ret = dict_get_int32 (dict, key, &interval);
if (ret == 0) {
@@ -3935,7 +3950,12 @@ gf_cli3_1_top_volume_cbk (struct rpc_req *req, struct iovec *iov,
ret = dict_get_str (dict, brick, &bricks);
if (ret)
goto out;
- cli_out ("Brick: %s", bricks);
+ ret = dict_get_str_boolean (dict, "nfs", _gf_false);
+ if (ret)
+ cli_out ("NFS Server : %s", bricks);
+ else
+ cli_out ("Brick: %s", bricks);
+
snprintf(key, sizeof (key), "%d-members", i);
ret = dict_get_int32 (dict, key, &members);
@@ -4237,7 +4257,7 @@ out:
}
void
-cli_print_volume_status_mem (dict_t *dict)
+cli_print_volume_status_mem (dict_t *dict, gf_boolean_t nfs)
{
int ret = -1;
char *volname = NULL;
@@ -4273,7 +4293,10 @@ cli_print_volume_status_mem (dict_t *dict)
ret = dict_get_str (dict, key, &path);
if (ret)
goto out;
- cli_out ("Brick : %s:%s", hostname, path);
+ if (nfs)
+ cli_out ("%s : %s", hostname, path);
+ else
+ cli_out ("Brick : %s:%s", hostname, path);
memset (key, 0, sizeof (key));
snprintf (key, sizeof (key), "brick%d.status", i);
@@ -4368,7 +4391,7 @@ out:
}
void
-cli_print_volume_status_clients (dict_t *dict)
+cli_print_volume_status_clients (dict_t *dict, gf_boolean_t nfs)
{
int ret = -1;
char *volname = NULL;
@@ -4408,7 +4431,11 @@ cli_print_volume_status_clients (dict_t *dict)
ret = dict_get_str (dict, key, &path);
if (ret)
goto out;
- cli_out ("Brick : %s:%s", hostname, path);
+
+ if (nfs)
+ cli_out ("%s : %s", hostname, path);
+ else
+ cli_out ("Brick : %s:%s", hostname, path);
memset (key, 0, sizeof (key));
snprintf (key, sizeof (key), "brick%d.status", i);
@@ -4609,7 +4636,7 @@ out:
}
void
-cli_print_volume_status_inode (dict_t *dict)
+cli_print_volume_status_inode (dict_t *dict, gf_boolean_t nfs)
{
int ret = -1;
char *volname = NULL;
@@ -4646,7 +4673,10 @@ cli_print_volume_status_inode (dict_t *dict)
ret = dict_get_str (dict, key, &path);
if (ret)
goto out;
- cli_out ("Brick : %s:%s", hostname, path);
+ if (nfs)
+ cli_out ("%s : %s", hostname, path);
+ else
+ cli_out ("Brick : %s:%s", hostname, path);
memset (key, 0, sizeof (key));
snprintf (key, sizeof (key), "brick%d.status", i);
@@ -4762,7 +4792,7 @@ out:
}
void
-cli_print_volume_status_fd (dict_t *dict)
+cli_print_volume_status_fd (dict_t *dict, gf_boolean_t nfs)
{
int ret = -1;
char *volname = NULL;
@@ -4799,7 +4829,11 @@ cli_print_volume_status_fd (dict_t *dict)
ret = dict_get_str (dict, key, &path);
if (ret)
goto out;
- cli_out ("Brick : %s:%s", hostname, path);
+
+ if (nfs)
+ cli_out ("%s : %s", hostname, path);
+ else
+ cli_out ("Brick : %s:%s", hostname, path);
memset (key, 0, sizeof (key));
snprintf (key, sizeof (key), "brick%d.status", i);
@@ -4976,7 +5010,7 @@ cli_print_volume_status_call_stack (dict_t *dict, char *prefix)
}
void
-cli_print_volume_status_callpool (dict_t *dict)
+cli_print_volume_status_callpool (dict_t *dict, gf_boolean_t nfs)
{
int ret = -1;
char *volname = NULL;
@@ -5013,7 +5047,11 @@ cli_print_volume_status_callpool (dict_t *dict)
ret = dict_get_str (dict, key, &path);
if (ret)
goto out;
- cli_out ("Brick : %s:%s", hostname, path);
+
+ if (nfs)
+ cli_out ("%s : %s", hostname, path);
+ else
+ cli_out ("Brick : %s:%s", hostname, path);
memset (key, 0, sizeof (key));
snprintf (key, sizeof (key), "brick%d.status", i);
@@ -5058,6 +5096,7 @@ gf_cli3_1_status_cbk (struct rpc_req *req, struct iovec *iov,
int i = 0;
int pid = -1;
uint32_t cmd = 0;
+ gf_boolean_t nfs = _gf_false;
char key[1024] = {0,};
char *hostname = NULL;
char *path = NULL;
@@ -5101,6 +5140,10 @@ gf_cli3_1_status_cbk (struct rpc_req *req, struct iovec *iov,
ret = 0;
goto out;
}
+
+ if (cmd & GF_CLI_STATUS_NFS)
+ nfs = _gf_true;
+
ret = dict_get_int32 (dict, "count", &count);
if (ret)
goto out;
@@ -5125,23 +5168,23 @@ gf_cli3_1_status_cbk (struct rpc_req *req, struct iovec *iov,
switch (cmd & GF_CLI_STATUS_MASK) {
case GF_CLI_STATUS_MEM:
- cli_print_volume_status_mem (dict);
+ cli_print_volume_status_mem (dict, nfs);
goto cont;
break;
case GF_CLI_STATUS_CLIENTS:
- cli_print_volume_status_clients (dict);
+ cli_print_volume_status_clients (dict, nfs);
goto cont;
break;
case GF_CLI_STATUS_INODE:
- cli_print_volume_status_inode (dict);
+ cli_print_volume_status_inode (dict, nfs);
goto cont;
break;
case GF_CLI_STATUS_FD:
- cli_print_volume_status_fd (dict);
+ cli_print_volume_status_fd (dict, nfs);
goto cont;
break;
case GF_CLI_STATUS_CALLPOOL:
- cli_print_volume_status_callpool (dict);
+ cli_print_volume_status_callpool (dict, nfs);
goto cont;
break;
default:
diff --git a/glusterfsd/src/glusterfsd-mgmt.c b/glusterfsd/src/glusterfsd-mgmt.c
index 57c664920..e45297d50 100644
--- a/glusterfsd/src/glusterfsd-mgmt.c
+++ b/glusterfsd/src/glusterfsd-mgmt.c
@@ -832,7 +832,7 @@ glusterfs_handle_brick_status (rpcsvc_request_t *req)
dict_t *output = NULL;
char *volname = NULL;
char *xname = NULL;
- int32_t cmd = 0;
+ uint32_t cmd = 0;
char *msg = NULL;
GF_ASSERT (req);
@@ -854,7 +854,7 @@ glusterfs_handle_brick_status (rpcsvc_request_t *req)
goto out;
}
- ret = dict_get_int32 (dict, "cmd", &cmd);
+ ret = dict_get_uint32 (dict, "cmd", &cmd);
if (ret) {
gf_log (this->name, GF_LOG_ERROR, "Couldn't get status op");
goto out;
@@ -959,6 +959,240 @@ glusterfs_command_done (int ret, call_frame_t *sync_frame, void *data)
}
int
+glusterfs_handle_nfs_status (rpcsvc_request_t *req)
+{
+ int ret = -1;
+ gd1_mgmt_brick_op_req nfs_req = {0,};
+ gd1_mgmt_brick_op_rsp rsp = {0,};
+ glusterfs_ctx_t *ctx = NULL;
+ glusterfs_graph_t *active = NULL;
+ xlator_t *any = NULL;
+ xlator_t *nfs = NULL;
+ xlator_t *subvol = NULL;
+ dict_t *dict = NULL;
+ dict_t *output = NULL;
+ char *volname = NULL;
+ uint32_t cmd = 0;
+ char *msg = NULL;
+
+ GF_ASSERT (req);
+
+ if (!xdr_to_generic (req->msg[0], &nfs_req,
+ (xdrproc_t)xdr_gd1_mgmt_brick_op_req)) {
+ req->rpc_err = GARBAGE_ARGS;
+ goto out;
+ }
+
+ dict = dict_new ();
+ ret = dict_unserialize (nfs_req.input.input_val,
+ nfs_req.input.input_len, &dict);
+ if (ret < 0) {
+ gf_log (THIS->name, GF_LOG_ERROR, "Failed to unserialize "
+ "req buffer to dictionary");
+ goto out;
+ }
+
+ ret = dict_get_uint32 (dict, "cmd", &cmd);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR, "Couldn't get status op");
+ goto out;
+ }
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR, "Couldn't get volname");
+ goto out;
+ }
+
+ ctx = glusterfs_ctx_get ();
+ GF_ASSERT (ctx);
+ active = ctx->active;
+ any = active->first;
+
+ nfs = xlator_search_by_name (any, "nfs-server");
+ if (!nfs) {
+ ret = -1;
+ gf_log (THIS->name, GF_LOG_ERROR, "nfs-server xlator is not"
+ " loaded");
+ goto out;
+ }
+
+ subvol = xlator_search_by_name (nfs, volname);
+ if (!subvol) {
+ ret = -1;
+ gf_log (THIS->name, GF_LOG_ERROR, "%s xlator is not loaded",
+ volname);
+ goto out;
+ }
+
+ output = dict_new ();
+ switch (cmd & GF_CLI_STATUS_MASK) {
+ case GF_CLI_STATUS_MEM:
+ ret = 0;
+ gf_proc_dump_mem_info_to_dict (output);
+ gf_proc_dump_mempool_info_to_dict (ctx, output);
+ break;
+
+ case GF_CLI_STATUS_CLIENTS:
+ ret = dict_set_str (output, "volname", volname);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR,
+ "Error setting volname to dict");
+ goto out;
+ }
+ ret = nfs->dumpops->priv_to_dict (nfs, output);
+ break;
+
+ case GF_CLI_STATUS_INODE:
+ ret = 0;
+ inode_table_dump_to_dict (subvol->itable, "conn0",
+ output);
+ ret = dict_set_int32 (output, "conncount", 1);
+ break;
+
+ case GF_CLI_STATUS_FD:
+ // cannot find fd-tables in nfs-server graph
+ // TODO: finish once found
+ break;
+
+ case GF_CLI_STATUS_CALLPOOL:
+ ret = 0;
+ gf_proc_dump_pending_frames_to_dict (ctx->pool, output);
+ break;
+
+ default:
+ ret = -1;
+ msg = gf_strdup ("Unknown status op");
+ gf_log (THIS->name, GF_LOG_ERROR, "%s", msg);
+ break;
+ }
+ rsp.op_ret = ret;
+ rsp.op_errno = 0;
+ if (ret && msg)
+ rsp.op_errstr = msg;
+ else
+ rsp.op_errstr = "";
+
+ ret = dict_allocate_and_serialize (output, &rsp.output.output_val,
+ (size_t *)&rsp.output.output_len);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR,
+ "Failed to serialize output dict to rsp");
+ goto out;
+ }
+
+ ret = glusterfs_submit_reply (req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gd1_mgmt_brick_op_rsp);
+
+out:
+ if (dict)
+ dict_unref (dict);
+ if (nfs_req.input.input_val)
+ free (nfs_req.input.input_val);
+ if (msg)
+ GF_FREE (msg);
+ if (rsp.output.output_val)
+ GF_FREE (rsp.output.output_val);
+
+ gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int
+glusterfs_handle_nfs_profile (rpcsvc_request_t *req)
+{
+ int ret = -1;
+ gd1_mgmt_brick_op_req nfs_req = {0,};
+ gd1_mgmt_brick_op_rsp rsp = {0,};
+ dict_t *dict = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+ glusterfs_graph_t *active = NULL;
+ xlator_t *any = NULL;
+ xlator_t *nfs = NULL;
+ xlator_t *subvol = NULL;
+ char *volname = NULL;
+ dict_t *output = NULL;
+
+ GF_ASSERT (req);
+
+ if (!xdr_to_generic (req->msg[0], &nfs_req,
+ (xdrproc_t)xdr_gd1_mgmt_brick_op_req)) {
+ req->rpc_err = GARBAGE_ARGS;
+ goto out;
+ }
+
+ dict = dict_new ();
+ ret = dict_unserialize (nfs_req.input.input_val,
+ nfs_req.input.input_len, &dict);
+ if (ret < 0) {
+ gf_log (THIS->name, GF_LOG_ERROR, "Failed to "
+ "unserialize req-buffer to dict");
+ goto out;
+ }
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR, "Couldn't get volname");
+ goto out;
+ }
+
+ ctx = glusterfs_ctx_get ();
+ GF_ASSERT (ctx);
+
+ active = ctx->active;
+ any = active->first;
+
+ // is this needed?
+ // are problems possible by searching for subvol directly from "any"?
+ nfs = xlator_search_by_name (any, "nfs-server");
+ if (!nfs) {
+ ret = -1;
+ gf_log (THIS->name, GF_LOG_ERROR, "xlator nfs-server is "
+ "not loaded");
+ goto out;
+ }
+
+ subvol = xlator_search_by_name (nfs, volname);
+ if (!subvol) {
+ ret = -1;
+ gf_log (THIS->name, GF_LOG_ERROR, "xlator %s is no loaded",
+ volname);
+ goto out;
+ }
+
+ output = dict_new ();
+ ret = subvol->notify (subvol, GF_EVENT_TRANSLATOR_INFO, dict, output);
+
+ rsp.op_ret = ret;
+ rsp.op_errno = 0;
+ rsp.op_errstr = "";
+
+ ret = dict_allocate_and_serialize (output, &rsp.output.output_val,
+ (size_t *)&rsp.output.output_len);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR,
+ "Failed to serialize ouput dict to rsp");
+ goto out;
+ }
+
+ ret = glusterfs_submit_reply (req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gd1_mgmt_brick_op_rsp);
+
+out:
+ if (nfs_req.input.input_val)
+ free (nfs_req.input.input_val);
+ if (dict)
+ dict_unref (dict);
+ if (output)
+ dict_unref (output);
+ if (rsp.output.output_val)
+ free (rsp.output.output_val);
+
+ gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int
glusterfs_handle_rpc_msg (rpcsvc_request_t *req)
{
int ret = -1;
@@ -987,6 +1221,11 @@ glusterfs_handle_rpc_msg (rpcsvc_request_t *req)
case GLUSTERD_BRICK_XLATOR_DEFRAG:
ret = glusterfs_handle_defrag (req);
break;
+ case GLUSTERD_NFS_PROFILE:
+ ret = glusterfs_handle_nfs_profile (req);
+ break;
+ case GLUSTERD_NFS_STATUS:
+ ret = glusterfs_handle_nfs_status (req);
default:
break;
}
@@ -1044,7 +1283,9 @@ rpcsvc_actor_t glusterfs_actors[] = {
[GLUSTERD_BRICK_XLATOR_INFO] = { "TRANSLATOR INFO", GLUSTERD_BRICK_XLATOR_INFO, glusterfs_handle_rpc_msg, NULL, NULL, 0},
[GLUSTERD_BRICK_XLATOR_OP] = { "TRANSLATOR OP", GLUSTERD_BRICK_XLATOR_OP, glusterfs_handle_rpc_msg, NULL, NULL, 0},
[GLUSTERD_BRICK_STATUS] = {"STATUS", GLUSTERD_BRICK_STATUS, glusterfs_handle_rpc_msg, NULL, NULL, 0},
- [GLUSTERD_BRICK_XLATOR_DEFRAG] = { "TRANSLATOR DEFRAG", GLUSTERD_BRICK_XLATOR_DEFRAG, glusterfs_handle_rpc_msg, NULL, NULL, 0}
+ [GLUSTERD_BRICK_XLATOR_DEFRAG] = { "TRANSLATOR DEFRAG", GLUSTERD_BRICK_XLATOR_DEFRAG, glusterfs_handle_rpc_msg, NULL, NULL, 0},
+ [GLUSTERD_NFS_PROFILE] = {"NFS PROFILE", GLUSTERD_NFS_PROFILE, glusterfs_handle_rpc_msg, NULL, NULL, 0},
+ [GLUSTERD_NFS_STATUS] = {"NFS STATUS", GLUSTERD_NFS_STATUS, glusterfs_handle_rpc_msg, NULL, NULL, 0}
};
struct rpcsvc_program glusterfs_mop_prog = {
diff --git a/rpc/rpc-lib/src/protocol-common.h b/rpc/rpc-lib/src/protocol-common.h
index cd7adde4e..0191c50aa 100644
--- a/rpc/rpc-lib/src/protocol-common.h
+++ b/rpc/rpc-lib/src/protocol-common.h
@@ -186,6 +186,8 @@ enum glusterd_brick_procnum {
GLUSTERD_BRICK_STATUS,
GLUSTERD_BRICK_OP,
GLUSTERD_BRICK_XLATOR_DEFRAG,
+ GLUSTERD_NFS_PROFILE,
+ GLUSTERD_NFS_STATUS,
GLUSTERD_BRICK_MAXVALUE,
};
diff --git a/rpc/xdr/src/cli1-xdr.h b/rpc/xdr/src/cli1-xdr.h
index 903b6ff72..979c2250f 100644
--- a/rpc/xdr/src/cli1-xdr.h
+++ b/rpc/xdr/src/cli1-xdr.h
@@ -166,6 +166,7 @@ enum gf_cli_status_type {
GF_CLI_STATUS_VOL = 0x100,
GF_CLI_STATUS_ALL = 0x200,
GF_CLI_STATUS_BRICK = 0x400,
+ GF_CLI_STATUS_NFS = 0x800,
};
typedef enum gf_cli_status_type gf_cli_status_type;
diff --git a/rpc/xdr/src/cli1-xdr.x b/rpc/xdr/src/cli1-xdr.x
index f45712ce0..72d2dbef4 100644
--- a/rpc/xdr/src/cli1-xdr.x
+++ b/rpc/xdr/src/cli1-xdr.x
@@ -110,7 +110,8 @@ enum gf_cli_status_type {
GF_CLI_STATUS_MASK = 0x0FF, /*000011111111 Used to get the op*/
GF_CLI_STATUS_VOL = 0x100, /*000100000000*/
GF_CLI_STATUS_ALL = 0x200, /*001000000000*/
- GF_CLI_STATUS_BRICK = 0x400 /*010000000000*/
+ GF_CLI_STATUS_BRICK = 0x400, /*010000000000*/
+ GF_CLI_STATUS_NFS = 0x800 /*100000000000*/
};
struct gf_cli_req {
diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c
index 4f9822db1..86bc0d7b1 100644
--- a/xlators/mgmt/glusterd/src/glusterd-handler.c
+++ b/xlators/mgmt/glusterd/src/glusterd-handler.c
@@ -2755,12 +2755,13 @@ glusterd_brick_rpc_notify (struct rpc_clnt *rpc, void *mydata,
}
int
-glusterd_shd_rpc_notify (struct rpc_clnt *rpc, void *mydata,
- rpc_clnt_event_t event,
- void *data)
+glusterd_nodesvc_rpc_notify (struct rpc_clnt *rpc, void *mydata,
+ rpc_clnt_event_t event,
+ void *data)
{
xlator_t *this = NULL;
glusterd_conf_t *conf = NULL;
+ char *server = NULL;
int ret = 0;
this = THIS;
@@ -2768,17 +2769,21 @@ glusterd_shd_rpc_notify (struct rpc_clnt *rpc, void *mydata,
conf = this->private;
GF_ASSERT (conf);
+ server = mydata;
+ if (!server)
+ return 0;
+
switch (event) {
case RPC_CLNT_CONNECT:
gf_log (this->name, GF_LOG_DEBUG, "got RPC_CLNT_CONNECT");
- (void) glusterd_shd_set_running (_gf_true);
+ (void) glusterd_nodesvc_set_running (server, _gf_true);
ret = default_notify (this, GF_EVENT_CHILD_UP, NULL);
break;
case RPC_CLNT_DISCONNECT:
gf_log (this->name, GF_LOG_DEBUG, "got RPC_CLNT_DISCONNECT");
- (void) glusterd_shd_set_running (_gf_false);
+ (void) glusterd_nodesvc_set_running (server, _gf_false);
break;
default:
diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
index bda5e61e4..46c02bff7 100644
--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c
+++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
@@ -245,6 +245,59 @@ out:
return ret;
}
+int
+glusterd_nfs_op_build_payload (glusterd_op_t op, gd1_mgmt_brick_op_req **req,
+ dict_t *dict)
+{
+ int ret = -1;
+ gd1_mgmt_brick_op_req *brick_req = NULL;
+
+ GF_ASSERT (op < GD_OP_MAX);
+ GF_ASSERT (op > GD_OP_NONE);
+ GF_ASSERT (req);
+
+ switch (op) {
+ case GD_OP_PROFILE_VOLUME:
+ brick_req = GF_CALLOC (1, sizeof (*brick_req),
+ gf_gld_mt_mop_brick_req_t);
+ if (!brick_req)
+ goto out;
+
+ brick_req->op = GLUSTERD_NFS_PROFILE;
+ brick_req->name = "";
+
+ break;
+
+ case GD_OP_STATUS_VOLUME:
+ brick_req = GF_CALLOC (1, sizeof (*brick_req),
+ gf_gld_mt_mop_brick_req_t);
+ if (!brick_req)
+ goto out;
+
+ brick_req->op = GLUSTERD_NFS_STATUS;
+ brick_req->name = "";
+
+ break;
+
+ default:
+ goto out;
+ }
+
+ ret = dict_allocate_and_serialize (dict, &brick_req->input.input_val,
+ (size_t*)&brick_req->input.input_len);
+
+ if (ret)
+ goto out;
+
+ *req = brick_req;
+ ret = 0;
+
+out:
+ if (ret && brick_req)
+ GF_FREE (brick_req);
+ gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
static int
glusterd_op_stage_set_volume (dict_t *dict, char **op_errstr)
@@ -1337,7 +1390,13 @@ glusterd_op_status_volume (dict_t *dict, char **op_errstr,
goto out;
}
- if ((cmd & GF_CLI_STATUS_BRICK) != 0) {
+ if ((cmd & GF_CLI_STATUS_NFS) != 0) {
+ ret = glusterd_add_node_to_dict ("nfs", rsp_dict, 0);
+ if (ret)
+ goto out;
+ brick_count = 1;
+
+ } else if ((cmd & GF_CLI_STATUS_BRICK) != 0) {
ret = dict_get_str (dict, "brick", &brick);
if (ret)
goto out;
@@ -1356,9 +1415,8 @@ glusterd_op_status_volume (dict_t *dict, char **op_errstr,
if (cmd & GF_CLI_STATUS_DETAIL)
glusterd_add_brick_detail_to_dict (volinfo, brickinfo,
rsp_dict, 0);
- ret = dict_set_int32 (rsp_dict, "count", 1);
+ brick_count = 1;
- goto out;
} else {
list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
brick_index++;
@@ -1387,6 +1445,51 @@ out:
}
static int
+glusterd_op_volume_dict_uuid_to_hostname (dict_t *dict, const char *key_fmt,
+ int idx_min, int idx_max)
+{
+ int ret = -1;
+ int i = 0;
+ char key[1024];
+ char *uuid_str = NULL;
+ uuid_t uuid = {0,};
+ char *hostname = NULL;
+
+ GF_ASSERT (dict);
+ GF_ASSERT (key_fmt);
+
+ for (i = idx_min; i < idx_max; i++) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), key_fmt, i);
+ ret = dict_get_str (dict, key, &uuid_str);
+ if (ret)
+ goto out;
+
+ ret = uuid_parse (uuid_str, uuid);
+ /* if parsing fails don't error out
+ * let the original value be retained
+ */
+ if (ret)
+ continue;
+
+ hostname = glusterd_uuid_to_hostname (uuid);
+ if (hostname) {
+ ret = dict_set_dynstr (dict, key, hostname);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR,
+ "Error setting hostname to dict");
+ GF_FREE (hostname);
+ goto out;
+ }
+ }
+ }
+
+out:
+ gf_log (THIS->name, 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;
@@ -1977,10 +2080,12 @@ out:
static int
glusterd_op_ac_rcvd_commit_op_acc (glusterd_op_sm_event_t *event, void *ctx)
{
- dict_t *dict = NULL;
+ dict_t *op_ctx = NULL;
int ret = 0;
gf_boolean_t commit_ack_inject = _gf_true;
glusterd_op_t op = GD_OP_NONE;
+ int count = 0;
+ uint32_t cmd = GF_CLI_STATUS_NONE;
op = glusterd_op_get_op ();
GF_ASSERT (event);
@@ -1992,15 +2097,15 @@ glusterd_op_ac_rcvd_commit_op_acc (glusterd_op_sm_event_t *event, void *ctx)
goto out;
if (op == GD_OP_REPLACE_BRICK) {
- dict = glusterd_op_get_ctx ();
- if (!dict) {
+ op_ctx = glusterd_op_get_ctx ();
+ if (!op_ctx) {
gf_log (THIS->name, GF_LOG_CRITICAL, "Operation "
"context is not present.");
ret = -1;
goto out;
}
- ret = glusterd_op_start_rb_timer (dict);
+ ret = glusterd_op_start_rb_timer (op_ctx);
if (ret) {
gf_log (THIS->name, GF_LOG_ERROR, "Couldn't start "
"replace-brick operation.");
@@ -2011,6 +2116,77 @@ glusterd_op_ac_rcvd_commit_op_acc (glusterd_op_sm_event_t *event, void *ctx)
goto out;
}
+ if (op == GD_OP_STATUS_VOLUME) {
+ op_ctx = glusterd_op_get_ctx();
+ if (!op_ctx) {
+ gf_log (THIS->name, GF_LOG_CRITICAL, "Operation "
+ "context is not present.");
+ ret = -1;
+ goto out;
+ }
+
+ ret = dict_get_uint32 (op_ctx, "cmd", &cmd);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR,
+ "Failed to get status cmd");
+ goto out;
+ }
+ if (!(cmd & GF_CLI_STATUS_NFS)) {
+ ret = 0;
+ goto out;
+ }
+
+ ret = dict_get_int32 (op_ctx, "count", &count);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR,
+ "Failed to get brick count");
+ goto out;
+ }
+
+ ret = glusterd_op_volume_dict_uuid_to_hostname (op_ctx,
+ "brick%d.path",
+ 0, count);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR,
+ "Failed uuid to hostname conversion");
+ ret = 0;
+ }
+
+ }
+
+ if (op == GD_OP_PROFILE_VOLUME) {
+ op_ctx = glusterd_op_get_ctx();
+ if (!op_ctx) {
+ gf_log (THIS->name, GF_LOG_CRITICAL, "Operation "
+ "context is not present.");
+ ret = -1;
+ goto out;
+ }
+
+ ret = dict_get_str_boolean (op_ctx, "nfs", _gf_false);
+ if (!ret) {
+ ret = 0;
+ goto out;
+ }
+
+ ret = dict_get_int32 (op_ctx, "count", &count);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR,
+ "Failed to get brick count");
+ goto out;
+ }
+
+ ret = glusterd_op_volume_dict_uuid_to_hostname (op_ctx,
+ "%d-brick",
+ 1, (count + 1));
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR,
+ "Failed uuid to hostname conversion");
+ ret = 0;
+ }
+
+ }
+
out:
if (commit_ack_inject) {
if (ret)
@@ -2534,21 +2710,29 @@ _profile_volume_add_brick_rsp (dict_t *this, char *key, data_t *value,
}
int
-glusterd_profile_volume_brick_rsp (glusterd_brickinfo_t *brickinfo,
+glusterd_profile_volume_brick_rsp (void *pending_entry,
dict_t *rsp_dict, dict_t *op_ctx,
- char **op_errstr)
+ char **op_errstr, gd_node_type type)
{
- int ret = 0;
- glusterd_pr_brick_rsp_conv_t rsp_ctx = {0};
- int32_t count = 0;
- char brick[PATH_MAX+1024] = {0};
- char key[256] = {0};
- char *full_brick = NULL;
+ int ret = 0;
+ glusterd_pr_brick_rsp_conv_t rsp_ctx = {0};
+ int32_t count = 0;
+ char brick[PATH_MAX+1024] = {0};
+ char key[256] = {0};
+ char *full_brick = NULL;
+ glusterd_brickinfo_t *brickinfo = NULL;
+ xlator_t *this = NULL;
+ glusterd_conf_t *priv = NULL;
GF_ASSERT (rsp_dict);
GF_ASSERT (op_ctx);
GF_ASSERT (op_errstr);
- GF_ASSERT (brickinfo);
+ GF_ASSERT (pending_entry);
+
+ this = THIS;
+ GF_ASSERT (this);
+ priv = this->private;
+ GF_ASSERT (priv);
ret = dict_get_int32 (op_ctx, "count", &count);
if (ret) {
@@ -2557,8 +2741,13 @@ glusterd_profile_volume_brick_rsp (glusterd_brickinfo_t *brickinfo,
count++;
}
snprintf (key, sizeof (key), "%d-brick", count);
- snprintf (brick, sizeof (brick), "%s:%s", brickinfo->hostname,
- brickinfo->path);
+ if (type == GD_NODE_BRICK) {
+ brickinfo = pending_entry;
+ snprintf (brick, sizeof (brick), "%s:%s", brickinfo->hostname,
+ brickinfo->path);
+ } else if (type == GD_NODE_NFS) {
+ snprintf (brick, sizeof (brick), "%s", uuid_utoa (priv->uuid));
+ }
full_brick = gf_strdup (brick);
GF_ASSERT (full_brick);
ret = dict_set_dynstr (op_ctx, key, full_brick);
@@ -2571,22 +2760,6 @@ glusterd_profile_volume_brick_rsp (glusterd_brickinfo_t *brickinfo,
return ret;
}
-void
-_status_volume_add_brick_rsp (dict_t *this, char *key, data_t *value,
- void *data)
-{
- char new_key[256] = {0,};
- data_t *new_value = 0;
- glusterd_pr_brick_rsp_conv_t *rsp_ctx = NULL;
-
- rsp_ctx = data;
- new_value = data_copy (value);
- snprintf (new_key, sizeof (new_key), "brick%d.%s", rsp_ctx->count, key);
- dict_set (rsp_ctx->dict, new_key, new_value);
-
- return;
-}
-
//input-key: <replica-id>:<child-id>-*
//output-key: <brick-id>-*
void
@@ -2675,9 +2848,24 @@ out:
return ret;
}
+void
+_status_volume_add_brick_rsp (dict_t *this, char *key, data_t *value,
+ void *data)
+{
+ char new_key[256] = {0,};
+ data_t *new_value = 0;
+ glusterd_pr_brick_rsp_conv_t *rsp_ctx = NULL;
+
+ rsp_ctx = data;
+ new_value = data_copy (value);
+ snprintf (new_key, sizeof (new_key), "brick%d.%s", rsp_ctx->count, key);
+ dict_set (rsp_ctx->dict, new_key, new_value);
+
+ return;
+}
+
int
-glusterd_status_volume_brick_rsp (glusterd_brickinfo_t *brickinfo,
- dict_t *rsp_dict, dict_t *op_ctx,
+glusterd_status_volume_brick_rsp (dict_t *rsp_dict, dict_t *op_ctx,
char **op_errstr)
{
int ret = 0;
@@ -2688,7 +2876,6 @@ glusterd_status_volume_brick_rsp (glusterd_brickinfo_t *brickinfo,
GF_ASSERT (rsp_dict);
GF_ASSERT (op_ctx);
GF_ASSERT (op_errstr);
- GF_ASSERT (brickinfo);
ret = dict_get_int32 (op_ctx, "count", &count);
if (ret) {
@@ -2704,6 +2891,7 @@ glusterd_status_volume_brick_rsp (glusterd_brickinfo_t *brickinfo,
rsp_ctx.count = index;
rsp_ctx.dict = op_ctx;
dict_foreach (rsp_dict, _status_volume_add_brick_rsp, &rsp_ctx);
+ ret = dict_set_int32 (op_ctx, "count", count);
out:
return ret;
@@ -2789,23 +2977,21 @@ out:
int32_t
glusterd_handle_node_rsp (glusterd_req_ctx_t *req_ctx, void *pending_entry,
glusterd_op_t op, dict_t *rsp_dict, dict_t *op_ctx,
- char **op_errstr)
+ char **op_errstr, gd_node_type type)
{
int ret = 0;
- glusterd_brickinfo_t *brickinfo = NULL;
GF_ASSERT (op_errstr);
switch (op) {
case GD_OP_PROFILE_VOLUME:
- brickinfo = pending_entry;
- ret = glusterd_profile_volume_brick_rsp (brickinfo, rsp_dict,
- op_ctx, op_errstr);
+ ret = glusterd_profile_volume_brick_rsp (pending_entry,
+ rsp_dict, op_ctx,
+ op_errstr, type);
break;
case GD_OP_STATUS_VOLUME:
- brickinfo = pending_entry;
- ret = glusterd_status_volume_brick_rsp (brickinfo, rsp_dict,
- op_ctx, op_errstr);
+ ret = glusterd_status_volume_brick_rsp (rsp_dict, op_ctx,
+ op_errstr);
break;
case GD_OP_DEFRAG_BRICK_VOLUME:
@@ -2987,6 +3173,30 @@ glusterd_bricks_select_profile_volume (dict_t *dict, char **op_errstr)
goto out;
break;
case GF_CLI_STATS_INFO:
+ ret = dict_get_str_boolean (dict, "nfs", _gf_false);
+ if (ret) {
+ if (!glusterd_nodesvc_is_running ("nfs")) {
+ ret = -1;
+ gf_log (this->name, GF_LOG_ERROR, "NFS server"
+ " is not running");
+ goto out;
+ }
+ pending_node = GF_CALLOC (1, sizeof (*pending_node),
+ gf_gld_mt_pending_node_t);
+ if (!pending_node) {
+ ret = -1;
+ goto out;
+ }
+ pending_node->node = priv->nfs;
+ pending_node->type = GD_NODE_NFS;
+ list_add_tail (&pending_node->list,
+ &opinfo.pending_bricks);
+ pending_node = NULL;
+
+ ret = 0;
+ goto out;
+
+ }
list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
if (glusterd_is_brick_started (brickinfo)) {
pending_node = GF_CALLOC (1, sizeof (*pending_node),
@@ -3006,6 +3216,30 @@ glusterd_bricks_select_profile_volume (dict_t *dict, char **op_errstr)
break;
case GF_CLI_STATS_TOP:
+ ret = dict_get_str_boolean (dict, "nfs", _gf_false);
+ if (ret) {
+ if (!glusterd_nodesvc_is_running ("nfs")) {
+ ret = -1;
+ gf_log (this->name, GF_LOG_ERROR, "NFS server"
+ " is not running");
+ goto out;
+ }
+ pending_node = GF_CALLOC (1, sizeof (*pending_node),
+ gf_gld_mt_pending_node_t);
+ if (!pending_node) {
+ ret = -1;
+ goto out;
+ }
+ pending_node->node = priv->nfs;
+ pending_node->type = GD_NODE_NFS;
+ list_add_tail (&pending_node->list,
+ &opinfo.pending_bricks);
+ pending_node = NULL;
+
+ ret = 0;
+ goto out;
+
+ }
ret = dict_get_str (dict, "brick", &brick);
if (!ret) {
ret = glusterd_volume_brickinfo_get_by_brick (brick, volinfo,
@@ -3308,7 +3542,7 @@ glusterd_bricks_select_status_volume (dict_t *dict, char **op_errstr)
ret = dict_get_int32 (dict, "cmd", &cmd);
if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Unable to get status type");
+ gf_log (this->name, GF_LOG_ERROR, "Unable to get status type");
goto out;
}
@@ -3321,13 +3555,14 @@ glusterd_bricks_select_status_volume (dict_t *dict, char **op_errstr)
case GF_CLI_STATUS_INODE:
case GF_CLI_STATUS_FD:
case GF_CLI_STATUS_CALLPOOL:
+ case GF_CLI_STATUS_NFS:
break;
default:
goto out;
}
ret = dict_get_str (dict, "volname", &volname);
if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Unable to get volname");
+ gf_log (this->name, GF_LOG_ERROR, "Unable to get volname");
goto out;
}
ret = glusterd_volinfo_find (volname, &volinfo);
@@ -3338,7 +3573,7 @@ glusterd_bricks_select_status_volume (dict_t *dict, char **op_errstr)
if ( (cmd & GF_CLI_STATUS_BRICK) != 0) {
ret = dict_get_str (dict, "brick", &brickname);
if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR,
+ gf_log (this->name, GF_LOG_ERROR,
"Unable to get brick");
goto out;
}
@@ -3365,6 +3600,25 @@ glusterd_bricks_select_status_volume (dict_t *dict, char **op_errstr)
list_add_tail (&pending_node->list, &opinfo.pending_bricks);
ret = 0;
+ } else if ((cmd & GF_CLI_STATUS_NFS) != 0) {
+ if (!glusterd_nodesvc_is_running ("nfs")) {
+ ret = -1;
+ gf_log (this->name, GF_LOG_ERROR,
+ "NFS server is not running");
+ goto out;
+ }
+ pending_node = GF_CALLOC (1, sizeof (*pending_node),
+ gf_gld_mt_pending_node_t);
+ if (!pending_node) {
+ ret = -1;
+ goto out;
+ }
+ pending_node->node = priv->nfs;
+ pending_node->type = GD_NODE_NFS;
+ pending_node->index = 0;
+ list_add_tail (&pending_node->list, &opinfo.pending_bricks);
+
+ ret = 0;
} else {
list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
brick_index++;
@@ -3444,6 +3698,7 @@ glusterd_op_ac_rcvd_brick_op_acc (glusterd_op_sm_event_t *event, void *ctx)
glusterd_op_brick_rsp_ctx_t *ev_ctx = NULL;
char *op_errstr = NULL;
glusterd_op_t op = GD_OP_NONE;
+ gd_node_type type = GD_NODE_NONE;
dict_t *op_ctx = NULL;
glusterd_req_ctx_t *req_ctx = NULL;
void *pending_entry = NULL;
@@ -3458,6 +3713,7 @@ glusterd_op_ac_rcvd_brick_op_acc (glusterd_op_sm_event_t *event, void *ctx)
op = req_ctx->op;
op_ctx = glusterd_op_get_ctx ();
pending_entry = ev_ctx->pending_node->node;
+ type = ev_ctx->pending_node->type;
ret = glusterd_remove_pending_entry (&opinfo.pending_bricks,
pending_entry);
@@ -3471,7 +3727,7 @@ glusterd_op_ac_rcvd_brick_op_acc (glusterd_op_sm_event_t *event, void *ctx)
opinfo.brick_pending_count--;
glusterd_handle_node_rsp (req_ctx, pending_entry, op, ev_ctx->rsp_dict,
- op_ctx, &op_errstr);
+ op_ctx, &op_errstr, type);
if (opinfo.brick_pending_count > 0)
goto out;
diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.h b/xlators/mgmt/glusterd/src/glusterd-op-sm.h
index b4df82017..cc2eacffd 100644
--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.h
+++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.h
@@ -162,6 +162,7 @@ typedef struct glusterd_heal_rsp_conv_ {
typedef struct glusterd_status_rsp_conv_ {
int count;
dict_t *dict;
+ gf_boolean_t nfs;
} glusterd_status_rsp_conv_t;
typedef struct glusterd_gsync_status_temp {
@@ -238,10 +239,13 @@ glusterd_op_bricks_select (glusterd_op_t op, dict_t *dict, char **op_errstr);
int
glusterd_brick_op_build_payload (glusterd_op_t op, glusterd_brickinfo_t *brickinfo,
gd1_mgmt_brick_op_req **req, dict_t *dict);
+int
+glusterd_nfs_op_build_payload (glusterd_op_t op, gd1_mgmt_brick_op_req **req,
+ dict_t *dict);
int32_t
-glusterd_handle_brick_rsp (glusterd_brickinfo_t *brickinfo,
- glusterd_op_t op, dict_t *rsp_dict, dict_t *ctx_dict,
- char **op_errstr);
+glusterd_handle_brick_rsp (void *pending_entry, glusterd_op_t op,
+ dict_t *rsp_dict, dict_t *ctx_dict, char **op_errstr,
+ gd_node_type type);
int32_t
glusterd_op_init_ctx (glusterd_op_t op);
int32_t
diff --git a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c
index 648ab418d..ef7a6a648 100644
--- a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c
+++ b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c
@@ -1011,16 +1011,25 @@ glusterd_volume_status_add_peer_rsp (dict_t *this, char *key, data_t *value,
{
glusterd_status_rsp_conv_t *rsp_ctx = NULL;
data_t *new_value = NULL;
+ char brick_key[1024] = {0,};
+ char new_key[1024] = {0,};
int32_t ret = 0;
- if (strcmp (key, "count") == 0)
+ if (!strcmp (key, "count") || !strcmp (key, "cmd"))
return;
rsp_ctx = data;
new_value = data_copy (value);
GF_ASSERT (new_value);
- ret = dict_set (rsp_ctx->dict, key, new_value);
+ if (rsp_ctx->nfs) {
+ sscanf (key, "brick%*d.%s", brick_key);
+ snprintf (new_key, sizeof (new_key), "brick%d.%s",
+ rsp_ctx->count, brick_key);
+ } else
+ strncpy (new_key, key, sizeof (new_key));
+
+ ret = dict_set (rsp_ctx->dict, new_key, new_value);
if (ret)
gf_log ("", GF_LOG_ERROR, "Unable to set key: %s in dict",
key);
@@ -1035,6 +1044,7 @@ glusterd_volume_status_use_rsp_dict (dict_t *rsp_dict)
glusterd_status_rsp_conv_t rsp_ctx = {0};
int32_t brick_count = 0;
int32_t count = 0;
+ int32_t cmd = 0;
dict_t *ctx_dict = NULL;
glusterd_op_t op = GD_OP_NONE;
@@ -1046,6 +1056,10 @@ glusterd_volume_status_use_rsp_dict (dict_t *rsp_dict)
goto out;
}
+ ret = dict_get_int32 (rsp_dict, "cmd", &cmd);
+ if (ret)
+ goto out;
+
op = glusterd_op_get_op ();
GF_ASSERT (GD_OP_STATUS_VOLUME == op);
ctx_dict = glusterd_op_get_ctx (op);
@@ -1053,6 +1067,11 @@ glusterd_volume_status_use_rsp_dict (dict_t *rsp_dict)
ret = dict_get_int32 (ctx_dict, "count", &count);
rsp_ctx.count = count;
rsp_ctx.dict = ctx_dict;
+ if (cmd & GF_CLI_STATUS_NFS)
+ rsp_ctx.nfs = _gf_true;
+ else
+ rsp_ctx.nfs = _gf_false;
+
dict_foreach (rsp_dict, glusterd_volume_status_add_peer_rsp, &rsp_ctx);
ret = dict_set_int32 (ctx_dict, "count", count + brick_count);
@@ -1833,10 +1852,17 @@ glusterd3_1_brick_op (call_frame_t *frame, xlator_t *this,
if (!dummy_frame)
continue;
- ret = glusterd_brick_op_build_payload (req_ctx->op,
- pending_node->node,
- (gd1_mgmt_brick_op_req **)&req,
- req_ctx->dict);
+ if (pending_node->type == GD_NODE_BRICK)
+ ret = glusterd_brick_op_build_payload
+ (req_ctx->op, pending_node->node,
+ (gd1_mgmt_brick_op_req **)&req,
+ req_ctx->dict);
+ else if (pending_node->type == GD_NODE_NFS)
+ ret = glusterd_nfs_op_build_payload
+ (req_ctx->op,
+ (gd1_mgmt_brick_op_req **)&req,
+ req_ctx->dict);
+
if (ret)
goto out;
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
index 58a894532..64b7ba9ad 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
@@ -2536,32 +2536,45 @@ glusterd_get_nodesvc_volfile (char *server, char *workdir,
}
void
-glusterd_shd_set_running (gf_boolean_t status)
+glusterd_nodesvc_set_running (char *server, gf_boolean_t status)
{
glusterd_conf_t *priv = NULL;
+ GF_ASSERT (server);
priv = THIS->private;
GF_ASSERT (priv);
GF_ASSERT (priv->shd);
+ GF_ASSERT (priv->nfs);
- priv->shd->running = status;
+ if (!strcmp("glustershd", server))
+ priv->shd->running = status;
+ else if (!strcmp ("nfs", server))
+ priv->nfs->running = status;
}
gf_boolean_t
-glusterd_shd_is_running ()
+glusterd_nodesvc_is_running (char *server)
{
glusterd_conf_t *conf = NULL;
+ gf_boolean_t running = _gf_false;
+ GF_ASSERT (server);
conf = THIS->private;
GF_ASSERT (conf);
GF_ASSERT (conf->shd);
+ GF_ASSERT (conf->nfs);
+
+ if (!strcmp (server, "glustershd"))
+ running = conf->shd->running;
+ else if (!strcmp (server, "nfs"))
+ running = conf->nfs->running;
- return conf->shd->running;
+ return running;
}
int32_t
-glusterd_shd_set_socket_filepath (char *rundir, uuid_t uuid,
- char *socketpath, int len)
+glusterd_nodesvc_set_socket_filepath (char *rundir, uuid_t uuid,
+ char *socketpath, int len)
{
char sockfilepath[PATH_MAX] = {0,};
char md5_str[PATH_MAX] = {0,};
@@ -2582,6 +2595,8 @@ glusterd_pending_node_get_rpc (glusterd_pending_node_t *pending_node)
glusterd_brickinfo_t *brickinfo = NULL;
nodesrv_t *shd = NULL;
glusterd_volinfo_t *volinfo = NULL;
+ nodesrv_t *nfs = NULL;
+
GF_VALIDATE_OR_GOTO (THIS->name, pending_node, out);
GF_VALIDATE_OR_GOTO (THIS->name, pending_node->node, out);
@@ -2598,6 +2613,10 @@ glusterd_pending_node_get_rpc (glusterd_pending_node_t *pending_node)
if (volinfo->defrag)
rpc = volinfo->defrag->rpc;
+ } else if (pending_node->type == GD_NODE_NFS) {
+ nfs = pending_node->node;
+ rpc = nfs->rpc;
+
} else {
GF_ASSERT (0);
}
@@ -2607,19 +2626,27 @@ out:
}
struct rpc_clnt*
-glusterd_shd_get_rpc (void)
+glusterd_nodesvc_get_rpc (char *server)
{
glusterd_conf_t *priv = NULL;
+ struct rpc_clnt *rpc = NULL;
+ GF_ASSERT (server);
priv = THIS->private;
GF_ASSERT (priv);
GF_ASSERT (priv->shd);
+ GF_ASSERT (priv->nfs);
+
+ if (!strcmp (server, "glustershd"))
+ rpc = priv->shd->rpc;
+ else if (!strcmp (server, "nfs"))
+ rpc = priv->nfs->rpc;
- return priv->shd->rpc;
+ return rpc;
}
int32_t
-glusterd_shd_set_rpc (struct rpc_clnt *rpc)
+glusterd_nodesvc_set_rpc (char *server, struct rpc_clnt *rpc)
{
int ret = 0;
xlator_t *this = NULL;
@@ -2630,14 +2657,18 @@ glusterd_shd_set_rpc (struct rpc_clnt *rpc)
priv = this->private;
GF_ASSERT (priv);
GF_ASSERT (priv->shd);
+ GF_ASSERT (priv->nfs);
- priv->shd->rpc = rpc;
+ if (!strcmp ("glustershd", server))
+ priv->shd->rpc = rpc;
+ else if (!strcmp ("nfs", server))
+ priv->nfs->rpc = rpc;
return ret;
}
int32_t
-glusterd_shd_connect (char *socketpath) {
+glusterd_nodesvc_connect (char *server, char *socketpath) {
int ret = 0;
dict_t *options = NULL;
struct rpc_clnt *rpc = NULL;
@@ -2646,17 +2677,17 @@ glusterd_shd_connect (char *socketpath) {
if (ret)
goto out;
ret = glusterd_rpc_create (&rpc, options,
- glusterd_shd_rpc_notify,
- NULL);
+ glusterd_nodesvc_rpc_notify,
+ server);
if (ret)
goto out;
- (void) glusterd_shd_set_rpc (rpc);
+ (void) glusterd_nodesvc_set_rpc (server, rpc);
out:
return ret;
}
int32_t
-glusterd_nodesvc_start (char *server, gf_boolean_t pmap_signin)
+glusterd_nodesvc_start (char *server)
{
int32_t ret = -1;
xlator_t *this = NULL;
@@ -2666,7 +2697,7 @@ glusterd_nodesvc_start (char *server, gf_boolean_t pmap_signin)
char logfile[PATH_MAX] = {0,};
char volfile[PATH_MAX] = {0,};
char rundir[PATH_MAX] = {0,};
- char shd_sockfpath[PATH_MAX] = {0,};
+ char sockfpath[PATH_MAX] = {0,};
char volfileid[256] = {0};
#ifdef DEBUG
char valgrind_logfile[PATH_MAX] = {0};
@@ -2702,16 +2733,11 @@ glusterd_nodesvc_start (char *server, gf_boolean_t pmap_signin)
server);
snprintf (volfileid, sizeof (volfileid), "gluster/%s", server);
- if (!strcmp (server, "glustershd")) {
- glusterd_shd_set_socket_filepath (rundir,
- priv->uuid,
- shd_sockfpath,
- sizeof (shd_sockfpath));
- }
+ glusterd_nodesvc_set_socket_filepath (rundir, priv->uuid,
+ sockfpath, sizeof (sockfpath));
runinit (&runner);
- //TODO: kp:change the assumption that shd is the one which signs in
- // use runner_add_args?
+
#ifdef DEBUG
if (priv->valgrind) {
snprintf (valgrind_logfile, PATH_MAX,
@@ -2725,27 +2751,19 @@ glusterd_nodesvc_start (char *server, gf_boolean_t pmap_signin)
}
#endif
- if (pmap_signin) {
- runner_add_args (&runner, SBIN_DIR"/glusterfs",
- "-s", "localhost",
- "--volfile-id", volfileid,
- "-p", pidfile,
- "-l", logfile,
- "-S", shd_sockfpath, NULL);
- } else {
- runner_add_args (&runner, SBIN_DIR"/glusterfs",
- "-f", volfile,
- "-p", pidfile,
- "-l", logfile, NULL);
- }
+ runner_add_args (&runner, SBIN_DIR"/glusterfs",
+ "-s", "localhost",
+ "--volfile-id", volfileid,
+ "-p", pidfile,
+ "-l", logfile,
+ "-S", sockfpath, NULL);
runner_log (&runner, "", GF_LOG_DEBUG,
"Starting the nfs/glustershd services");
ret = runner_run (&runner);
if (ret == 0) {
- if (pmap_signin)
- glusterd_shd_connect (shd_sockfpath);
+ glusterd_nodesvc_connect (server, sockfpath);
}
out:
return ret;
@@ -2754,13 +2772,13 @@ out:
int
glusterd_nfs_server_start ()
{
- return glusterd_nodesvc_start ("nfs", _gf_false);
+ return glusterd_nodesvc_start ("nfs");
}
int
glusterd_shd_start ()
{
- return glusterd_nodesvc_start ("glustershd", _gf_true);
+ return glusterd_nodesvc_start ("glustershd");
}
gf_boolean_t
@@ -2833,6 +2851,65 @@ glusterd_shd_stop ()
return glusterd_nodesvc_stop ("glustershd", SIGTERM);
}
+/* Only NFS server for now */
+int
+glusterd_add_node_to_dict (char *server, dict_t *dict, int count)
+{
+ int ret = -1;
+ glusterd_conf_t *priv = THIS->private;
+ char pidfile[PATH_MAX] = {0,};
+ gf_boolean_t running = _gf_false;
+ int pid = -1;
+ char key[1024] = {0,};
+
+ glusterd_get_nodesvc_pidfile (server, priv->workdir, pidfile,
+ sizeof (pidfile));
+ running = glusterd_is_service_running (pidfile, &pid);
+
+ /* For nfs servers setting
+ * brick<n>.hostname = "NFS server"
+ * brick<n>.path = uuid
+ * brick<n>.port = 0
+ *
+ * This might be confusing, but cli display's the name of
+ * the brick as hostname+path, so this will make more sense
+ * when output.
+ */
+ snprintf (key, sizeof (key), "brick%d.hostname", count);
+ ret = dict_set_str (dict, key, "NFS Server");
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.path", count);
+ ret = dict_set_dynstr (dict, key, gf_strdup (uuid_utoa (priv->uuid)));
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.port", count);
+ ret = dict_set_int32 (dict, key, 0);
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.pid", count);
+ ret = dict_set_int32 (dict, key, pid);
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "brick%d.status", count);
+ ret = dict_set_int32 (dict, key, running);
+ if (ret)
+ goto out;
+
+
+out:
+ gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
int
glusterd_remote_hostname_get (rpcsvc_request_t *req, char *remote_host, int len)
{
@@ -5030,3 +5107,32 @@ glusterd_restart_rebalance (glusterd_conf_t *conf)
}
return ret;
}
+
+/* Return hostname for given uuid if it exists
+ * else return NULL
+ */
+char *
+glusterd_uuid_to_hostname (uuid_t uuid)
+{
+ char *hostname = NULL;
+ glusterd_conf_t *priv = NULL;
+ glusterd_peerinfo_t *entry = NULL;
+
+ priv = THIS->private;
+ GF_ASSERT (priv);
+
+ if (!uuid_compare (priv->uuid, uuid)) {
+ hostname = gf_strdup ("localhost");
+ }
+ if (!list_empty (&priv->peers)) {
+ list_for_each_entry (entry, &priv->peers, uuid_list) {
+ if (!uuid_compare (entry->uuid, uuid)) {
+ hostname = gf_strdup (entry->hostname);
+ break;
+ }
+ }
+ }
+
+ return hostname;
+}
+
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h
index de6185753..7b5a387c2 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.h
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.h
@@ -193,26 +193,26 @@ int32_t
glusterd_shd_stop ();
int32_t
-glusterd_shd_set_socket_filepath (char *rundir, uuid_t uuid,
- char *socketpath, int len);
+glusterd_nodesvc_set_socket_filepath (char *rundir, uuid_t uuid,
+ char *socketpath, int len);
struct rpc_clnt*
glusterd_pending_node_get_rpc (glusterd_pending_node_t *pending_node);
struct rpc_clnt*
-glusterd_shd_get_rpc (void);
+glusterd_nodesvc_get_rpc (char *server);
int32_t
-glusterd_shd_set_rpc (struct rpc_clnt *rpc);
+glusterd_nodesvc_set_rpc (char *server, struct rpc_clnt *rpc);
int32_t
-glusterd_shd_connect (char *socketpath);
+glusterd_nodesvc_connect (char *server, char *socketpath);
void
-glusterd_shd_set_running (gf_boolean_t status);
+glusterd_nodesvc_set_running (char *server, gf_boolean_t status);
gf_boolean_t
-glusterd_shd_is_running ();
+glusterd_nodesvc_is_running (char *server);
int
glusterd_remote_hostname_get (rpcsvc_request_t *req,
@@ -413,4 +413,10 @@ glusterd_restart_rebalance (glusterd_conf_t *conf);
int32_t
glusterd_add_bricks_hname_path_to_dict (dict_t *dict);
+
+int
+glusterd_add_node_to_dict (char *server, dict_t *dict, int count);
+
+char *
+glusterd_uuid_to_hostname (uuid_t uuid);
#endif
diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
index 2d06ad834..ef338658b 100644
--- a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
+++ b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
@@ -1060,7 +1060,7 @@ glusterd_op_stage_heal_volume (dict_t *dict, char **op_errstr)
goto out;
}
- if (!glusterd_shd_is_running ()) {
+ if (!glusterd_nodesvc_is_running ("glustershd")) {
ret = -1;
snprintf (msg, sizeof (msg), "Self-heal daemon is not "
"running. Check self-heal daemon log file.");
diff --git a/xlators/mgmt/glusterd/src/glusterd.c b/xlators/mgmt/glusterd/src/glusterd.c
index 0f807ca57..3ffd7b8eb 100644
--- a/xlators/mgmt/glusterd/src/glusterd.c
+++ b/xlators/mgmt/glusterd/src/glusterd.c
@@ -928,6 +928,9 @@ init (xlator_t *this)
conf->shd = GF_CALLOC (1, sizeof (nodesrv_t),
gf_gld_mt_nodesrv_t);
GF_VALIDATE_OR_GOTO(this->name, conf->shd, out);
+ conf->nfs = GF_CALLOC (1, sizeof (nodesrv_t),
+ gf_gld_mt_nodesrv_t);
+ GF_VALIDATE_OR_GOTO(this->name, conf->nfs, out);
INIT_LIST_HEAD (&conf->peers);
INIT_LIST_HEAD (&conf->volumes);
@@ -964,7 +967,7 @@ init (xlator_t *this)
}
#endif
this->private = conf;
- (void) glusterd_shd_set_running (_gf_false);
+ (void) glusterd_nodesvc_set_running ("glustershd", _gf_false);
/* this->ctx->top = this;*/
ret = glusterd_uuid_init (first_time);
diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h
index e8193bba2..7a6ee653f 100644
--- a/xlators/mgmt/glusterd/src/glusterd.h
+++ b/xlators/mgmt/glusterd/src/glusterd.h
@@ -111,6 +111,7 @@ typedef struct {
char workdir[PATH_MAX];
rpcsvc_t *rpc;
nodesrv_t *shd;
+ nodesrv_t *nfs;
struct pmap_registry *pmap;
struct list_head volumes;
struct list_head xprt_list;
@@ -250,6 +251,7 @@ typedef enum gd_node_type_ {
GD_NODE_BRICK,
GD_NODE_SHD,
GD_NODE_REBALANCE,
+ GD_NODE_NFS,
} gd_node_type;
typedef struct glusterd_pending_node_ {
@@ -559,8 +561,8 @@ glusterd_brick_rpc_notify (struct rpc_clnt *rpc, void *mydata,
rpc_clnt_event_t event, void *data);
int
-glusterd_shd_rpc_notify (struct rpc_clnt *rpc, void *mydata,
- rpc_clnt_event_t event, void *data);
+glusterd_nodesvc_rpc_notify (struct rpc_clnt *rpc, void *mydata,
+ rpc_clnt_event_t event, void *data);
int
glusterd_rpc_create (struct rpc_clnt **rpc, dict_t *options,
diff --git a/xlators/nfs/server/src/nfs.c b/xlators/nfs/server/src/nfs.c
index ba68486bd..9a44c009a 100644
--- a/xlators/nfs/server/src/nfs.c
+++ b/xlators/nfs/server/src/nfs.c
@@ -827,12 +827,101 @@ nfs_forget (xlator_t *this, inode_t *inode)
return 0;
}
+gf_boolean_t
+_nfs_export_is_for_vol (char *exname, char *volname)
+{
+ gf_boolean_t ret = _gf_false;
+ char *tmp = NULL;
+
+ tmp = exname;
+ if (tmp[0] == '/')
+ tmp++;
+
+ if (!strcmp (tmp, volname))
+ ret = _gf_true;
+
+ return ret;
+}
+
+int
+nfs_priv_to_dict (xlator_t *this, dict_t *dict)
+{
+ int ret = -1;
+ struct nfs_state *priv = NULL;
+ struct mountentry *mentry = NULL;
+ char *volname = NULL;
+ char key[1024] = {0,};
+ int count = 0;
+
+ GF_VALIDATE_OR_GOTO (THIS->name, this, out);
+ GF_VALIDATE_OR_GOTO (THIS->name, dict, out);
+
+ priv = this->private;
+ GF_ASSERT (priv);
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Could not get volname");
+ goto out;
+ }
+
+ list_for_each_entry (mentry, &priv->mstate->mountlist, mlist) {
+ if (!_nfs_export_is_for_vol (mentry->exname, volname))
+ continue;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "client%d.hostname", count);
+ ret = dict_set_str (dict, key, mentry->hostname);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Error writing hostname to dict");
+ goto out;
+ }
+
+ /* No connection data available yet in nfs server.
+ * Hence, setting to 0 to prevent cli failing
+ */
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "client%d.bytesread", count);
+ ret = dict_set_uint64 (dict, key, 0);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Error writing bytes read to dict");
+ goto out;
+ }
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "client%d.byteswrite", count);
+ ret = dict_set_uint64 (dict, key, 0);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Error writing bytes write to dict");
+ goto out;
+ }
+
+ count++;
+ }
+
+ ret = dict_set_int32 (dict, "clientcount", count);
+ if (ret)
+ gf_log (this->name, GF_LOG_ERROR,
+ "Error writing client count to dict");
+
+out:
+ gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
struct xlator_cbks cbks = {
.forget = nfs_forget,
};
struct xlator_fops fops = { };
+struct xlator_dumpops dumpops = {
+ .priv_to_dict = nfs_priv_to_dict,
+};
+
/* TODO: If needed, per-volume options below can be extended to be export
+ * specific also because after export-dir is introduced, a volume is not
+ * neccessarily an export whereas different subdirectories within that volume