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 /xlators/mgmt/glusterd/src | |
| 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>
Diffstat (limited to 'xlators/mgmt/glusterd/src')
| -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 | 
7 files changed, 353 insertions, 2 deletions
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;  | 
