diff options
Diffstat (limited to 'cli/src')
| -rw-r--r-- | cli/src/cli-cmd-parser.c | 71 | ||||
| -rw-r--r-- | cli/src/cli-cmd-volume.c | 166 | ||||
| -rw-r--r-- | cli/src/cli-rpc-ops.c | 169 | ||||
| -rw-r--r-- | cli/src/cli.h | 28 | 
4 files changed, 381 insertions, 53 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index fa46fa06671..acbd960ba43 100644 --- a/cli/src/cli-cmd-parser.c +++ b/cli/src/cli-cmd-parser.c @@ -1795,23 +1795,84 @@ out:          return ret;  } -int32_t +int  cli_cmd_volume_status_parse (const char **words, int wordcount, -                                dict_t **options) +                             dict_t **options)  {          dict_t *dict            = NULL;          int     ret             = -1; +        int     cmd             = 0; -        GF_ASSERT (words);          GF_ASSERT (options);          dict = dict_new ();          if (!dict)                  goto out; -        GF_ASSERT(words[2]); +        switch (wordcount) { + +        case 2: +                cmd = GF_CLI_STATUS_ALL; +                ret = 0; +                break; + +        case 3: +                if (!strcmp (words[2], "all")) { + +                        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]); +                } +                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]); + +                } else { + +                        cmd = GF_CLI_STATUS_BRICK; +                        ret = dict_set_str (dict, "volname", (char *)words[2]); +                        if (ret) +                                goto out; +                        ret = dict_set_str (dict, "brick", (char *)words[3]); +                } +                break; + +        case 5: +                if (strcmp (words[4], "detail")) +                        goto out; + +                cmd = GF_CLI_STATUS_BRICK_DETAIL; +                ret = dict_set_str (dict, "volname", (char *)words[2]); +                if (ret) +                        goto out; +                ret = dict_set_str (dict, "brick", (char *)words[3]); +                break; + +        default: +                goto out; +        } + +        if (ret) +                goto out; -        ret = dict_set_str (dict, "volname", (char *)words[2]); +        ret = dict_set_int32 (dict, "cmd", cmd);          if (ret)                  goto out; diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c index 009896d9ce4..38c16797ea1 100644 --- a/cli/src/cli-cmd-volume.c +++ b/cli/src/cli-cmd-volume.c @@ -1344,39 +1344,177 @@ out:  int  cli_cmd_volume_status_cbk (struct cli_state *state, -                              struct cli_cmd_word *word, -                              const char **words, int wordcount) +                           struct cli_cmd_word *word, +                           const char **words, int wordcount)  {          int                   ret         = -1;          rpc_clnt_procedure_t *proc        = NULL;          call_frame_t         *frame       = NULL;          dict_t               *dict        = NULL; +        uint32_t              cmd         = 0; -        if (wordcount != 3) { +        ret = cli_cmd_volume_status_parse (words, wordcount, &dict); + +        if (ret) {                  cli_usage_out (word->pattern);                  goto out;          } -        proc = &cli_rpc_prog->proctable[GLUSTER_CLI_STATUS_VOLUME]; +        ret = dict_get_uint32 (dict, "cmd", &cmd); +        if (ret) +                goto out; + +        if (!(cmd & GF_CLI_STATUS_ALL)) { +                /* for one volume or brick */ +                proc = &cli_rpc_prog->proctable[GLUSTER_CLI_STATUS_VOLUME]; +        } else { +                /* volume status all or all detail */ +                proc = &cli_rpc_prog->proctable[GLUSTER_CLI_STATUS_ALL]; +        } + +        if (!proc->fn) +                goto out;          frame = create_frame (THIS, THIS->ctx->pool);          if (!frame)                  goto out; -        ret = cli_cmd_volume_status_parse (words, wordcount, &dict); +        ret = proc->fn (frame, THIS, dict); + + out: +        if (dict) +                dict_unref (dict); +        return ret; +} + + +int +cli_get_detail_status (dict_t *dict, int i, cli_volume_status_t *status) +{ +        uint64_t                   free            = -1; +        uint64_t                   total           = -1; +        char                       key[1024]       = {0}; +        int                        ret             = 0; + +        memset (key, 0, sizeof (key)); +        snprintf (key, sizeof (key), "brick%d.free", i); +        ret = dict_get_uint64 (dict, key, &free);          if (ret)                  goto out; -        if (proc->fn) -                ret = proc->fn (frame, THIS, dict); +        status->free = gf_uint64_2human_readable (free); +        if (!status->free) +                goto out; + +        memset (key, 0, sizeof (key)); +        snprintf (key, sizeof (key), "brick%d.total", i); +        ret = dict_get_uint64 (dict, key, &total); +        if (ret) +                goto out; + +        status->total = gf_uint64_2human_readable (total); +        if (!status->total) +                goto out; + +        memset (key, 0, sizeof (key)); +        snprintf (key, sizeof (key), "brick%d.device", i); +        ret = dict_get_str (dict, key, &(status->device)); +        if (ret) +                goto out; + +        memset (key, 0, sizeof (key)); +        snprintf (key, sizeof (key), "brick%d.block_size", i); +        ret = dict_get_uint64 (dict, key, &(status->block_size)); +        if (ret) +                goto out; + +        memset (key, 0, sizeof (key)); +        snprintf (key, sizeof (key), "brick%d.mnt_options", i); +        ret = dict_get_str (dict, key, &(status->mount_options)); +        if (ret) +                goto out; + +        memset (key, 0, sizeof (key)); +        snprintf (key, sizeof (key), "brick%d.fs_name", i); +        ret = dict_get_str (dict, key, &(status->fs_name)); +        if (ret) +                goto out; + +        if (IS_EXT_FS(status->fs_name) || +            !strcmp (status->fs_name, "xfs")) { + +                memset (key, 0, sizeof (key)); +                snprintf (key, sizeof (key), "brick%d.inode_size", i); +                ret = dict_get_str (dict, key, &(status->inode_size)); +                if (ret) +                        status->inode_size = NULL; + +                memset (key, 0, sizeof (key)); +                snprintf (key, sizeof (key), "brick%d.total_inodes", i); +                ret = dict_get_uint64 (dict, key, &(status->total_inodes)); +                if (ret) +                        goto out; + +                memset (key, 0, sizeof (key)); +                snprintf (key, sizeof (key), "brick%d.free_inodes", i); +                ret = dict_get_uint64 (dict, key, &(status->free_inodes)); +                if (ret) +                        goto out; + +        } else { +                status->inode_size = NULL; +                status->total_inodes = 0; +                status->free_inodes = 0; +        }   out:          return ret;  } +void +cli_print_detailed_status (cli_volume_status_t *status) +{ +        cli_out ("%-20s : %-20s", "Brick", status->brick); +        cli_out ("%-20s : %-20d", "Port", status->port); +        cli_out ("%-20s : %-20c", "Online", (status->online) ? 'Y' : 'N'); +        cli_out ("%-20s : %-20s", "Pid", status->pid_str); +        cli_out ("%-20s : %-20s", "File System", status->fs_name); +        cli_out ("%-20s : %-20s", "Device", status->device); + +        if (status->mount_options) { +                cli_out ("%-20s : %-20s", "Mount Options", +                         status->mount_options); +        } else { +                cli_out ("%-20s : %-20s", "Mount Options", "N/A"); +        } + +        cli_out ("%-20s : %-20s", "Disk Space Free", status->free); +        cli_out ("%-20s : %-20s", "Total Disk Space", status->total); + +        if (status->inode_size) { +                cli_out ("%-20s : %-20s", "Inode Size", +                         status->inode_size); +        } else { +                cli_out ("%-20s : %-20s", "Inode Size", "N/A"); +        } + +        if (status->total_inodes) { +                cli_out ("%-20s : %-20ld", "Inode Count", +                         status->total_inodes); +        } else { +                cli_out ("%-20s : %-20s", "Inode Count", "N/A"); +        } + +        if (status->free_inodes) { +                cli_out ("%-20s : %-20ld", "Free Inodes", +                         status->free_inodes); +        } else { +                cli_out ("%-20s : %-20s", "Free Inodes", "N/A"); +        } +}  int -cli_print_brick_status (char *brick, int port, int online, char *pid) +cli_print_brick_status (cli_volume_status_t *status)  {          int  fieldlen = CLI_VOL_STATUS_BRICK_LEN;          char buf[80] = {0,}; @@ -1385,22 +1523,24 @@ cli_print_brick_status (char *brick, int port, int online, char *pid)          char *p = NULL;          int  num_tabs = 0; -        bricklen = strlen (brick); -        p = brick; +        bricklen = strlen (status->brick); +        p = status->brick;          while (bricklen > 0) {                  if (bricklen > fieldlen) {                          i++;                          strncpy (buf, p, fieldlen);                          buf[strlen(buf) + 1] = '\0';                          cli_out ("%s", buf); -                        p = brick + i * fieldlen; +                        p = status->brick + i * fieldlen;                          bricklen -= fieldlen;                  } else {                          num_tabs = (fieldlen - bricklen) / CLI_TAB_LENGTH + 1;                          printf ("%s", p);                          while (num_tabs-- != 0)                                  printf ("\t"); -                        cli_out ("%d\t%c\t%s", port, online?'Y':'N', pid); +                        cli_out ("%d\t%c\t%s", +                                 status->port, status->online?'Y':'N', +                                 status->pid_str);                          bricklen = 0;                  }          } @@ -1597,7 +1737,7 @@ struct cli_cmd volume_cmds[] = {             cli_cmd_volume_top_cbk,             "volume top operations"}, -        { "volume status <VOLNAME>", +        { "volume status [all|<VOLNAME>] [brick] [detail]",            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 f6ae1d94122..06c52dac186 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -3796,22 +3796,19 @@ out:  static int  gf_cli3_1_status_cbk (struct rpc_req *req, struct iovec *iov, -                         int count, void *myframe) +                      int count, void *myframe)  { -        gf_cli_rsp                      rsp = {0,}; -        int                             ret = -1; -        dict_t                          *dict = NULL; -        char                            *hostname = NULL; -        char                            *path = NULL; -        int                             i = 0; -        int                             port = 0; -        int                             online = 0; -        char                            key[1024] = {0,}; -        int                             pid = -1; -        char                            *pid_str = NULL; -        char                            brick[8192] = {0,}; -        char                            *volname = NULL; - +        int                             ret            = -1; +        int                             i              = 0; +        int                             pid            = -1; +        uint32_t                        cmd            = 0; +        char                            key[1024]      = {0,}; +        char                           *hostname       = NULL; +        char                           *path           = NULL; +        char                           *volname        = NULL; +        dict_t                         *dict           = NULL; +        gf_cli_rsp                      rsp            = {0,}; +        cli_volume_status_t                 status         = {0};          if (req->rpc_status == -1)                  goto out; @@ -3839,16 +3836,39 @@ gf_cli3_1_status_cbk (struct rpc_req *req, struct iovec *iov,          if (ret)                  goto out; +        ret = dict_get_uint32 (dict, "cmd", &cmd); +        if (ret) +                goto out; + +        if ((cmd & GF_CLI_STATUS_ALL)) { +                ((call_frame_t *)myframe)->local = dict; +                ret = 0; +                goto out; +        }          ret = dict_get_int32 (dict, "count", &count);          if (ret)                  goto out; +        if (count == 0) { +                ret = -1; +                goto out; +        } + +        status.brick = GF_CALLOC (1, PATH_MAX + 256, gf_common_mt_strdup);          ret = dict_get_str (dict, "volname", &volname); +        if (ret) +                goto out; + +        cli_out ("\nSTATUS OF VOLUME: %s", volname); + +        if ((cmd & GF_CLI_STATUS_DETAIL) == 0) +                cli_out ("BRICK\t\t\t\t\t\t\tPORT\tONLINE\tPID"); -        cli_out ("Brick status for volume: %s", volname); -        cli_out ("Brick\t\t\t\t\t\t\tPort\tOnline\tPID");          for (i = 0; i < count; i++) { + +                cli_print_line (CLI_BRICK_STATUS_LINE_LEN); +                  memset (key, 0, sizeof (key));                  snprintf (key, sizeof (key), "brick%d.hostname", i);                  ret = dict_get_str (dict, key, &hostname); @@ -3861,15 +3881,19 @@ gf_cli3_1_status_cbk (struct rpc_req *req, struct iovec *iov,                  if (ret)                          goto out; +                memset (status.brick, 0, PATH_MAX + 255); +                snprintf (status.brick, PATH_MAX + 255, "%s:%s", +                          hostname, path); +                  memset (key, 0, sizeof (key));                  snprintf (key, sizeof (key), "brick%d.port", i); -                ret = dict_get_int32 (dict, key, &port); +                ret = dict_get_int32 (dict, key, &(status.port));                  if (ret)                          goto out;                  memset (key, 0, sizeof (key));                  snprintf (key, sizeof (key), "brick%d.status", i); -                ret = dict_get_int32 (dict, key, &online); +                ret = dict_get_int32 (dict, key, &(status.online));                  if (ret)                          goto out; @@ -3879,40 +3903,44 @@ gf_cli3_1_status_cbk (struct rpc_req *req, struct iovec *iov,                  if (ret)                          goto out;                  if (pid == -1) -                        ret = gf_asprintf (&pid_str, "%s", "N/A"); +                        ret = gf_asprintf (&(status.pid_str), "%s", "N/A");                  else -                        ret = gf_asprintf (&pid_str, "%d", pid); +                        ret = gf_asprintf (&(status.pid_str), "%d", pid);                  if (ret == -1)                          goto out; -                snprintf (brick, sizeof (brick) -1, "%s:%s", hostname, path); +                if ((cmd & GF_CLI_STATUS_DETAIL)) { +                        ret = cli_get_detail_status (dict, i, &status); +                        if (ret) +                                goto out; +                        cli_print_detailed_status (&status); -                cli_print_line (CLI_BRICK_STATUS_LINE_LEN); -                cli_print_brick_status (brick, port, online, pid_str); -                if (pid_str) -                        GF_FREE (pid_str); +                } else { +                        cli_print_brick_status (&status); +                }          }          ret = rsp.op_ret;   out: +        if (status.brick) +                GF_FREE (status.brick); +          cli_cmd_broadcast_response (ret);          return ret;  }  int32_t  gf_cli3_1_status_volume (call_frame_t *frame, xlator_t *this, -                            void *data) +                         void *data)  {          gf_cli_req                      req  = {{0,}}; -        int                             ret  = 0; -        dict_t                          *dict = NULL; +        int                             ret  = -1; +        dict_t                         *dict = NULL; -        if (!frame || !this || !data) { -                ret = -1; +        if (!frame || !this || !data)                  goto out; -        }          dict = data; @@ -3920,7 +3948,7 @@ gf_cli3_1_status_volume (call_frame_t *frame, xlator_t *this,                                             &req.dict.dict_val,                                             (size_t *)&req.dict.dict_len);          if (ret < 0) { -                gf_log (this->name, GF_LOG_ERROR, +                gf_log ("cli", GF_LOG_ERROR,                          "failed to serialize the data");                  goto out; @@ -3935,6 +3963,80 @@ gf_cli3_1_status_volume (call_frame_t *frame, xlator_t *this,          return ret;  } +int +gf_cli_status_volume_all (call_frame_t *frame, xlator_t *this, void *data) +{ +        int              i            = 0; +        int              ret          = -1; +        int              vol_count    = -1; +        uint32_t         cmd          = 0; +        char             key[1024]    = {0}; +        char            *volname      = NULL; +        dict_t          *vol_dict     = NULL; +        dict_t          *dict         = NULL; + +        dict = (dict_t *)data; +        ret = dict_get_uint32 (dict, "cmd", &cmd); +        if (ret) +                goto out; + +        ret = gf_cli3_1_status_volume (frame, this, data); +        if (ret) +                goto out; + +        vol_dict =  (dict_t *)(frame->local); + +        ret = dict_get_int32 (vol_dict, "vol_count", &vol_count); +        if (ret) { +                cli_out ("Failed to get names of volumes"); +                goto out; +        } + +        if (vol_count == 0) { +                cli_out ("No volumes present"); +                ret = 0; +                goto out; +        } + +        /* remove the "all" flag in cmd */ +        cmd &= ~GF_CLI_STATUS_ALL; +        cmd |= GF_CLI_STATUS_VOL; + +        for (i = 0; i < vol_count; i++) { + +                dict = dict_new (); +                if (!dict) +                        goto out; + +                memset (key, 0, sizeof (key)); +                snprintf (key, sizeof (key), "vol%d", i); +                ret = dict_get_str (vol_dict, key, &volname); +                if (ret) +                        goto out; + +                ret = dict_set_dynstr (dict, "volname", volname); +                if (ret) +                        goto out; + +                ret = dict_set_uint32 (dict, "cmd", cmd); +                if (ret) +                        goto out; + +                ret = gf_cli3_1_status_volume (frame, this, dict); +                if (ret) +                        goto out; + +                dict_unref (dict); +        } + + out: +        if (ret) +                gf_log ("cli", GF_LOG_ERROR, "status all failed"); +        if (ret && dict) +                dict_unref (dict); +        return ret; +} +  static int  gf_cli3_1_mount_cbk (struct rpc_req *req, struct iovec *iov,                    int count, void *myframe) @@ -4265,6 +4367,7 @@ struct rpc_clnt_procedure gluster_cli_actors[GLUSTER_CLI_MAXVALUE] = {          [GLUSTER_CLI_TOP_VOLUME]       = {"TOP_VOLUME", gf_cli3_1_top_volume},          [GLUSTER_CLI_GETWD]            = {"GETWD", gf_cli3_1_getwd},          [GLUSTER_CLI_STATUS_VOLUME]    = {"STATUS_VOLUME", gf_cli3_1_status_volume}, +        [GLUSTER_CLI_STATUS_ALL]       = {"STATUS_ALL", gf_cli_status_volume_all},          [GLUSTER_CLI_MOUNT]            = {"MOUNT", gf_cli3_1_mount},          [GLUSTER_CLI_UMOUNT]           = {"UMOUNT", gf_cli3_1_umount},          [GLUSTER_CLI_HEAL_VOLUME]      = {"HEAL_VOLUME", gf_cli3_1_heal_volume}, diff --git a/cli/src/cli.h b/cli/src/cli.h index 1d2e069735a..e091e7004a8 100644 --- a/cli/src/cli.h +++ b/cli/src/cli.h @@ -37,7 +37,7 @@  #define DEFAULT_CLI_LOG_FILE_DIRECTORY     DATADIR "/log/glusterfs"  #define CLI_VOL_STATUS_BRICK_LEN              55  #define CLI_TAB_LENGTH                         8 -#define CLI_BRICK_STATUS_LINE_LEN             75 +#define CLI_BRICK_STATUS_LINE_LEN             78  enum argp_option_keys {  	ARGP_DEBUG_KEY = 133, @@ -124,6 +124,24 @@ struct cli_local {          dict_t          *dict;  }; +struct cli_volume_status { +        int            port; +        int            online; +        uint64_t       block_size; +        uint64_t       total_inodes; +        uint64_t       free_inodes; +        char          *brick; +        char          *pid_str; +        char          *fs_name; +        char          *free; +        char          *total; +        char          *mount_options; +        char          *device; +        char          *inode_size; +}; + +typedef struct cli_volume_status cli_volume_status_t; +  typedef struct cli_local cli_local_t;  typedef ssize_t (*cli_serialize_t) (struct iovec outmsg, void *args); @@ -236,7 +254,13 @@ cli_cmd_volume_status_parse (const char **words, int wordcount,                               dict_t **options);  int -cli_print_brick_status (char *brick, int port, int online, char *pid); +cli_print_brick_status (cli_volume_status_t *status); + +void +cli_print_detailed_status (cli_volume_status_t *status); + +int +cli_get_detail_status (dict_t *dict, int i, cli_volume_status_t *status);  void  cli_print_line (int len);  | 
