diff options
| -rw-r--r-- | cli/src/cli-cmd-parser.c | 90 | ||||
| -rw-r--r-- | cli/src/cli-cmd-volume.c | 3 | ||||
| -rw-r--r-- | cli/src/cli-rpc-ops.c | 891 | ||||
| -rw-r--r-- | glusterfsd/src/glusterfsd-mgmt.c | 139 | ||||
| -rw-r--r-- | libglusterfs/src/fd.c | 92 | ||||
| -rw-r--r-- | libglusterfs/src/inode.c | 96 | ||||
| -rw-r--r-- | libglusterfs/src/stack.c | 188 | ||||
| -rw-r--r-- | libglusterfs/src/stack.h | 3 | ||||
| -rw-r--r-- | libglusterfs/src/statedump.c | 110 | ||||
| -rw-r--r-- | libglusterfs/src/statedump.h | 8 | ||||
| -rw-r--r-- | libglusterfs/src/xlator.h | 27 | ||||
| -rw-r--r-- | rpc/rpc-lib/src/protocol-common.h | 1 | ||||
| -rw-r--r-- | rpc/xdr/src/cli1-xdr.h | 20 | ||||
| -rw-r--r-- | rpc/xdr/src/cli1-xdr.x | 20 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-op-sm.c | 233 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-rpc-ops.c | 22 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd.h | 1 | ||||
| -rw-r--r-- | xlators/protocol/server/src/server.c | 139 | 
18 files changed, 2008 insertions, 75 deletions
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|<VOLNAME>] [brick] [detail]", +        { "volume status [all|{<VOLNAME> [<BRICKNAME>] " +          "[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); diff --git a/glusterfsd/src/glusterfsd-mgmt.c b/glusterfsd/src/glusterfsd-mgmt.c index 9e98190ba1f..558ab165161 100644 --- a/glusterfsd/src/glusterfsd-mgmt.c +++ b/glusterfsd/src/glusterfsd-mgmt.c @@ -45,6 +45,7 @@  #include "glusterfsd-mem-types.h"  #include "rpcsvc.h"  #include "cli1-xdr.h" +#include "statedump.h"  static char is_mgmt_rpc_reconnect; @@ -736,6 +737,138 @@ out:  }  int +glusterfs_handle_brick_status (rpcsvc_request_t *req) +{ +        int                     ret = -1; +        gd1_mgmt_brick_op_req   brick_req = {0,}; +        gd1_mgmt_brick_op_rsp   rsp = {0,}; +        glusterfs_ctx_t         *ctx = NULL; +        glusterfs_graph_t       *active = NULL; +        xlator_t                *this = NULL; +        xlator_t                *any = NULL; +        xlator_t                *xlator = NULL; +        dict_t                  *dict = NULL; +        dict_t                  *output = NULL; +        char                    *volname = NULL; +        char                    *xname = NULL; +        int32_t                 cmd = 0; +        char                    *msg = NULL; + +        GF_ASSERT (req); +        this = THIS; +        GF_ASSERT (this); + +        if (!xdr_to_generic (req->msg[0], &brick_req, +            (xdrproc_t)xdr_gd1_mgmt_brick_op_req)) { +                req->rpc_err = GARBAGE_ARGS; +                goto out; +        } + +        dict = dict_new (); +        ret = dict_unserialize (brick_req.input.input_val, +                                brick_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_int32 (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; + +        ret = gf_asprintf (&xname, "%s-server", volname); +        if (-1 == ret) { +                gf_log (this->name, GF_LOG_ERROR, "Out of memory"); +                goto out; +        } + +        xlator = xlator_search_by_name (any, xname); +        if (!xlator) { +                gf_log (this->name, GF_LOG_ERROR, "xlator %s is not loaded", +                        xname); +                ret = -1; +                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 = xlator->dumpops->priv_to_dict (xlator, output); +                        break; + +                case GF_CLI_STATUS_INODE: +                        ret = xlator->dumpops->inode_to_dict (xlator, output); +                        break; + +                case GF_CLI_STATUS_FD: +                        ret = xlator->dumpops->fd_to_dict (xlator, output); +                        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"); +                        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 (brick_req.input.input_val) +                free (brick_req.input.input_val); +        if (xname) +                GF_FREE (xname); +        if (msg) +                GF_FREE (msg); +        if (rsp.output.output_val) +                GF_FREE (rsp.output.output_val); + +        return ret; +} + +int  glusterfs_handle_rpc_msg (rpcsvc_request_t *req)  {          int     ret = -1; @@ -751,6 +884,9 @@ glusterfs_handle_rpc_msg (rpcsvc_request_t *req)          case GLUSTERD_BRICK_XLATOR_HEAL:                  ret = glusterfs_handle_translator_heal (req);                  break; +        case GLUSTERD_BRICK_STATUS: +                ret = glusterfs_handle_brick_status (req); +                break;          default:                  break;          } @@ -806,7 +942,8 @@ rpcsvc_actor_t glusterfs_actors[] = {          [GLUSTERD_BRICK_NULL]        = { "NULL",    GLUSTERD_BRICK_NULL, glusterfs_handle_rpc_msg, NULL, NULL, 0},          [GLUSTERD_BRICK_TERMINATE] = { "TERMINATE", GLUSTERD_BRICK_TERMINATE, glusterfs_handle_rpc_msg, NULL, NULL, 0},          [GLUSTERD_BRICK_XLATOR_INFO] = { "TRANSLATOR INFO", GLUSTERD_BRICK_XLATOR_INFO, glusterfs_handle_rpc_msg, NULL, NULL, 0}, -        [GLUSTERD_BRICK_XLATOR_HEAL] = { "TRANSLATOR HEAL", GLUSTERD_BRICK_XLATOR_HEAL, glusterfs_handle_rpc_msg, NULL, NULL, 0} +        [GLUSTERD_BRICK_XLATOR_HEAL] = { "TRANSLATOR HEAL", GLUSTERD_BRICK_XLATOR_HEAL, glusterfs_handle_rpc_msg, NULL, NULL, 0}, +        [GLUSTERD_BRICK_STATUS] = {"STATUS", GLUSTERD_BRICK_STATUS, glusterfs_handle_rpc_msg, NULL, NULL, 0}  };  struct rpcsvc_program glusterfs_mop_prog = { diff --git a/libglusterfs/src/fd.c b/libglusterfs/src/fd.c index 50a564ee6df..62a70c457e7 100644 --- a/libglusterfs/src/fd.c +++ b/libglusterfs/src/fd.c @@ -905,3 +905,95 @@ out:          return;  } + +void +fdentry_dump_to_dict (fdentry_t *fdentry, char *prefix, dict_t *dict, +                      int *openfds) +{ +        char    key[GF_DUMP_MAX_BUF_LEN] = {0,}; +        int     ret = -1; + +        if (!fdentry) +                return; +        if (!dict) +                return; + +        if (GF_FDENTRY_ALLOCATED != fdentry->next_free) +                return; + +        if (fdentry->fd) { +                memset (key, 0, sizeof (key)); +                snprintf (key, sizeof (key), "%s.pid", prefix); +                ret = dict_set_int32 (dict, key, fdentry->fd->pid); +                if (ret) +                        return; + +                memset (key, 0, sizeof (key)); +                snprintf (key, sizeof (key), "%s.refcount", prefix); +                ret = dict_set_int32 (dict, key, fdentry->fd->refcount); +                if (ret) +                        return; + +                memset (key, 0, sizeof (key)); +                snprintf (key, sizeof (key), "%s.flags", prefix); +                ret = dict_set_int32 (dict, key, fdentry->fd->flags); + +                (*openfds)++; +        } +        return; +} + +void +fdtable_dump_to_dict (fdtable_t *fdtable, char *prefix, dict_t *dict) +{ +        char    key[GF_DUMP_MAX_BUF_LEN] = {0,}; +        int     i = 0; +        int     openfds = 0; +        int     ret = -1; + +        if (!fdtable) +                return; +        if (!dict) +                return; + +        ret = pthread_mutex_trylock (&fdtable->lock); +        if (ret) +                goto out; + +        memset (key, 0, sizeof (key)); +        snprintf (key, sizeof (key), "%s.fdtable.refcount", prefix); +        ret = dict_set_int32 (dict, key, fdtable->refcount); +        if (ret) +                goto out; + +        memset (key, 0, sizeof (key)); +        snprintf (key, sizeof (key), "%s.fdtable.maxfds", prefix); +        ret = dict_set_uint32 (dict, key, fdtable->max_fds); +        if (ret) +                goto out; + +        memset (key, 0, sizeof (key)); +        snprintf (key, sizeof (key), "%s.fdtable.firstfree", prefix); +        ret = dict_set_int32 (dict, key, fdtable->first_free); +        if (ret) +                goto out; + +        for (i = 0; i < fdtable->max_fds; i++) { +                if (GF_FDENTRY_ALLOCATED == +                    fdtable->fdentries[i].next_free) { +                        memset (key, 0, sizeof (key)); +                        snprintf (key, sizeof (key), "%s.fdtable.fdentry%d", +                                  prefix, i); +                        fdentry_dump_to_dict (&fdtable->fdentries[i], key, +                                              dict, &openfds); +                } +        } + +        memset (key, 0, sizeof (key)); +        snprintf (key, sizeof (key), "%s.fdtable.openfds", prefix); +        ret = dict_set_int32 (dict, key, openfds); + +out: +        pthread_mutex_unlock (&fdtable->lock); +        return; +} diff --git a/libglusterfs/src/inode.c b/libglusterfs/src/inode.c index c23f0f0e545..4685ec8d255 100644 --- a/libglusterfs/src/inode.c +++ b/libglusterfs/src/inode.c @@ -1637,3 +1637,99 @@ inode_table_dump (inode_table_t *itable, char *prefix)          pthread_mutex_unlock(&itable->lock);  } + +void +inode_dump_to_dict (inode_t *inode, char *prefix, dict_t *dict) +{ +        int             ret = -1; +        char            key[GF_DUMP_MAX_BUF_LEN] = {0,}; + +        ret = TRY_LOCK (&inode->lock); +        if (ret) +                return; + +        memset (key, 0, sizeof (key)); +        snprintf (key, sizeof (key), "%s.gfid", prefix); +        ret = dict_set_str (dict, key, gf_strdup (uuid_utoa (inode->gfid))); +        if (ret) +                goto out; + +        memset (key, 0, sizeof (key)); +        snprintf (key, sizeof (key), "%s.nlookup", prefix); +        ret = dict_set_uint64 (dict, key, inode->nlookup); +        if (ret) +                goto out; + +        memset (key, 0, sizeof (key)); +        snprintf (key, sizeof (key), "%s.ref", prefix); +        ret = dict_set_uint32 (dict, key, inode->ref); +        if (ret) +                goto out; + +        memset (key, 0, sizeof (key)); +        snprintf (key, sizeof (key), "%s.ia_type", prefix); +        ret = dict_set_int32 (dict, key, inode->ia_type); + +out: +        UNLOCK (&inode->lock); +        return; +} + +void +inode_table_dump_to_dict (inode_table_t *itable, char *prefix, dict_t *dict) +{ +        char            key[GF_DUMP_MAX_BUF_LEN] = {0,}; +        int             ret = 0; +        inode_t         *inode = NULL; +        int             count = 0; + +        ret = pthread_mutex_trylock (&itable->lock); +        if (ret) +                return; + +        memset (key, 0, sizeof (key)); +        snprintf (key, sizeof (key), "%s.itable.active_size", prefix); +        ret = dict_set_uint32 (dict, key, itable->active_size); +        if (ret) +                goto out; + +        memset (key, 0, sizeof (key)); +        snprintf (key, sizeof (key), "%s.itable.lru_size", prefix); +        ret = dict_set_uint32 (dict, key, itable->lru_size); +        if (ret) +                goto out; + +        memset (key, 0, sizeof (key)); +        snprintf (key, sizeof (key), "%s.itable.purge_size", prefix); +        ret = dict_set_uint32 (dict, key, itable->purge_size); +        if (ret) +                goto out; + +        list_for_each_entry (inode, &itable->active, list) { +                memset (key, 0, sizeof (key)); +                snprintf (key, sizeof (key), "%s.itable.active%d", prefix, +                          count++); +                inode_dump_to_dict (inode, key, dict); +        } +        count = 0; + +        list_for_each_entry (inode, &itable->lru, list) { +                memset (key, 0, sizeof (key)); +                snprintf (key, sizeof (key), "%s.itable.lru%d", prefix, +                          count++); +                inode_dump_to_dict (inode, key, dict); +        } +        count = 0; + +        list_for_each_entry (inode, &itable->purge, list) { +                memset (key, 0, sizeof (key)); +                snprintf (key, sizeof (key), "%s.itable.purge%d", prefix, +                          count++); +                inode_dump_to_dict (inode, key, dict); +        } + +out: +        pthread_mutex_unlock (&itable->lock); + +        return; +} diff --git a/libglusterfs/src/stack.c b/libglusterfs/src/stack.c index 0f65faa6fb7..29b44aedfac 100644 --- a/libglusterfs/src/stack.c +++ b/libglusterfs/src/stack.c @@ -161,6 +161,194 @@ gf_proc_dump_pending_frames (call_pool_t *call_pool)          UNLOCK (&(call_pool->lock));  } +void +gf_proc_dump_call_frame_to_dict (call_frame_t *call_frame, +                                 char *prefix, dict_t *dict) +{ +        int             ret = -1; +        char            key[GF_DUMP_MAX_BUF_LEN] = {0,}; +        call_frame_t    tmp_frame = {0,}; + +        if (!call_frame || !dict) +                return; + +        ret = TRY_LOCK (&call_frame->lock); +        if (ret) +                return; +        memcpy (&tmp_frame, call_frame, sizeof (tmp_frame)); +        UNLOCK (&call_frame->lock); + +        memset (key, 0, sizeof (key)); +        snprintf (key, sizeof (key), "%s.refcount", prefix); +        ret = dict_set_int32 (dict, key, tmp_frame.ref_count); +        if (ret) +                return; + +        memset (key, 0, sizeof (key)); +        snprintf (key, sizeof (key), "%s.translator", prefix); +        ret = dict_set_str (dict, key, gf_strdup (tmp_frame.this->name)); +        if (ret) +                return; + +        memset (key, 0, sizeof (key)); +        snprintf (key, sizeof (key), "%s.complete", prefix); +        ret = dict_set_int32 (dict, key, tmp_frame.complete); +        if (ret) +                return; + +        if (tmp_frame.parent) { +                memset (key, 0, sizeof (key)); +                snprintf (key, sizeof (key), "%s.parent", prefix); +                ret = dict_set_str (dict, key, +                                    gf_strdup (tmp_frame.parent->this->name)); +                if (ret) +                        return; +        } + +        if (tmp_frame.wind_from) { +                memset (key, 0, sizeof (key)); +                snprintf (key, sizeof (key), "%s.windfrom", prefix); +                ret = dict_set_str (dict, key, gf_strdup (tmp_frame.wind_from)); +                if (ret) +                        return; +        } + +        if (tmp_frame.wind_to) { +                memset (key, 0, sizeof (key)); +                snprintf (key, sizeof (key), "%s.windto", prefix); +                ret = dict_set_str (dict, key, gf_strdup (tmp_frame.wind_to)); +                if (ret) +                        return; +        } + +        if (tmp_frame.unwind_from) { +                memset (key, 0, sizeof (key)); +                snprintf (key, sizeof (key), "%s.unwindfrom", prefix); +                ret = dict_set_str (dict, key, gf_strdup (tmp_frame.unwind_from)); +                if (ret) +                        return; +        } + +        if (tmp_frame.unwind_to) { +                memset (key, 0, sizeof (key)); +                snprintf (key, sizeof (key), "%s.unwind_to", prefix); +                ret = dict_set_str (dict, key, gf_strdup (tmp_frame.unwind_to)); +        } + +        return; +} + +void +gf_proc_dump_call_stack_to_dict (call_stack_t *call_stack, +                                 char *prefix, dict_t *dict) +{ +        int             ret = -1; +        char            key[GF_DUMP_MAX_BUF_LEN] = {0,}; +        call_frame_t    *trav = NULL; +        int             count = 0; +        int             i = 0; + +        if (!call_stack || !dict) +                return; + +        count = call_frames_count (&call_stack->frames); + +        memset (key, 0, sizeof (key)); +        snprintf (key, sizeof (key), "%s.uid", prefix); +        ret = dict_set_int32 (dict, key, call_stack->uid); +        if (ret) +                return; + +        memset (key, 0, sizeof (key)); +        snprintf (key, sizeof (key), "%s.gid", prefix); +        ret = dict_set_int32 (dict, key, call_stack->gid); +        if (ret) +                return; + +        memset (key, 0, sizeof (key)); +        snprintf (key, sizeof (key), "%s.pid", prefix); +        ret = dict_set_int32 (dict, key, call_stack->pid); +        if (ret) +                return; + +        memset (key, 0, sizeof (key)); +        snprintf (key, sizeof (key), "%s.unique", prefix); +        ret = dict_set_uint64 (dict, key, call_stack->unique); +        if (ret) +                return; + +        memset (key, 0, sizeof (key)); +        snprintf (key, sizeof (key), "%s.op", prefix); +        if (call_stack->type == GF_OP_TYPE_FOP) +                ret = dict_set_str (dict, key, +                                    gf_fop_list[call_stack->op]); +        else if (call_stack->type == GF_OP_TYPE_MGMT) +                ret = dict_set_str (dict, key, +                                    gf_mgmt_list[call_stack->op]); +        if (ret) +                return; + +        memset (key, 0, sizeof (key)); +        snprintf (key, sizeof (key), "%s.type", prefix); +        ret = dict_set_int32 (dict, key, call_stack->type); +        if (ret) +                return; + +        memset (key, 0, sizeof (key)); +        snprintf (key, sizeof (key), "%s.count", prefix); +        ret = dict_set_int32 (dict, key, count); +        if (ret) +                return; + +        trav = &call_stack->frames; +        for (i = 0; i < count; i++) { +                if (trav) { +                        memset (key, 0, sizeof (key)); +                        snprintf (key, sizeof (key), "%s.frame%d", +                                  prefix, i); +                        gf_proc_dump_call_frame_to_dict (trav, key, dict); +                        trav = trav->next; +                } +        } + +        return; +} + +void +gf_proc_dump_pending_frames_to_dict (call_pool_t *call_pool, dict_t *dict) +{ +        int             ret = -1; +        call_stack_t    *trav = NULL; +        char            key[GF_DUMP_MAX_BUF_LEN] = {0,}; +        int             i = 0; + +        if (!call_pool || !dict) +                return; + +        ret = TRY_LOCK (&call_pool->lock); +        if (ret) { +                gf_log (THIS->name, GF_LOG_WARNING, "Unable to dump call pool" +                        " to dict. errno: %d", errno); +                return; +        } + +        ret = dict_set_int32 (dict, "callpool.count", call_pool->cnt); +        if (ret) +                goto out; + +        list_for_each_entry (trav, &call_pool->all_frames, all_frames) { +                memset (key, 0, sizeof (key)); +                snprintf (key, sizeof (key), "callpool.stack%d", i); +                gf_proc_dump_call_stack_to_dict (trav, key, dict); +                i++; +        } + +out: +        UNLOCK (&call_pool->lock); + +        return; +} +  gf_boolean_t  __is_fuse_call (call_frame_t *frame)  { diff --git a/libglusterfs/src/stack.h b/libglusterfs/src/stack.h index a5689e0966f..c8404057610 100644 --- a/libglusterfs/src/stack.h +++ b/libglusterfs/src/stack.h @@ -414,6 +414,7 @@ create_frame (xlator_t *xl, call_pool_t *pool)  }  void gf_proc_dump_pending_frames(call_pool_t *call_pool); - +void gf_proc_dump_pending_frames_to_dict (call_pool_t *call_pool, +                                          dict_t *dict);  gf_boolean_t __is_fuse_call (call_frame_t *frame);  #endif /* _STACK_H */ diff --git a/libglusterfs/src/statedump.c b/libglusterfs/src/statedump.c index c744c6c5ff8..8c6fe92158d 100644 --- a/libglusterfs/src/statedump.c +++ b/libglusterfs/src/statedump.c @@ -235,6 +235,61 @@ gf_proc_dump_mem_info ()  }  void +gf_proc_dump_mem_info_to_dict (dict_t *dict) +{ +        if (!dict) +                return; +#ifdef HAVE_MALLOC_STATS +        struct  mallinfo info; +        int     ret = -1; + +        memset (&info, 0, sizeof(struct mallinfo)); +        info = mallinfo (); + +        ret = dict_set_int32 (dict, "mallinfo.arena", info.arena); +        if (ret) +                return; + +        ret = dict_set_int32 (dict, "mallinfo.ordblks", info.ordblks); +        if (ret) +                return; + +        ret = dict_set_int32 (dict, "mallinfo.smblks", info.smblks); +        if (ret) +                return; + +        ret = dict_set_int32 (dict, "mallinfo.hblks", info.hblks); +        if (ret) +                return; + +        ret = dict_set_int32 (dict, "mallinfo.hblkhd", info.hblkhd); +        if (ret) +                return; + +        ret = dict_set_int32 (dict, "mallinfo.usmblks", info.usmblks); +        if (ret) +                return; + +        ret = dict_set_int32 (dict, "mallinfo.fsmblks", info.fsmblks); +        if (ret) +                return; + +        ret = dict_set_int32 (dict, "mallinfo.uordblks", info.uordblks); +        if (ret) +                return; + +        ret = dict_set_int32 (dict, "mallinfo.fordblks", info.fordblks); +        if (ret) +                return; + +        ret = dict_set_int32 (dict, "mallinfo.keepcost", info.keepcost); +        if (ret) +                return; +#endif +        return; +} + +void  gf_proc_dump_mempool_info (glusterfs_ctx_t *ctx)  {          struct mem_pool *pool = NULL; @@ -253,6 +308,61 @@ gf_proc_dump_mempool_info (glusterfs_ctx_t *ctx)          }  } +void +gf_proc_dump_mempool_info_to_dict (glusterfs_ctx_t *ctx, dict_t *dict) +{ +        struct mem_pool *pool = NULL; +        char            key[GF_DUMP_MAX_BUF_LEN] = {0,}; +        int             count = 0; +        int             ret = -1; + +        if (!ctx || !dict) +                return; + +        list_for_each_entry (pool, &ctx->mempool_list, global_list) { +                memset (key, 0, sizeof (key)); +                snprintf (key, sizeof (key), "pool%d.name", count); +                ret = dict_set_str (dict, key, pool->name); +                if (ret) +                        return; + +                memset (key, 0, sizeof (key)); +                snprintf (key, sizeof (key), "pool%d.hotcount", count); +                ret = dict_set_int32 (dict, key, pool->hot_count); +                if (ret) +                        return; + +                memset (key, 0, sizeof (key)); +                snprintf (key, sizeof (key), "pool%d.coldcount", count); +                ret = dict_set_int32 (dict, key, pool->cold_count); +                if (ret) +                        return; + +                memset (key, 0, sizeof (key)); +                snprintf (key, sizeof (key), "pool%d.paddedsizeof", count); +                ret = dict_set_uint64 (dict, key, pool->padded_sizeof_type); +                if (ret) +                        return; + +                memset (key, 0, sizeof (key)); +                snprintf (key, sizeof (key), "pool%d.alloccount", count); +                ret = dict_set_uint64 (dict, key, pool->alloc_count); +                if (ret) +                        return; + +                memset (key, 0, sizeof (key)); +                snprintf (key, sizeof (key), "pool%d.max_alloc", count); +                ret = dict_set_int32 (dict, key, pool->max_alloc); +                if (ret) +                        return; + +                count++; +        } +        ret = dict_set_int32 (dict, "mempool-count", count); + +        return; +} +  void gf_proc_dump_latency_info (xlator_t *xl);  void diff --git a/libglusterfs/src/statedump.h b/libglusterfs/src/statedump.h index 1c56d6cfa8a..cdeb5b7fc0c 100644 --- a/libglusterfs/src/statedump.h +++ b/libglusterfs/src/statedump.h @@ -77,9 +77,17 @@ int gf_proc_dump_write(char *key, char *value,...);  void inode_table_dump(inode_table_t *itable, char *prefix); +void inode_table_dump_to_dict (inode_table_t *itable, char *prefix, dict_t *dict); +  void fdtable_dump(fdtable_t *fdtable, char *prefix); +void fdtable_dump_to_dict (fdtable_t *fdtable, char *prefix, dict_t *dict); +  void inode_dump(inode_t *inode, char *prefix); +void gf_proc_dump_mem_info_to_dict (dict_t *dict); + +void gf_proc_dump_mempool_info_to_dict (glusterfs_ctx_t *ctx, dict_t *dict); +  void glusterd_init (int sig);  #endif /* STATEDUMP_H */ diff --git a/libglusterfs/src/xlator.h b/libglusterfs/src/xlator.h index bc3d7a6dcf6..cca2505ab18 100644 --- a/libglusterfs/src/xlator.h +++ b/libglusterfs/src/xlator.h @@ -756,12 +756,29 @@ typedef int32_t (*dumpop_inodectx_t) (xlator_t *this, inode_t *ino);  typedef int32_t (*dumpop_fdctx_t) (xlator_t *this, fd_t *fd); +typedef int32_t (*dumpop_priv_to_dict_t) (xlator_t *this, dict_t *dict); + +typedef int32_t (*dumpop_inode_to_dict_t) (xlator_t *this, dict_t *dict); + +typedef int32_t (*dumpop_fd_to_dict_t) (xlator_t *this, dict_t *dict); + +typedef int32_t (*dumpop_inodectx_to_dict_t) (xlator_t *this, inode_t *ino, +                                              dict_t *dict); + +typedef int32_t (*dumpop_fdctx_to_dict_t) (xlator_t *this, fd_t *fd, +                                           dict_t *dict); +  struct xlator_dumpops { -        dumpop_priv_t            priv; -        dumpop_inode_t           inode; -        dumpop_fd_t              fd; -        dumpop_inodectx_t        inodectx; -        dumpop_fdctx_t           fdctx; +        dumpop_priv_t                   priv; +        dumpop_inode_t                  inode; +        dumpop_fd_t                     fd; +        dumpop_inodectx_t               inodectx; +        dumpop_fdctx_t                  fdctx; +        dumpop_priv_to_dict_t           priv_to_dict; +        dumpop_inode_to_dict_t          inode_to_dict; +        dumpop_fd_to_dict_t             fd_to_dict; +        dumpop_inodectx_to_dict_t       inodectx_to_dict; +        dumpop_fdctx_to_dict_t          fdctx_to_dict;  };  typedef struct xlator_list { diff --git a/rpc/rpc-lib/src/protocol-common.h b/rpc/rpc-lib/src/protocol-common.h index b35cdf911a5..97199609133 100644 --- a/rpc/rpc-lib/src/protocol-common.h +++ b/rpc/rpc-lib/src/protocol-common.h @@ -180,6 +180,7 @@ enum glusterd_brick_procnum {          GLUSTERD_BRICK_TERMINATE,          GLUSTERD_BRICK_XLATOR_INFO,          GLUSTERD_BRICK_XLATOR_HEAL, +        GLUSTERD_BRICK_STATUS,          GLUSTERD_BRICK_OP,          GLUSTERD_BRICK_MAXVALUE,  }; diff --git a/rpc/xdr/src/cli1-xdr.h b/rpc/xdr/src/cli1-xdr.h index d5593977d97..ea8ab02b6c7 100644 --- a/rpc/xdr/src/cli1-xdr.h +++ b/rpc/xdr/src/cli1-xdr.h @@ -161,14 +161,18 @@ enum gf1_cli_top_op {  typedef enum gf1_cli_top_op gf1_cli_top_op;  enum gf_cli_status_type { -	GF_CLI_STATUS_NONE = 0x0000, -	GF_CLI_STATUS_VOL = 0x0100, -	GF_CLI_STATUS_ALL = 0x0200, -	GF_CLI_STATUS_BRICK = 0x0400, -	GF_CLI_STATUS_DETAIL = 0x0800, -	GF_CLI_STATUS_VOL_DETAIL = 0x0900, -	GF_CLI_STATUS_ALL_DETAIL = 0x0A00, -	GF_CLI_STATUS_BRICK_DETAIL = 0x0C00, +	GF_CLI_STATUS_INVAL = -1, +	GF_CLI_STATUS_NONE = 0x000, +	GF_CLI_STATUS_MEM = 0x001, +	GF_CLI_STATUS_CLIENTS = 0x002, +	GF_CLI_STATUS_INODE = 0x004, +	GF_CLI_STATUS_FD = 0x008, +	GF_CLI_STATUS_CALLPOOL = 0x010, +	GF_CLI_STATUS_DETAIL = 0x020, +	GF_CLI_STATUS_MASK = 0x0FF, +	GF_CLI_STATUS_VOL = 0x100, +	GF_CLI_STATUS_ALL = 0x200, +	GF_CLI_STATUS_BRICK = 0x400,  };  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 5697310ad7d..a2edc57ebab 100644 --- a/rpc/xdr/src/cli1-xdr.x +++ b/rpc/xdr/src/cli1-xdr.x @@ -106,14 +106,18 @@ enum gf1_cli_top_op {  /* The unconventional hex numbers help us perform     bit-wise operations which reduces complexity */  enum gf_cli_status_type { -        GF_CLI_STATUS_NONE         = 0x0000, -        GF_CLI_STATUS_VOL          = 0x0100, -        GF_CLI_STATUS_ALL          = 0x0200, -        GF_CLI_STATUS_BRICK        = 0x0400, -        GF_CLI_STATUS_DETAIL       = 0x0800, -        GF_CLI_STATUS_VOL_DETAIL   = 0x0900, -        GF_CLI_STATUS_ALL_DETAIL   = 0x0A00, -        GF_CLI_STATUS_BRICK_DETAIL = 0x0C00 +        GF_CLI_STATUS_INVAL        = -1, +        GF_CLI_STATUS_NONE         = 0x000, +        GF_CLI_STATUS_MEM          = 0x001,     /*000000000001*/ +        GF_CLI_STATUS_CLIENTS      = 0x002,     /*000000000010*/ +        GF_CLI_STATUS_INODE        = 0x004,     /*000000000100*/ +        GF_CLI_STATUS_FD           = 0x008,     /*000000001000*/ +        GF_CLI_STATUS_CALLPOOL     = 0x010,     /*000000010000*/ +        GF_CLI_STATUS_DETAIL       = 0x020,     /*000000100000*/ +        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*/  };   struct gf_cli_req { diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c index d7258191031..38d73b1f737 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c @@ -192,6 +192,18 @@ glusterd_brick_op_build_payload (glusterd_op_t op, glusterd_brickinfo_t *brickin                  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) { +                        gf_log (THIS->name, GF_LOG_ERROR, "Out of memory"); +                        goto out; +                } +                brick_req->op = GLUSTERD_BRICK_STATUS; +                brick_req->name = ""; +        } +                break;          default:                  goto out;          break; @@ -562,7 +574,6 @@ glusterd_op_stage_status_volume (dict_t *dict, char **op_errstr)          if (ret) {                  snprintf (msg, sizeof(msg), "Volume %s does not exist", volname);                  gf_log (THIS->name, GF_LOG_ERROR, "%s", msg); -                *op_errstr = gf_strdup(msg);                  ret = -1;                  goto out;          } @@ -573,8 +584,12 @@ glusterd_op_stage_status_volume (dict_t *dict, char **op_errstr)                          goto out;                  ret = glusterd_brickinfo_from_brick (brick, &brickinfo); -                if (ret) +                if (ret) { +                        snprintf (msg, sizeof (msg), "%s is not a brick", +                                  brick); +                        gf_log (THIS->name, GF_LOG_ERROR, "%s", msg);                          goto out; +                }                  ret = glusterd_volume_brickinfo_get (NULL,                                                       brickinfo->hostname, @@ -588,7 +603,6 @@ glusterd_op_stage_status_volume (dict_t *dict, char **op_errstr)                                    " volume %s", brick, volname);                          gf_log (THIS->name, GF_LOG_ERROR, "%s", msg); -                        *op_errstr = gf_strdup(msg);                          ret = -1;                          goto out;                  } @@ -597,8 +611,12 @@ glusterd_op_stage_status_volume (dict_t *dict, char **op_errstr)          ret = 0;   out: -        if (ret && !(*op_errstr)) -                *op_errstr = gf_strdup ("Validation Failed for Status"); +        if (ret) { +                if (msg[0] != '\0') +                        *op_errstr = gf_strdup (msg); +                else +                        *op_errstr = gf_strdup ("Validation Failed for Status"); +        }          gf_log (THIS->name, GF_LOG_DEBUG, "Returning: %d", ret);          return ret; @@ -1242,14 +1260,13 @@ glusterd_op_status_volume (dict_t *dict, char **op_errstr,  {          int                     ret             = -1;          int                     brick_count     = 0; -        int32_t                 brick_index     = 0; +        int                     brick_index     = -1;          uint32_t                cmd             = 0;          char                   *volname         = NULL;          char                   *brick           = NULL;          xlator_t               *this            = NULL;          glusterd_volinfo_t     *volinfo         = NULL;          glusterd_brickinfo_t   *brickinfo       = NULL; -        glusterd_brickinfo_t   *tmpbrickinfo    = NULL;          glusterd_conf_t        *priv            = NULL;          this = THIS; @@ -1301,36 +1318,41 @@ glusterd_op_status_volume (dict_t *dict, char **op_errstr,                  ret = dict_get_str (dict, "brick", &brick);                  if (ret)                          goto out; -                ret = glusterd_brickinfo_from_brick (brick, &tmpbrickinfo); + +                ret = glusterd_volume_brickinfo_get_by_brick (brick, +                                                              volinfo, +                                                              &brickinfo, +                                                              GF_PATH_COMPLETE);                  if (ret)                          goto out; -                if (uuid_is_null (tmpbrickinfo->uuid) && -                    glusterd_resolve_brick (tmpbrickinfo)) + +                if (uuid_compare (brickinfo->uuid, priv->uuid))                          goto out; -        } -        list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { -                if (!uuid_compare (brickinfo->uuid, priv->uuid)) { +                glusterd_add_brick_to_dict (volinfo, brickinfo, rsp_dict, 0); +                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); -                        if ((cmd & GF_CLI_STATUS_BRICK) != 0 && -                            (strcmp (tmpbrickinfo->path, -                                     brickinfo->path) || -                             uuid_compare (tmpbrickinfo->uuid, -                                           brickinfo->uuid))) +                goto out; +        } else { +                list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { +                        brick_index++; +                        if (uuid_compare (brickinfo->uuid, priv->uuid))                                  continue;                          glusterd_add_brick_to_dict (volinfo, brickinfo,                                                      rsp_dict, brick_index); -                        if (cmd & GF_CLI_STATUS_DETAIL) +                        if (cmd & GF_CLI_STATUS_DETAIL) {                                  glusterd_add_brick_detail_to_dict (volinfo,                                                                     brickinfo,                                                                     rsp_dict,                                                                     brick_index); +                        }                          brick_count++;                  } -                if (!(cmd & GF_CLI_STATUS_BRICK)) -                        brick_index++;          }          ret = dict_set_int32 (rsp_dict, "count", brick_count); @@ -2149,6 +2171,7 @@ glusterd_need_brick_op (glusterd_op_t op)          switch (op) {          case GD_OP_PROFILE_VOLUME: +        case GD_OP_STATUS_VOLUME:                  ret = _gf_true;                  break;          default: @@ -2503,6 +2526,57 @@ 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; +} + +int +glusterd_status_volume_brick_rsp (glusterd_brickinfo_t *brickinfo, +                                  dict_t *rsp_dict, dict_t *op_ctx, +                                  char **op_errstr) +{ +        int                             ret = 0; +        glusterd_pr_brick_rsp_conv_t    rsp_ctx = {0}; +        int32_t                         count = 0; +        int                             index = 0; + +        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) { +                count = 0; +        } else { +                count++; +        } +        ret = dict_get_int32 (rsp_dict, "index", &index); +        if (ret) +                goto out; +        dict_del (rsp_dict, "index"); + +        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; +} +  int32_t  glusterd_handle_brick_rsp (glusterd_brickinfo_t *brickinfo,                             glusterd_op_t op, dict_t *rsp_dict, dict_t *op_ctx, @@ -2516,7 +2590,11 @@ glusterd_handle_brick_rsp (glusterd_brickinfo_t *brickinfo,          case GD_OP_PROFILE_VOLUME:                  ret = glusterd_profile_volume_brick_rsp (brickinfo, rsp_dict,                                                           op_ctx, op_errstr); -        break; +                break; +        case GD_OP_STATUS_VOLUME: +                ret = glusterd_status_volume_brick_rsp (brickinfo, rsp_dict, +                                                        op_ctx, op_errstr); +                break;          default:                  break; @@ -2869,6 +2947,113 @@ out:  }  static int +glusterd_bricks_select_status_volume (dict_t *dict, char **op_errstr) +{ +        int                     ret = -1; +        int                     cmd = 0; +        int                     brick_index = -1; +        char                    *volname = NULL; +        char                    *brickname = NULL; +        glusterd_volinfo_t      *volinfo = NULL; +        glusterd_brickinfo_t    *brickinfo = NULL; +        glusterd_pending_node_t *pending_node = NULL; +        xlator_t                *this = NULL; +        glusterd_conf_t         *priv = NULL; + +        GF_ASSERT (dict); + +        this = THIS; +        GF_ASSERT (this); +        priv = this->private; +        GF_ASSERT (priv); + +        ret = dict_get_int32 (dict, "cmd", &cmd); +        if (ret) { +                gf_log (THIS->name, GF_LOG_ERROR, "Unable to get status type"); +                goto out; +        } + +        if (cmd & GF_CLI_STATUS_ALL) +                goto out; + +        switch (cmd & GF_CLI_STATUS_MASK) { +        case GF_CLI_STATUS_MEM: +        case GF_CLI_STATUS_CLIENTS: +        case GF_CLI_STATUS_INODE: +        case GF_CLI_STATUS_FD: +        case GF_CLI_STATUS_CALLPOOL: +                break; +        default: +                goto out; +        } +        ret = dict_get_str (dict, "volname", &volname); +        if (ret) { +                gf_log (THIS->name, GF_LOG_ERROR, "Unable to get volname"); +                goto out; +        } +        ret = glusterd_volinfo_find (volname, &volinfo); +        if (ret) { +                goto out; +        } + +        if ( (cmd & GF_CLI_STATUS_BRICK) != 0) { +                ret = dict_get_str (dict, "brick", &brickname); +                if (ret) { +                        gf_log (THIS->name, GF_LOG_ERROR, +                                "Unable to get brick"); +                        goto out; +                } +                ret = glusterd_volume_brickinfo_get_by_brick (brickname, +                                                              volinfo, +                                                              &brickinfo, +                                                              GF_PATH_COMPLETE); +                if (ret) +                        goto out; + +                if (uuid_compare (brickinfo->uuid, priv->uuid)|| +                    !glusterd_is_brick_started (brickinfo)) +                        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 = brickinfo; +                pending_node->type = GD_NODE_BRICK; +                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++; +                        if (uuid_compare (brickinfo->uuid, priv->uuid) || +                            !glusterd_is_brick_started (brickinfo)) { +                                continue; +                        } +                        pending_node = GF_CALLOC (1, sizeof (*pending_node), +                                                  gf_gld_mt_pending_node_t); +                        if (!pending_node) { +                                ret = -1; +                                gf_log (THIS->name ,GF_LOG_ERROR, +                                        "Unable to allocate memory"); +                                goto out; +                        } +                        pending_node->node = brickinfo; +                        pending_node->type = GD_NODE_BRICK; +                        pending_node->index = brick_index; +                        list_add_tail (&pending_node->list, +                                       &opinfo.pending_bricks); +                        pending_node = NULL; +                } +        } +out: +        return ret; +} + +static int  glusterd_op_ac_send_brick_op (glusterd_op_sm_event_t *event, void *ctx)  {          int                             ret = 0; @@ -2990,6 +3175,10 @@ glusterd_op_bricks_select (glusterd_op_t op, dict_t *dict, char **op_errstr)                  ret = glusterd_bricks_select_heal_volume (dict, op_errstr);                  break; +        case GD_OP_STATUS_VOLUME: +                ret = glusterd_bricks_select_status_volume (dict, op_errstr); +                break; +          default:                  break;           } diff --git a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c index a4dd7e25c6c..21d8ab0aca0 100644 --- a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c @@ -1038,8 +1038,7 @@ glusterd_volume_status_use_rsp_dict (dict_t *rsp_dict)          rsp_ctx.count = count;          rsp_ctx.dict = ctx_dict;          dict_foreach (rsp_dict, glusterd_volume_status_add_peer_rsp, &rsp_ctx); -        dict_del (ctx_dict, "count"); -        ret = dict_get_int32 (ctx_dict, "count", &brick_count); +          ret = dict_set_int32 (ctx_dict, "count", count + brick_count);  out:          return ret; @@ -1626,9 +1625,13 @@ glusterd3_1_brick_op_cbk (struct rpc_req *req, struct iovec *iov,          call_frame_t                  *frame = NULL;          glusterd_op_brick_rsp_ctx_t   *ev_ctx = NULL;          dict_t                        *dict = NULL; +        int                           index = 0; +        glusterd_req_ctx_t            *req_ctx = NULL; +        glusterd_pending_node_t       *node = NULL;          GF_ASSERT (req);          frame = myframe; +        req_ctx = frame->local;          if (-1 == req->rpc_status) {                  rsp.op_ret   = -1; @@ -1643,7 +1646,7 @@ glusterd3_1_brick_op_cbk (struct rpc_req *req, struct iovec *iov,                  gf_log ("", GF_LOG_ERROR, "error");                  rsp.op_ret   = -1;                  rsp.op_errno = EINVAL; -                rsp.op_errstr = strdup ("Unable to decode response"); +                rsp.op_errstr = strdup ("Unable to decode brick op response");  		event_type = GD_OP_EVENT_RCVD_RJT;                  goto out;          } @@ -1668,6 +1671,19 @@ glusterd3_1_brick_op_cbk (struct rpc_req *req, struct iovec *iov,          op_ret = rsp.op_ret; +        /* Add index to rsp_dict for GD_OP_STATUS_VOLUME */ +        if (GD_OP_STATUS_VOLUME == req_ctx->op) { +                node = frame->cookie; +                index = node->index; +                ret = dict_set_int32 (dict, "index", index); +                if (ret) { +                        gf_log (THIS->name, GF_LOG_ERROR, +                                "Error setting index on brick status rsp dict"); +                        rsp.op_ret = -1; +                        event_type = GD_OP_EVENT_RCVD_RJT; +                        goto out; +                } +        }  out:          ev_ctx = GF_CALLOC (1, sizeof (*ev_ctx), gf_gld_mt_brick_rsp_ctx_t);          GF_ASSERT (ev_ctx); diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h index 6e96192506f..44f84d78d70 100644 --- a/xlators/mgmt/glusterd/src/glusterd.h +++ b/xlators/mgmt/glusterd/src/glusterd.h @@ -240,6 +240,7 @@ typedef struct glusterd_pending_node_ {          struct list_head list;          void   *node;          gd_node_type type; +        int32_t index;  } glusterd_pending_node_t;  enum glusterd_op_ret { diff --git a/xlators/protocol/server/src/server.c b/xlators/protocol/server/src/server.c index d767199d0a7..60bc517ddbe 100644 --- a/xlators/protocol/server/src/server.c +++ b/xlators/protocol/server/src/server.c @@ -164,6 +164,38 @@ ret:  /* */  int +server_fd_to_dict (xlator_t *this, dict_t *dict) +{ +        server_conf_t           *conf = NULL; +        server_connection_t     *trav = NULL; +        char                    key[GF_DUMP_MAX_BUF_LEN] = {0,}; +        int                     count = 0; +        int                     ret = -1; + +        GF_VALIDATE_OR_GOTO (THIS->name, this, out); +        GF_VALIDATE_OR_GOTO (this->name, dict, out); + +        conf = this->private; +        if (!conf) +                return -1; + +        ret = pthread_mutex_trylock (&conf->mutex); +        if (ret) +                return -1; + +        list_for_each_entry (trav, &conf->conns, list) { +                memset (key, 0, sizeof (key)); +                snprintf (key, sizeof (key), "conn%d", count++); +                fdtable_dump_to_dict (trav->fdtable, key, dict); +        } +        pthread_mutex_unlock (&conf->mutex); + +        ret = dict_set_int32 (dict, "conncount", count); +out: +        return ret; +} + +int  server_fd (xlator_t *this)  {          server_conf_t        *conf = NULL; @@ -218,6 +250,53 @@ out:  }  int +server_priv_to_dict (xlator_t *this, dict_t *dict) +{ +        server_conf_t   *conf = NULL; +        rpc_transport_t *xprt = NULL; +        peer_info_t     *peerinfo = NULL; +        char            key[32] = {0,}; +        int             count = 0; +        int             ret = -1; + +        GF_VALIDATE_OR_GOTO (THIS->name, this, out); +        GF_VALIDATE_OR_GOTO (THIS->name, dict, out); + +        conf = this->private; +        if (!conf) +                return 0; +        //TODO: Dump only specific info to dict + +        list_for_each_entry (xprt, &conf->xprt_list, list) { +                peerinfo = &xprt->peerinfo; +                memset (key, 0, sizeof (key)); +                snprintf (key, sizeof (key), "client%d.hostname", count); +                ret = dict_set_str (dict, key, peerinfo->identifier); +                if (ret) +                        goto out; + +                memset (key, 0, sizeof (key)); +                snprintf (key, sizeof (key), "client%d.bytesread", count); +                ret = dict_set_uint64 (dict, key, xprt->total_bytes_read); +                if (ret) +                        goto out; + +                memset (key, 0, sizeof (key)); +                snprintf (key, sizeof (key), "client%d.byteswrite", count); +                ret = dict_set_uint64 (dict, key, xprt->total_bytes_write); +                if (ret) +                        goto out; + +                count++; +        } + +        ret = dict_set_int32 (dict, "clientcount", count); + +out: +        return ret; +} + +int  server_priv (xlator_t *this)  {          server_conf_t    *conf = NULL; @@ -250,6 +329,57 @@ out:  }  int +server_inode_to_dict (xlator_t *this, dict_t *dict) +{ +        server_conf_t           *conf = NULL; +        server_connection_t     *trav = NULL; +        char                    key[32] = {0,}; +        int                     count = 0; +        int                     ret = -1; +        xlator_t                *prev_bound_xl = NULL; + +        GF_VALIDATE_OR_GOTO (THIS->name, this, out); +        GF_VALIDATE_OR_GOTO (this->name, dict, out); + +        conf = this->private; +        if (!conf) +                return -1; + +        ret = pthread_mutex_trylock (&conf->mutex); +        if (ret) +                return -1; + +        list_for_each_entry (trav, &conf->conns, list) { +                if (trav->bound_xl && trav->bound_xl->itable) { +                        /* Presently every brick contains only one +                         * bound_xl for all connections. This will lead +                         * to duplicating of the inode lists, if listing +                         * is done for every connection. This simple check +                         * prevents duplication in the present case. If +                         * need arises the check can be improved. +                         */ +                        if (trav->bound_xl == prev_bound_xl) +                                continue; +                        prev_bound_xl = trav->bound_xl; + +                        memset (key, 0, sizeof (key)); +                        snprintf (key, sizeof (key), "conn%d", count); +                        inode_table_dump_to_dict (trav->bound_xl->itable, +                                                  key, dict); +                        count++; +                } +        } +        pthread_mutex_unlock (&conf->mutex); + +        ret = dict_set_int32 (dict, "conncount", count); + +out: +        if (prev_bound_xl) +                prev_bound_xl = NULL; +        return ret; +} + +int  server_inode (xlator_t *this)  {          server_conf_t        *conf = NULL; @@ -811,9 +941,12 @@ struct xlator_cbks cbks = {  };  struct xlator_dumpops dumpops = { -        .priv  = server_priv, -        .fd    = server_fd, -        .inode = server_inode, +        .priv           = server_priv, +        .fd             = server_fd, +        .inode          = server_inode, +        .priv_to_dict   = server_priv_to_dict, +        .fd_to_dict     = server_fd_to_dict, +        .inode_to_dict  = server_inode_to_dict,  };  | 
