diff options
author | Krutika Dhananjay <kdhananj@redhat.com> | 2013-09-24 17:01:46 +0530 |
---|---|---|
committer | Anand Avati <avati@redhat.com> | 2013-10-08 23:13:16 -0700 |
commit | e51ca3c1c991416895e1e8693f7c3e6332d57464 (patch) | |
tree | 1d77373831ba8129eaaa3e6c257702062591f6e3 /cli/src | |
parent | 11bb1fc5849a557d1a26e59bd651fbd0d07a1b8d (diff) |
cli,glusterd: Implement 'volume status tasks'
oVirt's Gluster Integration needs an inexpensive command that can be
executed every 10 seconds to monitor async tasks and their parameters,
for all volumes.
The solution involves adding a 'tasks' sub-command to 'volume status'
to fetch only the async task IDs, type and other relevant parameters.
Only the originator glusterd participates in this command as all the
information needed is available on all the nodes. This is to make the
command suitable for being executed every 10 seconds.
Change-Id: I1edc607baf29b001a5585079dec681d7c641b3d1
BUG: 1012346
Signed-off-by: Krutika Dhananjay <kdhananj@redhat.com>
Reviewed-on: http://review.gluster.org/6006
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Kaushal M <kaushal@redhat.com>
Diffstat (limited to 'cli/src')
-rw-r--r-- | cli/src/cli-cmd-parser.c | 19 | ||||
-rw-r--r-- | cli/src/cli-cmd-volume.c | 2 | ||||
-rw-r--r-- | cli/src/cli-rpc-ops.c | 155 | ||||
-rw-r--r-- | cli/src/cli-xml-output.c | 31 | ||||
-rw-r--r-- | cli/src/cli.h | 2 |
5 files changed, 156 insertions, 53 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index 33a6c0104b0..62f5c3723a7 100644 --- a/cli/src/cli-cmd-parser.c +++ b/cli/src/cli-cmd-parser.c @@ -2182,7 +2182,7 @@ 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", NULL}; + "inode", "callpool", "tasks", NULL}; struct { char *opname; uint32_t opcode; @@ -2193,6 +2193,7 @@ cli_cmd_get_statusop (const char *arg) { "fd", GF_CLI_STATUS_FD }, { "inode", GF_CLI_STATUS_INODE }, { "callpool", GF_CLI_STATUS_CALLPOOL }, + { "tasks", GF_CLI_STATUS_TASKS }, { NULL } }; @@ -2307,8 +2308,9 @@ cli_cmd_volume_status_parse (const char **words, int wordcount, if (!strcmp (words[3], "nfs")) { if (cmd == GF_CLI_STATUS_FD || - cmd == GF_CLI_STATUS_DETAIL) { - cli_err ("Detail/FD status not available" + cmd == GF_CLI_STATUS_DETAIL || + cmd == GF_CLI_STATUS_TASKS) { + cli_err ("Detail/FD/Tasks status not available" " for NFS Servers"); ret = -1; goto out; @@ -2317,14 +2319,21 @@ cli_cmd_volume_status_parse (const char **words, int wordcount, } else if (!strcmp (words[3], "shd")){ if (cmd == GF_CLI_STATUS_FD || cmd == GF_CLI_STATUS_CLIENTS || - cmd == GF_CLI_STATUS_DETAIL) { - cli_err ("Detail/FD/Clients status not " + cmd == GF_CLI_STATUS_DETAIL || + cmd == GF_CLI_STATUS_TASKS) { + cli_err ("Detail/FD/Clients/Tasks status not " "available for Self-heal Daemons"); ret = -1; goto out; } cmd |= GF_CLI_STATUS_SHD; } else { + if (cmd == GF_CLI_STATUS_TASKS) { + cli_err ("Tasks status not available for " + "bricks"); + ret = -1; + goto out; + } cmd |= GF_CLI_STATUS_BRICK; ret = dict_set_str (dict, "brick", (char *)words[3]); } diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c index 040f610adca..56ad65ebb58 100644 --- a/cli/src/cli-cmd-volume.c +++ b/cli/src/cli-cmd-volume.c @@ -1914,7 +1914,7 @@ struct cli_cmd volume_cmds[] = { "volume top operations"}, { "volume status [all | <VOLNAME> [nfs|shd|<BRICK>]]" - " [detail|clients|mem|inode|fd|callpool]", + " [detail|clients|mem|inode|fd|callpool|tasks]", 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 f9605c10492..5dddbb41bb0 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -6299,43 +6299,57 @@ out: return; } - static void -cli_print_volume_tasks (dict_t *dict) { - int ret = -1; - int tasks = 0; - char *op = 0; - char *task_id_str = NULL; - int status = 0; - char key[1024] = {0,}; - int i = 0; +cli_print_volume_status_tasks (dict_t *dict) +{ + int ret = -1; + int i = 0; + int j = 0; + int count = 0; + int task_count = 0; + int status = 0; + char *op = NULL; + char *task_id_str = NULL; + char *volname = NULL; + char key[1024] = {0,}; + char task[1024] = {0,}; + char *brick = NULL; + char *src_brick = NULL; + char *dest_brick = NULL; - ret = dict_get_int32 (dict, "tasks", &tasks); + ret = dict_get_str (dict, "volname", &volname); + if (ret) + goto out; + + ret = dict_get_int32 (dict, "tasks", &task_count); if (ret) { - gf_log ("cli", GF_LOG_ERROR, - "Failed to get tasks count"); + gf_log ("cli", GF_LOG_ERROR, "Failed to get tasks count"); return; } - if (tasks == 0) { + cli_out ("Task Status of Volume %s", volname); + cli_print_line (CLI_BRICK_STATUS_LINE_LEN); + + if (task_count == 0) { cli_out ("There are no active volume tasks"); + cli_out (" "); return; } - cli_out ("%15s%40s%15s", "Task", "ID", "Status"); - cli_out ("%15s%40s%15s", "----", "--", "------"); - for (i = 0; i < tasks; i++) { + for (i = 0; i < task_count; i++) { memset (key, 0, sizeof (key)); snprintf (key, sizeof (key), "task%d.type", i); ret = dict_get_str(dict, key, &op); if (ret) return; + cli_out ("%-20s : %-20s", "Task", op); memset (key, 0, sizeof (key)); snprintf (key, sizeof (key), "task%d.id", i); ret = dict_get_str (dict, key, &task_id_str); if (ret) return; + cli_out ("%-20s : %-20s", "ID", task_id_str); memset (key, 0, sizeof (key)); snprintf (key, sizeof (key), "task%d.status", i); @@ -6343,22 +6357,63 @@ cli_print_volume_tasks (dict_t *dict) { if (ret) return; + snprintf (task, sizeof (task), "task%d", i); + /* Replace brick only has two states - In progress and Complete Ref: xlators/mgmt/glusterd/src/glusterd-replace-brick.c */ + if (!strcmp (op, "Replace brick")) { - if (status) { - status = GF_DEFRAG_STATUS_COMPLETE; - } else { - status = GF_DEFRAG_STATUS_STARTED; - } - } + if (status) + status = GF_DEFRAG_STATUS_COMPLETE; + else + status = GF_DEFRAG_STATUS_STARTED; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.src-brick", task); + ret = dict_get_str (dict, key, &src_brick); + if (ret) + goto out; + + cli_out ("%-20s : %-20s", "Source Brick", src_brick); - cli_out ("%15s%40s%15s", op, task_id_str, + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.dst-brick", task); + ret = dict_get_str (dict, key, &dest_brick); + if (ret) + goto out; + + cli_out ("%-20s : %-20s", "Destination Brick", + dest_brick); + + } else if (!strcmp (op, "Remove brick")) { + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.count", task); + ret = dict_get_int32 (dict, key, &count); + if (ret) + goto out; + + cli_out ("%-20s", "Removed bricks:"); + + for (j = 1; j <= count; j++) { + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key),"%s.brick%d", + task, j); + ret = dict_get_str (dict, key, &brick); + if (ret) + goto out; + + cli_out ("%-20s", brick); + } + } + cli_out ("%-20s : %-20s", "Status", cli_vol_task_status_str[status]); + cli_out (" "); } +out: + return; } static int @@ -6462,23 +6517,6 @@ gf_cli_status_cbk (struct rpc_req *req, struct iovec *iov, if ((cmd & GF_CLI_STATUS_NFS) || (cmd & GF_CLI_STATUS_SHD)) notbrick = _gf_true; - ret = dict_get_int32 (dict, "count", &count); - if (ret) - goto out; - if (count == 0) { - ret = -1; - goto out; - } - - ret = dict_get_int32 (dict, "brick-index-max", &brick_index_max); - if (ret) - goto out; - ret = dict_get_int32 (dict, "other-count", &other_count); - if (ret) - goto out; - - index_max = brick_index_max + other_count; - if (global_state->mode & GLUSTER_MODE_XML) { if (!local->all) { ret = cli_xml_output_vol_status_begin (local, @@ -6491,11 +6529,21 @@ gf_cli_status_cbk (struct rpc_req *req, struct iovec *iov, goto out; } } - ret = cli_xml_output_vol_status (local, dict); - if (ret) { - gf_log ("cli", GF_LOG_ERROR, - "Error outputting to xml"); - goto out; + if (cmd & GF_CLI_STATUS_TASKS) { + ret = cli_xml_output_vol_status_tasks_detail (local, + dict); + if (ret) { + gf_log ("cli", GF_LOG_ERROR,"Error outputting " + "to xml"); + goto out; + } + } else { + ret = cli_xml_output_vol_status (local, dict); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, + "Error outputting to xml"); + goto out; + } } if (!local->all) { @@ -6531,6 +6579,10 @@ gf_cli_status_cbk (struct rpc_req *req, struct iovec *iov, cli_print_volume_status_callpool (dict, notbrick); goto cont; break; + case GF_CLI_STATUS_TASKS: + cli_print_volume_status_tasks (dict); + goto cont; + break; default: break; } @@ -6539,6 +6591,17 @@ gf_cli_status_cbk (struct rpc_req *req, struct iovec *iov, if (ret) goto out; + ret = dict_get_int32 (dict, "brick-index-max", &brick_index_max); + if (ret) + goto out; + + ret = dict_get_int32 (dict, "other-count", &other_count); + if (ret) + goto out; + + index_max = brick_index_max + other_count; + + cli_out ("Status of volume: %s", volname); if ((cmd & GF_CLI_STATUS_DETAIL) == 0) { @@ -6612,7 +6675,7 @@ gf_cli_status_cbk (struct rpc_req *req, struct iovec *iov, cli_out (" "); if ((cmd & GF_CLI_STATUS_MASK) == GF_CLI_STATUS_NONE) - cli_print_volume_tasks (dict); + cli_print_volume_status_tasks (dict); cont: ret = rsp.op_ret; diff --git a/cli/src/cli-xml-output.c b/cli/src/cli-xml-output.c index 6cc734a18ea..cc021a34d64 100644 --- a/cli/src/cli-xml-output.c +++ b/cli/src/cli-xml-output.c @@ -1564,6 +1564,36 @@ out: gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret); return ret; } + +int +cli_xml_output_vol_status_tasks_detail (cli_local_t *local, dict_t *dict) +{ + int ret = -1; + char *volname = NULL; + + /*<volume>*/ + ret = xmlTextWriterStartElement (local->writer, (xmlChar *)"volume"); + XML_RET_CHECK_AND_GOTO (ret, out); + + ret = dict_get_str (dict, "volname", &volname); + if (ret) + goto out; + ret = xmlTextWriterWriteFormatElement (local->writer, + (xmlChar *)"volName", "%s", + volname); + XML_RET_CHECK_AND_GOTO (ret, out); + + ret = cli_xml_output_vol_status_tasks (local, dict); + if (ret) + goto out; + + /* </volume> */ + ret = xmlTextWriterEndElement (local->writer); + XML_RET_CHECK_AND_GOTO (ret, out); + +out: + return ret; +} #endif int @@ -1683,7 +1713,6 @@ cli_xml_output_vol_status (cli_local_t *local, dict_t *dict) goto out; } break; - default: break; diff --git a/cli/src/cli.h b/cli/src/cli.h index 5a491eba7a4..a36c1606f58 100644 --- a/cli/src/cli.h +++ b/cli/src/cli.h @@ -393,6 +393,8 @@ cli_xml_output_generic_volume (char *op, dict_t *dict, int op_ret, int op_errno, int cli_xml_output_vol_gsync (dict_t *dict, int op_ret, int op_errno, char *op_errstr); +int +cli_xml_output_vol_status_tasks_detail (cli_local_t *local, dict_t *dict); char * is_server_debug_xlator (void *myframe); |