diff options
| author | Pranith K <pranithk@gluster.com> | 2011-03-10 02:19:39 +0000 | 
|---|---|---|
| committer | Vijay Bellur <vijay@dev.gluster.com> | 2011-03-10 08:09:47 -0800 | 
| commit | 34bf8de743aaff3e7c242833a10791aedc404ea3 (patch) | |
| tree | 0d00570fead89437cb4612a510c3978dd5907530 /xlators/mgmt/glusterd/src/glusterd-handler.c | |
| parent | 970b22e377e20408df8646cdc61a968b55c145b1 (diff) | |
mgmt/glusterd: gluster profile implementation
Signed-off-by: Pranith Kumar K <pranithk@gluster.com>
Signed-off-by: Vijay Bellur <vijay@dev.gluster.com>
BUG: 1965 (need a cmd to get io-stat details)
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=1965
Diffstat (limited to 'xlators/mgmt/glusterd/src/glusterd-handler.c')
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-handler.c | 517 | 
1 files changed, 310 insertions, 207 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c index 0db5992fc2c..7635f15546c 100644 --- a/xlators/mgmt/glusterd/src/glusterd-handler.c +++ b/xlators/mgmt/glusterd/src/glusterd-handler.c @@ -398,6 +398,37 @@ out:          return ret;  } +int32_t +glusterd_op_txn_begin () +{ +        int32_t                 ret = -1; +        glusterd_conf_t         *priv = NULL; +        int32_t                 locked = 0; + +        priv = THIS->private; +        GF_ASSERT (priv); + +        ret = glusterd_lock (priv->uuid); + +        if (ret) { +                gf_log ("glusterd", GF_LOG_ERROR, +                        "Unable to acquire local lock, ret: %d", ret); +                goto out; +        } + +        locked = 1; +        gf_log ("glusterd", GF_LOG_NORMAL, "Acquired local lock"); + +        ret = glusterd_op_sm_inject_event (GD_OP_EVENT_START_LOCK, NULL); + +        gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret); + +out: +        if (locked && ret) +                glusterd_unlock (priv->uuid); +        return ret; +} +  int  glusterd_handle_cluster_lock (rpcsvc_request_t *req)  { @@ -439,147 +470,137 @@ out:  }  int -glusterd_handle_stage_op (rpcsvc_request_t *req) +glusterd_req_ctx_create (rpcsvc_request_t *rpc_req, +                         glusterd_op_t op, uuid_t uuid, +                         char *buf_val, size_t buf_len, +                         gf_gld_mem_types_t mem_type, +                         glusterd_req_ctx_t **req_ctx_out)  { -        int32_t                         ret = -1; -        gd1_mgmt_stage_op_req           stage_req = {{0,}}; -        glusterd_op_stage_ctx_t         *ctx = NULL; +        int                             ret = -1; +        glusterd_req_ctx_t              *req_ctx = NULL; +        char                            str[50] = {0,}; +        dict_t                          *dict = NULL;          char                            volname[GLUSTERD_MAX_VOLUME_NAME] = {0};          char                            *dup_volname = NULL; -        GF_ASSERT (req); - -        if (!gd_xdr_to_mgmt_stage_op_req (req->msg[0], &stage_req)) { -                //failed to decode msg; -                req->rpc_err = GARBAGE_ARGS; -                goto out; -        } - +        uuid_unparse (uuid, str);          gf_log ("glusterd", GF_LOG_NORMAL, -                "Received stage op from uuid: %s", uuid_utoa (stage_req.uuid)); - -        ctx = GF_CALLOC (1, sizeof (*ctx), gf_gld_mt_op_stage_ctx_t); -        if (!ctx) { -                //respond here -                goto err; -        } - -        ctx->dict = dict_new(); -        if (!ctx->dict) -                goto err; +                "Received op from uuid: %s", str); -        uuid_copy (ctx->uuid, stage_req.uuid); -        ctx->op   = stage_req.op; -        ctx->req  = req; +        dict = dict_new (); +        if (!dict) +                goto out; +        req_ctx = GF_CALLOC (1, sizeof (*req_ctx), mem_type); -        if (!stage_req.buf.buf_val) +        if (!req_ctx) {                  goto out; +        } -        if (GD_OP_DELETE_VOLUME == stage_req.op) { -                strncpy (volname, stage_req.buf.buf_val, stage_req.buf.buf_len); +        uuid_copy (req_ctx->uuid, uuid); +        req_ctx->op = op; +        if (GD_OP_DELETE_VOLUME == op) { +                strncpy (volname, buf_val, buf_len);                  dup_volname = gf_strdup (volname);                  if (dup_volname) { -                        ret = dict_set_dynstr (ctx->dict, "volname", dup_volname); -                        if (ret) +                        ret = dict_set_dynstr (dict, "volname", dup_volname); +                        if (ret) {                                  gf_log ("", GF_LOG_WARNING, -                                        "failed to set volume name from payload"); +                                                "failed to set volume name from payload"); +                                goto out; +                        } +                } else { +                        ret = -1; +                        goto out;                  } -          } else { -                ret = dict_unserialize (stage_req.buf.buf_val, -                                        stage_req.buf.buf_len, -                                        &ctx->dict); +                ret = dict_unserialize (buf_val, buf_len, &dict); -                if (ret) +                if (ret) {                          gf_log ("", GF_LOG_WARNING, -                                "failed to unserialize the dictionary"); +                                        "failed to unserialize the dictionary"); +                        goto out; +                }          } -        ret = glusterd_op_sm_inject_event (GD_OP_EVENT_STAGE_OP, ctx); - +        req_ctx->dict = dict; +        req_ctx->req   = rpc_req; +        *req_ctx_out = req_ctx; +        ret = 0;  out: -        if (stage_req.buf.buf_val) -                free (stage_req.buf.buf_val);//malloced by xdr - -        glusterd_friend_sm (); -        glusterd_op_sm (); -err: +        if (ret) { +                if (dict) +                        dict_unref (dict); +                if (req_ctx) +                        GF_FREE (req_ctx); +        }          return ret;  }  int -glusterd_handle_commit_op (rpcsvc_request_t *req) +glusterd_handle_stage_op (rpcsvc_request_t *req)  {          int32_t                         ret = -1; -        gd1_mgmt_commit_op_req          commit_req = {{0},}; -        glusterd_op_commit_ctx_t        *ctx = NULL; -        char                            volname[GLUSTERD_MAX_VOLUME_NAME] = {0}; -        char                            *dup_volname = NULL; +        glusterd_req_ctx_t              *req_ctx = NULL; +        gd1_mgmt_stage_op_req           op_req = {{0},};          GF_ASSERT (req); - -        if (!gd_xdr_to_mgmt_commit_op_req (req->msg[0], &commit_req)) { +        if (!gd_xdr_to_mgmt_stage_op_req (req->msg[0], &op_req)) {                  //failed to decode msg;                  req->rpc_err = GARBAGE_ARGS;                  goto out;          } +        ret = glusterd_req_ctx_create (req, op_req.op, op_req.uuid, +                                       op_req.buf.buf_val, op_req.buf.buf_len, +                                       gf_gld_mt_op_stage_ctx_t, &req_ctx); +        if (ret) +                goto out; -        gf_log ("glusterd", GF_LOG_NORMAL, -                "Received commit op from uuid: %s", uuid_utoa (commit_req.uuid)); - -        ctx = GF_CALLOC (1, sizeof (*ctx), gf_gld_mt_op_commit_ctx_t); - -        if (!ctx) { -                //respond here -                goto err; -        } +        ret = glusterd_op_sm_inject_event (GD_OP_EVENT_STAGE_OP, req_ctx); -        ctx->req = req; + out: +        if (op_req.buf.buf_val) +                free (op_req.buf.buf_val);//malloced by xdr +        glusterd_friend_sm (); +        glusterd_op_sm (); +        return ret; +} -        uuid_copy (ctx->uuid, commit_req.uuid); -        ctx->op = commit_req.op; +int +glusterd_handle_commit_op (rpcsvc_request_t *req) +{ +        int32_t                         ret = -1; +        glusterd_req_ctx_t              *req_ctx = NULL; +        gd1_mgmt_commit_op_req          op_req = {{0},}; -        ctx->dict = dict_new(); -        if (!ctx->dict) -                goto err; +        GF_ASSERT (req); -        if (!commit_req.buf.buf_val) +        if (!gd_xdr_to_mgmt_commit_op_req (req->msg[0], &op_req)) { +                //failed to decode msg; +                req->rpc_err = GARBAGE_ARGS;                  goto out; - -        if (GD_OP_DELETE_VOLUME == commit_req.op) { -                strncpy (volname, commit_req.buf.buf_val, commit_req.buf.buf_len); -                dup_volname = gf_strdup (volname); -                if (dup_volname) { -                        ret = dict_set_dynstr (ctx->dict, "volname", dup_volname); -                        if (ret) -                                gf_log ("", GF_LOG_WARNING, -                                        "failed to set volume name from payload"); -                } - -        } else { -                ret = dict_unserialize (commit_req.buf.buf_val, -                                        commit_req.buf.buf_len, -                                        &ctx->dict); - -                if (ret) -                        gf_log ("", GF_LOG_WARNING, -                                "failed to unserialize the dictionary");          } -        ret = glusterd_op_sm_inject_event (GD_OP_EVENT_COMMIT_OP, ctx); +        //the structures should always be equal +        GF_ASSERT (sizeof (gd1_mgmt_commit_op_req) == sizeof (gd1_mgmt_stage_op_req)); +        ret = glusterd_req_ctx_create (req, op_req.op, op_req.uuid, +                                       op_req.buf.buf_val, op_req.buf.buf_len, +                                       gf_gld_mt_op_commit_ctx_t, &req_ctx); +        if (ret) +                goto out; -out: -        if (commit_req.buf.buf_val) -                free (commit_req.buf.buf_val);//malloced by xdr +        ret = glusterd_op_sm_inject_event (GD_OP_EVENT_COMMIT_OP, req_ctx); +        if (ret) +                goto out; +        ret = glusterd_op_init_ctx (op_req.op); +out: +        if (op_req.buf.buf_val) +                free (op_req.buf.buf_val);//malloced by xdr          glusterd_friend_sm ();          glusterd_op_sm (); - -err:          return ret;  } -  int  glusterd_handle_cli_probe (rpcsvc_request_t *req)  { @@ -804,37 +825,6 @@ out:  }  int32_t -glusterd_op_txn_begin () -{ -        int32_t                 ret = -1; -        glusterd_conf_t         *priv = NULL; -        int32_t                 locked = 0; - -        priv = THIS->private; -        GF_ASSERT (priv); - -        ret = glusterd_lock (priv->uuid); - -        if (ret) { -                gf_log ("glusterd", GF_LOG_ERROR, -                        "Unable to acquire local lock, ret: %d", ret); -                goto out; -        } - -        locked = 1; -        gf_log ("glusterd", GF_LOG_NORMAL, "Acquired local lock"); - -        ret = glusterd_op_sm_inject_event (GD_OP_EVENT_START_LOCK, NULL); - -        gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret); - -out: -        if (locked && ret) -                glusterd_unlock (priv->uuid); -        return ret; -} - -int32_t  glusterd_op_begin (rpcsvc_request_t *req, glusterd_op_t op, void *ctx,                     gf_boolean_t is_ctx_free)  { @@ -2924,6 +2914,77 @@ out:  }  int +glusterd_handle_cli_profile_volume (rpcsvc_request_t *req) +{ +        int32_t                         ret     = -1; +        gf1_cli_stats_volume_req        cli_req = {0,}; +        dict_t                          *dict = NULL; +        char                            msg[2048] = {0,}; +        gf_boolean_t                    free_volname = _gf_true; +        int                             lock_fail = 0; +        glusterd_op_t                   cli_op = GD_OP_PROFILE_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_stats_volume_req (req->msg[0], &cli_req)) { +                //failed to decode msg; +                req->rpc_err = GARBAGE_ARGS; +                goto out; +        } + +        gf_log ("glusterd", GF_LOG_NORMAL, "Received volume profile 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) { +                gf_log ("", GF_LOG_ERROR, "volume name set failed"); +                snprintf (msg, sizeof (msg), "volume name set failed"); +                goto out; +        } else { +                free_volname = _gf_false; +        } + +        ret = dict_set_int32 (dict, "op", cli_req.op); +        if (ret) { +                gf_log ("", GF_LOG_ERROR, "op set failed"); +                goto out; +        } + +        ret = glusterd_op_begin (req, cli_op, dict, _gf_true); + +out: +        glusterd_friend_sm (); +        glusterd_op_sm (); +        if (ret) +                dict_unref (dict); +        if (free_volname) +                free (cli_req.volname); // malloced by xdr +        if (ret) { +                ret = glusterd_op_send_cli_response (cli_op, ret, 0, req, +                                                     NULL, "operation failed"); +                if (!lock_fail) +                        (void) glusterd_opinfo_unlock (); + +        } + +        gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret); +        return ret; +} + +int  glusterd_friend_remove (uuid_t uuid, char *hostname)  {          int                           ret = 0; @@ -2940,96 +3001,83 @@ out:  }  int -glusterd_friend_rpc_create (struct rpc_clnt **rpc, -                            const char *hoststr, int port, -                            glusterd_peerctx_t *peerctx) +glusterd_rpc_create (struct rpc_clnt **rpc, +                     dict_t *options, +                     rpc_clnt_notify_t notify_fn, +                     void *notify_data)  {          struct rpc_clnt         *new_rpc = NULL; -        dict_t                  *options = NULL; -        struct rpc_clnt_config  rpc_cfg = {0,};          int                     ret = -1; -        char                    *hostname = NULL; -        int32_t                 intvl = 0;          xlator_t                *this = NULL; -        GF_ASSERT (hoststr);          this = THIS;          GF_ASSERT (this); -        options = dict_new (); -        if (!options) +        GF_ASSERT (options); +        new_rpc = rpc_clnt_new (options, this->ctx, this->name); + +        if (!new_rpc)                  goto out; -        ret = dict_get_int32 (this->options, -                              "transport.socket.keepalive-interval", -                              &intvl); -        if (!ret) { -                ret = dict_set_int32 (options, -                        "transport.socket.keepalive-interval", intvl); -                if (ret) -                        goto out; +        ret = rpc_clnt_register_notify (new_rpc, notify_fn, notify_data); +        *rpc = new_rpc; +        if (ret) +                goto out; +        ret = rpc_clnt_start (new_rpc); +out: +        if (ret) { +                if (new_rpc) { +                        (void) rpc_clnt_unref (new_rpc); +                }          } +        gf_log ("", GF_LOG_DEBUG, "returning %d", ret); +        return ret; +} + +int +glusterd_transport_keepalive_options_get (int *interval, int *time) +{ +        int     ret = 0; +        xlator_t *this = NULL; + +        this = THIS; +        GF_ASSERT (this); + +        ret = dict_get_int32 (this->options, +                              "transport.socket.keepalive-interval", +                              interval);          ret = dict_get_int32 (this->options,                                "transport.socket.keepalive-time", -                              &intvl); -        if (!ret) { -                ret = dict_set_int32 (options, -                        "transport.socket.keepalive-time", intvl); -                if (ret) -                        goto out; -        } +                              time); +        return 0; +} -        hostname = gf_strdup((char*)hoststr); -        if (!hostname) { -                ret = -1; -                goto out; -        } +int +glusterd_transport_inet_keepalive_options_build (dict_t **options, +                                                 const char *hostname, int port) +{ +        dict_t  *dict = NULL; +        int32_t interval = -1; +        int32_t time     = -1; +        int     ret = 0; -        ret = dict_set_dynstr (options, "remote-host", hostname); -        if (ret) -                goto out; +        GF_ASSERT (options); +        GF_ASSERT (hostname);          if (!port)                  port = GLUSTERD_DEFAULT_PORT; - -        rpc_cfg.remote_host = (char *)hoststr; -        rpc_cfg.remote_port = port; - -        ret = dict_set_int32 (options, "remote-port", port); -        if (ret) -                goto out; - -        ret = dict_set_str (options, "transport.address-family", "inet"); +        ret = rpc_transport_inet_options_build (&dict, hostname, port);          if (ret)                  goto out; -        new_rpc = rpc_clnt_new (options, this->ctx, this->name); +        glusterd_transport_keepalive_options_get (&interval, &time); -        if (!new_rpc) { -                gf_log ("glusterd", GF_LOG_ERROR, -                        "new_rpc init failed for peer: %s!", hoststr); -                ret = -1; -                goto out; -        } - -        ret = rpc_clnt_register_notify (new_rpc, glusterd_rpc_notify, -                                        peerctx); -        if (ret) -                goto out; -        *rpc = new_rpc; -        rpc_clnt_start (new_rpc); +        if ((interval > 0) || (time > 0)) +                ret = rpc_transport_keepalive_options_set (dict, interval, time); +        *options = dict;  out: -        if (ret) { -                if (new_rpc) { -                        (void) rpc_clnt_unref (new_rpc); -                } -                if (options) -                        dict_unref (options); -                *rpc = NULL; -        } - -        gf_log ("", GF_LOG_DEBUG, "returning %d", ret); +        gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret);          return ret;  } @@ -3042,14 +3090,16 @@ glusterd_friend_add (const char *hoststr, int port,                       gf_boolean_t restore,                       glusterd_peerctx_args_t *args)  { -        int                     ret = 0; -        glusterd_conf_t         *conf = NULL; -        glusterd_peerinfo_t     *peerinfo = NULL; +        int                    ret = 0; +        glusterd_conf_t        *conf = NULL; +        glusterd_peerinfo_t    *peerinfo = NULL;          glusterd_peerctx_t     *peerctx = NULL; -        gf_boolean_t            is_allocated = _gf_false; +        gf_boolean_t           is_allocated = _gf_false; +        dict_t                 *options = NULL;          conf = THIS->private;          GF_ASSERT (conf) +        GF_ASSERT (hoststr);          peerctx = GF_CALLOC (1, sizeof (*peerctx), gf_gld_mt_peerctx_t);          if (!peerctx) { @@ -3067,17 +3117,24 @@ glusterd_friend_add (const char *hoststr, int port,          if (friend)                  *friend = peerinfo; -        if (hoststr) { -                if (!rpc) { -                        ret = glusterd_friend_rpc_create (&rpc, hoststr, port, -                                                          peerctx); -                        if (ret) -                                goto out; -                        is_allocated = _gf_true; +        if (!rpc) { +                ret = glusterd_transport_inet_keepalive_options_build (&options, +                                                                 hoststr, port); +                if (ret) +                        goto out; +                ret = glusterd_rpc_create (&rpc, options, +                                           glusterd_peer_rpc_notify, +                                           peerctx); +                if (ret) { +                        gf_log ("glusterd", GF_LOG_ERROR, "failed to create rpc for" +                                " peer %s", (char*)hoststr); +                        goto out;                  } -                peerinfo->rpc = rpc; +                is_allocated = _gf_true;          } +        peerinfo->rpc = rpc; +          if (!restore)                  ret = glusterd_store_update_peerinfo (peerinfo); @@ -3482,14 +3539,58 @@ out:  }  int -glusterd_rpc_notify (struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event, -                     void *data) +glusterd_brick_rpc_notify (struct rpc_clnt *rpc, void *mydata, +                          rpc_clnt_event_t event, +                          void *data) +{ +        xlator_t                *this = NULL; +        glusterd_conf_t         *conf = NULL; +        int                     ret = 0; +        glusterd_brickinfo_t    *brickinfo = NULL; + +        brickinfo = mydata; +        if (!brickinfo) +                return 0; + +        this = THIS; +        GF_ASSERT (this); +        conf = this->private; +        GF_ASSERT (conf); + +        switch (event) { +        case RPC_CLNT_CONNECT: +                gf_log (this->name, GF_LOG_DEBUG, "got RPC_CLNT_CONNECT"); +                glusterd_set_brick_status (brickinfo, GF_BRICK_STARTED); +                ret = default_notify (this, GF_EVENT_CHILD_UP, NULL); + +                break; + +        case RPC_CLNT_DISCONNECT: +                gf_log (this->name, GF_LOG_DEBUG, "got RPC_CLNT_DISCONNECT"); +                glusterd_set_brick_status (brickinfo, GF_BRICK_STOPPED); +                if (brickinfo->timer && brickinfo->timer->callbk) +                        brickinfo->timer->callbk (brickinfo->timer->data); +                break; + +        default: +                gf_log (this->name, GF_LOG_TRACE, +                        "got some other RPC event %d", event); +                break; +        } + +        return ret; +} + +int +glusterd_peer_rpc_notify (struct rpc_clnt *rpc, void *mydata, +                          rpc_clnt_event_t event, +                          void *data)  {          xlator_t                *this = NULL;          glusterd_conf_t         *conf = NULL;          int                     ret = 0;          glusterd_peerinfo_t     *peerinfo = NULL; -        glusterd_peerctx_t     *peerctx = NULL; +        glusterd_peerctx_t      *peerctx = NULL;          peerctx = mydata;          if (!peerctx) @@ -3579,6 +3680,7 @@ rpcsvc_actor_t gd_svc_cli_actors[] = {          [GLUSTER_CLI_RESET_VOLUME]  = { "RESET_VOLUME", GLUSTER_CLI_RESET_VOLUME, glusterd_handle_reset_volume, NULL, NULL},          [GLUSTER_CLI_FSM_LOG]       = { "FSM_LOG", GLUSTER_CLI_FSM_LOG, glusterd_handle_fsm_log, NULL, NULL},          [GLUSTER_CLI_GSYNC_SET]     = { "GSYNC_SET", GLUSTER_CLI_GSYNC_SET, glusterd_handle_gsync_set, NULL, NULL}, +        [GLUSTER_CLI_PROFILE_VOLUME] = { "STATS_VOLUME", GLUSTER_CLI_PROFILE_VOLUME, glusterd_handle_cli_profile_volume, NULL, NULL}  };  struct rpcsvc_program gd_svc_cli_prog = { @@ -3621,6 +3723,7 @@ rpcsvc_actor_t glusterd1_mgmt_actors[] = {          [GD_MGMT_CLI_RESET_VOLUME] = { "RESET_VOLUME", GD_MGMT_CLI_RESET_VOLUME, glusterd_handle_reset_volume, NULL, NULL},          [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}  };  struct rpcsvc_program glusterd1_mop_prog = {  | 
