diff options
author | Kaushal M <kaushal@gluster.com> | 2011-09-05 14:33:43 +0530 |
---|---|---|
committer | Vijay Bellur <vijay@gluster.com> | 2011-09-27 06:45:10 -0700 |
commit | 45172a5415abc6b2f17eea74d51805ac85cc0072 (patch) | |
tree | e2576cf6cda22bd0f3109bc358c51fb419f3a390 /xlators/mgmt/glusterd/src/glusterd-volume-ops.c | |
parent | 16b7e3bf201686ca03f8c35c20295e05abe52df8 (diff) |
cli : new volume statedump command
Changes:
1. Add a new 'volume statedump' command, that performs statedumps of
all the bricks in the volume and saves them in a specified location.
2. Add new server option 'server.statedump-path'.
3. Remove multiple function definitions in glusterd.h
Statedump Information:
The 'volume statedump' command performs statedumps on all the bricks in
a given volume. The syntax of the command is,
gluster volume statedump <VOLNAME> [type]......
Types include,
* all
* mem
* iobuf
* callpool
* priv
* fd
* inode
Defaults to 'all' when no type is specified.
The statedump files are created by default in /tmp directory of the
server on which the bricks are present.
This path can be changed by setting the 'server.statedump-path' option.
The statedump files will be named as,
<brick-name>.<pid of brick process>.dump
Change-Id: I01c0e1a8aad490da818e086d89f292bd2ed06fd4
BUG: 1964
Reviewed-on: http://review.gluster.com/321
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Amar Tumballi <amar@gluster.com>
Diffstat (limited to 'xlators/mgmt/glusterd/src/glusterd-volume-ops.c')
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-volume-ops.c | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c index 816ef9b184e..21e7973863a 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c @@ -447,6 +447,65 @@ out: return ret; } +int +glusterd_handle_cli_statedump_volume (rpcsvc_request_t *req) +{ + int32_t ret = -1; + gf1_cli_statedump_vol_req cli_req = {0,}; + char *dup_volname = NULL; + char *dup_options = NULL; + dict_t *dict = NULL; + + GF_ASSERT (req); + + ret = -1; + if (!xdr_to_generic (req->msg[0], &cli_req, + (xdrproc_t)xdr_gf1_cli_statedump_vol_req)) { + req->rpc_err = GARBAGE_ARGS; + goto out; + } + gf_log ("glusterd", GF_LOG_INFO, "Recieved statedump request for " + "volume %s with options %s", cli_req.volname, cli_req.options); + dict = dict_new (); + + if (!dict) + goto out; + + dup_volname = gf_strdup (cli_req.volname); + if (!dup_volname) + goto out; + ret = dict_set_dynstr (dict, "volname", dup_volname); + if (ret) + goto out; + + dup_options = gf_strdup(cli_req.options); + if (!dup_volname) + goto out; + ret = dict_set_dynstr (dict, "options", dup_options); + if (ret) + goto out; + + ret = dict_set_int32 (dict, "option_cnt", cli_req.option_cnt); + if (ret) + goto out; + + ret = glusterd_op_begin (req, GD_OP_STATEDUMP_VOLUME, dict); + + gf_cmd_log ("statedump", "on volume %s %s", cli_req.volname, + ((0 == ret) ? "SUCCEEDED" : "FAILED")); + +out: + if (ret && dict) + dict_unref (dict); + if (cli_req.volname) + free (cli_req.volname); + if (cli_req.options) + free (cli_req.options); + glusterd_friend_sm (); + glusterd_op_sm(); + + return ret; +} /* op-sm */ int @@ -610,6 +669,37 @@ out: } int +glusterd_op_statedump_volume_args_get (dict_t *dict, char **volname, + char **options, int *option_cnt) +{ + int ret = -1; + + if (!dict || !volname || !options || !option_cnt) + goto out; + + ret = dict_get_str (dict, "volname", volname); + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to get volname"); + goto out; + } + + ret = dict_get_str (dict, "options", options); + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to get options"); + goto out; + } + + ret = dict_get_int32 (dict, "option_cnt", option_cnt); + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to get option count"); + goto out; + } + +out: + return ret; +} + +int glusterd_op_stage_start_volume (dict_t *dict, char **op_errstr) { int ret = 0; @@ -905,6 +995,46 @@ out: } int +glusterd_op_stage_statedump_volume (dict_t *dict, char **op_errstr) +{ + int ret = -1; + char *volname = NULL; + char *options = NULL; + int option_cnt = 0; + gf_boolean_t is_running = _gf_false; + glusterd_volinfo_t *volinfo = NULL; + char msg[2408] = {0,}; + + ret = glusterd_op_statedump_volume_args_get (dict, &volname, &options, + &option_cnt); + if (ret) + goto out; + + ret = glusterd_volinfo_find (volname, &volinfo); + if (ret) { + snprintf (msg, sizeof(msg), "Volume %s does not exist", + volname); + gf_log ("", GF_LOG_ERROR, "%s", msg); + *op_errstr = gf_strdup (msg); + goto out; + } + + is_running = glusterd_is_volume_started (volinfo); + if (!is_running) { + snprintf (msg, sizeof(msg), "Volume %s is not in a started" + " state", volname); + gf_log ("", GF_LOG_ERROR, "%s", msg); + *op_errstr = gf_strdup (msg); + ret = -1; + goto out; + } + +out: + gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); + return ret; +} + +int glusterd_op_create_volume (dict_t *dict, char **op_errstr) { int ret = 0; @@ -1204,3 +1334,34 @@ glusterd_op_heal_volume (dict_t *dict, char **op_errstr) return ret; } + +int +glusterd_op_statedump_volume (dict_t *dict) +{ + int ret = 0; + char *volname = NULL; + char *options = NULL; + int option_cnt = 0; + glusterd_volinfo_t *volinfo = NULL; + glusterd_brickinfo_t *brickinfo = NULL; + + ret = glusterd_op_statedump_volume_args_get (dict, &volname, &options, + &option_cnt); + if (ret) + goto out; + + ret = glusterd_volinfo_find (volname, &volinfo); + if (ret) + goto out; + gf_log ("", GF_LOG_DEBUG, "Performing statedump on volume %s", volname); + list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { + ret = glusterd_brick_statedump (volinfo, brickinfo, options, + option_cnt); + if (ret) + goto out; + } + +out: + return ret; +} + |