diff options
| author | Vijay Bellur <vijay@gluster.com> | 2011-08-18 23:19:22 +0530 | 
|---|---|---|
| committer | Anand Avati <avati@gluster.com> | 2011-08-19 01:29:18 -0700 | 
| commit | 0143a2ef653d0f7a337c8220f127655dadbca942 (patch) | |
| tree | 61896872f41f8ccb39b692a521a62569516bab2d | |
| parent | d2849bd349081b332540713cfeaa561f57356b2a (diff) | |
mgmt/glusterd, cli: Introduce gluster volume status <volname>
Change-Id: Iea835b9e448e736016da2e44e3c9bfff93f2fa78
BUG: 3439
Reviewed-on: http://review.gluster.com/259
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Anand Avati <avati@gluster.com>
| -rw-r--r-- | cli/src/cli-cmd-parser.c | 34 | ||||
| -rw-r--r-- | cli/src/cli-cmd-volume.c | 72 | ||||
| -rw-r--r-- | cli/src/cli-rpc-ops.c | 127 | ||||
| -rw-r--r-- | cli/src/cli.c | 11 | ||||
| -rw-r--r-- | cli/src/cli.h | 13 | ||||
| -rw-r--r-- | rpc/rpc-lib/src/protocol-common.h | 2 | ||||
| -rw-r--r-- | rpc/xdr/src/cli1-xdr.c | 129 | ||||
| -rw-r--r-- | rpc/xdr/src/cli1-xdr.h | 120 | ||||
| -rw-r--r-- | rpc/xdr/src/cli1-xdr.x | 24 | ||||
| -rw-r--r-- | rpc/xdr/src/cli1.c | 36 | ||||
| -rw-r--r-- | rpc/xdr/src/cli1.h | 16 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-handler.c | 61 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-op-sm.c | 113 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-op-sm.h | 5 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-rpc-ops.c | 84 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.c | 87 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.h | 4 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd.h | 1 | 
18 files changed, 828 insertions, 111 deletions
| diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index a442b3aee85..9f35cc47e5b 100644 --- a/cli/src/cli-cmd-parser.c +++ b/cli/src/cli-cmd-parser.c @@ -1646,3 +1646,37 @@ out:                  dict_destroy (dict);          return ret;  } + +int32_t +cli_cmd_volume_status_parse (const char **words, int wordcount, +                                dict_t **options) +{ +        dict_t *dict            = NULL; +        int     ret             = -1; + +        GF_ASSERT (words); +        GF_ASSERT (options); + + +        GF_ASSERT ((strncmp(words[0], "volume", 6) == 0)); +        GF_ASSERT ((strncmp(words[1], "status", 5) == 0)); + + +        dict = dict_new (); +        if (!dict) +                goto out; + +        GF_ASSERT(words[2]); + +        ret = dict_set_str (dict, "volname", (char *)words[2]); +        if (ret) +                goto out; + +        *options = dict; + + out: +        if (ret && dict) +                dict_destroy (dict); + +        return ret; +} diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c index ab7f1ddc7b3..b61eb31c0bc 100644 --- a/cli/src/cli-cmd-volume.c +++ b/cli/src/cli-cmd-volume.c @@ -1211,6 +1211,74 @@ cli_cmd_log_level_cbk (struct cli_state *state, struct cli_cmd_word *word,          return ret;  } +int +cli_cmd_volume_status_cbk (struct cli_state *state, +                              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; +        int                   parse_error = 0; + +        if (wordcount != 3) { +                cli_usage_out (word->pattern); +                parse_error = 1; +                goto out; +        } + +        proc = &cli_rpc_prog->proctable[GLUSTER_CLI_STATUS_VOLUME]; + +        frame = create_frame (THIS, THIS->ctx->pool); +        if (!frame) +                goto out; + +        ret = cli_cmd_volume_status_parse (words, wordcount, &dict); +        if (ret) +                goto out; + +        if (proc->fn) +                ret = proc->fn (frame, THIS, dict); + + out: +        return ret; +} + + +int +cli_print_brick_status (char *brick, int port, int online, int pid) +{ +        int  fieldlen = CLI_VOL_STATUS_BRICK_LEN; +        char buf[80] = {0,}; +        int  bricklen = 0; +        int  i = 0; +        char *p = NULL; +        int  num_tabs = 0; + +        bricklen = strlen (brick); +        p = 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; +                        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%d", port, online?'Y':'N', pid); +                        bricklen = 0; +                } +        } + +        return 0; +} +  struct cli_cmd volume_cmds[] = {          { "volume info [all|<VOLNAME>]",            cli_cmd_volume_info_cbk, @@ -1309,6 +1377,10 @@ struct cli_cmd volume_cmds[] = {           cli_cmd_log_level_cbk,           "log level for translator"}, +        { "volume status <VOLNAME>", +          cli_cmd_volume_status_cbk, +         "display status of specified volume"}, +          { NULL, NULL, NULL }  }; diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c index b6fbf3f05fc..498cdbf74e2 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -3562,6 +3562,130 @@ out:          return ret;  } +static int +gf_cli3_1_status_cbk (struct rpc_req *req, struct iovec *iov, +                         int count, void *myframe) +{ +        gf1_cli_status_volume_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 = 0; +        char                            brick[8192] = {0,}; +        char                            *volname = NULL; + + +        if (req->rpc_status == -1) +                goto out; + +        ret = gf_xdr_to_cli_status_volume_rsp (*iov, &rsp); +        if (ret < 0) { +                gf_log ("cli", GF_LOG_ERROR, "Volume status response error"); +                goto out; +        } + +        gf_log ("cli", GF_LOG_DEBUG, "Received response to status cmd"); + +        if (rsp.op_ret && strcmp (rsp.op_errstr, "")) +                cli_out ("%s", rsp.op_errstr); +        else if (rsp.op_ret) +                cli_out ("Unable to obtain volume status information."); + +        dict = dict_new (); +        if (!dict) +                goto out; + +        ret = dict_unserialize (rsp.dict.dict_val, +                                rsp.dict.dict_len, +                                &dict); +        if (ret) +                goto out; + + +        ret = dict_get_int32 (dict, "count", &count); +        if (ret) +                goto out; + +        ret = dict_get_str (dict, "volname", &volname); + +        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++) { +                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; + +                memset (key, 0, sizeof (key)); +                snprintf (key, sizeof (key), "brick%d.port", i); +                ret = dict_get_int32 (dict, key, &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); +                if (ret) +                        goto out; + +                memset (key, 0, sizeof (key)); +                snprintf (key, sizeof (key), "brick%d.pid", i); +                ret = dict_get_int32 (dict, key, &pid); + +                snprintf (brick, sizeof (brick) -1, "%s:%s", hostname, path); + +                cli_print_line (CLI_BRICK_STATUS_LINE_LEN); +                cli_print_brick_status (brick, port, online, pid); +        } + +        ret = rsp.op_ret; + + out: +        cli_cmd_broadcast_response (ret); +        return ret; +} + +int32_t +gf_cli3_1_status_volume (call_frame_t *frame, xlator_t *this, +                            void *data) +{ +        gf1_cli_status_volume_req       req  = {0,}; +        int                             ret  = 0; +        dict_t                          *dict = NULL; + +        if (!frame || !this || !data) { +                ret = -1; +                goto out; +        } + +        dict = data; + +        ret = dict_get_str (dict, "volname", &req.volname); +        if (ret) +                goto out; + +        ret = cli_cmd_submit (&req, frame, cli_rpc_prog, +                              GLUSTER_CLI_STATUS_VOLUME, NULL, +                              gf_xdr_from_cli_status_volume_req, +                              this, gf_cli3_1_status_cbk, +                              (xdrproc_t)xdr_gf1_cli_status_volume_req); + + out: +        gf_log ("cli", GF_LOG_DEBUG, "Returning: %d", ret); +        return ret; +}  struct rpc_clnt_procedure gluster_cli_actors[GLUSTER_CLI_MAXVALUE] = {          [GLUSTER_CLI_NULL]             = {"NULL", NULL }, @@ -3593,7 +3717,8 @@ struct rpc_clnt_procedure gluster_cli_actors[GLUSTER_CLI_MAXVALUE] = {          [GLUSTER_CLI_QUOTA]            = {"QUOTA", gf_cli3_1_quota},          [GLUSTER_CLI_TOP_VOLUME]       = {"TOP_VOLUME", gf_cli3_1_top_volume},          [GLUSTER_CLI_LOG_LEVEL]        = {"VOLUME_LOGLEVEL", gf_cli3_1_log_level}, -        [GLUSTER_CLI_GETWD]            = {"GETWD", gf_cli3_1_getwd} +        [GLUSTER_CLI_GETWD]            = {"GETWD", gf_cli3_1_getwd}, +        [GLUSTER_CLI_STATUS_VOLUME]    = {"STATUS_VOLUME", gf_cli3_1_status_volume},  };  struct rpc_clnt_program cli_prog = { diff --git a/cli/src/cli.c b/cli/src/cli.c index 1703c0ca63b..eec14d6fad0 100644 --- a/cli/src/cli.c +++ b/cli/src/cli.c @@ -698,3 +698,14 @@ out:          return ret;  } + +void +cli_print_line (int len) +{ +        GF_ASSERT (len > 0); + +        while (len--) +                printf ("-"); + +        printf ("\n"); +} diff --git a/cli/src/cli.h b/cli/src/cli.h index 91fca102ea1..55d0d89f1d0 100644 --- a/cli/src/cli.h +++ b/cli/src/cli.h @@ -34,6 +34,9 @@  #define CLI_DEFAULT_CONN_TIMEOUT             120  #define CLI_DEFAULT_CMD_TIMEOUT              120  #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  enum argp_option_keys {  	ARGP_DEBUG_KEY = 133, @@ -248,4 +251,14 @@ cli_cmd_volume_top_parse (const char **words, int wordcount,  int32_t  cli_cmd_log_level_parse (const char **words, int wordcount,                           dict_t **options); + +int32_t +cli_cmd_volume_status_parse (const char **words, int wordcount, +                             dict_t **options); + +int +cli_print_brick_status (char *brick, int port, int online, int pid); + +void +cli_print_line (int len);  #endif /* __CLI_H__ */ diff --git a/rpc/rpc-lib/src/protocol-common.h b/rpc/rpc-lib/src/protocol-common.h index a456fb727b4..216429e79a6 100644 --- a/rpc/rpc-lib/src/protocol-common.h +++ b/rpc/rpc-lib/src/protocol-common.h @@ -109,6 +109,7 @@ enum gf_mgmt_procnum_ {          GD_MGMT_CLI_PROFILE_VOLUME,          GD_MGMT_BRICK_OP,          GD_MGMT_CLI_LOG_LEVEL, +        GD_MGMT_CLI_STATUS_VOLUME,          GD_MGMT_MAXVALUE,  }; @@ -201,6 +202,7 @@ enum gluster_cli_procnum {          GLUSTER_CLI_TOP_VOLUME,          GLUSTER_CLI_GETWD,          GLUSTER_CLI_LOG_LEVEL, +        GLUSTER_CLI_STATUS_VOLUME,          GLUSTER_CLI_MAXVALUE,  }; diff --git a/rpc/xdr/src/cli1-xdr.c b/rpc/xdr/src/cli1-xdr.c index d4523c359f0..a37e4cd21af 100644 --- a/rpc/xdr/src/cli1-xdr.c +++ b/rpc/xdr/src/cli1-xdr.c @@ -17,7 +17,6 @@    <http://www.gnu.org/licenses/>.  */ -  /*   * Please do not edit this file.   * It was generated using rpcgen. @@ -112,9 +111,9 @@ bool_t  xdr_gf1_cli_top_op (XDR *xdrs, gf1_cli_top_op *objp)  { -         if (!xdr_enum (xdrs, (enum_t *) objp)) -                 return FALSE; -        return TRUE; +	 if (!xdr_enum (xdrs, (enum_t *) objp)) +		 return FALSE; +	return TRUE;  }  bool_t @@ -131,6 +130,7 @@ xdr_gf1_cli_probe_req (XDR *xdrs, gf1_cli_probe_req *objp)  bool_t  xdr_gf1_cli_probe_rsp (XDR *xdrs, gf1_cli_probe_rsp *objp)  { +  	register int32_t *buf;  	if (xdrs->x_op == XDR_ENCODE) { @@ -548,36 +548,6 @@ xdr_gf1_cli_reset_vol_rsp (XDR *xdrs, gf1_cli_reset_vol_rsp *objp)  }  bool_t -xdr_gf1_cli_quota_req (XDR *xdrs, gf1_cli_quota_req *objp) -{ - -	 if (!xdr_string (xdrs, &objp->volname, ~0)) -		 return FALSE; -	 if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val, (u_int *) &objp->dict.dict_len, ~0)) -		 return FALSE; -	return TRUE; -} - -bool_t -xdr_gf1_cli_quota_rsp (XDR *xdrs, gf1_cli_quota_rsp *objp) -{ - -	 if (!xdr_int (xdrs, &objp->op_ret)) -		 return FALSE; -	 if (!xdr_int (xdrs, &objp->op_errno)) -		 return FALSE; -	 if (!xdr_string (xdrs, &objp->volname, ~0)) -		 return FALSE; -	 if (!xdr_string (xdrs, &objp->op_errstr, ~0)) -		 return FALSE; -	 if (!xdr_string (xdrs, &objp->limit_list, ~0)) -		 return FALSE; -	 if (!xdr_gf_quota_type (xdrs, &objp->type)) -		 return FALSE; -	return TRUE; -} - -bool_t  xdr_gf1_cli_set_vol_req (XDR *xdrs, gf1_cli_set_vol_req *objp)  { @@ -750,10 +720,8 @@ xdr_gf1_cli_gsync_set_rsp (XDR *xdrs, gf1_cli_gsync_set_rsp *objp)  		 return FALSE;  	 if (!xdr_int (xdrs, &objp->type))  		 return FALSE; -        if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val, -                        (u_int *) &objp->dict.dict_len, ~0)) -                return FALSE; - +	 if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val, (u_int *) &objp->dict.dict_len, ~0)) +		 return FALSE;  	return TRUE;  } @@ -767,7 +735,6 @@ xdr_gf1_cli_stats_volume_req (XDR *xdrs, gf1_cli_stats_volume_req *objp)  		 return FALSE;  	 if (!xdr_bytes (xdrs, (char **)&objp->dict_req.dict_req_val, (u_int *) &objp->dict_req.dict_req_len, ~0))  		 return FALSE; -  	return TRUE;  } @@ -787,8 +754,39 @@ xdr_gf1_cli_stats_volume_rsp (XDR *xdrs, gf1_cli_stats_volume_rsp *objp)  }  bool_t +xdr_gf1_cli_quota_req (XDR *xdrs, gf1_cli_quota_req *objp) +{ + +	 if (!xdr_string (xdrs, &objp->volname, ~0)) +		 return FALSE; +	 if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val, (u_int *) &objp->dict.dict_len, ~0)) +		 return FALSE; +	return TRUE; +} + +bool_t +xdr_gf1_cli_quota_rsp (XDR *xdrs, gf1_cli_quota_rsp *objp) +{ + +	 if (!xdr_int (xdrs, &objp->op_ret)) +		 return FALSE; +	 if (!xdr_int (xdrs, &objp->op_errno)) +		 return FALSE; +	 if (!xdr_string (xdrs, &objp->volname, ~0)) +		 return FALSE; +	 if (!xdr_string (xdrs, &objp->op_errstr, ~0)) +		 return FALSE; +	 if (!xdr_string (xdrs, &objp->limit_list, ~0)) +		 return FALSE; +	 if (!xdr_gf_quota_type (xdrs, &objp->type)) +		 return FALSE; +	return TRUE; +} + +bool_t  xdr_gf1_cli_getwd_req (XDR *xdrs, gf1_cli_getwd_req *objp)  { +  	 if (!xdr_int (xdrs, &objp->unused))  		 return FALSE;  	return TRUE; @@ -797,6 +795,7 @@ xdr_gf1_cli_getwd_req (XDR *xdrs, gf1_cli_getwd_req *objp)  bool_t  xdr_gf1_cli_getwd_rsp (XDR *xdrs, gf1_cli_getwd_rsp *objp)  { +  	 if (!xdr_int (xdrs, &objp->op_ret))  		 return FALSE;  	 if (!xdr_int (xdrs, &objp->op_errno)) @@ -809,29 +808,51 @@ xdr_gf1_cli_getwd_rsp (XDR *xdrs, gf1_cli_getwd_rsp *objp)  bool_t  xdr_gf1_cli_log_level_req (XDR *xdrs, gf1_cli_log_level_req *objp)  { -        if (!xdr_string (xdrs, &objp->volname, ~0)) -                return FALSE; -        if (!xdr_string (xdrs, &objp->xlator, ~0)) -                return FALSE; +	 if (!xdr_string (xdrs, &objp->volname, ~0)) +		 return FALSE; +	 if (!xdr_string (xdrs, &objp->xlator, ~0)) +		 return FALSE; +	 if (!xdr_string (xdrs, &objp->loglevel, ~0)) +		 return FALSE; +	return TRUE; +} -        if (!xdr_string (xdrs, &objp->loglevel, ~0)) -                return FALSE; +bool_t +xdr_gf1_cli_log_level_rsp (XDR *xdrs, gf1_cli_log_level_rsp *objp) +{ -        return TRUE; +	 if (!xdr_int (xdrs, &objp->op_ret)) +		 return FALSE; +	 if (!xdr_int (xdrs, &objp->op_errno)) +		 return FALSE; +	 if (!xdr_string (xdrs, &objp->op_errstr, ~0)) +		 return FALSE; +	return TRUE;  }  bool_t -xdr_gf1_cli_log_level_rsp (XDR *xdrs, gf1_cli_log_level_rsp *objp) +xdr_gf1_cli_status_volume_req (XDR *xdrs, gf1_cli_status_volume_req *objp)  { -        if (!xdr_int (xdrs, &objp->op_ret)) -                return FALSE; -        if (!xdr_int (xdrs, &objp->op_errno)) -                return FALSE; +	 if (!xdr_string (xdrs, &objp->volname, ~0)) +		 return FALSE; +	 if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val, (u_int *) &objp->dict.dict_len, ~0)) +		 return FALSE; +	return TRUE; +} -        if (!xdr_string (xdrs, &objp->op_errstr, ~0)) -                return FALSE; +bool_t +xdr_gf1_cli_status_volume_rsp (XDR *xdrs, gf1_cli_status_volume_rsp *objp) +{ -        return TRUE; +	 if (!xdr_int (xdrs, &objp->op_ret)) +		 return FALSE; +	 if (!xdr_int (xdrs, &objp->op_errno)) +		 return FALSE; +	 if (!xdr_string (xdrs, &objp->op_errstr, ~0)) +		 return FALSE; +	 if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val, (u_int *) &objp->dict.dict_len, ~0)) +		 return FALSE; +	return TRUE;  } diff --git a/rpc/xdr/src/cli1-xdr.h b/rpc/xdr/src/cli1-xdr.h index 81319c2906c..cce3ecbe89a 100644 --- a/rpc/xdr/src/cli1-xdr.h +++ b/rpc/xdr/src/cli1-xdr.h @@ -26,7 +26,6 @@  #include <rpc/rpc.h> -#include "xdr-common.h"  #ifdef __cplusplus  extern "C" { @@ -90,8 +89,7 @@ enum gf1_cli_gsync_set {  	GF_GSYNC_OPTION_TYPE_START = 1,  	GF_GSYNC_OPTION_TYPE_STOP = 2,  	GF_GSYNC_OPTION_TYPE_CONFIG = 3, -        GF_GSYNC_OPTION_TYPE_STATUS = 4, - +	GF_GSYNC_OPTION_TYPE_STATUS = 4,  };  typedef enum gf1_cli_gsync_set gf1_cli_gsync_set; @@ -100,19 +98,19 @@ enum gf1_cli_stats_op {  	GF_CLI_STATS_START = 1,  	GF_CLI_STATS_STOP = 2,  	GF_CLI_STATS_INFO = 3, -        GF_CLI_STATS_TOP = 4, +	GF_CLI_STATS_TOP = 4,  };  typedef enum gf1_cli_stats_op gf1_cli_stats_op;  enum gf1_cli_top_op { -        GF_CLI_TOP_NONE = 0, -        GF_CLI_TOP_OPEN = 0 + 1, -        GF_CLI_TOP_READ = 0 + 2, -        GF_CLI_TOP_WRITE = 0 + 3, -        GF_CLI_TOP_OPENDIR = 0 + 4, -        GF_CLI_TOP_READDIR = 0 + 5, -        GF_CLI_TOP_READ_PERF = 0 + 6, -        GF_CLI_TOP_WRITE_PERF = 0 + 7, +	GF_CLI_TOP_NONE = 0, +	GF_CLI_TOP_OPEN = 0 + 1, +	GF_CLI_TOP_READ = 0 + 2, +	GF_CLI_TOP_WRITE = 0 + 3, +	GF_CLI_TOP_OPENDIR = 0 + 4, +	GF_CLI_TOP_READDIR = 0 + 5, +	GF_CLI_TOP_READ_PERF = 0 + 6, +	GF_CLI_TOP_WRITE_PERF = 0 + 7,  };  typedef enum gf1_cli_top_op gf1_cli_top_op; @@ -353,25 +351,6 @@ struct gf1_cli_reset_vol_rsp {  };  typedef struct gf1_cli_reset_vol_rsp gf1_cli_reset_vol_rsp; -struct gf1_cli_quota_req { -	char *volname; -	struct { -		u_int dict_len; -		char *dict_val; -	} dict; -}; -typedef struct gf1_cli_quota_req gf1_cli_quota_req; - -struct gf1_cli_quota_rsp { -	int op_ret; -	int op_errno; -	char *volname; -	char *op_errstr; -	char *limit_list; -	gf_quota_type type; -}; -typedef struct gf1_cli_quota_rsp gf1_cli_quota_rsp; -  struct gf1_cli_set_vol_req {  	char *volname;  	struct { @@ -488,7 +467,7 @@ struct gf1_cli_stats_volume_req {  	gf1_cli_stats_op op;  	struct {  		u_int dict_req_len; -		char* dict_req_val; +		char *dict_req_val;  	} dict_req;  };  typedef struct gf1_cli_stats_volume_req gf1_cli_stats_volume_req; @@ -504,6 +483,25 @@ struct gf1_cli_stats_volume_rsp {  };  typedef struct gf1_cli_stats_volume_rsp gf1_cli_stats_volume_rsp; +struct gf1_cli_quota_req { +	char *volname; +	struct { +		u_int dict_len; +		char *dict_val; +	} dict; +}; +typedef struct gf1_cli_quota_req gf1_cli_quota_req; + +struct gf1_cli_quota_rsp { +	int op_ret; +	int op_errno; +	char *volname; +	char *op_errstr; +	char *limit_list; +	gf_quota_type type; +}; +typedef struct gf1_cli_quota_rsp gf1_cli_quota_rsp; +  struct gf1_cli_getwd_req {  	int unused;  }; @@ -517,32 +515,52 @@ struct gf1_cli_getwd_rsp {  typedef struct gf1_cli_getwd_rsp gf1_cli_getwd_rsp;  struct gf1_cli_log_level_req { -        char *volname; -        char *xlator; -        char *loglevel; +	char *volname; +	char *xlator; +	char *loglevel;  };  typedef struct gf1_cli_log_level_req gf1_cli_log_level_req;  struct gf1_cli_log_level_rsp { -        int op_ret; -        int op_errno; -        char *op_errstr; +	int op_ret; +	int op_errno; +	char *op_errstr;  };  typedef struct gf1_cli_log_level_rsp gf1_cli_log_level_rsp; +struct gf1_cli_status_volume_req { +	char *volname; +	struct { +		u_int dict_len; +		char *dict_val; +	} dict; +}; +typedef struct gf1_cli_status_volume_req gf1_cli_status_volume_req; + +struct gf1_cli_status_volume_rsp { +	int op_ret; +	int op_errno; +	char *op_errstr; +	struct { +		u_int dict_len; +		char *dict_val; +	} dict; +}; +typedef struct gf1_cli_status_volume_rsp gf1_cli_status_volume_rsp; +  /* the xdr functions */  #if defined(__STDC__) || defined(__cplusplus)  extern  bool_t xdr_gf1_cluster_type (XDR *, gf1_cluster_type*);  extern  bool_t xdr_gf1_cli_replace_op (XDR *, gf1_cli_replace_op*); +extern  bool_t xdr_gf_quota_type (XDR *, gf_quota_type*);  extern  bool_t xdr_gf1_cli_friends_list (XDR *, gf1_cli_friends_list*);  extern  bool_t xdr_gf1_cli_get_volume (XDR *, gf1_cli_get_volume*);  extern  bool_t xdr_gf1_cli_sync_volume (XDR *, gf1_cli_sync_volume*);  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_top_op (XDR *, gf1_cli_top_op*);  extern  bool_t xdr_gf1_cli_stats_op (XDR *, gf1_cli_stats_op*); -extern  bool_t xdr_gf_quota_type (XDR *, gf_quota_type*); +extern  bool_t xdr_gf1_cli_top_op (XDR *, gf1_cli_top_op*);  extern  bool_t xdr_gf1_cli_probe_req (XDR *, gf1_cli_probe_req*);  extern  bool_t xdr_gf1_cli_probe_rsp (XDR *, gf1_cli_probe_rsp*);  extern  bool_t xdr_gf1_cli_deprobe_req (XDR *, gf1_cli_deprobe_req*); @@ -572,8 +590,6 @@ extern  bool_t xdr_gf1_cli_replace_brick_req (XDR *, gf1_cli_replace_brick_req*)  extern  bool_t xdr_gf1_cli_replace_brick_rsp (XDR *, gf1_cli_replace_brick_rsp*);  extern  bool_t xdr_gf1_cli_reset_vol_req (XDR *, gf1_cli_reset_vol_req*);  extern  bool_t xdr_gf1_cli_reset_vol_rsp (XDR *, gf1_cli_reset_vol_rsp*); -extern  bool_t xdr_gf1_cli_quota_req (XDR *, gf1_cli_quota_req*); -extern  bool_t xdr_gf1_cli_quota_rsp (XDR *, gf1_cli_quota_rsp*);  extern  bool_t xdr_gf1_cli_set_vol_req (XDR *, gf1_cli_set_vol_req*);  extern  bool_t xdr_gf1_cli_set_vol_rsp (XDR *, gf1_cli_set_vol_rsp*);  extern  bool_t xdr_gf1_cli_log_filename_req (XDR *, gf1_cli_log_filename_req*); @@ -590,14 +606,19 @@ extern  bool_t xdr_gf1_cli_gsync_set_req (XDR *, gf1_cli_gsync_set_req*);  extern  bool_t xdr_gf1_cli_gsync_set_rsp (XDR *, gf1_cli_gsync_set_rsp*);  extern  bool_t xdr_gf1_cli_stats_volume_req (XDR *, gf1_cli_stats_volume_req*);  extern  bool_t xdr_gf1_cli_stats_volume_rsp (XDR *, gf1_cli_stats_volume_rsp*); -extern  bool_t xdr_gf1_cli_log_level_req (XDR *, gf1_cli_log_level_req *); -extern  bool_t xdr_gf1_cli_log_level_rsp (XDR *, gf1_cli_log_level_rsp *); +extern  bool_t xdr_gf1_cli_quota_req (XDR *, gf1_cli_quota_req*); +extern  bool_t xdr_gf1_cli_quota_rsp (XDR *, gf1_cli_quota_rsp*);  extern  bool_t xdr_gf1_cli_getwd_req (XDR *, gf1_cli_getwd_req*);  extern  bool_t xdr_gf1_cli_getwd_rsp (XDR *, gf1_cli_getwd_rsp*); +extern  bool_t xdr_gf1_cli_log_level_req (XDR *, gf1_cli_log_level_req*); +extern  bool_t xdr_gf1_cli_log_level_rsp (XDR *, gf1_cli_log_level_rsp*); +extern  bool_t xdr_gf1_cli_status_volume_req (XDR *, gf1_cli_status_volume_req*); +extern  bool_t xdr_gf1_cli_status_volume_rsp (XDR *, gf1_cli_status_volume_rsp*);  #else /* K&R C */  extern bool_t xdr_gf1_cluster_type ();  extern bool_t xdr_gf1_cli_replace_op (); +extern bool_t xdr_gf_quota_type ();  extern bool_t xdr_gf1_cli_friends_list ();  extern bool_t xdr_gf1_cli_get_volume ();  extern bool_t xdr_gf1_cli_sync_volume (); @@ -605,7 +626,6 @@ 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_quota_type ();  extern bool_t xdr_gf1_cli_probe_req ();  extern bool_t xdr_gf1_cli_probe_rsp ();  extern bool_t xdr_gf1_cli_deprobe_req (); @@ -635,8 +655,6 @@ extern bool_t xdr_gf1_cli_replace_brick_req ();  extern bool_t xdr_gf1_cli_replace_brick_rsp ();  extern bool_t xdr_gf1_cli_reset_vol_req ();  extern bool_t xdr_gf1_cli_reset_vol_rsp (); -extern bool_t xdr_gf1_cli_quota_req (); -extern bool_t xdr_gf1_cli_quota_rsp ();  extern bool_t xdr_gf1_cli_set_vol_req ();  extern bool_t xdr_gf1_cli_set_vol_rsp ();  extern bool_t xdr_gf1_cli_log_filename_req (); @@ -653,10 +671,14 @@ extern bool_t xdr_gf1_cli_gsync_set_req ();  extern bool_t xdr_gf1_cli_gsync_set_rsp ();  extern bool_t xdr_gf1_cli_stats_volume_req ();  extern bool_t xdr_gf1_cli_stats_volume_rsp (); -extern bool_t xdr_gf1_cli_log_level_req (); -extern bool_t xdr_gf1_cli_log_level_rsp (); +extern bool_t xdr_gf1_cli_quota_req (); +extern bool_t xdr_gf1_cli_quota_rsp ();  extern bool_t xdr_gf1_cli_getwd_req ();  extern bool_t xdr_gf1_cli_getwd_rsp (); +extern bool_t xdr_gf1_cli_log_level_req (); +extern bool_t xdr_gf1_cli_log_level_rsp (); +extern bool_t xdr_gf1_cli_status_volume_req (); +extern bool_t xdr_gf1_cli_status_volume_rsp ();  #endif /* K&R C */ diff --git a/rpc/xdr/src/cli1-xdr.x b/rpc/xdr/src/cli1-xdr.x index ee21d4bb3d8..db15b822a8f 100644 --- a/rpc/xdr/src/cli1-xdr.x +++ b/rpc/xdr/src/cli1-xdr.x @@ -1,7 +1,8 @@   enum gf1_cluster_type {          GF_CLUSTER_TYPE_NONE = 0,          GF_CLUSTER_TYPE_STRIPE, -        GF_CLUSTER_TYPE_REPLICATE +        GF_CLUSTER_TYPE_REPLICATE, +        GF_CLUSTER_TYPE_STRIPE_REPLICATE  } ;   enum gf1_cli_replace_op { @@ -344,6 +345,7 @@ struct gf1_cli_gsync_set_rsp {  struct gf1_cli_stats_volume_req {          string           volname<>;          gf1_cli_stats_op op; +        opaque           dict_req<>;  };  struct gf1_cli_stats_volume_rsp { @@ -378,13 +380,25 @@ struct gf1_cli_getwd_rsp {  };  struct gf1_cli_log_level_req { -       char *volname; -       char *xlator; -       char *loglevel; +       string volname<>; +       string xlator<>; +       string loglevel<>;  };  struct gf1_cli_log_level_rsp {         int op_ret;         int op_errno; -       char *op_errstr; +       string op_errstr<>; +}; + +struct gf1_cli_status_volume_req { +        string  volname<>; +        opaque  dict<>; +}; + +struct gf1_cli_status_volume_rsp { +       int op_ret; +       int op_errno; +       string op_errstr<>; +       opaque dict<>;  }; diff --git a/rpc/xdr/src/cli1.c b/rpc/xdr/src/cli1.c index 56d59bea6f0..b69aa612027 100644 --- a/rpc/xdr/src/cli1.c +++ b/rpc/xdr/src/cli1.c @@ -776,3 +776,39 @@ gf_xdr_from_cli_log_level_rsp (struct iovec outmsg, void *args)          return xdr_serialize_generic (outmsg, (void *)args,                                        (xdrproc_t)xdr_gf1_cli_log_level_rsp);  } + +ssize_t +gf_xdr_serialize_cli_status_volume_rsp (struct iovec outmsg, void *rsp) +{ +        return xdr_serialize_generic (outmsg, (void *)rsp, +                                    (xdrproc_t)xdr_gf1_cli_status_volume_rsp); + +} + +ssize_t +gf_xdr_to_cli_status_volume_req (struct iovec inmsg, void *args) +{ +        return xdr_to_generic (inmsg, (void *)args, +                               (xdrproc_t)xdr_gf1_cli_status_volume_req); +} + +ssize_t +gf_xdr_from_cli_status_volume_req (struct iovec outmsg, void *args) +{ +        return xdr_serialize_generic (outmsg, (void*)args, +                                    (xdrproc_t)xdr_gf1_cli_status_volume_req); +} + +ssize_t +gf_xdr_to_cli_status_volume_rsp (struct iovec inmsg, void *args) +{ +        return xdr_to_generic (inmsg, (void *)args, +                               (xdrproc_t)xdr_gf1_cli_status_volume_rsp); +} + +ssize_t +gf_xdr_from_cli_status_volume_rsp (struct iovec outmsg, void *args) +{ +        return xdr_serialize_generic (outmsg, (void *)args, +                                    (xdrproc_t)xdr_gf1_cli_status_volume_rsp); +} diff --git a/rpc/xdr/src/cli1.h b/rpc/xdr/src/cli1.h index 22c16862ef3..9da385cbb21 100644 --- a/rpc/xdr/src/cli1.h +++ b/rpc/xdr/src/cli1.h @@ -343,4 +343,20 @@ gf_xdr_to_cli_getwd_rsp (struct iovec inmsg, void *args);  ssize_t  gf_xdr_from_cli_getwd_rsp (struct iovec outmsg, void *args); + +ssize_t +gf_xdr_serialize_cli_status_volume_rsp (struct iovec outmsg, void *rsp); + +ssize_t +gf_xdr_to_cli_status_volume_req (struct iovec inmsg, void *args); + +ssize_t +gf_xdr_to_cli_status_volume_rsp (struct iovec inmsg, void *args); + +ssize_t +gf_xdr_from_cli_status_volume_req (struct iovec outmsg, void *req); + +ssize_t +gf_xdr_serialize_cli_status_volume_rsp (struct iovec outmsg, void *rsp); +  #endif /* !_CLI1_H */ diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c index 39f8976e833..09ed6ae2ce2 100644 --- a/xlators/mgmt/glusterd/src/glusterd-handler.c +++ b/xlators/mgmt/glusterd/src/glusterd-handler.c @@ -3875,6 +3875,63 @@ out:  }  int +glusterd_handle_status_volume (rpcsvc_request_t *req) +{ +        int32_t                         ret     = -1; +        gf1_cli_status_volume_req       cli_req = {0,}; +        dict_t                          *dict    = NULL; +        int                             lock_fail = 0; +        glusterd_op_t                   cli_op = GD_OP_STATUS_VOLUME; + +        GF_ASSERT (req); + +        ret = glusterd_op_set_cli_op (cli_op); +        if (ret) { +                gf_log ("", GF_LOG_ERROR, "Unable to set cli op: %d", +                        ret); +                lock_fail = 1; +                goto out; +        } + +        ret = -1; +        if (!gf_xdr_to_cli_status_volume_req (req->msg[0], &cli_req)) { +                //failed to decode msg; +                req->rpc_err = GARBAGE_ARGS; +                goto out; +        } + +        gf_log ("glusterd", GF_LOG_INFO, "Received status volume req " +                "for volume %s", cli_req.volname); + +        dict = dict_new (); +        if (!dict) +                goto out; + +        ret = dict_set_dynmstr (dict, "volname", cli_req.volname); +        if (ret) +                goto out; + +        ret = glusterd_op_begin (req, GD_OP_STATUS_VOLUME, dict, _gf_true); + +out: +        if (ret && dict) +                dict_unref (dict); + +        glusterd_friend_sm (); +        glusterd_op_sm (); + +        if (ret) { +                ret = glusterd_op_send_cli_response (cli_op, ret, 0, req, +                                                     NULL, "operation failed"); +                if (!lock_fail) +                        (void) glusterd_opinfo_unlock (); + +        } + +        return ret; +} + +int  glusterd_brick_rpc_notify (struct rpc_clnt *rpc, void *mydata,                            rpc_clnt_event_t event,                            void *data) @@ -4020,6 +4077,7 @@ rpcsvc_actor_t gd_svc_cli_actors[] = {          [GLUSTER_CLI_QUOTA]         = { "QUOTA", GLUSTER_CLI_QUOTA, glusterd_handle_quota, NULL, NULL},          [GLUSTER_CLI_LOG_LEVEL]     = {"LOG_LEVEL", GLUSTER_CLI_LOG_LEVEL, glusterd_handle_log_level, NULL, NULL},          [GLUSTER_CLI_GETWD]         = { "GETWD", GLUSTER_CLI_GETWD, glusterd_handle_getwd, NULL, NULL}, +        [GLUSTER_CLI_STATUS_VOLUME]  = {"STATUS_VOLUME", GLUSTER_CLI_STATUS_VOLUME, glusterd_handle_status_volume, NULL, NULL},  }; @@ -4064,7 +4122,8 @@ rpcsvc_actor_t glusterd1_mgmt_actors[] = {          [GD_MGMT_CLI_FSM_LOG] = { "FSM_LOG", GD_MGMT_CLI_FSM_LOG, glusterd_handle_fsm_log, NULL, NULL},          [GD_MGMT_CLI_GSYNC_SET] = {"GSYNC_SET", GD_MGMT_CLI_GSYNC_SET, glusterd_handle_gsync_set, NULL, NULL},          [GD_MGMT_CLI_PROFILE_VOLUME] = { "STATS_VOLUME", GD_MGMT_CLI_PROFILE_VOLUME, glusterd_handle_cli_profile_volume, NULL, NULL}, -        [GD_MGMT_CLI_LOG_LEVEL] = {"LOG_LEVEL", GD_MGMT_CLI_LOG_LEVEL, glusterd_handle_log_level, NULL, NULL} +        [GD_MGMT_CLI_LOG_LEVEL] = {"LOG_LEVEL", GD_MGMT_CLI_LOG_LEVEL, glusterd_handle_log_level, NULL, NULL}, +        [GD_MGMT_CLI_STATUS_VOLUME] = {"STATUS_VOLUME", GD_MGMT_CLI_STATUS_VOLUME, glusterd_handle_status_volume, NULL, NULL}  };  struct rpcsvc_program glusterd1_mop_prog = { diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c index 0875ec97ae3..a99c9fa1372 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c @@ -1856,6 +1856,48 @@ out:          return ret;  } +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,}; + +        GF_ASSERT (dict); +        this = THIS; +        GF_ASSERT (this); +        priv = this->private; +        GF_ASSERT(priv); + + +        ret = dict_get_str (dict, "volname", &volname); +        if (ret) { +                gf_log ("glusterd", GF_LOG_ERROR, "Unable to get volume name"); +                goto out; +        } + +        exists = glusterd_check_volume_exists (volname); +        if (!exists) { +                snprintf (msg, sizeof(msg), "Volume %s does not exist", volname); +                gf_log ("glusterd", 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); +        return ret; +}  int  glusterd_query_extutil (char *resbuf, runner_t *runner) @@ -6440,6 +6482,67 @@ out:  }  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; + +        this = THIS; +        GF_ASSERT (this); +        priv = this->private; + +        GF_ASSERT (priv); + +        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; +                } +        } + +        if (!rsp_dict) { +                //this should happen only on source +                ret = 0; +                rsp_dict = glusterd_op_get_ctx (GD_OP_STATUS_VOLUME); +        } + +        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_int32 (rsp_dict, "count", brick_count); + +out: +        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); + +        return ret; +} + +static int  glusterd_op_ac_none (glusterd_op_sm_event_t *event, void *ctx)  {          int ret = 0; @@ -6664,6 +6767,7 @@ glusterd_op_build_payload (glusterd_op_t op, dict_t **req)                  case GD_OP_GSYNC_SET:                  case GD_OP_PROFILE_VOLUME:                  case GD_OP_LOG_LEVEL: +                case GD_OP_STATUS_VOLUME:                          {                                  dict_t  *dict = ctx;                                  dict_copy (dict, req_dict); @@ -7628,6 +7732,10 @@ glusterd_op_stage_validate (glusterd_op_t op, dict_t *dict, char **op_errstr,                          ret = glusterd_op_stage_log_level (dict, op_errstr);                          break; +                case GD_OP_STATUS_VOLUME: +                        ret = glusterd_op_stage_status_volume (dict, op_errstr); +                        break; +                  default:                          gf_log ("", GF_LOG_ERROR, "Unknown op %d",                                  op); @@ -7711,6 +7819,10 @@ glusterd_op_commit_perform (glusterd_op_t op, dict_t *dict, char **op_errstr,                         ret = glusterd_op_log_level (dict);                         break; +               case GD_OP_STATUS_VOLUME: +                       ret = glusterd_op_status_volume (dict, op_errstr, rsp_dict); +                       break; +                  default:                          gf_log ("", GF_LOG_ERROR, "Unknown op %d",                                  op); @@ -8733,6 +8845,7 @@ glusterd_op_free_ctx (glusterd_op_t op, void *ctx, gf_boolean_t ctx_free)                  case GD_OP_QUOTA:                  case GD_OP_PROFILE_VOLUME:                  case GD_OP_LOG_LEVEL: +                case GD_OP_STATUS_VOLUME:                          dict_unref (ctx);                          break;                  case GD_OP_DELETE_VOLUME: diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.h b/xlators/mgmt/glusterd/src/glusterd-op-sm.h index 5dc1a56372a..b95d584aca6 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.h +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.h @@ -163,6 +163,11 @@ typedef struct glusterd_pr_brick_rsp_conv_t {          dict_t *dict;  } glusterd_pr_brick_rsp_conv_t; +typedef struct glusterd_status_rsp_conv_ { +        int count; +        dict_t *dict; +} glusterd_status_rsp_conv_t; +  typedef struct glusterd_gsync_slaves {          char *slave;          char *host_uuid; diff --git a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c index fa60430da91..36868d3ce3c 100644 --- a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c @@ -57,7 +57,7 @@ glusterd_op_send_cli_response (glusterd_op_t op, int32_t op_ret,          dict_t          *ctx = NULL;          char            *free_ptr = NULL;          glusterd_conf_t *conf = NULL; -        xdrproc_t       xdrproc; +        xdrproc_t       xdrproc = NULL;          GF_ASSERT (THIS); @@ -407,6 +407,26 @@ glusterd_op_send_cli_response (glusterd_op_t op, int32_t op_ret,                  break;          } + +        case GD_OP_STATUS_VOLUME: +        { +                gf1_cli_status_volume_rsp rsp = {0,}; +                rsp.op_ret = op_ret; +                rsp.op_errno = op_errno; +                if (op_errstr) +                        rsp.op_errstr = op_errstr; +                else +                        rsp.op_errstr = ""; +                ctx = op_ctx; +                dict_allocate_and_serialize (ctx, +                             &rsp.dict.dict_val, +                             (size_t*)&rsp.dict.dict_len); +                free_ptr = rsp.dict.dict_val; +                cli_rsp = &rsp; +                sfunc = gf_xdr_serialize_cli_status_volume_rsp; +                xdrproc = (xdrproc_t) xdr_gf1_cli_status_volume_rsp; +                break; +        }          case GD_OP_NONE:          case GD_OP_MAX:          { @@ -1219,6 +1239,62 @@ out:          return ret;  } +void +glusterd_volume_status_add_peer_rsp (dict_t *this, char *key, data_t *value, +                                     void *data) +{ +        glusterd_status_rsp_conv_t      *rsp_ctx = NULL; +        data_t                          *new_value = NULL; +        int32_t                         ret = 0; + +        if (strcmp (key, "count") == 0) +                return; + +        rsp_ctx = data; +        new_value = data_copy (value); +        GF_ASSERT (new_value); + +        ret = dict_set (rsp_ctx->dict, key, new_value); +        if (ret) +                gf_log ("", GF_LOG_ERROR, "Unable to set key: %s in dict", +                        key); + +        return; +} + +int +glusterd_volume_status_use_rsp_dict (dict_t *rsp_dict) +{ +        int                             ret = 0; +        glusterd_status_rsp_conv_t      rsp_ctx = {0}; +        int32_t                         brick_count = 0; +        int32_t                         count = 0; +        dict_t                          *ctx_dict = NULL; +        glusterd_op_t                   op = GD_OP_NONE; + +        GF_ASSERT (rsp_dict); + +        ret = dict_get_int32 (rsp_dict, "count", &brick_count); +        if (ret) { +                ret = 0; //no bricks in the rsp +                goto out; +        } + +        op = glusterd_op_get_op (); +        GF_ASSERT (GD_OP_STATUS_VOLUME == op); +        ctx_dict = glusterd_op_get_ctx (op); + +        ret = dict_get_int32 (ctx_dict, "count", &count); +        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; +} +  int32_t  glusterd3_1_commit_op_cbk (struct rpc_req *req, struct iovec *iov,                            int count, void *myframe) @@ -1330,6 +1406,12 @@ glusterd3_1_commit_op_cbk (struct rpc_req *req, struct iovec *iov,                                  goto out;                  break; +                case GD_OP_STATUS_VOLUME: +                        ret = glusterd_volume_status_use_rsp_dict (dict); +                        if (ret) +                                goto out; +                break; +                  default:                  break;                  } diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c index fb7f75c523b..278b25c954a 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -2538,6 +2538,93 @@ out:          return -1;  } +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}; +        FILE            *file = NULL; +        int32_t         pid = -1; +        xlator_t        *this = NULL; +        glusterd_conf_t *priv = NULL; + +        GF_ASSERT (volinfo); +        GF_ASSERT (brickinfo); +        GF_ASSERT (dict); + +        this = THIS; +        GF_ASSERT (this); + +        priv = this->private; + +        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; + +        memset (key, 0, sizeof (key)); +        snprintf (key, sizeof (key), "%s.path", base_key); +        ret = dict_set_str (dict, key, brickinfo->path); +        if (ret) +                goto out; + +        memset (key, 0, sizeof (key)); +        snprintf (key, sizeof (key), "%s.port", base_key); +        ret = dict_set_int32 (dict, key, brickinfo->port); +        if (ret) +                goto out; + + +        memset (key, 0, sizeof (key)); +        snprintf (key, sizeof (key), "%s.status", base_key); +        ret = dict_set_int32 (dict, key, brickinfo->signed_in); +        if (ret) +                goto out; + +        if (!brickinfo->signed_in) +                goto out; + + +        GLUSTERD_GET_VOLUME_DIR (path, volinfo, priv); +        GLUSTERD_GET_BRICK_PIDFILE (pidfile, path, brickinfo->hostname, +                                    brickinfo->path); + +        file = fopen (pidfile, "r+"); +        if (!file) { +                gf_log ("", GF_LOG_ERROR, "Unable to open pidfile: %s", +                        pidfile); +                ret = -1; +                goto out; +        } + +        ret = fscanf (file, "%d", &pid); +        if (ret <= 0) { +                gf_log ("", GF_LOG_ERROR, "Unable to read pidfile: %s", +                        pidfile); +                ret = -1; +                goto out; +        } + +        memset (key, 0, sizeof (key)); +        snprintf (key, sizeof (key), "%s.pid", base_key); +        ret = dict_set_int32 (dict, key, pid); +        if (ret) +                goto out; + +out: +        if (ret) +                gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); + +        return ret; +} +  int  glusterd_all_volume_cond_check (glusterd_condition_func func, int status,                                  void *ctx) diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h index 1f5223fefc1..93e2cb92d22 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.h +++ b/xlators/mgmt/glusterd/src/glusterd-utils.h @@ -282,4 +282,8 @@ glusterd_recreate_bricks (glusterd_conf_t *conf);  int32_t  glusterd_handle_upgrade_downgrade (dict_t *options, glusterd_conf_t *conf); +int32_t +glusterd_add_brick_to_dict (glusterd_volinfo_t *volinfo, +                            glusterd_brickinfo_t *brickinfo, +                            dict_t  *dict, int32_t count);  #endif diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h index ab4049d0ba5..4362984fef4 100644 --- a/xlators/mgmt/glusterd/src/glusterd.h +++ b/xlators/mgmt/glusterd/src/glusterd.h @@ -77,6 +77,7 @@ typedef enum glusterd_op_ {          GD_OP_PROFILE_VOLUME,          GD_OP_QUOTA,          GD_OP_LOG_LEVEL, +        GD_OP_STATUS_VOLUME,          GD_OP_MAX,  } glusterd_op_t; | 
