diff options
| author | Krishnan Parthasarathi <kp@gluster.com> | 2011-09-16 10:40:32 +0530 | 
|---|---|---|
| committer | Vijay Bellur <vijay@gluster.com> | 2011-09-22 09:43:25 -0700 | 
| commit | 4765dd1a1c51c67ab86687fbd871c89156680c34 (patch) | |
| tree | d1d3890457cbcb01131d21f66e40ec8a1c537cf1 /glusterfsd/src | |
| parent | 53b5da6dfab2e6b11ab2e40119e92ff7d4527b2c (diff) | |
glusterd: Implemented cmd to trigger self-heal on a replicate volume.v3.3.0qa10
This cmd is used in the context of proactive self-heal for replicated
volumes. User invokes the following cmd when (s)he suspects that self-heal
needs to be done on a particular volume,
        gluster volume heal <VOLNAME>.
Change-Id: I3954353b53488c28b70406e261808239b44997f3
BUG: 3602
Reviewed-on: http://review.gluster.com/454
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Vijay Bellur <vijay@gluster.com>
Diffstat (limited to 'glusterfsd/src')
| -rw-r--r-- | glusterfsd/src/glusterfsd-mgmt.c | 127 | 
1 files changed, 126 insertions, 1 deletions
diff --git a/glusterfsd/src/glusterfsd-mgmt.c b/glusterfsd/src/glusterfsd-mgmt.c index 43d49b3f4e8..adce060a6d2 100644 --- a/glusterfsd/src/glusterfsd-mgmt.c +++ b/glusterfsd/src/glusterfsd-mgmt.c @@ -316,6 +316,41 @@ out:  }  int +glusterfs_translator_heal_response_send (rpcsvc_request_t *req, int op_ret, +                                         char *msg, dict_t *output) +{ +        gd1_mgmt_brick_op_rsp    rsp = {0,}; +        int                      ret = -1; +        GF_ASSERT (msg); +        GF_ASSERT (req); +        GF_ASSERT (output); + +        rsp.op_ret = op_ret; +        rsp.op_errno = 0; +        if (ret && msg[0]) +                rsp.op_errstr = msg; +        else +                rsp.op_errstr = ""; + +        ret = dict_allocate_and_serialize (output, &rsp.output.output_val, +                                        (size_t *)&rsp.output.output_len); +        if (ret) { +                gf_log (THIS->name, GF_LOG_ERROR, "Couldn't serialize " +                        "output dict."); +                goto out; +        } + +        ret = glusterfs_submit_reply (req, &rsp, NULL, 0, NULL, +                                     (xdrproc_t)xdr_gd1_mgmt_brick_op_rsp); + +out: +        if (rsp.output.output_val) +                GF_FREE (rsp.output.output_val); + +        return ret; +} + +int  glusterfs_handle_translator_info_get (rpcsvc_request_t *req)  {          int32_t                  ret     = -1; @@ -615,6 +650,92 @@ out:  }  int +glusterfs_handle_translator_heal (rpcsvc_request_t *req) +{ +        int32_t                  ret     = -1; +        gd1_mgmt_brick_op_req    xlator_req = {0,}; +        dict_t                   *dict    = NULL; +        xlator_t                 *xlator = NULL; +        xlator_t                 *any = NULL; +        dict_t                   *output = NULL; +        char                     msg[2048] = {0}; +        char                     key[2048] = {0}; +        char                    *xname = NULL; +        glusterfs_ctx_t          *ctx = NULL; +        glusterfs_graph_t        *active = NULL; +        xlator_t                 *this = NULL; +        int                      i = 0; +        int                      count = 0; + +        GF_ASSERT (req); +        this = THIS; +        GF_ASSERT (this); + +        ctx = glusterfs_ctx_get (); +        GF_ASSERT (ctx); + +        active = ctx->active; +        any = active->first; +        if (!xdr_to_generic (req->msg[0], &xlator_req, +                             (xdrproc_t)xdr_gd1_mgmt_brick_op_req)) { +                //failed to decode msg; +                req->rpc_err = GARBAGE_ARGS; +                goto out; +        } +        dict = dict_new (); + +        ret = dict_unserialize (xlator_req.input.input_val, +                                xlator_req.input.input_len, +                                &dict); +        if (ret < 0) { +                gf_log (this->name, GF_LOG_ERROR, +                        "failed to " +                        "unserialize req-buffer to dictionary"); +                goto out; +        } + +        ret = dict_get_int32 (dict, "count", &count); +        i = 0; +        while (i < count)  { +                snprintf (key, sizeof (key), "heal-%d", i); +                ret = dict_get_str (dict, key, &xname); +                if (ret) { +                        gf_log (this->name, GF_LOG_ERROR, "Couldn't get " +                                "replicate xlator %s to trigger " +                                "self-heal", xname); +                        goto out; +                } +                xlator = xlator_search_by_name (any, xname); +                if (!xlator) { +                        snprintf (msg, sizeof (msg), "xlator %s is not loaded", +                                  xlator_req.name); +                        ret = -1; +                        goto out; +                } + +                ret = xlator_notify (xlator, GF_EVENT_TRIGGER_HEAL, dict, NULL); +                i++; +        } +        output = dict_new (); +        if (!output) +                goto out; + +        /* output dict is not used currently, could be used later. */ +        ret = glusterfs_translator_heal_response_send (req, ret, msg, output); +out: +        if (dict) +                dict_unref (dict); +        if (xlator_req.input.input_val) +                free (xlator_req.input.input_val); // malloced by xdr +        if (output) +                dict_unref (output); +        if (xlator_req.name) +                free (xlator_req.name); //malloced by xdr + +        return ret; +} + +int  glusterfs_handle_rpc_msg (rpcsvc_request_t *req)  {          int     ret = -1; @@ -627,6 +748,9 @@ glusterfs_handle_rpc_msg (rpcsvc_request_t *req)          case GF_BRICK_XLATOR_INFO:                  ret = glusterfs_handle_translator_info_get (req);                  break; +        case GF_BRICK_XLATOR_HEAL: +                ret = glusterfs_handle_translator_heal (req); +                break;          default:                  break;          } @@ -681,7 +805,8 @@ rpc_clnt_prog_t clnt_handshake_prog = {  rpcsvc_actor_t glusterfs_actors[] = {          [GF_BRICK_NULL]        = { "NULL",    GF_BRICK_NULL, glusterfs_handle_rpc_msg, NULL, NULL},          [GF_BRICK_TERMINATE] = { "TERMINATE", GF_BRICK_TERMINATE, glusterfs_handle_rpc_msg, NULL, NULL}, -        [GF_BRICK_XLATOR_INFO] = { "TRANSLATOR INFO", GF_BRICK_XLATOR_INFO, glusterfs_handle_rpc_msg, NULL, NULL} +        [GF_BRICK_XLATOR_INFO] = { "TRANSLATOR INFO", GF_BRICK_XLATOR_INFO, glusterfs_handle_rpc_msg, NULL, NULL}, +        [GF_BRICK_XLATOR_HEAL] = { "TRANSLATOR HEAL", GF_BRICK_XLATOR_HEAL, glusterfs_handle_rpc_msg, NULL, NULL}  };  struct rpcsvc_program glusterfs_mop_prog = {  | 
