diff options
| -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 | ||||
| -rw-r--r-- | libglusterfs/src/common-utils.c | 49 | ||||
| -rw-r--r-- | libglusterfs/src/common-utils.h | 8 | ||||
| -rw-r--r-- | rpc/rpc-lib/src/protocol-common.h | 1 | ||||
| -rw-r--r-- | rpc/xdr/src/cli1-xdr.c | 11 | ||||
| -rw-r--r-- | rpc/xdr/src/cli1-xdr.h | 14 | ||||
| -rw-r--r-- | rpc/xdr/src/cli1-xdr.x | 13 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-handler.c | 28 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-op-sm.c | 172 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.c | 375 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.h | 11 | 
14 files changed, 992 insertions, 124 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); diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c index 1d0fb822fc5..d22ebd2ef04 100644 --- a/libglusterfs/src/common-utils.c +++ b/libglusterfs/src/common-utils.c @@ -1607,6 +1607,55 @@ nwstrtail (char *str, char *pattern)          return *pattern ? NULL : str;  } +void +skipword (char **s) +{ +        if (!*s) +                return; + +        skipwhite (s); + +        while (!isspace(**s)) +                (*s)++; +} + +char * +get_nth_word (const char *str, int n) +{ +        char           buf[4096] = {0}; +        char          *start     = NULL; +        char          *word      = NULL; +        int            i         = 0; +        int            word_len  = 0; +        const char    *end       = NULL; + +        if (!str) +                goto out; + +        snprintf (buf, sizeof (buf), "%s", str); +        start = buf; + +        for (i = 0; i < n-1; i++) +                skipword (&start); + +        skipwhite (&start); +        end = strpbrk ((const char *)start, " \t\n\0"); + +        if (!end) +                goto out; + +        word_len = abs (end - start); + +        word = GF_CALLOC (1, word_len + 1, gf_common_mt_strdup); +        if (!word) +                goto out; + +        strncpy (word, start, word_len); +        *(word + word_len) = '\0'; + out: +        return word; +} +  /* RFC 1123 & 952 */  char  valid_host_name (char *address, int length) diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h index 4cb3843d980..6045cd3efe0 100644 --- a/libglusterfs/src/common-utils.h +++ b/libglusterfs/src/common-utils.h @@ -74,6 +74,11 @@ void trap (void);  #define WIPE(statp) do { typeof(*statp) z = {0,}; if (statp) *statp = z; } while (0) +#define IS_EXT_FS(fs_name)          \ +        (!strcmp (fs_name, "ext2") || \ +         !strcmp (fs_name, "ext3") || \ +         !strcmp (fs_name, "ext4")) +  enum _gf_boolean  {  	_gf_false = 0, @@ -409,6 +414,9 @@ int get_checksum_for_path (char *path, uint32_t *checksum);  char *strtail (char *str, const char *pattern);  void skipwhite (char **s);  char *nwstrtail (char *str, char *pattern); +void skip_word (char **str); +/* returns a new string with nth word of given string. n>=1 */ +char *get_nth_word (const char *str, int n);  char valid_host_name (char *address, int length);  char valid_ipv4_address (char *address, int length); diff --git a/rpc/rpc-lib/src/protocol-common.h b/rpc/rpc-lib/src/protocol-common.h index 9b358f49730..fd7c89aadb8 100644 --- a/rpc/rpc-lib/src/protocol-common.h +++ b/rpc/rpc-lib/src/protocol-common.h @@ -148,6 +148,7 @@ enum gluster_cli_procnum {          GLUSTER_CLI_TOP_VOLUME,          GLUSTER_CLI_GETWD,          GLUSTER_CLI_STATUS_VOLUME, +        GLUSTER_CLI_STATUS_ALL,          GLUSTER_CLI_MOUNT,          GLUSTER_CLI_UMOUNT,          GLUSTER_CLI_HEAL_VOLUME, diff --git a/rpc/xdr/src/cli1-xdr.c b/rpc/xdr/src/cli1-xdr.c index b0ac0799a8d..56562ee3d00 100644 --- a/rpc/xdr/src/cli1-xdr.c +++ b/rpc/xdr/src/cli1-xdr.c @@ -177,6 +177,17 @@ xdr_gf1_cli_top_op (XDR *xdrs, gf1_cli_top_op *objp)  }  bool_t +xdr_gf_cli_status_type (XDR *xdrs, gf_cli_status_type *objp) +{ +	register int32_t *buf; +        buf = NULL; + +	 if (!xdr_enum (xdrs, (enum_t *) objp)) +		 return FALSE; +	return TRUE; +} + +bool_t  xdr_gf_cli_req (XDR *xdrs, gf_cli_req *objp)  {  	register int32_t *buf; diff --git a/rpc/xdr/src/cli1-xdr.h b/rpc/xdr/src/cli1-xdr.h index 1d0faa996b5..d5593977d97 100644 --- a/rpc/xdr/src/cli1-xdr.h +++ b/rpc/xdr/src/cli1-xdr.h @@ -160,6 +160,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, +}; +typedef enum gf_cli_status_type gf_cli_status_type; +  struct gf_cli_req {  	struct {  		u_int dict_len; @@ -298,6 +310,7 @@ extern  bool_t xdr_gf1_cli_op_flags (XDR *, gf1_cli_op_flags*);  extern  bool_t xdr_gf1_cli_gsync_set (XDR *, gf1_cli_gsync_set*);  extern  bool_t xdr_gf1_cli_stats_op (XDR *, gf1_cli_stats_op*);  extern  bool_t xdr_gf1_cli_top_op (XDR *, gf1_cli_top_op*); +extern  bool_t xdr_gf_cli_status_type (XDR *, gf_cli_status_type*);  extern  bool_t xdr_gf_cli_req (XDR *, gf_cli_req*);  extern  bool_t xdr_gf_cli_rsp (XDR *, gf_cli_rsp*);  extern  bool_t xdr_gf1_cli_probe_req (XDR *, gf1_cli_probe_req*); @@ -329,6 +342,7 @@ extern bool_t xdr_gf1_cli_op_flags ();  extern bool_t xdr_gf1_cli_gsync_set ();  extern bool_t xdr_gf1_cli_stats_op ();  extern bool_t xdr_gf1_cli_top_op (); +extern bool_t xdr_gf_cli_status_type ();  extern bool_t xdr_gf_cli_req ();  extern bool_t xdr_gf_cli_rsp ();  extern bool_t xdr_gf1_cli_probe_req (); diff --git a/rpc/xdr/src/cli1-xdr.x b/rpc/xdr/src/cli1-xdr.x index 129f5f971ab..5697310ad7d 100644 --- a/rpc/xdr/src/cli1-xdr.x +++ b/rpc/xdr/src/cli1-xdr.x @@ -103,6 +103,19 @@ enum gf1_cli_top_op {          GF_CLI_TOP_WRITE_PERF  }; +/* 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 +}; +   struct gf_cli_req {          opaque  dict<>;  }  ; diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c index 664798ca376..7817e1dd653 100644 --- a/xlators/mgmt/glusterd/src/glusterd-handler.c +++ b/xlators/mgmt/glusterd/src/glusterd-handler.c @@ -2511,10 +2511,11 @@ int  glusterd_handle_status_volume (rpcsvc_request_t *req)  {          int32_t                         ret     = -1; +        uint32_t                        cmd     = 0; +        dict_t                         *dict    = NULL; +        char                           *volname = 0;          gf_cli_req                      cli_req = {{0,}}; -        dict_t                          *dict    = NULL; -        glusterd_op_t                   cli_op = GD_OP_STATUS_VOLUME; -        char                            *volname = 0; +        glusterd_op_t                   cli_op  = GD_OP_STATUS_VOLUME;          GF_ASSERT (req); @@ -2530,7 +2531,7 @@ glusterd_handle_status_volume (rpcsvc_request_t *req)                  if (!dict)                          goto out;                  ret = dict_unserialize (cli_req.dict.dict_val, -                                  cli_req.dict.dict_len, &dict); +                                        cli_req.dict.dict_len, &dict);                  if (ret < 0) {                          gf_log (THIS->name, GF_LOG_ERROR, "failed to "                                  "unserialize buffer"); @@ -2539,15 +2540,22 @@ glusterd_handle_status_volume (rpcsvc_request_t *req)          } -        ret = dict_get_str (dict, "volname", &volname); -        if (ret) { -                gf_log (THIS->name, GF_LOG_ERROR, "failed to get volname"); +        ret = dict_get_uint32 (dict, "cmd", &cmd); +        if (ret)                  goto out; -        } -        gf_log ("glusterd", GF_LOG_INFO, "Received status volume req " -                "for volume %s", volname); +        if (!(cmd & GF_CLI_STATUS_ALL)) { +                ret = dict_get_str (dict, "volname", &volname); +                if (ret) { +                        gf_log (THIS->name, GF_LOG_ERROR, +                                "failed to get volname"); +                        goto out; +                } +                gf_log (THIS->name, GF_LOG_INFO, +                        "Received status volume req " +                        "for volume %s", volname); +        }          ret = glusterd_op_begin (req, GD_OP_STATUS_VOLUME, dict); diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c index 8f2d55aaf3a..68a98b16b7b 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c @@ -527,12 +527,16 @@ out:  static int  glusterd_op_stage_status_volume (dict_t *dict, char **op_errstr)  { -        int                 ret            = -1; -        gf_boolean_t        exists         = _gf_false; -        char               *volname        = NULL; -        glusterd_conf_t    *priv           = NULL; -        xlator_t           *this           = NULL; -        char msg[2048]                     = {0,}; +        int                    ret            = -1; +        uint32_t               cmd            = 0; +        char                   msg[2048]      = {0,}; +        char                  *volname        = NULL; +        char                  *brick          = NULL; +        xlator_t              *this           = NULL; +        glusterd_conf_t       *priv           = NULL; +        glusterd_brickinfo_t  *brickinfo      = NULL; +        glusterd_brickinfo_t  *tmpbrickinfo   = NULL; +        glusterd_volinfo_t    *volinfo        = NULL;          GF_ASSERT (dict);          this = THIS; @@ -540,30 +544,63 @@ glusterd_op_stage_status_volume (dict_t *dict, char **op_errstr)          priv = this->private;          GF_ASSERT(priv); +        ret = dict_get_uint32 (dict, "cmd", &cmd); +        if (ret) +                goto out; + +        if (cmd & GF_CLI_STATUS_ALL) +                goto out;          ret = dict_get_str (dict, "volname", &volname);          if (ret) { -                gf_log ("glusterd", GF_LOG_ERROR, "Unable to get volume name"); +                gf_log (THIS->name, GF_LOG_ERROR, +                        "Unable to get volume name");                  goto out;          } -        exists = glusterd_check_volume_exists (volname); -        if (!exists) { +        ret = glusterd_volinfo_find (volname, &volinfo); +        if (ret) {                  snprintf (msg, sizeof(msg), "Volume %s does not exist", volname); -                gf_log ("glusterd", GF_LOG_ERROR, "%s", msg); - +                gf_log (THIS->name, GF_LOG_ERROR, "%s", msg);                  *op_errstr = gf_strdup(msg);                  ret = -1;                  goto out;          } +        if ((cmd & GF_CLI_STATUS_BRICK) != 0) { +                ret = dict_get_str (dict, "brick", &brick); +                if (ret) +                        goto out; + +                ret = glusterd_brickinfo_from_brick (brick, &brickinfo); +                if (ret) +                        goto out; + +                ret = glusterd_volume_brickinfo_get (NULL, +                                                     brickinfo->hostname, +                                                     brickinfo->path, +                                                     volinfo, +                                                     &tmpbrickinfo, +                                                     GF_PATH_COMPLETE); + +                if (ret) { +                        snprintf (msg, sizeof(msg), "No brick %s in" +                                  " volume %s", brick, volname); +                        gf_log (THIS->name, GF_LOG_ERROR, "%s", msg); + +                        *op_errstr = gf_strdup(msg); +                        ret = -1; +                        goto out; +                } +        } +          ret = 0;   out:          if (ret && !(*op_errstr))                  *op_errstr = gf_strdup ("Validation Failed for Status"); -        gf_log ("glusterd", GF_LOG_DEBUG, "Returning: %d", ret); +        gf_log (THIS->name, GF_LOG_DEBUG, "Returning: %d", ret);          return ret;  } @@ -1203,15 +1240,17 @@ static int  glusterd_op_status_volume (dict_t *dict, char **op_errstr,                             dict_t *rsp_dict)  { -        int                     ret = -1; -        char                    *volname = NULL; -        int                     count = 0; -        int                     brick_count = 0; -        glusterd_volinfo_t      *volinfo = NULL; -        glusterd_brickinfo_t    *brickinfo = NULL; -        glusterd_conf_t         *priv = NULL; -        xlator_t                *this = NULL; -        int32_t                 brick_index = 0; +        int                     ret             = -1; +        int                     brick_count     = 0; +        int32_t                 brick_index     = 0; +        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;          GF_ASSERT (this); @@ -1221,41 +1260,83 @@ glusterd_op_status_volume (dict_t *dict, char **op_errstr,          GF_ASSERT (dict); - -        ret = dict_get_str (dict, "volname", &volname); -        if (!ret) { -                ret = glusterd_volinfo_find (volname, &volinfo); -                if (ret) { -                        gf_log ("", GF_LOG_ERROR, "Volume with name: %s " -                                "does not exist", volname); -                        goto out; -                } -        } +        ret = dict_get_uint32 (dict, "cmd", &cmd); +        if (ret) +                goto out;          if (!rsp_dict) {                  //this should happen only on source                  ret = 0;                  rsp_dict = glusterd_op_get_ctx (); + +                if ((cmd & GF_CLI_STATUS_ALL)) { +                        ret = glusterd_get_all_volnames (rsp_dict); +                        if (ret) +                                gf_log (THIS->name, GF_LOG_ERROR, +                                        "failed to get all volume " +                                        "names for status"); +                } +          } -        if (volname) { -                list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { -                        if (!uuid_compare (brickinfo->uuid, priv->uuid)) { -                                ret = glusterd_add_brick_to_dict (volinfo, -                                                                  brickinfo, -                                                                  rsp_dict, -                                                                  brick_index); -                                count++; -                                brick_count = count; -                        } -                        brick_index++; +        ret = dict_set_uint32 (rsp_dict, "cmd", cmd); +        if (ret) +                goto out; + +        if (cmd & GF_CLI_STATUS_ALL) +                goto out; + +        ret = dict_get_str (dict, "volname", &volname); +        if (ret) +                goto out; + +        ret = glusterd_volinfo_find (volname, &volinfo); +        if (ret) { +                gf_log (THIS->name, GF_LOG_ERROR, "Volume with name: %s " +                        "does not exist", volname); +                goto out; +        } + +        if ((cmd & GF_CLI_STATUS_BRICK) != 0) { +                ret = dict_get_str (dict, "brick", &brick); +                if (ret) +                        goto out; +                ret = glusterd_brickinfo_from_brick (brick, &tmpbrickinfo); +                if (ret) +                        goto out; +                if (uuid_is_null (tmpbrickinfo->uuid) && +                    glusterd_resolve_brick (tmpbrickinfo)) +                        goto out; +        } + +        list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { +                if (!uuid_compare (brickinfo->uuid, priv->uuid)) { + +                        if ((cmd & GF_CLI_STATUS_BRICK) != 0 && +                            (strcmp (tmpbrickinfo->path, +                                     brickinfo->path) || +                             uuid_compare (tmpbrickinfo->uuid, +                                           brickinfo->uuid))) +                                continue; + +                        glusterd_add_brick_to_dict (volinfo, brickinfo, +                                                    rsp_dict, brick_index); + +                        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);  out: -        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); +        gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);          return ret;  } @@ -2119,7 +2200,7 @@ glusterd_op_ac_commit_op (glusterd_op_sm_event_t *event, void *ctx)                                               rsp_dict);          if (status) { -                gf_log ("", GF_LOG_ERROR, "Commit failed: %d", status); +                gf_log (THIS->name, GF_LOG_ERROR, "Commit failed: %d", status);          }          ret = glusterd_op_commit_send_resp (req_ctx->req, req_ctx->op, @@ -2131,7 +2212,8 @@ glusterd_op_ac_commit_op (glusterd_op_sm_event_t *event, void *ctx)          if (rsp_dict)                  dict_unref (rsp_dict); -        gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret); + +        gf_log (THIS->name, GF_LOG_DEBUG, "Returning with %d", ret);          return ret;  } diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c index 2eaf4f4a2f4..b2d0bcdd7ad 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -58,6 +58,9 @@  #include <rpc/pmap_clnt.h>  #include <unistd.h>  #include <fnmatch.h> +#include <sys/statvfs.h> + +  #ifdef GF_SOLARIS_HOST_OS  #include <sys/sockio.h>  #endif @@ -679,11 +682,11 @@ glusterd_brickinfo_from_brick (char *brick,          GF_ASSERT (brickinfo);          tmp_host = gf_strdup (brick); -        if (tmp_host) -                get_host_name (tmp_host, &hostname); +        if (tmp_host && !get_host_name (tmp_host, &hostname)) +                goto out;          tmp_path = gf_strdup (brick); -        if (tmp_path) -                get_path_name (tmp_path, &path); +        if (tmp_path && !get_path_name (tmp_path, &path)) +                goto out;          GF_ASSERT (hostname);          GF_ASSERT (path); @@ -3084,21 +3087,331 @@ out:          return -1;  } +int +glusterd_get_brick_root (char *path, char **mount_point) +{ +        char           *ptr            = NULL; +        struct stat     brickstat      = {0}; +        struct stat     buf            = {0}; + +        if (!path) +                goto err; +        *mount_point = gf_strdup (path); +        if (!*mount_point) +                goto err; +        if (stat (*mount_point, &brickstat)) +                goto err; + +        while ((ptr = strrchr (*mount_point, '/')) && +               ptr != *mount_point) { + +                *ptr = '\0'; +                if (stat (*mount_point, &buf)) { +                        gf_log (THIS->name, GF_LOG_ERROR, "error in " +                                "stat: %s", strerror (errno)); +                        goto err; +                } + +                if (brickstat.st_dev != buf.st_dev) { +                        *ptr = '/'; +                        break; +                } +        } + +        if (ptr == *mount_point) { +                if (stat ("/", &buf)) { +                        gf_log (THIS->name, GF_LOG_ERROR, "error in " +                                "stat: %s", strerror (errno)); +                        goto err; +                } +                if (brickstat.st_dev == buf.st_dev) +                        strcpy (*mount_point, "/"); +        } + +        return 0; + + err: +        if (*mount_point) +                GF_FREE (*mount_point); +        return -1; +} + +static int +glusterd_add_inode_size_to_dict (dict_t *dict, int count) +{ +        int             ret               = -1; +        int             fd                = -1; +        char            key[1024]         = {0}; +        char            buffer[4096]      = {0}; +        char            cmd_str[4096]     = {0}; +        char           *inode_size        = NULL; +        char           *device            = NULL; +        char           *fs_name           = NULL; + +        memset (key, 0, sizeof (key)); +        snprintf (key, sizeof (key), "brick%d.device", count); +        ret = dict_get_str (dict, key, &device); +        if (ret) +                goto out; + +        memset (key, 0, sizeof (key)); +        snprintf (key, sizeof (key), "brick%d.fs_name", count); +        ret = dict_get_str (dict, key, &fs_name); +        if (ret) +                goto out; + +        /* get inode size for xfs or ext2/3/4 */ +        if (!strcmp (fs_name, "xfs")) { + +                snprintf (cmd_str, sizeof (cmd_str), +                          "xfs_info %s | " +                          "grep isize | " +                          "cut -d ' ' -f 2-  | " +                          "cut -d '=' -f 2 | " +                          "cut -d ' ' -f 1 " +                          "> /tmp/gf_status.txt ", +                          device); + +        } else if (IS_EXT_FS(fs_name)) { + +                snprintf (cmd_str, sizeof (cmd_str), +                          "tune2fs -l %s | " +                          "grep -i 'inode size' | " +                          "awk '{print $3}' " +                          "> /tmp/gf_status.txt ", +                          device); + +        } else { +                ret = 0; +                gf_log (THIS->name, GF_LOG_INFO, "Skipped fetching " +                        "inode size for %s: FS type not recommended", +                        fs_name); +                goto out; +        } + +        ret = runcmd ("/bin/sh", "-c", cmd_str, NULL); +        if (ret) { +                gf_log (THIS->name, GF_LOG_ERROR, "could not get inode " +                        "size for %s : %s package missing", fs_name, +                        ((strcmp (fs_name, "xfs")) ? +                         "e2fsprogs" : "xfsprogs")); +                goto out; +        } + +        fd = open ("/tmp/gf_status.txt", O_RDONLY); +        unlink ("/tmp/gf_status.txt"); +        if (fd < 0) { +                ret = -1; +                goto out; +        } +        memset (buffer, 0, sizeof (buffer)); +        ret = read (fd, buffer, sizeof (buffer)); +        if (ret < 2) { +                ret = -1; +                goto out; +        } + +        memset (key, 0, sizeof (key)); +        snprintf (key, sizeof (key), "brick%d.inode_size", count); + +        inode_size = get_nth_word (buffer, 1); +        if (!inode_size) { +                ret = -1; +                goto out; +        } + +        ret = dict_set_dynstr (dict, key, inode_size); + + out: +        if (fd >= 0) +                close (fd); +        if (ret) +                gf_log (THIS->name, GF_LOG_ERROR, "failed to get inode size"); +        return ret; +} + +static int +glusterd_add_brick_mount_details (glusterd_brickinfo_t *brickinfo, +                                  dict_t *dict, int count) +{ +        int             ret                  = -1; +        int             fd                   = -1; +        char            key[1024]            = {0}; +        char            base_key[1024]       = {0}; +        char            buffer[4096]         = {0}; +        char            cmd_str[1024]        = {0}; +        char           *mnt_pt               = NULL; +        char           *fs_name              = NULL; +        char           *mnt_options          = NULL; +        char           *device               = NULL; +        runner_t        runner               = {0}; + +        snprintf (base_key, sizeof (base_key), "brick%d", count); + +        ret = glusterd_get_brick_root (brickinfo->path, &mnt_pt); +        if (ret) +                goto out; + +        /* get mount details of brick in back-end */ +        snprintf (cmd_str, sizeof (cmd_str), " %s ", mnt_pt); + +        runinit (&runner); +        runner_add_args (&runner, "grep", cmd_str, "/etc/mtab", NULL); +        runner_redir (&runner, STDOUT_FILENO, RUN_PIPE); + +        ret = runner_start (&runner); +        if (ret) +                goto out; + +        if (!fgets (buffer, sizeof(buffer), +                    runner_chio (&runner, STDOUT_FILENO))) { +                ret = -1; +                goto out; +        } + +        runner_end (&runner); + +        /* get device file */ +        memset (key, 0, sizeof (key)); +        snprintf (key, sizeof (key), "%s.device", base_key); + +        device = get_nth_word (buffer, 1); +        if (!device) +                goto out; + +        ret = dict_set_dynstr (dict, key, device); +        if (ret) +                goto out; + +        /* fs type */ +        memset (key, 0, sizeof (key)); +        snprintf (key, sizeof (key), "%s.fs_name", base_key); + +        fs_name = get_nth_word (buffer, 3); +        if (!fs_name) +                goto out; + +        ret = dict_set_dynstr (dict, key, fs_name); +        if (ret) +                goto out; + +        /* mount options */ +        memset (key, 0, sizeof (key)); +        snprintf (key, sizeof (key), "%s.mnt_options", base_key); + +        mnt_options = get_nth_word (buffer, 4); +        if (!mnt_options) +                goto out; +        ret = dict_set_dynstr (dict, key, mnt_options); + + out: +        if (mnt_pt) +                GF_FREE (mnt_pt); +        if (fd >= 0) +                close (fd); +        return ret; +} + +int +glusterd_add_brick_detail_to_dict (glusterd_volinfo_t *volinfo, +                                   glusterd_brickinfo_t *brickinfo, +                                   dict_t *dict, int count) +{ +        int             ret               = -1; +        uint64_t        memtotal          = 0; +        uint64_t        memfree           = 0; +        uint64_t        inodes_total      = 0; +        uint64_t        inodes_free       = 0; +        uint64_t        block_size        = 0; +        char            key[1024]         = {0}; +        char            base_key[1024]    = {0}; +        struct statvfs  brickstat         = {0}; + +        GF_ASSERT (volinfo); +        GF_ASSERT (brickinfo); +        GF_ASSERT (dict); + +        snprintf (base_key, sizeof (base_key), "brick%d", count); + +        ret = statvfs (brickinfo->path, &brickstat); +        if (ret) { +                gf_log (THIS->name, GF_LOG_ERROR, "statfs error: %s ", +                        strerror (errno)); +                goto out; +        } + +        /* file system block size */ +        block_size = brickstat.f_bsize; +        memset (key, 0, sizeof (key)); +        snprintf (key, sizeof (key), "%s.block_size", base_key); +        ret = dict_set_uint64 (dict, key, block_size); +        if (ret) +                goto out; + +        /* free space in brick */ +        memfree = brickstat.f_bfree * brickstat.f_bsize; +        memset (key, 0, sizeof (key)); +        snprintf (key, sizeof (key), "%s.free", base_key); +        ret = dict_set_uint64 (dict, key, memfree); +        if (ret) +                goto out; + +        /* total space of brick */ +        memtotal = brickstat.f_blocks * brickstat.f_bsize; +        memset (key, 0, sizeof (key)); +        snprintf (key, sizeof (key), "%s.total", base_key); +        ret = dict_set_uint64 (dict, key, memtotal); +        if (ret) +                goto out; + +        /* inodes: total and free counts only for ext2/3/4 and xfs */ +        inodes_total = brickstat.f_files; +        if (inodes_total) { +                memset (key, 0, sizeof (key)); +                snprintf (key, sizeof (key), "%s.total_inodes", base_key); +                ret = dict_set_uint64 (dict, key, inodes_total); +                if (ret) +                        goto out; +        } + +        inodes_free = brickstat.f_ffree; +        if (inodes_free) { +                memset (key, 0, sizeof (key)); +                snprintf (key, sizeof (key), "%s.free_inodes", base_key); +                ret = dict_set_uint64 (dict, key, inodes_free); +                if (ret) +                        goto out; +        } + +        ret = glusterd_add_brick_mount_details (brickinfo, dict, count); +        if (ret) +                goto out; + +        ret = glusterd_add_inode_size_to_dict (dict, count); + + out: +        if (ret) +                gf_log (THIS->name, GF_LOG_DEBUG, "Error adding brick" +                        " detail to dict: %s", strerror (errno)); +        return ret; +} +  int32_t  glusterd_add_brick_to_dict (glusterd_volinfo_t *volinfo,                              glusterd_brickinfo_t *brickinfo,                              dict_t  *dict, int32_t count)  { -        int             ret = -1; -        char            key[8192] = {0,}; -        char            base_key[8192] = {0}; -        char            pidfile[PATH_MAX] = {0}; -        char            path[PATH_MAX] = {0}; -        int32_t         pid = -1; -        int32_t         brick_online = -1; -        xlator_t        *this = NULL; -        glusterd_conf_t *priv = NULL; +        int             ret                   = -1; +        int32_t         pid                   = -1; +        int32_t         brick_online          = -1; +        char            key[1024]             = {0}; +        char            base_key[1024]        = {0}; +        char            pidfile[PATH_MAX]     = {0}; +        char            path[PATH_MAX]        = {0}; +        xlator_t        *this                 = NULL; +        glusterd_conf_t *priv                 = NULL; +          GF_ASSERT (volinfo);          GF_ASSERT (brickinfo); @@ -3111,6 +3424,7 @@ glusterd_add_brick_to_dict (glusterd_volinfo_t *volinfo,          snprintf (base_key, sizeof (base_key), "brick%d", count);          snprintf (key, sizeof (key), "%s.hostname", base_key); +          ret = dict_set_str (dict, key, brickinfo->hostname);          if (ret)                  goto out; @@ -3142,13 +3456,42 @@ glusterd_add_brick_to_dict (glusterd_volinfo_t *volinfo,          memset (key, 0, sizeof (key));          snprintf (key, sizeof (key), "%s.status", base_key);          ret = dict_set_int32 (dict, key, brick_online); -        if (ret) -                goto out;  out:          if (ret) -                gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); +                gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret); + +        return ret; +} + +int32_t +glusterd_get_all_volnames (dict_t *dict) +{ +        int                    ret        = -1; +        int32_t                vol_count  = 0; +        char                   key[256]   = {0}; +        glusterd_volinfo_t    *entry      = NULL; +        glusterd_conf_t       *priv       = NULL; +        priv = THIS->private; +        GF_ASSERT (priv); + +        list_for_each_entry (entry, &priv->volumes, vol_list) { +                memset (key, sizeof (key), 0); +                snprintf (key, sizeof (key), "vol%d", vol_count); +                ret = dict_set_str (dict, key, entry->volname); +                if (ret) +                        goto out; + +                vol_count++; +        } + +        ret = dict_set_int32 (dict, "vol_count", vol_count); + + out: +        if (ret) +                gf_log (THIS->name, GF_LOG_ERROR, "failed to get all " +                        "volume names for status");          return ret;  } diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h index a34956b0c4a..0ce17450284 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.h +++ b/xlators/mgmt/glusterd/src/glusterd-utils.h @@ -347,11 +347,22 @@ glusterd_recreate_bricks (glusterd_conf_t *conf);  int32_t  glusterd_handle_upgrade_downgrade (dict_t *options, glusterd_conf_t *conf); +int +glusterd_get_brick_root (char *path, char **mount_point); + +int +glusterd_add_brick_detail_to_dict (glusterd_volinfo_t *volinfo, +                                   glusterd_brickinfo_t *brickinfo, +                                   dict_t  *dict, int32_t count); +  int32_t  glusterd_add_brick_to_dict (glusterd_volinfo_t *volinfo,                              glusterd_brickinfo_t *brickinfo,                              dict_t  *dict, int32_t count); +int32_t +glusterd_get_all_volnames (dict_t *dict); +  gf_boolean_t  glusterd_is_fuse_available ();  | 
