From 623919a78a7faac30d1f0df5793681da2c449e32 Mon Sep 17 00:00:00 2001 From: Kaushal M Date: Sun, 1 Jan 2012 15:59:28 +0530 Subject: cli: Extend "volume status" with statedump info This patch enhances and extends the "volume status" command with information obtained from the statedump of the bricks of volumes. Adds new status types : clients, inode, fd, mem, callpool The new syntax of "volume status" is, #gluster volume status [all|{ [] [misc-details|clients|inode|fd|mem|callpool]}] Change-Id: I8d019718465bbc3de727653a839de7238f45da5c BUG: 765495 Signed-off-by: Kaushal M Reviewed-on: http://review.gluster.com/2637 Tested-by: Gluster Build System Reviewed-by: Krishnan Parthasarathi --- cli/src/cli-cmd-parser.c | 90 +++-- cli/src/cli-cmd-volume.c | 3 +- cli/src/cli-rpc-ops.c | 891 ++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 960 insertions(+), 24 deletions(-) (limited to 'cli') diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index acbd960ba43..afd668ea2d2 100644 --- a/cli/src/cli-cmd-parser.c +++ b/cli/src/cli-cmd-parser.c @@ -1795,6 +1795,42 @@ out: return ret; } +gf_boolean_t +cli_cmd_validate_statusop (const char *arg) +{ + char *opwords[] = {"misc-details", "mem", "clients", "fd", "inode", + "callpool", NULL}; + char *w = NULL; + + w = str_getunamb (arg, opwords); + if (!w) { + gf_log ("cli", GF_LOG_ERROR, "Unknown status op %s", + arg); + return _gf_false; + } + return _gf_true; +} + +int +cli_cmd_get_statusop (const char *arg) +{ + int ret = GF_CLI_STATUS_INVAL; + if (!strcmp (arg, "misc-details")) + ret = GF_CLI_STATUS_DETAIL; + else if (!strcmp (arg, "mem")) + ret = GF_CLI_STATUS_MEM; + else if (!strcmp (arg, "clients")) + ret = GF_CLI_STATUS_CLIENTS; + else if (!strcmp (arg, "inode")) + ret = GF_CLI_STATUS_INODE; + else if (!strcmp (arg, "fd")) + ret = GF_CLI_STATUS_FD; + else if (!strcmp (arg, "callpool")) + ret = GF_CLI_STATUS_CALLPOOL; + + return ret; +} + int cli_cmd_volume_status_parse (const char **words, int wordcount, dict_t **options) @@ -1821,12 +1857,6 @@ cli_cmd_volume_status_parse (const char **words, int wordcount, cmd = GF_CLI_STATUS_ALL; ret = 0; - - } else if (!strcmp (words[2], "detail")) { - - cmd = GF_CLI_STATUS_ALL_DETAIL; - ret = 0; - } else { cmd = GF_CLI_STATUS_VOL; ret = dict_set_str (dict, "volname", (char *)words[2]); @@ -1834,34 +1864,50 @@ cli_cmd_volume_status_parse (const char **words, int wordcount, break; case 4: - if (!strcmp (words[2], "all") && - !strcmp (words[3], "detail")) { - - cmd = GF_CLI_STATUS_ALL_DETAIL; - ret = 0; - - } else if (!strcmp (words[3], "detail")) { - cmd = GF_CLI_STATUS_VOL_DETAIL; - ret = dict_set_str (dict, "volname", (char *)words[2]); - + if (!strcmp (words[2], "all")) { + cli_out ("Cannot specify brick/status-type for \"all\""); + ret = -1; + goto out; } else { - - cmd = GF_CLI_STATUS_BRICK; + cmd = GF_CLI_STATUS_VOL; ret = dict_set_str (dict, "volname", (char *)words[2]); if (ret) goto out; + } + + if (cli_cmd_validate_statusop (words[3])) { + ret = cli_cmd_get_statusop (words[3]); + if (GF_CLI_STATUS_INVAL == ret) + goto out; + cmd |= ret; + ret = 0; + } else { + cmd = GF_CLI_STATUS_BRICK; ret = dict_set_str (dict, "brick", (char *)words[3]); } break; case 5: - if (strcmp (words[4], "detail")) + if (!cli_cmd_validate_statusop (words[4])) { + ret = -1; goto out; + } - cmd = GF_CLI_STATUS_BRICK_DETAIL; - ret = dict_set_str (dict, "volname", (char *)words[2]); - if (ret) + cmd = GF_CLI_STATUS_BRICK; + ret = cli_cmd_get_statusop (words[4]); + if (GF_CLI_STATUS_INVAL == ret) + goto out; + cmd |= ret; + + if (!strcmp (words[2], "all")) { + cli_out ("Cannot specify brick/status-type for \"all\""); + ret = -1; goto out; + } else { + ret = dict_set_str (dict, "volname", (char *)words[2]); + if (ret) + goto out; + } ret = dict_set_str (dict, "brick", (char *)words[3]); break; diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c index a572bdc3f48..0168628dd0d 100644 --- a/cli/src/cli-cmd-volume.c +++ b/cli/src/cli-cmd-volume.c @@ -1740,7 +1740,8 @@ struct cli_cmd volume_cmds[] = { cli_cmd_volume_top_cbk, "volume top operations"}, - { "volume status [all|] [brick] [detail]", + { "volume status [all|{ [] " + "[misc-details|clients|mem|inode|fd|callpool]}]", cli_cmd_volume_status_cbk, "display status of specified volume"}, diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c index bb6cd07541a..6a212919c32 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -3807,6 +3807,869 @@ out: return ret; } +void +cli_print_volume_status_mempool (dict_t *dict, char *prefix) +{ + int ret = -1; + int32_t mempool_count = 0; + char *name = NULL; + int32_t hotcount = 0; + int32_t coldcount = 0; + uint64_t paddedsizeof = 0; + uint64_t alloccount = 0; + int32_t maxalloc = 0; + char key[1024] = {0,}; + int i = 0; + + GF_ASSERT (dict); + GF_ASSERT (prefix); + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.mempool-count",prefix); + ret = dict_get_int32 (dict, key, &mempool_count); + if (ret) + goto out; + + cli_out ("Mempool Stats\n-------------"); + cli_out ("%-30s %9s %9s %12s %10s %8s", "Name", "HotCount","ColdCount", + "PaddedSizeof", "AllocCount", "MaxAlloc"); + cli_out ("%-30s %9s %9s %12s %10s %8s", "----", "--------", "---------", + "------------", "----------", "--------"); + + for (i = 0; i < mempool_count; i++) { + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.pool%d.name", prefix, i); + ret = dict_get_str (dict, key, &name); + if (ret) + goto out; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.pool%d.hotcount", prefix, i); + ret = dict_get_int32 (dict, key, &hotcount); + if (ret) + goto out; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.pool%d.coldcount", prefix, i); + ret = dict_get_int32 (dict, key, &coldcount); + if (ret) + goto out; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.pool%d.paddedsizeof", + prefix, i); + ret = dict_get_uint64 (dict, key, &paddedsizeof); + if (ret) + goto out; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.pool%d.alloccount", prefix, i); + ret = dict_get_uint64 (dict, key, &alloccount); + if (ret) + goto out; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.pool%d.max_alloc", prefix, i); + ret = dict_get_int32 (dict, key, &maxalloc); + if (ret) + goto out; + + cli_out ("%-30s %9d %9d %12"PRIu64" %10"PRIu64" %8d", name, + hotcount, coldcount, paddedsizeof, alloccount, + maxalloc); + } + +out: + return; + +} + +void +cli_print_volume_status_mem (dict_t *dict) +{ + int ret = -1; + char *volname = NULL; + char *hostname = NULL; + char *path = NULL; + int online = -1; + char key[1024] = {0,}; + int brick_count = 0; + int val = 0; + int i = 0; + + GF_ASSERT (dict); + + ret = dict_get_str (dict, "volname", &volname); + if (ret) + goto out; + cli_out ("Memory status for volume : %s", volname); + + ret = dict_get_int32 (dict, "count", &brick_count); + if (ret) + goto out; + + for (i = 0; i < brick_count; i++) { + cli_out ("----------------------------------------------"); + + 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; + cli_out ("Brick : %s:%s", hostname, path); + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "brick%d.status", i); + ret = dict_get_int32 (dict, key, &online); + if (ret) + goto out; + if (!online) { + cli_out ("Brick is offline"); + continue; + } + + cli_out ("Mallinfo\n--------"); + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "brick%d.mallinfo.arena", i); + ret = dict_get_int32 (dict, key, &val); + if (ret) + goto out; + cli_out ("%-8s : %d","Arena", val); + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "brick%d.mallinfo.ordblks", i); + ret = dict_get_int32 (dict, key, &val); + if(ret) + goto out; + cli_out ("%-8s : %d","Ordblks", val); + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "brick%d.mallinfo.smblks", i); + ret = dict_get_int32 (dict, key, &val); + if(ret) + goto out; + cli_out ("%-8s : %d","Smblks", val); + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "brick%d.mallinfo.hblks", i); + ret = dict_get_int32 (dict, key, &val); + if(ret) + goto out; + cli_out ("%-8s : %d", "Hblks", val); + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "brick%d.mallinfo.hblkhd", i); + ret = dict_get_int32 (dict, key, &val); + if (ret) + goto out; + cli_out ("%-8s : %d", "Hblkhd", val); + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "brick%d.mallinfo.usmblks", i); + ret = dict_get_int32 (dict, key, &val); + if (ret) + goto out; + cli_out ("%-8s : %d", "Usmblks", val); + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "brick%d.mallinfo.fsmblks", i); + ret = dict_get_int32 (dict, key, &val); + if (ret) + goto out; + cli_out ("%-8s : %d", "Fsmblks", val); + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "brick%d.mallinfo.uordblks", i); + ret = dict_get_int32 (dict, key, &val); + if (ret) + goto out; + cli_out ("%-8s : %d", "Uordblks", val); + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "brick%d.mallinfo.fordblks", i); + ret = dict_get_int32 (dict, key, &val); + if (ret) + goto out; + cli_out ("%-8s : %d", "Fordblks", val); + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "brick%d.mallinfo.keepcost", i); + ret = dict_get_int32 (dict, key, &val); + if (ret) + goto out; + cli_out ("%-8s : %d", "Keepcost", val); + + cli_out (" "); + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "brick%d", i); + cli_print_volume_status_mempool (dict, key); + } +out: + cli_out ("----------------------------------------------\n"); + return; +} + +void +cli_print_volume_status_clients (dict_t *dict) +{ + int ret = -1; + char *volname = NULL; + int brick_count = 0; + char *hostname = NULL; + char *path = NULL; + int online = -1; + int client_count = 0; + char *clientname = NULL; + uint64_t bytesread = 0; + uint64_t byteswrite = 0; + char key[1024] = {0,}; + int i = 0; + int j = 0; + + 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, "count", &brick_count); + if (ret) + goto out; + + for ( i = 0; i < brick_count; i++) { + cli_out ("----------------------------------------------"); + + 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; + cli_out ("Brick : %s:%s", hostname, path); + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "brick%d.status", i); + ret = dict_get_int32 (dict, key, &online); + if (ret) + goto out; + if (!online) { + cli_out ("Brick is offline"); + continue; + } + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "brick%d.clientcount", i); + ret = dict_get_int32 (dict, key, &client_count); + if (ret) + goto out; + + cli_out ("Clients connected : %d", client_count); + cli_out ("%-48s %15s %15s", "Hostname", "BytesRead", + "BytesWritten"); + cli_out ("%-48s %15s %15s", "--------", "---------", + "------------"); + for (j =0; j < client_count; j++) { + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), + "brick%d.client%d.hostname", i, j); + ret = dict_get_str (dict, key, &clientname); + if (ret) + goto out; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), + "brick%d.client%d.bytesread", i, j); + ret = dict_get_uint64 (dict, key, &bytesread); + if (ret) + goto out; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), + "brick%d.client%d.byteswrite", i, j); + ret = dict_get_uint64 (dict, key, &byteswrite); + if (ret) + goto out; + + cli_out ("%-48s %15"PRIu64" %15"PRIu64, + clientname, bytesread, byteswrite); + } + } +out: + cli_out ("----------------------------------------------\n"); + return; +} + +void +cli_print_volume_status_inode_entry (dict_t *dict, char *prefix) +{ + int ret = -1; + char key[1024] = {0,}; + char *gfid = NULL; + uint64_t nlookup = 0; + uint32_t ref = 0; + int ia_type = 0; + + GF_ASSERT (dict); + GF_ASSERT (prefix); + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.gfid", prefix); + ret = dict_get_str (dict, key, &gfid); + if (ret) + goto out; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.nlookup", prefix); + ret = dict_get_uint64 (dict, key, &nlookup); + if (ret) + goto out; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.ref", prefix); + ret = dict_get_uint32 (dict, key, &ref); + if (ret) + goto out; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.ia_type", prefix); + ret = dict_get_int32 (dict, key, &ia_type); + if (ret) + goto out; + + cli_out ("%-40s %14"PRIu64" %14"PRIu32" %9d", + gfid, nlookup, ref, ia_type); + +out: + return; + +} + +void +cli_print_volume_status_itables (dict_t *dict, char *prefix) +{ + int ret = -1; + char key[1024] = {0,}; + uint32_t active_size = 0; + uint32_t lru_size = 0; + uint32_t purge_size = 0; + int i =0; + + GF_ASSERT (dict); + GF_ASSERT (prefix); + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.active_size", prefix); + ret = dict_get_uint32 (dict, key, &active_size); + if (ret) + goto out; + if (active_size != 0) { + cli_out ("Active inodes:"); + cli_out ("%-40s %14s %14s %9s", "GFID", "Lookups", "Ref", + "IA type"); + cli_out ("%-40s %14s %14s %9s", "----", "-------", "---", + "-------"); + } + for (i = 0; i < active_size; i++) { + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.active%d", prefix, i); + cli_print_volume_status_inode_entry (dict, key); + } + cli_out (" "); + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.lru_size", prefix); + ret = dict_get_uint32 (dict, key, &lru_size); + if (ret) + goto out; + if (lru_size != 0) { + cli_out ("LRU inodes:"); + cli_out ("%-40s %14s %14s %9s", "GFID", "Lookups", "Ref", + "IA type"); + cli_out ("%-40s %14s %14s %9s", "----", "-------", "---", + "-------"); + } + for (i = 0; i < lru_size; i++) { + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.lru%d", prefix, i); + cli_print_volume_status_inode_entry (dict, key); + } + cli_out (" "); + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.purge_size", prefix); + ret = dict_get_uint32 (dict, key, &purge_size); + if (ret) + goto out; + if (purge_size != 0) { + cli_out ("Purged inodes:"); + cli_out ("%-40s %14s %14s %9s", "GFID", "Lookups", "Ref", + "IA type"); + cli_out ("%-40s %14s %14s %9s", "----", "-------", "---", + "-------"); + } + for (i = 0; i < purge_size; i++) { + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.purge%d", prefix, i); + cli_print_volume_status_inode_entry (dict, key); + } + +out: + return; +} + +void +cli_print_volume_status_inode (dict_t *dict) +{ + int ret = -1; + char *volname = NULL; + int brick_count = 0; + char *hostname = NULL; + char *path = NULL; + int online = -1; + int conn_count = 0; + char key[1024] = {0,}; + int i = 0; + int j = 0; + + GF_ASSERT (dict); + + ret = dict_get_str (dict, "volname", &volname); + if (ret) + goto out; + cli_out ("Inode tables for volume %s", volname); + + ret = dict_get_int32 (dict, "count", &brick_count); + if (ret) + goto out; + + for (i = 0; i < brick_count; i++) { + cli_out ("----------------------------------------------"); + + 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; + cli_out ("Brick : %s:%s", hostname, path); + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "brick%d.status", i); + ret = dict_get_int32 (dict, key, &online); + if (ret) + goto out; + if (!online) { + cli_out ("Brick is offline"); + continue; + } + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "brick%d.conncount", i); + ret = dict_get_int32 (dict, key, &conn_count); + if (ret) + goto out; + + for (j = 0; j < conn_count; j++) { + if (conn_count > 1) + cli_out ("Connection %d:", j+1); + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "brick%d.conn%d.itable", + i, j); + cli_print_volume_status_itables (dict, key); + cli_out (" "); + } + } +out: + cli_out ("----------------------------------------------"); + return; +} + +void +cli_print_volume_status_fdtable (dict_t *dict, char *prefix) +{ + int ret = -1; + char key[1024] = {0,}; + int refcount = 0; + uint32_t maxfds = 0; + int firstfree = 0; + int openfds = 0; + int fd_pid = 0; + int fd_refcount = 0; + int fd_flags = 0; + int i = 0; + + GF_ASSERT (dict); + GF_ASSERT (prefix); + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.refcount", prefix); + ret = dict_get_int32 (dict, key, &refcount); + if (ret) + goto out; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.maxfds", prefix); + ret = dict_get_uint32 (dict, key, &maxfds); + if (ret) + goto out; + + memset (key, 0 ,sizeof (key)); + snprintf (key, sizeof (key), "%s.firstfree", prefix); + ret = dict_get_int32 (dict, key, &firstfree); + if (ret) + goto out; + + cli_out ("RefCount = %d MaxFDs = %d FirstFree = %d", + refcount, maxfds, firstfree); + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.openfds", prefix); + ret = dict_get_int32 (dict, key, &openfds); + if (ret) + goto out; + if (0 == openfds) { + cli_out ("No open fds"); + goto out; + } + + cli_out ("%-19s %-19s %-19s %-19s", "FD Entry", "PID", + "RefCount", "Flags"); + cli_out ("%-19s %-19s %-19s %-19s", "--------", "---", + "--------", "-----"); + + for (i = 0; i < maxfds ; i++) { + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.fdentry%d.pid", prefix, i); + ret = dict_get_int32 (dict, key, &fd_pid); + if (ret) + continue; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.fdentry%d.refcount", + prefix, i); + ret = dict_get_int32 (dict, key, &fd_refcount); + if (ret) + continue; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.fdentry%d.flags", prefix, i); + ret = dict_get_int32 (dict, key, &fd_flags); + if (ret) + continue; + + cli_out ("%-19d %-19d %-19d %-19d", i, fd_pid, fd_refcount, + fd_flags); + } + +out: + return; +} + +void +cli_print_volume_status_fd (dict_t *dict) +{ + int ret = -1; + char *volname = NULL; + int brick_count = 0; + char *hostname = NULL; + char *path = NULL; + int online = -1; + int conn_count = 0; + char key[1024] = {0,}; + int i = 0; + int j = 0; + + GF_ASSERT (dict); + + ret = dict_get_str (dict, "volname", &volname); + if (ret) + goto out; + cli_out ("FD tables for volume %s", volname); + + ret = dict_get_int32 (dict, "count", &brick_count); + if (ret) + goto out; + + for (i = 0; i < brick_count; i++) { + cli_out ("----------------------------------------------"); + + 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; + cli_out ("Brick : %s:%s", hostname, path); + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "brick%d.status", i); + ret = dict_get_int32 (dict, key, &online); + if (ret) + goto out; + if (!online) { + cli_out ("Brick is offline"); + continue; + } + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "brick%d.conncount", i); + ret = dict_get_int32 (dict, key, &conn_count); + if (ret) + goto out; + + for (j = 0; j < conn_count; j++) { + cli_out ("Connection %d:", j+1); + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "brick%d.conn%d.fdtable", + i, j); + cli_print_volume_status_fdtable (dict, key); + cli_out (" "); + } + } +out: + cli_out ("----------------------------------------------"); + return; +} + +void +cli_print_volume_status_call_frame (dict_t *dict, char *prefix) +{ + int ret = -1; + char key[1024] = {0,}; + int ref_count = 0; + char *translator = 0; + int complete = 0; + char *parent = NULL; + char *wind_from = NULL; + char *wind_to = NULL; + char *unwind_from = NULL; + char *unwind_to = NULL; + + if (!dict || !prefix) + return; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.refcount", prefix); + ret = dict_get_int32 (dict, key, &ref_count); + if (ret) + return; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.translator", prefix); + ret = dict_get_str (dict, key, &translator); + if (ret) + return; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.complete", prefix); + ret = dict_get_int32 (dict, key, &complete); + if (ret) + return; + + cli_out (" Ref Count = %d", ref_count); + cli_out (" Translator = %s", translator); + cli_out (" Completed = %s", (complete ? "Yes" : "No")); + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.parent", prefix); + ret = dict_get_str (dict, key, &parent); + if (!ret) + cli_out (" Parent = %s", parent); + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.windfrom", prefix); + ret = dict_get_str (dict, key, &wind_from); + if (!ret) + cli_out (" Wind From = %s", wind_from); + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.windto", prefix); + ret = dict_get_str (dict, key, &wind_to); + if (!ret) + cli_out (" Wind To = %s", wind_to); + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.unwindfrom", prefix); + ret = dict_get_str (dict, key, &unwind_from); + if (!ret) + cli_out (" Unwind From = %s", unwind_from); + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.unwindto", prefix); + ret = dict_get_str (dict, key, &unwind_to); + if (!ret) + cli_out (" Unwind To = %s", unwind_to); +} + +void +cli_print_volume_status_call_stack (dict_t *dict, char *prefix) +{ + int ret = -1; + char key[1024] = {0,}; + int uid = 0; + int gid = 0; + int pid = 0; + uint64_t unique = 0; + //char *op = NULL; + int count = 0; + int i = 0; + + if (!dict || !prefix) + return; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.uid", prefix); + ret = dict_get_int32 (dict, key, &uid); + if (ret) + return; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.gid", prefix); + ret = dict_get_int32 (dict, key, &gid); + if (ret) + return; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.pid", prefix); + ret = dict_get_int32 (dict, key, &pid); + if (ret) + return; + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.unique", prefix); + ret = dict_get_uint64 (dict, key, &unique); + if (ret) + return; + + /* + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.op", prefix); + ret = dict_get_str (dict, key, &op); + if (ret) + return; + */ + + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.count", prefix); + ret = dict_get_int32 (dict, key, &count); + if (ret) + return; + + cli_out (" UID : %d", uid); + cli_out (" GID : %d", gid); + cli_out (" PID : %d", pid); + cli_out (" Unique : %"PRIu64, unique); + //cli_out ("\tOp : %s", op); + cli_out (" Frames : %d", count); + + for (i = 0; i < count; i++) { + cli_out (" Frame %d", i+1); + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s.frame%d", prefix, i); + cli_print_volume_status_call_frame (dict, key); + } + + cli_out (" "); +} + +void +cli_print_volume_status_callpool (dict_t *dict) +{ + int ret = -1; + char *volname = NULL; + int brick_count = 0; + char *hostname = NULL; + char *path = NULL; + int online = -1; + int call_count = 0; + char key[1024] = {0,}; + int i = 0; + int j = 0; + + GF_ASSERT (dict); + + ret = dict_get_str (dict, "volname", &volname); + if (ret) + goto out; + cli_out ("Pending calls for volume %s", volname); + + ret = dict_get_int32 (dict, "count", &brick_count); + if (ret) + goto out; + + for (i = 0; i < brick_count; i++) { + cli_out ("----------------------------------------------"); + + 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; + cli_out ("Brick : %s:%s", hostname, path); + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "brick%d.status", i); + ret = dict_get_int32 (dict, key, &online); + if (ret) + goto out; + if (!online) { + cli_out ("Brick is offline"); + continue; + } + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "brick%d.callpool.count", i); + ret = dict_get_int32 (dict, key, &call_count); + if (ret) + goto out; + cli_out ("Pending calls: %d", call_count); + + if (0 == call_count) + continue; + + for (j = 0; j < call_count; j++) { + cli_out ("Call Stack%d", j+1); + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), + "brick%d.callpool.stack%d", i, j); + cli_print_volume_status_call_stack (dict, key); + } + } + +out: + cli_out ("----------------------------------------------"); + return; +} + static int gf_cli3_1_status_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) @@ -3869,6 +4732,31 @@ gf_cli3_1_status_cbk (struct rpc_req *req, struct iovec *iov, status.brick = GF_CALLOC (1, PATH_MAX + 256, gf_common_mt_strdup); + switch (cmd & GF_CLI_STATUS_MASK) { + case GF_CLI_STATUS_MEM: + cli_print_volume_status_mem (dict); + goto cont; + break; + case GF_CLI_STATUS_CLIENTS: + cli_print_volume_status_clients (dict); + goto cont; + break; + case GF_CLI_STATUS_INODE: + cli_print_volume_status_inode (dict); + goto cont; + break; + case GF_CLI_STATUS_FD: + cli_print_volume_status_fd (dict); + goto cont; + break; + case GF_CLI_STATUS_CALLPOOL: + cli_print_volume_status_callpool (dict); + goto cont; + break; + default: + break; + } + ret = dict_get_str (dict, "volname", &volname); if (ret) goto out; @@ -3934,9 +4822,10 @@ gf_cli3_1_status_cbk (struct rpc_req *req, struct iovec *iov, } } +cont: ret = rsp.op_ret; - out: +out: if (status.brick) GF_FREE (status.brick); -- cgit