diff options
Diffstat (limited to 'xlators/mgmt')
| -rw-r--r-- | xlators/mgmt/glusterd/src/Makefile.am | 2 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-handler.c | 517 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-handshake.c | 2 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-mem-types.h | 12 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-op-sm.c | 1144 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-op-sm.h | 45 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-pmap.c | 8 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-rpc-ops.c | 321 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.c | 157 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.h | 9 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd.c | 2 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd.h | 38 | 
12 files changed, 1895 insertions, 362 deletions
diff --git a/xlators/mgmt/glusterd/src/Makefile.am b/xlators/mgmt/glusterd/src/Makefile.am index 84209b6f8cf..cfed2fd4b22 100644 --- a/xlators/mgmt/glusterd/src/Makefile.am +++ b/xlators/mgmt/glusterd/src/Makefile.am @@ -15,7 +15,7 @@ noinst_HEADERS = glusterd.h glusterd-utils.h glusterd-op-sm.h glusterd-sm.h \  AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS)\  	-I$(top_srcdir)/libglusterfs/src -shared -nostartfiles $(GF_CFLAGS)\  	-I$(rpclibdir) -L$(xlatordir)/ -I$(CONTRIBDIR)/rbtree -I$(top_srcdir)/rpc/xdr/src\ -	-I$(top_srcdir)/rpc/rpc-lib/src -I$(CONTRIBDIR)/uuid -DGFS_PREFIX=\"$(prefix)\" \ +	-I$(top_srcdir)/rpc/rpc-lib/src -I$(CONTRIBDIR)/uuid -I$(top_srcdir)/contrib/md5 -DGFS_PREFIX=\"$(prefix)\" \  	-DDATADIR=\"$(localstatedir)\" -DGSYNCD_PREFIX=\"$(libexecdir)\" 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 = { diff --git a/xlators/mgmt/glusterd/src/glusterd-handshake.c b/xlators/mgmt/glusterd/src/glusterd-handshake.c index d364339a671..dda8a03bb12 100644 --- a/xlators/mgmt/glusterd/src/glusterd-handshake.c +++ b/xlators/mgmt/glusterd/src/glusterd-handshake.c @@ -418,7 +418,7 @@ glusterd_peer_handshake (xlator_t *this, struct rpc_clnt *rpc,          req.gfs_id = 0xcafe; -        ret = glusterd_submit_request (peerctx->peerinfo, &req, frame, +        ret = glusterd_submit_request (peerctx->peerinfo->rpc, &req, frame,                                         &glusterd_dump_prog, GF_DUMP_DUMP,                                         NULL, xdr_from_dump_req, this,                                         glusterd_peer_dump_version_cbk); diff --git a/xlators/mgmt/glusterd/src/glusterd-mem-types.h b/xlators/mgmt/glusterd/src/glusterd-mem-types.h index 5a4da805671..bd7b1b65fd2 100644 --- a/xlators/mgmt/glusterd/src/glusterd-mem-types.h +++ b/xlators/mgmt/glusterd/src/glusterd-mem-types.h @@ -23,7 +23,7 @@  #include "mem-types.h" -enum gf_gld_mem_types_ { +typedef enum gf_gld_mem_types_ {          gf_gld_mt_dir_entry_t                   = gf_common_mt_end + 1,          gf_gld_mt_volfile_ctx                   = gf_common_mt_end + 2,          gf_gld_mt_glusterd_state_t              = gf_common_mt_end + 3, @@ -59,8 +59,12 @@ enum gf_gld_mem_types_ {          gf_gld_mt_log_locate_ctx_t              = gf_common_mt_end + 33,          gf_gld_mt_log_rotate_ctx_t              = gf_common_mt_end + 34,          gf_gld_mt_peerctx_t                     = gf_common_mt_end + 35, -        gf_gld_mt_sm_tr_log_t                = gf_common_mt_end + 36, -        gf_gld_mt_end                           = gf_common_mt_end + 37 -}; +        gf_gld_mt_sm_tr_log_t                   = gf_common_mt_end + 36, +        gf_gld_mt_pending_node_t                = gf_common_mt_end + 37, +        gf_gld_mt_brick_rsp_ctx_t               = gf_common_mt_end + 38, +        gf_gld_mt_mop_brick_req_t               = gf_common_mt_end + 39, +        gf_gld_mt_op_allack_ctx_t               = gf_common_mt_end + 40, +        gf_gld_mt_end                           = gf_common_mt_end + 41 +} gf_gld_mem_types_t;  #endif diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c index a25f4909b10..a1bd2b43f8e 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c @@ -67,6 +67,12 @@ static char *glusterd_op_sm_state_names[] = {          "Commit op sent",          "Commited",          "Unlock sent", +        "Stage op failed", +        "Commit op failed", +        "Brick op sent", +        "Brick op failed", +        "Brick op Committed", +        "Brick op Commit failed",          "Invalid",  }; @@ -83,6 +89,7 @@ static char *glusterd_op_sm_event_names[] = {          "GD_OP_EVENT_COMMIT_OP",          "GD_OP_EVENT_UNLOCK",          "GD_OP_EVENT_START_UNLOCK", +        "GD_OP_EVENT_ALL_ACK",          "GD_OP_EVENT_INVALID"  }; @@ -128,30 +135,6 @@ glusterd_destroy_lock_ctx (glusterd_op_lock_ctx_t *ctx)  }  void -glusterd_destroy_stage_ctx (glusterd_op_stage_ctx_t *ctx) -{ -        if (!ctx) -                return; - -        if (ctx->dict) -                dict_unref (ctx->dict); - -        GF_FREE (ctx); -} - -void -glusterd_destroy_commit_ctx (glusterd_op_commit_ctx_t *ctx) -{ -        if (!ctx) -                return; - -        if (ctx->dict) -                dict_unref (ctx->dict); - -        GF_FREE (ctx); -} - -void  glusterd_set_volume_status (glusterd_volinfo_t  *volinfo,                              glusterd_volume_status status)  { @@ -196,6 +179,67 @@ glusterd_op_sm_inject_all_acc ()          return ret;  } +int +glusterd_brick_op_build_payload (glusterd_op_t op, glusterd_brickinfo_t *brickinfo, +                                 gd1_mgmt_brick_op_req **req) +{ +        int                     ret = -1; +        gd1_mgmt_brick_op_req   *brick_req = NULL; +        dict_t                  *dict = NULL; + +        GF_ASSERT (op < GD_OP_MAX); +        GF_ASSERT (op > GD_OP_NONE); +        GF_ASSERT (req); + +        dict = dict_new (); +        if (!dict) +                goto out; + +         switch (op) { +        case GD_OP_REMOVE_BRICK: +        case GD_OP_STOP_VOLUME: +                brick_req = GF_CALLOC (1, sizeof (*brick_req), +                                       gf_gld_mt_mop_brick_req_t); +                if (!brick_req) { +                        gf_log ("", GF_LOG_ERROR, "Out of Memory"); +                        goto out; +                } +                brick_req->op = GF_BRICK_TERMINATE; +                brick_req->name = ""; +        break; +        case GD_OP_PROFILE_VOLUME: +                brick_req = GF_CALLOC (1, sizeof (*brick_req), +                                       gf_gld_mt_mop_brick_req_t); + +                if (!brick_req) { +                        gf_log ("", GF_LOG_ERROR, "Out of Memory"); +                        goto out; +                } + +                brick_req->op = GF_BRICK_XLATOR_INFO; +                brick_req->name = brickinfo->path; +        break; +        default: +                goto out; +        break; +        } + +        ret = dict_allocate_and_serialize (dict, &brick_req->input.input_val, +                                           (size_t*)&brick_req->input.input_len); +        if (ret) +                goto out; +        *req = brick_req; +        ret = 0; + +out: +        if (dict) +                dict_unref (dict); +        if (ret && brick_req) +                GF_FREE (brick_req); +        gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret); +        return ret; +} +  static int  glusterd_op_stage_create_volume (dict_t *dict, char **op_errstr)  { @@ -1897,6 +1941,90 @@ out:  }  static int +glusterd_op_stage_stats_volume (dict_t *dict, char **op_errstr) +{ +        int                                     ret = -1; +        char                                    *volname = NULL; +        gf_boolean_t                            exists = _gf_false; +        char                                    msg[2048] = {0,}; +        int32_t                                 stats_op = GF_CLI_STATS_NONE; +        char                                    *latency_key = NULL; +        char                                    *fd_stats_key = NULL; +        char                                    *value = NULL; +        gf_boolean_t                            enabled = _gf_false; +        glusterd_volinfo_t                      *volinfo = NULL; + +        latency_key = "diagnostics.latency-measurement"; +        fd_stats_key = "diagnostics.dump-fd-stats"; + +        ret = dict_get_str (dict, "volname", &volname); +        if (ret) { +                gf_log ("glusterd", GF_LOG_ERROR, "volume name get failed"); +                goto out; +        } + +        exists = glusterd_check_volume_exists (volname); +        ret = glusterd_volinfo_find (volname, &volinfo); +        if ((!exists) || (ret < 0)) { +                snprintf (msg, sizeof (msg), "volume %s, " +                         "doesn't exist", volname); +                gf_log ("glusterd", GF_LOG_ERROR, "%s", msg); +                *op_errstr = gf_strdup (msg); +                ret = -1; +                goto out; +        } + +        ret = dict_get_int32 (dict, "op", &stats_op); +        if (ret) { +                gf_log ("glusterd", GF_LOG_ERROR, "volume profile op get failed"); +                goto out; +        } + +        if (GF_CLI_STATS_INFO == stats_op)  { +                if (glusterd_is_volume_started (volinfo)) { +                        snprintf (msg, sizeof (msg), "volume %s is not started.", +                                  volinfo->volname); +                        gf_log ("glusterd", GF_LOG_ERROR, "%s", msg); +                        *op_errstr = gf_strdup (msg); +                        ret = -1; +                        goto out; +                } + +                ret = dict_get_str (volinfo->dict, latency_key, &value); +                if (value) { +                        ret = gf_string2boolean (value, &enabled); +                } +                if (ret || (_gf_false == enabled)) { +                        snprintf (msg, sizeof (msg), "Profiling is not enabled for " +                                  "volume %s", volinfo->volname); +                        gf_log ("glusterd", GF_LOG_ERROR, "%s", msg); +                        *op_errstr = gf_strdup (msg); +                        ret = -1; +                        goto out; +                } +                enabled = _gf_false; +                value = NULL; +                ret = dict_get_str (volinfo->dict, fd_stats_key, &value); +                if (value) { +                        ret = gf_string2boolean (value, &enabled); +                } +                if (ret || (_gf_false == enabled)) { +                        snprintf (msg, sizeof (msg), "Profiling is not enabled for " +                                  "volume %s", volinfo->volname); +                        gf_log ("glusterd", GF_LOG_ERROR, "%s", msg); +                        *op_errstr = gf_strdup (msg); +                        ret = -1; +                        goto out; +                } +        } + +out: +        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); + +        return ret; +} + +static int  glusterd_op_create_volume (dict_t *dict, char **op_errstr)  {          int                   ret        = 0; @@ -4541,10 +4669,8 @@ glusterd_op_sync_volume (dict_t *dict, char **op_errstr,          if (!ret) {                  ret = glusterd_volinfo_find (volname, &volinfo);                  if (ret) { -                        snprintf (msg, sizeof (msg), "Volume %s does not exist", -                                  volname); -                        gf_log ("", GF_LOG_ERROR, "%s", msg); -                        *op_errstr = gf_strdup (msg); +                        gf_log ("", GF_LOG_ERROR, "Volume with name: %s " +                                "not exists", volname);                          goto out;                  }          } @@ -4578,6 +4704,156 @@ out:  }  static int +glusterd_op_stats_volume (dict_t *dict, char **op_errstr, +                          dict_t *rsp_dict) +{ +        int                                     ret = -1; +        char                                    *volname = NULL; +        char                                    msg[2048] = {0,}; +        glusterd_conf_t                         *priv = NULL; +        glusterd_volinfo_t                      *volinfo = NULL; +        xlator_t                                *this = NULL; +        int32_t                                 stats_op = GF_CLI_STATS_NONE; +        char                                    *fd_stats_value = NULL; +        char                                    *latency_value = NULL; +        char                                    *latency_key = NULL; +        char                                    *fd_stats_key = NULL; +        char                                    *key_found = NULL; +        int                                     exists = 0; + +        this = THIS; +        GF_ASSERT (this); +        priv = this->private; +        GF_ASSERT (priv); + +        latency_key = "diagnostics.latency-measurement"; +        fd_stats_key = "diagnostics.dump-fd-stats"; + +        ret = dict_get_str (dict, "volname", &volname); +        if (ret) { +                gf_log ("glusterd", GF_LOG_ERROR, "volume name get failed"); +                goto out; +        } + +        ret = glusterd_volinfo_find (volname, &volinfo); +        if (ret) { +                snprintf (msg, sizeof (msg), "Volume %s does not exists", +                          volname); + +                gf_log ("", GF_LOG_ERROR, "%s", msg); +                goto out; +        } + +        ret = dict_get_int32 (dict, "op", &stats_op); +        if (ret) { +                gf_log ("glusterd", GF_LOG_ERROR, "volume profile op get failed"); +                goto out; +        } + +        exists = glusterd_check_option_exists (latency_key, &key_found); +        if (key_found) +                GF_FREE (key_found); +        if (!exists) { +                snprintf (msg, sizeof (msg), "Volume Option %s does not exist", +                          latency_key); +                gf_log ("glusterd", GF_LOG_ERROR, "%s", msg); +                *op_errstr = gf_strdup (msg); +                ret = -1; +                goto out; +        } + +        exists = glusterd_check_option_exists (fd_stats_key, &key_found); +        if (key_found) +                GF_FREE (key_found); +        if (!exists) { +                snprintf (msg, sizeof (msg), "Volume Option %s does not exist", +                          fd_stats_key); +                gf_log ("glusterd", GF_LOG_ERROR, "%s", msg); +                *op_errstr = gf_strdup (msg); +                ret = -1; +                goto out; +        } + +        switch (stats_op) { +        case GF_CLI_STATS_START: +                fd_stats_value = gf_strdup ("on"); +                latency_value = gf_strdup ("on"); +                break; +        case GF_CLI_STATS_STOP: +                fd_stats_value = gf_strdup ("off"); +                latency_value = gf_strdup ("off"); +                break; +        case GF_CLI_STATS_INFO: +                //info is already collected in brick op. +                //just goto out; +                ret = 0; +                goto out; +                break; +        default: +                GF_ASSERT (0); +                gf_log ("glusterd", GF_LOG_ERROR, "Invalid profile op: %d", +                        stats_op); +                ret = -1; +                goto out; +                break; +        } + +        if (!fd_stats_value || !latency_value) { +                ret = -1; +                gf_log ("glusterd", GF_LOG_ERROR, "Out of memory"); +                goto out; +        } + +        ret = dict_set_dynstr (volinfo->dict, latency_key, latency_value); +        if (ret) { +                gf_log ("glusterd", GF_LOG_ERROR, "failed to set the volume %s " + + +                        "option %s value %s", +                        volinfo->volname, latency_key, latency_value); +                goto out; +        } + +        ret = dict_set_dynstr (volinfo->dict, fd_stats_key, fd_stats_value); +        if (ret) { +                gf_log ("glusterd", GF_LOG_ERROR, "failed to set the volume %s " +                        "option %s value %s", +                        volinfo->volname, fd_stats_key, fd_stats_value); +                goto out; +        } +	ret = glusterd_create_volfiles (volinfo); + +	if (ret) { +                gf_log ("", GF_LOG_ERROR, "Unable to create volfile for" +					  " 'volume set'"); +		ret = -1; +		goto out; +        } + +        ret = glusterd_store_update_volume (volinfo); +        if (ret) +                goto out; + +        ret = glusterd_volume_compute_cksum (volinfo); +        if (ret) +                goto out; + +        if (GLUSTERD_STATUS_STARTED == volinfo->status) +                ret = glusterd_check_generate_start_nfs (volinfo); + +        ret = 0; + +out: +        if (ret && fd_stats_value) +                GF_FREE (fd_stats_value); +        if (ret && latency_value) +                GF_FREE (latency_value); +        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; @@ -4729,9 +5005,10 @@ glusterd_op_ac_rcvd_lock_acc (glusterd_op_sm_event_t *event, void *ctx)          GF_ASSERT (event); -        opinfo.pending_count--; +        if (opinfo.pending_count > 0) +                opinfo.pending_count--; -        if (opinfo.pending_count) +        if (opinfo.pending_count > 0)                  goto out;          ret = glusterd_op_sm_inject_event (GD_OP_EVENT_ALL_ACC, NULL); @@ -4798,6 +5075,7 @@ glusterd_op_build_payload (glusterd_op_t op, dict_t **req)                  case GD_OP_LOG_ROTATE:                  case GD_OP_SYNC_VOLUME:                  case GD_OP_GSYNC_SET: +                case GD_OP_PROFILE_VOLUME:                          {                                  dict_t  *dict = ctx;                                  dict_copy (dict, req_dict); @@ -5046,9 +5324,10 @@ glusterd_op_ac_rcvd_stage_op_acc (glusterd_op_sm_event_t *event, void *ctx)          GF_ASSERT (event); -        opinfo.pending_count--; +        if (opinfo.pending_count > 0) +                opinfo.pending_count--; -        if (opinfo.pending_count) +        if (opinfo.pending_count > 0)                  goto out;          ret = glusterd_op_sm_inject_event (GD_OP_EVENT_STAGE_ACC, NULL); @@ -5059,6 +5338,118 @@ out:          return ret;  } +static int +glusterd_op_ac_stage_op_failed (glusterd_op_sm_event_t *event, void *ctx) +{ +        int                     ret = 0; + +        GF_ASSERT (event); + +        if (opinfo.pending_count > 0) +                opinfo.pending_count--; + +        if (opinfo.pending_count > 0) +                goto out; + +        ret = glusterd_op_sm_inject_event (GD_OP_EVENT_ALL_ACK, NULL); + +out: +        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); + +        return ret; +} + +static int +glusterd_op_ac_commit_op_failed (glusterd_op_sm_event_t *event, void *ctx) +{ +        int                     ret = 0; + +        GF_ASSERT (event); + +        if (opinfo.pending_count > 0) +                opinfo.pending_count--; + +        if (opinfo.pending_count > 0) +                goto out; + +        ret = glusterd_op_sm_inject_event (GD_OP_EVENT_ALL_ACK, NULL); + +out: +        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); + +        return ret; +} + +static int +glusterd_op_ac_brick_op_failed (glusterd_op_sm_event_t *event, void *ctx) +{ +        int                     ret = 0; +        glusterd_op_brick_rsp_ctx_t *ev_ctx = NULL; +        glusterd_brickinfo_t        *brickinfo = NULL; +        gf_boolean_t                free_errstr = _gf_false; + +        GF_ASSERT (event); +        GF_ASSERT (ctx); +        ev_ctx = ctx; +        brickinfo = ev_ctx->brickinfo; +        GF_ASSERT (brickinfo); + +        ret = glusterd_remove_pending_entry (&opinfo.pending_bricks, brickinfo); +        if (ret) { +                gf_log ("glusterd", GF_LOG_ERROR, "unknown response received " +                        "from %s:%s", brickinfo->hostname, brickinfo->path); +                ret = -1; +                free_errstr = _gf_true; +                goto out; +        } +        if (opinfo.brick_pending_count > 0) +                opinfo.brick_pending_count--; +        if (opinfo.op_ret == 0) +                opinfo.op_ret = ev_ctx->op_ret; + +        if (opinfo.op_errstr == NULL) +                opinfo.op_errstr = ev_ctx->op_errstr; +        else +                free_errstr = _gf_true; + +        if (opinfo.brick_pending_count > 0) +                goto out; + +        ret = glusterd_op_sm_inject_event (GD_OP_EVENT_ALL_ACK, ev_ctx->commit_ctx); + +out: +        if (ev_ctx->rsp_dict) +                dict_unref (ev_ctx->rsp_dict); +        if (free_errstr && ev_ctx->op_errstr) +                GF_FREE (ev_ctx->op_errstr); +        GF_FREE (ctx); +        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); + +        return ret; +} + +void +glusterd_op_brick_disconnect (void *data) +{ +        glusterd_brickinfo_t *brickinfo = NULL; +        glusterd_op_brick_rsp_ctx_t *ev_ctx = NULL; + +        ev_ctx = data; +        GF_ASSERT (ev_ctx); +        brickinfo = ev_ctx->brickinfo; +        GF_ASSERT (brickinfo); + +	if (brickinfo->timer) { +		gf_timer_call_cancel (THIS->ctx, brickinfo->timer); +		brickinfo->timer = NULL; +                gf_log ("", GF_LOG_DEBUG, +                        "Cancelled timer thread"); +	} + +        glusterd_op_sm_inject_event (GD_OP_EVENT_RCVD_ACC, ev_ctx); +        glusterd_op_sm (); +} +  void  glusterd_do_replace_brick (void *data)  { @@ -5210,9 +5601,10 @@ glusterd_op_ac_rcvd_commit_op_acc (glusterd_op_sm_event_t *event, void *ctx)          priv = THIS->private;          GF_ASSERT (event); -        opinfo.pending_count--; +        if (opinfo.pending_count > 0) +                opinfo.pending_count--; -        if (opinfo.pending_count) +        if (opinfo.pending_count > 0)                  goto out;          dict = glusterd_op_get_ctx (GD_OP_REPLACE_BRICK); @@ -5243,9 +5635,10 @@ glusterd_op_ac_rcvd_unlock_acc (glusterd_op_sm_event_t *event, void *ctx)          GF_ASSERT (event); -        opinfo.pending_count--; +        if (opinfo.pending_count > 0) +                opinfo.pending_count--; -        if (opinfo.pending_count) +        if (opinfo.pending_count > 0)                  goto out;          ret = glusterd_op_sm_inject_event (GD_OP_EVENT_ALL_ACC, NULL); @@ -5352,23 +5745,10 @@ glusterd_op_ac_unlocked_all (glusterd_op_sm_event_t *event, void *ctx)  static int -glusterd_op_ac_commit_error (glusterd_op_sm_event_t *event, void *ctx) -{ -        int                     ret = 0; - -        //Log here with who failed the commit -        // - -        ret = glusterd_op_sm_inject_event (GD_OP_EVENT_START_UNLOCK, NULL); - -        return ret; -} - -static int  glusterd_op_ac_stage_op (glusterd_op_sm_event_t *event, void *ctx)  {          int                     ret = -1; -        glusterd_op_stage_ctx_t *stage_ctx = NULL; +        glusterd_req_ctx_t      *req_ctx = NULL;          int32_t                 status = 0;          dict_t                  *rsp_dict  = NULL;          char                    *op_errstr = NULL; @@ -5376,9 +5756,9 @@ glusterd_op_ac_stage_op (glusterd_op_sm_event_t *event, void *ctx)          GF_ASSERT (ctx); -        stage_ctx = ctx; +        req_ctx = ctx; -        dict = stage_ctx->dict; +        dict = req_ctx->dict;          rsp_dict = dict_new ();          if (!rsp_dict) { @@ -5387,14 +5767,14 @@ glusterd_op_ac_stage_op (glusterd_op_sm_event_t *event, void *ctx)                  return -1;          } -        status = glusterd_op_stage_validate (stage_ctx->op, dict, &op_errstr, +        status = glusterd_op_stage_validate (req_ctx->op, dict, &op_errstr,                                               rsp_dict);          if (status) {                  gf_log ("", GF_LOG_ERROR, "Validate failed: %d", status);          } -        ret = glusterd_op_stage_send_resp (stage_ctx->req, stage_ctx->op, +        ret = glusterd_op_stage_send_resp (req_ctx->req, req_ctx->op,                                             status, op_errstr, rsp_dict);          if (op_errstr && (strcmp (op_errstr, ""))) @@ -5412,39 +5792,30 @@ static int  glusterd_op_ac_commit_op (glusterd_op_sm_event_t *event, void *ctx)  {          int                       ret        = 0; -        glusterd_op_commit_ctx_t *commit_ctx = NULL; +        glusterd_req_ctx_t      *req_ctx = NULL;          int32_t                   status     = 0;          char                     *op_errstr  = NULL; -        dict_t                   *rsp_dict   = NULL; +        dict_t                   *op_ctx   = NULL;          dict_t                   *dict       = NULL;          GF_ASSERT (ctx); -        commit_ctx = ctx; +        req_ctx = ctx; -        dict = commit_ctx->dict; +        dict = req_ctx->dict; -        rsp_dict = dict_new (); -        if (!rsp_dict) { -                gf_log ("", GF_LOG_DEBUG, -                        "Out of memory"); -                ret = -1; -                goto out; -        } - -        status = glusterd_op_commit_perform (commit_ctx->op, dict, &op_errstr, -                                             rsp_dict); +        op_ctx = glusterd_op_get_ctx (req_ctx->op); +        status = glusterd_op_commit_perform (req_ctx->op, dict, &op_errstr, +                                             op_ctx);          if (status) {                  gf_log ("", GF_LOG_ERROR, "Commit failed: %d", status);          } -        ret = glusterd_op_commit_send_resp (commit_ctx->req, commit_ctx->op, -                                            status, op_errstr, rsp_dict); +        ret = glusterd_op_commit_send_resp (req_ctx->req, req_ctx->op, +                                            status, op_errstr, op_ctx); -out: -        if (rsp_dict) -                dict_unref (rsp_dict); +        glusterd_op_fini_ctx (req_ctx->op);          if (op_errstr && (strcmp (op_errstr, "")))                  GF_FREE (op_errstr); @@ -5453,6 +5824,32 @@ out:          return ret;  } +static int +glusterd_op_ac_send_commit_failed (glusterd_op_sm_event_t *event, void *ctx) +{ +        int                             ret = 0; +        glusterd_req_ctx_t              *req_ctx = NULL; +        dict_t                          *op_ctx = NULL; + +        GF_ASSERT (ctx); + +        req_ctx = ctx; + +        op_ctx = glusterd_op_get_ctx (req_ctx->op); + +        ret = glusterd_op_commit_send_resp (req_ctx->req, req_ctx->op, +                                            opinfo.op_ret, opinfo.op_errstr, +                                            op_ctx); + +        glusterd_op_fini_ctx (req_ctx->op); +        if (opinfo.op_errstr && (strcmp (opinfo.op_errstr, ""))) { +                GF_FREE (opinfo.op_errstr); +                opinfo.op_errstr = NULL; +        } + +        gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret); +        return ret; +}  static int  glusterd_op_sm_transition_state (glusterd_op_info_t *opinfo, @@ -5536,6 +5933,11 @@ glusterd_op_stage_validate (glusterd_op_t op, dict_t *dict, char **op_errstr,                          ret = glusterd_op_stage_gsync_set (dict, op_errstr);                          break; +                case GD_OP_PROFILE_VOLUME: +                        ret = glusterd_op_stage_stats_volume (dict, op_errstr); +                        break; + +                  default:                          gf_log ("", GF_LOG_ERROR, "Unknown op %d",                                  op); @@ -5606,11 +6008,419 @@ glusterd_op_commit_perform (glusterd_op_t op, dict_t *dict, char **op_errstr,                          ret = glusterd_op_gsync_set (dict);                          break; +                case GD_OP_PROFILE_VOLUME: +                        ret = glusterd_op_stats_volume (dict, op_errstr, +                                                        rsp_dict); +                        break; +                  default:                          gf_log ("", GF_LOG_ERROR, "Unknown op %d",                                  op); +                        break; +        } + +        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); + +        return ret; +} + +void +_profile_volume_add_brick_rsp (dict_t *this, char *key, data_t *value, +                             void *data) +{ +        char    new_key[256] = {0}; +        glusterd_pr_brick_rsp_conv_t *rsp_ctx = NULL; +        data_t  *new_value = NULL; + +        rsp_ctx = data; +        new_value = data_copy (value); +        GF_ASSERT (new_value); +        snprintf (new_key, sizeof (new_key), "%d-%s", rsp_ctx->count, key); +        dict_set (rsp_ctx->dict, new_key, new_value); +} + +int +glusterd_profile_volume_brick_rsp (glusterd_brickinfo_t *brickinfo, +                                   dict_t *rsp_dict, dict_t *op_ctx, +                                   char **op_errstr) +{ +        int     ret = 0; +        glusterd_pr_brick_rsp_conv_t rsp_ctx = {0}; +        int32_t count = 0; +        char    brick[PATH_MAX+1024] = {0}; +        char    key[256] = {0}; +        char    *full_brick = NULL; + +        GF_ASSERT (rsp_dict); +        GF_ASSERT (op_ctx); +        GF_ASSERT (op_errstr); +        GF_ASSERT (brickinfo); + +        ret = dict_get_int32 (op_ctx, "count", &count); +        if (ret) { +                count = 1; +        } else { +                count++; +        } +        snprintf (key, sizeof (key), "%d-brick", count); +        snprintf (brick, sizeof (brick), "%s:%s", brickinfo->hostname, +                  brickinfo->path); +        full_brick = gf_strdup (brick); +        GF_ASSERT (full_brick); +        ret = dict_set_dynstr (op_ctx, key, full_brick); + +        rsp_ctx.count = count; +        rsp_ctx.dict = op_ctx; +        dict_foreach (rsp_dict, _profile_volume_add_brick_rsp, &rsp_ctx); +        dict_del (op_ctx, "count"); +        ret = dict_set_int32 (op_ctx, "count", count); +        return ret; +} + +int32_t +glusterd_handle_brick_rsp (glusterd_brickinfo_t *brickinfo, +                           glusterd_op_t op, dict_t *rsp_dict, dict_t *op_ctx, +                           char **op_errstr) +{ +        int     ret = 0; + +        GF_ASSERT (op_errstr); + +        switch (op) { +        case GD_OP_PROFILE_VOLUME: +                ret = glusterd_profile_volume_brick_rsp (brickinfo, rsp_dict, +                                                         op_ctx, op_errstr); +        break; + +        default: +                break; +        } + +        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); +        return ret; +} + +static int +glusterd_bricks_select_stop_volume (dict_t *dict, char **op_errstr) +{ +        int                                     ret = 0; +        int                                     flags = 0; +        char                                    *volname = NULL; +        glusterd_volinfo_t                      *volinfo = NULL; +        glusterd_brickinfo_t                    *brickinfo = NULL; +        glusterd_pending_node_t                 *pending_node = NULL; + +        ret = glusterd_op_stop_volume_args_get (dict, &volname, &flags); +        if (ret) +                goto out; + +        ret  = glusterd_volinfo_find (volname, &volinfo); + +        if (ret) +                goto out; + +        list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { +                if (!glusterd_is_brick_started (brickinfo)) { +                        pending_node = GF_CALLOC (1, sizeof (*pending_node), +                                                  gf_gld_mt_pending_node_t); +                        if (!pending_node) { +                                ret = -1; +                                goto out; +                        } else { +                                pending_node->node = brickinfo; +                                list_add_tail (&pending_node->list, &opinfo.pending_bricks); +                                pending_node = NULL; +                        } +                } +        } + +out: +        return ret; +} + +static int +glusterd_bricks_select_remove_brick (dict_t *dict, char **op_errstr) +{ +        int                                     ret = -1; +        char                                    *volname = NULL; +        glusterd_volinfo_t                      *volinfo = NULL; +        glusterd_brickinfo_t                    *brickinfo = NULL; +        char                                    *brick = NULL; +        int32_t                                 count = 0; +        int32_t                                 i = 1; +        char                                    key[256] = {0,}; +        glusterd_pending_node_t                 *pending_node = NULL; + +        ret = dict_get_str (dict, "volname", &volname); + +        if (ret) { +                gf_log ("", GF_LOG_ERROR, "Unable to get volume name"); +                goto out; +        } + +        ret = glusterd_volinfo_find (volname, &volinfo); + +        if (ret) { +                gf_log ("", GF_LOG_ERROR, "Unable to allocate memory"); +                goto out; +        } + +        ret = dict_get_int32 (dict, "count", &count); +        if (ret) { +                gf_log ("", GF_LOG_ERROR, "Unable to get count"); +                goto out; +        } + + +        while ( i <= count) { +                snprintf (key, 256, "brick%d", i); +                ret = dict_get_str (dict, key, &brick); +                if (ret) { +                        gf_log ("glusterd", GF_LOG_ERROR, "Unable to get brick"); +                        goto out; +                } + +                ret = glusterd_volume_brickinfo_get_by_brick (brick, volinfo, +                                                              &brickinfo); +                if (ret) +                        goto out; +                if (!glusterd_is_brick_started (brickinfo)) { +                        pending_node = GF_CALLOC (1, sizeof (*pending_node), +                                                  gf_gld_mt_pending_node_t); +                        if (!pending_node) { +                                ret = -1; +                                goto out; +                        } else { +                                pending_node->node = brickinfo; +                                list_add_tail (&pending_node->list, &opinfo.pending_bricks); +                                pending_node = NULL; +                        } +                } +                i++; +        } + +out: +        return ret; +} + +static int +glusterd_bricks_select_profile_volume (dict_t *dict, char **op_errstr) +{ +        int                                     ret = -1; +        char                                    *volname = NULL; +        char                                    msg[2048] = {0,}; +        glusterd_conf_t                         *priv = NULL; +        glusterd_volinfo_t                      *volinfo = NULL; +        xlator_t                                *this = NULL; +        int32_t                                 stats_op = GF_CLI_STATS_NONE; +        glusterd_brickinfo_t                    *brickinfo = NULL; +        glusterd_pending_node_t                 *pending_node = NULL; + +        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, "volume name get failed"); +                goto out; +        } + +        ret = glusterd_volinfo_find (volname, &volinfo); +        if (ret) { +                snprintf (msg, sizeof (msg), "Volume %s does not exists", +                          volname); + +                gf_log ("", GF_LOG_ERROR, "%s", msg); +                goto out; +        } + +        ret = dict_get_int32 (dict, "op", &stats_op); +        if (ret) { +                gf_log ("glusterd", GF_LOG_ERROR, "volume profile op get failed"); +                goto out; +        } + +        switch (stats_op) { +        case GF_CLI_STATS_START: +        case GF_CLI_STATS_STOP: +                goto out; +                break; +        case GF_CLI_STATS_INFO: +                list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { +                        if (!glusterd_is_brick_started (brickinfo)) { +                                pending_node = GF_CALLOC (1, sizeof (*pending_node), +                                                          gf_gld_mt_pending_node_t); +                                if (!pending_node) { +                                        ret = -1; +                                        goto out; +                                } else { +                                        pending_node->node = brickinfo; +                                        list_add_tail (&pending_node->list, +                                                       &opinfo.pending_bricks); +                                        pending_node = NULL; +                                } +                        } +                } +                break; +        default: +                GF_ASSERT (0); +                gf_log ("glusterd", GF_LOG_ERROR, "Invalid profile op: %d", +                        stats_op); +                ret = -1; +                goto out; +                break;          } + +out: +        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); + +        return ret; +} + +static int +glusterd_op_ac_send_brick_op (glusterd_op_sm_event_t *event, void *ctx) +{ +        int                             ret = 0; +        rpc_clnt_procedure_t            *proc = NULL; +        glusterd_conf_t                 *priv = NULL; +        xlator_t                        *this = NULL; +        glusterd_op_t                   op = GD_OP_NONE; +        glusterd_req_ctx_t              *req_ctx = NULL; + +        this = THIS; +        priv = this->private; + +        if (ctx) { +                req_ctx = ctx; +        } else { +                req_ctx = GF_CALLOC (1, sizeof (*req_ctx), +                                     gf_gld_mt_op_allack_ctx_t); +                op = glusterd_op_get_op (); +                req_ctx->op = op; +                uuid_copy (req_ctx->uuid, priv->uuid); +                ret = glusterd_op_build_payload (op, &req_ctx->dict); +                if (ret)//TODO:what to do?? +                        goto out; +        } + +        proc = &priv->gfs_mgmt->proctable[GD_MGMT_BRICK_OP]; +        if (proc->fn) { +                ret = proc->fn (NULL, this, req_ctx); +                if (ret) +                        goto out; +        } + +        if (!opinfo.pending_count && !opinfo.brick_pending_count) { +                glusterd_clear_pending_nodes (&opinfo.pending_bricks); +                ret = glusterd_op_sm_inject_event (GD_OP_EVENT_ALL_ACK, req_ctx); +        } + +out: +        gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret); + +        return ret; +} + + +static int +glusterd_op_ac_rcvd_brick_op_acc (glusterd_op_sm_event_t *event, void *ctx) +{ +        int                     ret = 0; +        glusterd_op_brick_rsp_ctx_t *ev_ctx = NULL; +        glusterd_brickinfo_t        *brickinfo = NULL; +        char                        *op_errstr = NULL; +        glusterd_op_t               op = GD_OP_NONE; +        dict_t                      *op_ctx = NULL; +        gf_boolean_t                free_errstr = _gf_true; +        glusterd_req_ctx_t          *req_ctx = NULL; + +        GF_ASSERT (event); +        GF_ASSERT (ctx); +        ev_ctx = ctx; + +        req_ctx = ev_ctx->commit_ctx; +        GF_ASSERT (req_ctx); + +        brickinfo = ev_ctx->brickinfo; +        GF_ASSERT (brickinfo); + +        ret = glusterd_remove_pending_entry (&opinfo.pending_bricks, brickinfo); +        if (ret) { +                gf_log ("glusterd", GF_LOG_ERROR, "unknown response received " +                        "from %s:%s", brickinfo->hostname, brickinfo->path); +                ret = -1; +                free_errstr = _gf_true; +                goto out; +        } + +        if (opinfo.brick_pending_count > 0) +                opinfo.brick_pending_count--; +        op = req_ctx->op; +        op_ctx = glusterd_op_get_ctx (op); + +        glusterd_handle_brick_rsp (brickinfo, op, ev_ctx->rsp_dict, +                                   op_ctx, &op_errstr); +        if (opinfo.brick_pending_count > 0) +                goto out; + +        ret = glusterd_op_sm_inject_event (GD_OP_EVENT_ALL_ACK, ev_ctx->commit_ctx); + +out: +        if (ev_ctx->rsp_dict) +                dict_unref (ev_ctx->rsp_dict); +        GF_FREE (ev_ctx); +        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); + +        return ret; +} + +int32_t +glusterd_op_bricks_select (glusterd_op_t op, dict_t *dict, char **op_errstr) +{ +        int     ret = 0; + +        GF_ASSERT (dict); +        GF_ASSERT (op_errstr); + +        switch (op) { +        case GD_OP_CREATE_VOLUME: +        case GD_OP_START_BRICK: +        case GD_OP_STOP_BRICK: +        case GD_OP_DELETE_VOLUME: +        case GD_OP_START_VOLUME: +        case GD_OP_RENAME_VOLUME: +        case GD_OP_DEFRAG_VOLUME: +        case GD_OP_ADD_BRICK: +        case GD_OP_REPLACE_BRICK: +        case GD_OP_SET_VOLUME: +        case GD_OP_RESET_VOLUME: +        case GD_OP_SYNC_VOLUME: +        case GD_OP_LOG_FILENAME: +        case GD_OP_LOG_LOCATE: +        case GD_OP_LOG_ROTATE: +                //nothing to be done +                break; +        case GD_OP_STOP_VOLUME: +                ret = glusterd_bricks_select_stop_volume (dict, op_errstr); +                break; + +        case GD_OP_REMOVE_BRICK: +                ret = glusterd_bricks_select_remove_brick (dict, op_errstr); +                break; + +        case GD_OP_PROFILE_VOLUME: +                ret = glusterd_bricks_select_profile_volume (dict, op_errstr); +                break; + +        default: +                gf_log ("", GF_LOG_ERROR, "Unknown op %d", op); +                ret = -1; +                break; +         } +          gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);          return ret; @@ -5629,6 +6439,7 @@ glusterd_op_sm_t glusterd_op_state_default [] = {          {GD_OP_STATE_DEFAULT, glusterd_op_ac_none}, //EVENT_COMMIT_OP          {GD_OP_STATE_DEFAULT, glusterd_op_ac_unlock}, //EVENT_UNLOCK          {GD_OP_STATE_DEFAULT, glusterd_op_ac_none}, //EVENT_START_UNLOCK +        {GD_OP_STATE_DEFAULT, glusterd_op_ac_none}, //EVENT_ALL_ACK          {GD_OP_STATE_DEFAULT, glusterd_op_ac_none}, //EVENT_MAX  }; @@ -5645,6 +6456,7 @@ glusterd_op_sm_t glusterd_op_state_lock_sent [] = {          {GD_OP_STATE_LOCK_SENT, glusterd_op_ac_none}, //EVENT_COMMIT_OP          {GD_OP_STATE_DEFAULT, glusterd_op_ac_unlock}, //EVENT_UNLOCK          {GD_OP_STATE_LOCK_SENT, glusterd_op_ac_none}, //EVENT_START_UNLOCK +        {GD_OP_STATE_LOCK_SENT, glusterd_op_ac_none}, //EVENT_ALL_ACK          {GD_OP_STATE_LOCK_SENT, glusterd_op_ac_none}, //EVENT_MAX  }; @@ -5661,6 +6473,7 @@ glusterd_op_sm_t glusterd_op_state_locked [] = {          {GD_OP_STATE_LOCKED, glusterd_op_ac_none}, //EVENT_COMMIT_OP          {GD_OP_STATE_DEFAULT, glusterd_op_ac_unlock}, //EVENT_UNLOCK          {GD_OP_STATE_LOCKED, glusterd_op_ac_none}, //EVENT_START_UNLOCK +        {GD_OP_STATE_LOCKED, glusterd_op_ac_none}, //EVENT_ALL_ACK          {GD_OP_STATE_LOCKED, glusterd_op_ac_none}, //EVENT_MAX  }; @@ -5669,17 +6482,35 @@ glusterd_op_sm_t glusterd_op_state_stage_op_sent [] = {          {GD_OP_STATE_STAGE_OP_SENT, glusterd_op_ac_none},//EVENT_START_LOCK          {GD_OP_STATE_STAGE_OP_SENT, glusterd_op_ac_none}, //EVENT_LOCK          {GD_OP_STATE_STAGE_OP_SENT, glusterd_op_ac_rcvd_stage_op_acc}, //EVENT_RCVD_ACC -        {GD_OP_STATE_STAGE_OP_SENT, glusterd_op_ac_send_stage_op}, //EVENT_ALL_ACC -        {GD_OP_STATE_COMMIT_OP_SENT, glusterd_op_ac_send_commit_op}, //EVENT_STAGE_ACC +        {GD_OP_STATE_BRICK_OP_SENT,  glusterd_op_ac_send_brick_op}, //EVENT_ALL_ACC +        {GD_OP_STATE_BRICK_OP_SENT, glusterd_op_ac_send_brick_op}, //EVENT_STAGE_ACC          {GD_OP_STATE_STAGE_OP_SENT, glusterd_op_ac_none}, //EVENT_COMMIT_ACC -        {GD_OP_STATE_UNLOCK_SENT,   glusterd_op_ac_send_unlock}, //EVENT_RCVD_RJT +        {GD_OP_STATE_STAGE_OP_FAILED,   glusterd_op_ac_stage_op_failed}, //EVENT_RCVD_RJT          {GD_OP_STATE_STAGE_OP_SENT, glusterd_op_ac_none}, //EVENT_STAGE_OP          {GD_OP_STATE_STAGE_OP_SENT, glusterd_op_ac_none}, //EVENT_COMMIT_OP -        {GD_OP_STATE_STAGE_OP_SENT, glusterd_op_ac_unlock}, //EVENT_UNLOCK +        {GD_OP_STATE_DEFAULT, glusterd_op_ac_unlock}, //EVENT_UNLOCK          {GD_OP_STATE_STAGE_OP_SENT, glusterd_op_ac_none}, //EVENT_START_UNLOCK +        {GD_OP_STATE_STAGE_OP_SENT, glusterd_op_ac_none}, //EVENT_ALL_ACK          {GD_OP_STATE_STAGE_OP_SENT, glusterd_op_ac_none}, //EVENT_MAX  }; +glusterd_op_sm_t glusterd_op_state_stage_op_failed [] = { +        {GD_OP_STATE_STAGE_OP_FAILED, glusterd_op_ac_none}, //EVENT_NONE +        {GD_OP_STATE_STAGE_OP_FAILED, glusterd_op_ac_none},//EVENT_START_LOCK +        {GD_OP_STATE_STAGE_OP_FAILED, glusterd_op_ac_none}, //EVENT_LOCK +        {GD_OP_STATE_STAGE_OP_FAILED, glusterd_op_ac_stage_op_failed}, //EVENT_RCVD_ACC +        {GD_OP_STATE_STAGE_OP_FAILED, glusterd_op_ac_none}, //EVENT_ALL_ACC +        {GD_OP_STATE_STAGE_OP_FAILED, glusterd_op_ac_none}, //EVENT_STAGE_ACC +        {GD_OP_STATE_STAGE_OP_FAILED, glusterd_op_ac_none}, //EVENT_COMMIT_ACC +        {GD_OP_STATE_STAGE_OP_FAILED, glusterd_op_ac_stage_op_failed}, //EVENT_RCVD_RJT +        {GD_OP_STATE_STAGE_OP_FAILED, glusterd_op_ac_none}, //EVENT_STAGE_OP +        {GD_OP_STATE_STAGE_OP_FAILED, glusterd_op_ac_none}, //EVENT_COMMIT_OP +        {GD_OP_STATE_DEFAULT, glusterd_op_ac_unlock}, //EVENT_UNLOCK +        {GD_OP_STATE_STAGE_OP_FAILED, glusterd_op_ac_none}, //EVENT_START_UNLOCK +        {GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_send_unlock}, //EVENT_ALL_ACK +        {GD_OP_STATE_STAGE_OP_FAILED, glusterd_op_ac_none}, //EVENT_MAX +}; +  glusterd_op_sm_t glusterd_op_state_staged [] = {          {GD_OP_STATE_STAGED, glusterd_op_ac_none}, //EVENT_NONE          {GD_OP_STATE_STAGED, glusterd_op_ac_none},//EVENT_START_LOCK @@ -5690,12 +6521,98 @@ glusterd_op_sm_t glusterd_op_state_staged [] = {          {GD_OP_STATE_STAGED, glusterd_op_ac_none}, //EVENT_COMMIT_ACC          {GD_OP_STATE_STAGED, glusterd_op_ac_none}, //EVENT_RCVD_RJT          {GD_OP_STATE_STAGED, glusterd_op_ac_none}, //EVENT_STAGE_OP -        {GD_OP_STATE_COMMITED, glusterd_op_ac_commit_op}, //EVENT_COMMIT_OP +        {GD_OP_STATE_BRICK_COMMITTED, glusterd_op_ac_send_brick_op}, //EVENT_COMMIT_OP          {GD_OP_STATE_DEFAULT, glusterd_op_ac_unlock}, //EVENT_UNLOCK          {GD_OP_STATE_STAGED, glusterd_op_ac_none}, //EVENT_START_UNLOCK +        {GD_OP_STATE_STAGED, glusterd_op_ac_none}, //EVENT_ALL_ACK          {GD_OP_STATE_STAGED, glusterd_op_ac_none}, //EVENT_MAX  }; +glusterd_op_sm_t glusterd_op_state_brick_op_sent [] = { +        {GD_OP_STATE_BRICK_OP_SENT, glusterd_op_ac_none}, //EVENT_NONE +        {GD_OP_STATE_BRICK_OP_SENT, glusterd_op_ac_none},//EVENT_START_LOCK +        {GD_OP_STATE_BRICK_OP_SENT, glusterd_op_ac_none}, //EVENT_LOCK +        {GD_OP_STATE_BRICK_OP_SENT, glusterd_op_ac_rcvd_brick_op_acc}, //EVENT_RCVD_ACC +        {GD_OP_STATE_BRICK_OP_SENT, glusterd_op_ac_none}, //EVENT_ALL_ACC +        {GD_OP_STATE_BRICK_OP_SENT, glusterd_op_ac_none}, //EVENT_STAGE_ACC +        {GD_OP_STATE_BRICK_OP_SENT, glusterd_op_ac_none}, //EVENT_COMMIT_ACC +        {GD_OP_STATE_BRICK_OP_FAILED,   glusterd_op_ac_brick_op_failed}, //EVENT_RCVD_RJT +        {GD_OP_STATE_BRICK_OP_SENT, glusterd_op_ac_none}, //EVENT_BRICK_OP +        {GD_OP_STATE_BRICK_OP_SENT, glusterd_op_ac_none}, //EVENT_COMMIT_OP +        {GD_OP_STATE_DEFAULT, glusterd_op_ac_unlock}, //EVENT_UNLOCK +        {GD_OP_STATE_BRICK_OP_SENT, glusterd_op_ac_none}, //EVENT_START_UNLOCK +        {GD_OP_STATE_COMMIT_OP_SENT, glusterd_op_ac_send_commit_op}, //EVENT_ALL_ACK +        {GD_OP_STATE_BRICK_OP_SENT, glusterd_op_ac_none}, //EVENT_MAX +}; + +glusterd_op_sm_t glusterd_op_state_brick_op_failed [] = { +        {GD_OP_STATE_BRICK_OP_FAILED, glusterd_op_ac_none}, //EVENT_NONE +        {GD_OP_STATE_BRICK_OP_FAILED, glusterd_op_ac_none},//EVENT_START_LOCK +        {GD_OP_STATE_BRICK_OP_FAILED, glusterd_op_ac_none}, //EVENT_LOCK +        {GD_OP_STATE_BRICK_OP_FAILED, glusterd_op_ac_brick_op_failed}, //EVENT_RCVD_ACC +        {GD_OP_STATE_BRICK_OP_FAILED, glusterd_op_ac_none}, //EVENT_ALL_ACC +        {GD_OP_STATE_BRICK_OP_FAILED, glusterd_op_ac_none}, //EVENT_STAGE_ACC +        {GD_OP_STATE_BRICK_OP_FAILED, glusterd_op_ac_none}, //EVENT_COMMIT_ACC +        {GD_OP_STATE_BRICK_OP_FAILED, glusterd_op_ac_brick_op_failed}, //EVENT_RCVD_RJT +        {GD_OP_STATE_BRICK_OP_FAILED, glusterd_op_ac_none}, //EVENT_BRICK_OP +        {GD_OP_STATE_BRICK_OP_FAILED, glusterd_op_ac_none}, //EVENT_COMMIT_OP +        {GD_OP_STATE_DEFAULT, glusterd_op_ac_unlock}, //EVENT_UNLOCK +        {GD_OP_STATE_BRICK_OP_FAILED, glusterd_op_ac_none}, //EVENT_START_UNLOCK +        {GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_send_unlock}, //EVENT_ALL_ACK +        {GD_OP_STATE_BRICK_OP_FAILED, glusterd_op_ac_none}, //EVENT_MAX +}; + +glusterd_op_sm_t glusterd_op_state_brick_committed [] = { +        {GD_OP_STATE_BRICK_COMMITTED, glusterd_op_ac_none}, //EVENT_NONE +        {GD_OP_STATE_BRICK_COMMITTED, glusterd_op_ac_none},//EVENT_START_LOCK +        {GD_OP_STATE_BRICK_COMMITTED, glusterd_op_ac_none}, //EVENT_LOCK +        {GD_OP_STATE_BRICK_COMMITTED, glusterd_op_ac_rcvd_brick_op_acc}, //EVENT_RCVD_ACC +        {GD_OP_STATE_BRICK_COMMITTED, glusterd_op_ac_none}, //EVENT_ALL_ACC +        {GD_OP_STATE_BRICK_COMMITTED, glusterd_op_ac_none}, //EVENT_STAGE_ACC +        {GD_OP_STATE_BRICK_COMMITTED, glusterd_op_ac_none}, //EVENT_COMMIT_ACC +        {GD_OP_STATE_BRICK_COMMIT_FAILED, glusterd_op_ac_brick_op_failed}, //EVENT_RCVD_RJT +        {GD_OP_STATE_BRICK_COMMITTED, glusterd_op_ac_none}, //EVENT_STAGE_OP +        {GD_OP_STATE_BRICK_COMMITTED, glusterd_op_ac_none}, //EVENT_COMMIT_OP +        {GD_OP_STATE_DEFAULT, glusterd_op_ac_unlock}, //EVENT_UNLOCK +        {GD_OP_STATE_BRICK_COMMITTED, glusterd_op_ac_none}, //EVENT_START_UNLOCK +        {GD_OP_STATE_COMMITED, glusterd_op_ac_commit_op}, //EVENT_ALL_ACK +        {GD_OP_STATE_BRICK_COMMITTED, glusterd_op_ac_none}, //EVENT_MAX +}; + +glusterd_op_sm_t glusterd_op_state_brick_commit_failed [] = { +        {GD_OP_STATE_BRICK_COMMIT_FAILED, glusterd_op_ac_none}, //EVENT_NONE +        {GD_OP_STATE_BRICK_COMMIT_FAILED, glusterd_op_ac_none},//EVENT_START_LOCK +        {GD_OP_STATE_BRICK_COMMIT_FAILED, glusterd_op_ac_none}, //EVENT_LOCK +        {GD_OP_STATE_BRICK_COMMIT_FAILED, glusterd_op_ac_brick_op_failed}, //EVENT_RCVD_ACC +        {GD_OP_STATE_BRICK_COMMIT_FAILED, glusterd_op_ac_none}, //EVENT_ALL_ACC +        {GD_OP_STATE_BRICK_COMMIT_FAILED, glusterd_op_ac_none}, //EVENT_STAGE_ACC +        {GD_OP_STATE_BRICK_COMMIT_FAILED, glusterd_op_ac_none}, //EVENT_COMMIT_ACC +        {GD_OP_STATE_BRICK_COMMIT_FAILED, glusterd_op_ac_brick_op_failed}, //EVENT_RCVD_RJT +        {GD_OP_STATE_BRICK_COMMIT_FAILED, glusterd_op_ac_none}, //EVENT_STAGE_OP +        {GD_OP_STATE_BRICK_COMMIT_FAILED, glusterd_op_ac_none}, //EVENT_COMMIT_OP +        {GD_OP_STATE_DEFAULT, glusterd_op_ac_unlock}, //EVENT_UNLOCK +        {GD_OP_STATE_BRICK_COMMIT_FAILED, glusterd_op_ac_none}, //EVENT_START_UNLOCK +        {GD_OP_STATE_BRICK_COMMIT_FAILED, glusterd_op_ac_send_commit_failed}, //EVENT_ALL_ACK +        {GD_OP_STATE_BRICK_COMMIT_FAILED, glusterd_op_ac_none}, //EVENT_MAX +}; + +glusterd_op_sm_t glusterd_op_state_commit_op_failed [] = { +        {GD_OP_STATE_COMMIT_OP_FAILED, glusterd_op_ac_none}, //EVENT_NONE +        {GD_OP_STATE_COMMIT_OP_FAILED, glusterd_op_ac_none},//EVENT_START_LOCK +        {GD_OP_STATE_COMMIT_OP_FAILED, glusterd_op_ac_none}, //EVENT_LOCK +        {GD_OP_STATE_COMMIT_OP_FAILED, glusterd_op_ac_commit_op_failed}, //EVENT_RCVD_ACC +        {GD_OP_STATE_COMMIT_OP_FAILED, glusterd_op_ac_none}, //EVENT_ALL_ACC +        {GD_OP_STATE_COMMIT_OP_FAILED, glusterd_op_ac_none}, //EVENT_STAGE_ACC +        {GD_OP_STATE_COMMIT_OP_FAILED, glusterd_op_ac_none}, //EVENT_COMMIT_ACC +        {GD_OP_STATE_COMMIT_OP_FAILED, glusterd_op_ac_commit_op_failed}, //EVENT_RCVD_RJT +        {GD_OP_STATE_COMMIT_OP_FAILED, glusterd_op_ac_none}, //EVENT_STAGE_OP +        {GD_OP_STATE_COMMIT_OP_FAILED, glusterd_op_ac_none}, //EVENT_COMMIT_OP +        {GD_OP_STATE_DEFAULT, glusterd_op_ac_unlock}, //EVENT_UNLOCK +        {GD_OP_STATE_COMMIT_OP_FAILED, glusterd_op_ac_none}, //EVENT_START_UNLOCK +        {GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_send_unlock}, //EVENT_ALL_ACK +        {GD_OP_STATE_COMMIT_OP_FAILED, glusterd_op_ac_none}, //EVENT_MAX +}; +  glusterd_op_sm_t glusterd_op_state_commit_op_sent [] = {          {GD_OP_STATE_COMMIT_OP_SENT, glusterd_op_ac_none}, //EVENT_NONE          {GD_OP_STATE_COMMIT_OP_SENT, glusterd_op_ac_none},//EVENT_START_LOCK @@ -5704,11 +6621,12 @@ glusterd_op_sm_t glusterd_op_state_commit_op_sent [] = {          {GD_OP_STATE_UNLOCK_SENT,    glusterd_op_ac_send_unlock}, //EVENT_ALL_ACC          {GD_OP_STATE_COMMIT_OP_SENT, glusterd_op_ac_none}, //EVENT_STAGE_ACC          {GD_OP_STATE_UNLOCK_SENT,    glusterd_op_ac_send_unlock}, //EVENT_COMMIT_ACC -        {GD_OP_STATE_COMMIT_OP_SENT, glusterd_op_ac_commit_error}, //EVENT_RCVD_RJT +        {GD_OP_STATE_COMMIT_OP_FAILED, glusterd_op_ac_commit_op_failed}, //EVENT_RCVD_RJT          {GD_OP_STATE_COMMIT_OP_SENT, glusterd_op_ac_none}, //EVENT_STAGE_OP          {GD_OP_STATE_COMMIT_OP_SENT, glusterd_op_ac_none}, //EVENT_COMMIT_OP -        {GD_OP_STATE_COMMIT_OP_SENT, glusterd_op_ac_unlock}, //EVENT_UNLOCK +        {GD_OP_STATE_DEFAULT,        glusterd_op_ac_unlock}, //EVENT_UNLOCK          {GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_send_unlock}, //EVENT_START_UNLOCK +        {GD_OP_STATE_COMMIT_OP_SENT, glusterd_op_ac_none}, //EVENT_ALL_ACK          {GD_OP_STATE_COMMIT_OP_SENT, glusterd_op_ac_none}, //EVENT_MAX  }; @@ -5725,6 +6643,7 @@ glusterd_op_sm_t glusterd_op_state_commited [] = {          {GD_OP_STATE_COMMITED, glusterd_op_ac_none}, //EVENT_COMMIT_OP          {GD_OP_STATE_DEFAULT, glusterd_op_ac_unlock}, //EVENT_UNLOCK          {GD_OP_STATE_COMMITED, glusterd_op_ac_none}, //EVENT_START_UNLOCK +        {GD_OP_STATE_COMMITED, glusterd_op_ac_none}, //EVENT_ALL_ACK          {GD_OP_STATE_COMMITED, glusterd_op_ac_none}, //EVENT_MAX  }; @@ -5739,8 +6658,9 @@ glusterd_op_sm_t glusterd_op_state_unlock_sent [] = {          {GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_none}, //EVENT_RCVD_RJT          {GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_none}, //EVENT_STAGE_OP          {GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_none}, //EVENT_COMMIT_OP -        {GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_unlock}, //EVENT_UNLOCK +        {GD_OP_STATE_DEFAULT,     glusterd_op_ac_unlock}, //EVENT_UNLOCK          {GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_none}, //EVENT_START_UNLOCK +        {GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_none}, //EVENT_ALL_ACK          {GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_none}, //EVENT_MAX  }; @@ -5753,7 +6673,13 @@ glusterd_op_sm_t *glusterd_op_state_table [] = {          glusterd_op_state_staged,          glusterd_op_state_commit_op_sent,          glusterd_op_state_commited, -        glusterd_op_state_unlock_sent +        glusterd_op_state_unlock_sent, +        glusterd_op_state_stage_op_failed, +        glusterd_op_state_commit_op_failed, +        glusterd_op_state_brick_op_sent, +        glusterd_op_state_brick_op_failed, +        glusterd_op_state_brick_committed, +        glusterd_op_state_brick_commit_failed  };  int @@ -5804,6 +6730,16 @@ out:  }  void +glusterd_destroy_req_ctx (glusterd_req_ctx_t *ctx) +{ +        if (!ctx) +                return; +        if (ctx->dict) +                dict_unref (ctx->dict); +        GF_FREE (ctx); +} + +void  glusterd_destroy_op_event_ctx (glusterd_op_sm_event_t *event)  {          if (!event) @@ -5815,10 +6751,8 @@ glusterd_destroy_op_event_ctx (glusterd_op_sm_event_t *event)                  glusterd_destroy_lock_ctx (event->ctx);                  break;          case GD_OP_EVENT_STAGE_OP: -                glusterd_destroy_stage_ctx (event->ctx); -                break; -        case GD_OP_EVENT_COMMIT_OP: -                glusterd_destroy_commit_ctx (event->ctx); +        case GD_OP_EVENT_ALL_ACK: +                glusterd_destroy_req_ctx (event->ctx);                  break;          default:                  break; @@ -5929,7 +6863,7 @@ int32_t  glusterd_op_set_cli_op (glusterd_op_t op)  { -        int32_t         ret; +        int32_t         ret = 0;          ret = pthread_mutex_trylock (&opinfo.lock); @@ -5992,6 +6926,41 @@ glusterd_op_clear_op (glusterd_op_t op)  }  int32_t +glusterd_op_init_ctx (glusterd_op_t op) +{ +        int     ret = 0; +        dict_t *dict = NULL; + +        dict = dict_new (); +        if (dict == NULL) { +                ret = -1; +                goto out; +        } +        ret = glusterd_op_set_ctx (op, dict); +        if (ret) +                goto out; +        ret = glusterd_op_set_ctx_free (op, _gf_true); +        if (ret) +                goto out; +out: +        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); +        return ret; +} + +int32_t +glusterd_op_fini_ctx (glusterd_op_t op) +{ +        dict_t *dict = NULL; + +        if (glusterd_op_get_ctx_free (op)) { +                dict = glusterd_op_get_ctx (op); +                if (dict) +                        dict_unref (dict); +        } +        return 0; +} + +int32_t  glusterd_op_set_ctx (glusterd_op_t op, void *ctx)  { @@ -6025,6 +6994,7 @@ glusterd_op_free_ctx (glusterd_op_t op, void *ctx, gf_boolean_t ctx_free)                  case GD_OP_START_VOLUME:                  case GD_OP_RESET_VOLUME:                  case GD_OP_GSYNC_SET: +                case GD_OP_PROFILE_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 30d4fe9c8d2..c9c3889b57f 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.h +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.h @@ -48,6 +48,12 @@ typedef enum glusterd_op_sm_state_ {          GD_OP_STATE_COMMIT_OP_SENT,          GD_OP_STATE_COMMITED,          GD_OP_STATE_UNLOCK_SENT, +        GD_OP_STATE_STAGE_OP_FAILED, +        GD_OP_STATE_COMMIT_OP_FAILED, +        GD_OP_STATE_BRICK_OP_SENT, +        GD_OP_STATE_BRICK_OP_FAILED, +        GD_OP_STATE_BRICK_COMMITTED, +        GD_OP_STATE_BRICK_COMMIT_FAILED,          GD_OP_STATE_MAX,  } glusterd_op_sm_state_t; @@ -64,6 +70,7 @@ typedef enum glusterd_op_sm_event_type_ {          GD_OP_EVENT_COMMIT_OP,          GD_OP_EVENT_UNLOCK,          GD_OP_EVENT_START_UNLOCK, +        GD_OP_EVENT_ALL_ACK,          GD_OP_EVENT_MAX  } glusterd_op_sm_event_type_t; @@ -91,6 +98,7 @@ typedef struct glusterd_op_sm_state_info_ {  struct glusterd_op_info_ {          glusterd_op_sm_state_info_t     state;          int32_t                         pending_count; +        int32_t                         brick_pending_count;          int32_t                         op_count;          glusterd_op_t                   op[GD_OP_MAX];          glusterd_op_t                   pending_op[GD_OP_MAX]; @@ -104,6 +112,7 @@ struct glusterd_op_info_ {          int32_t                         cli_op;          gf_boolean_t                    ctx_free[GD_OP_MAX];          char                            *op_errstr; +        struct  list_head               pending_bricks;  };  typedef struct glusterd_op_info_ glusterd_op_info_t; @@ -128,23 +137,27 @@ struct glusterd_op_lock_ctx_ {  typedef struct glusterd_op_lock_ctx_ glusterd_op_lock_ctx_t; -struct glusterd_op_stage_ctx_ { +struct glusterd_req_ctx_ {          rpcsvc_request_t *req;  	u_char            uuid[16];  	int               op;          dict_t           *dict;  }; -typedef struct glusterd_op_stage_ctx_ glusterd_op_stage_ctx_t; +typedef struct glusterd_req_ctx_ glusterd_req_ctx_t; -struct glusterd_op_commit_ctx_ { -        rpcsvc_request_t *req; -	u_char            uuid[16]; -	int               op; -        dict_t           *dict; -}; +typedef struct glusterd_op_brick_rsp_ctx_ { +        int  op_ret; +        char *op_errstr; +        dict_t *rsp_dict; +        glusterd_req_ctx_t *commit_ctx; +        glusterd_brickinfo_t *brickinfo; +} glusterd_op_brick_rsp_ctx_t; -typedef struct glusterd_op_commit_ctx_ glusterd_op_commit_ctx_t; +typedef struct glusterd_pr_brick_rsp_conv_t { +        int count; +        dict_t *dict; +} glusterd_pr_brick_rsp_conv_t;  int  glusterd_op_sm_new_event (glusterd_op_sm_event_type_t event_type, @@ -241,4 +254,18 @@ glusterd_op_sm_state_name_get (int state);  char*  glusterd_op_sm_event_name_get (int event); +int32_t +glusterd_op_bricks_select (glusterd_op_t op, dict_t *dict, char **op_errstr); +int +glusterd_brick_op_build_payload (glusterd_op_t op, glusterd_brickinfo_t *brickinfo, +                                 gd1_mgmt_brick_op_req **req); +int32_t +glusterd_handle_brick_rsp (glusterd_brickinfo_t *brickinfo, +                           glusterd_op_t op, dict_t *rsp_dict, dict_t *ctx_dict, +                           char **op_errstr); +void glusterd_op_brick_disconnect (void *data); +int32_t +glusterd_op_init_ctx (glusterd_op_t op); +int32_t +glusterd_op_fini_ctx (glusterd_op_t op);  #endif diff --git a/xlators/mgmt/glusterd/src/glusterd-pmap.c b/xlators/mgmt/glusterd/src/glusterd-pmap.c index 67d10bfa65e..f1f49fc60b1 100644 --- a/xlators/mgmt/glusterd/src/glusterd-pmap.c +++ b/xlators/mgmt/glusterd/src/glusterd-pmap.c @@ -418,9 +418,6 @@ gluster_pmap_signin (rpcsvc_request_t *req)          ret = glusterd_get_brickinfo (THIS, args.brick, args.port, _gf_true,                                        &brickinfo); -        if (!ret) -                glusterd_set_brick_status (brickinfo, GF_BRICK_STARTED); -  fail:          glusterd_submit_reply (req, &rsp, NULL, 0, NULL,                                 (gd_serialize_t)xdr_from_pmap_signin_rsp); @@ -452,11 +449,8 @@ gluster_pmap_signout (rpcsvc_request_t *req)          rsp.op_ret = pmap_registry_remove (THIS, args.port, args.brick,                                             GF_PMAP_PORT_BRICKSERVER, req->trans); -        ret = glusterd_get_brickinfo (THIS, args.brick, args.port, _gf_true,  +        ret = glusterd_get_brickinfo (THIS, args.brick, args.port, _gf_true,                                        &brickinfo); -        if (!ret) -                glusterd_set_brick_status (brickinfo, GF_BRICK_STOPPED); -  fail:          glusterd_submit_reply (req, &rsp, NULL, 0, NULL,                                 (gd_serialize_t)xdr_from_pmap_signout_rsp); diff --git a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c index e7134c990b7..8eba024a919 100644 --- a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c @@ -41,10 +41,12 @@  #define SERVER_PATH_MAX  (16 * 1024) -extern glusterd_op_info_t    opinfo; - +extern glusterd_op_info_t opinfo;  int32_t +glusterd3_1_brick_op (call_frame_t *frame, xlator_t *this, +                      void *data); +int32_t  glusterd_op_send_cli_response (glusterd_op_t op, int32_t op_ret,                                 int32_t op_errno, rpcsvc_request_t *req,                                 void *op_ctx, char *op_errstr) @@ -53,6 +55,7 @@ glusterd_op_send_cli_response (glusterd_op_t op, int32_t op_ret,          gd_serialize_t  sfunc = NULL;          void            *cli_rsp = NULL;          dict_t          *ctx = NULL; +        char            *free_ptr = NULL;          switch (op) {          case GD_OP_CREATE_VOLUME: @@ -307,19 +310,37 @@ glusterd_op_send_cli_response (glusterd_op_t op, int32_t op_ret,                  gf_log ("", GF_LOG_DEBUG, "not supported op %d", op);                  break;          } +        case GD_OP_PROFILE_VOLUME: +        { +                gf1_cli_stats_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.stats_info.stats_info_val, +                        (size_t*)&rsp.stats_info.stats_info_len); +                free_ptr = rsp.stats_info.stats_info_val; +                cli_rsp = &rsp; +                sfunc = gf_xdr_from_cli_stats_volume_rsp; +                break; +        }          case GD_OP_NONE:          case GD_OP_MAX: +        {                  gf_log ("", GF_LOG_ERROR, "invalid operation %d", op);                  break;          } +        }          ret = glusterd_submit_reply (req, cli_rsp, NULL, 0, NULL,                                       sfunc); -        if (ret) -                goto out; - -out: +        if (free_ptr) +                GF_FREE (free_ptr);          gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);          return ret;  } @@ -867,7 +888,8 @@ glusterd3_1_stage_op_cbk (struct rpc_req *req, struct iovec *iov,          if (op_ret) {                  event_type = GD_OP_EVENT_RCVD_RJT;                  opinfo.op_ret = op_ret; -                opinfo.op_errstr = gf_strdup(rsp.op_errstr); +                if (strcmp ("", rsp.op_errstr)) +                        opinfo.op_errstr = gf_strdup(rsp.op_errstr);                  if (!opinfo.op_errstr) {                          gf_log ("", GF_LOG_ERROR, "memory allocation failed");                          ret = -1; @@ -922,6 +944,59 @@ out:  } +void +_profile_volume_add_friend_rsp (dict_t *this, char *key, data_t *value, +                               void *data) +{ +        char    new_key[256] = {0}; +        glusterd_pr_brick_rsp_conv_t *rsp_ctx = NULL; +        data_t  *new_value = NULL; +        int     brick_count = 0; +        char    brick_key[256]; + +        if (strcmp (key, "count") == 0) +                return; +        sscanf (key, "%d%s", &brick_count, brick_key); +        rsp_ctx = data; +        new_value = data_copy (value); +        GF_ASSERT (new_value); +        snprintf (new_key, sizeof (new_key), "%d%s", +                  rsp_ctx->count + brick_count, brick_key); +        dict_set (rsp_ctx->dict, new_key, new_value); +} + +int +glusterd_profile_volume_use_rsp_dict (dict_t *rsp_dict) +{ +        int     ret = 0; +        glusterd_pr_brick_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_PROFILE_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, _profile_volume_add_friend_rsp, &rsp_ctx); +        dict_del (ctx_dict, "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) @@ -1001,14 +1076,22 @@ glusterd3_1_commit_op_cbk (struct rpc_req *req, struct iovec *iov,                          ret = glusterd_rb_use_rsp_dict (dict);                          if (ret)                                  goto out; -                        break; +                break; +                  case GD_OP_SYNC_VOLUME:                          ret = glusterd_sync_use_rsp_dict (dict);                          if (ret)                                  goto out; -                        break; +                break; + +                case GD_OP_PROFILE_VOLUME: +                        ret = glusterd_profile_volume_use_rsp_dict (dict); +                        if (ret) +                                goto out; +                break; +                  default: -                        break; +                break;                  }          } @@ -1066,7 +1149,7 @@ glusterd3_1_probe (call_frame_t *frame, xlator_t *this,          req.hostname = gf_strdup (hostname);          req.port = port; -        ret = glusterd_submit_request (peerinfo, &req, frame, peerinfo->mgmt, +        ret = glusterd_submit_request (peerinfo->rpc, &req, frame, peerinfo->mgmt,                                         GD_MGMT_PROBE_QUERY,                                         NULL, gd_xdr_from_mgmt_probe_req,                                         this, glusterd3_1_probe_cbk); @@ -1119,7 +1202,7 @@ glusterd3_1_friend_add (call_frame_t *frame, xlator_t *this,          if (ret)                  goto out; -        ret = glusterd_submit_request (peerinfo, &req, frame, peerinfo->mgmt, +        ret = glusterd_submit_request (peerinfo->rpc, &req, frame, peerinfo->mgmt,                                         GD_MGMT_FRIEND_ADD,                                         NULL, gd_xdr_from_mgmt_friend_req,                                         this, glusterd3_1_friend_add_cbk); @@ -1161,7 +1244,7 @@ glusterd3_1_friend_remove (call_frame_t *frame, xlator_t *this,          uuid_copy (req.uuid, priv->uuid);          req.hostname = peerinfo->hostname;          req.port = peerinfo->port; -        ret = glusterd_submit_request (peerinfo, &req, frame, peerinfo->mgmt, +        ret = glusterd_submit_request (peerinfo->rpc, &req, frame, peerinfo->mgmt,                                         GD_MGMT_FRIEND_REMOVE,                                         NULL, gd_xdr_from_mgmt_friend_req,                                         this, glusterd3_1_friend_remove_cbk); @@ -1206,7 +1289,7 @@ glusterd3_1_friend_update (call_frame_t *frame, xlator_t *this,          uuid_copy (req.uuid, priv->uuid);          dummy_frame = create_frame (this, this->ctx->pool); -        ret = glusterd_submit_request (peerinfo, &req, dummy_frame, +        ret = glusterd_submit_request (peerinfo->rpc, &req, dummy_frame,                                         peerinfo->mgmt,                                         GD_MGMT_FRIEND_UPDATE,                                         NULL, gd_xdr_from_mgmt_friend_update, @@ -1244,7 +1327,7 @@ glusterd3_1_cluster_lock (call_frame_t *frame, xlator_t *this,          if (!dummy_frame)                  goto out; -        ret = glusterd_submit_request (peerinfo, &req, dummy_frame, +        ret = glusterd_submit_request (peerinfo->rpc, &req, dummy_frame,                                         peerinfo->mgmt, GD_MGMT_CLUSTER_LOCK,                                         NULL,                                         gd_xdr_from_mgmt_cluster_lock_req, @@ -1278,7 +1361,7 @@ glusterd3_1_cluster_unlock (call_frame_t *frame, xlator_t *this,          if (!dummy_frame)                  goto out; -        ret = glusterd_submit_request (peerinfo, &req, dummy_frame, +        ret = glusterd_submit_request (peerinfo->rpc, &req, dummy_frame,                                         peerinfo->mgmt, GD_MGMT_CLUSTER_UNLOCK,                                         NULL,                                         gd_xdr_from_mgmt_cluster_unlock_req, @@ -1337,7 +1420,7 @@ glusterd3_1_stage_op (call_frame_t *frame, xlator_t *this,          if (!dummy_frame)                  goto out; -        ret = glusterd_submit_request (peerinfo, &req, dummy_frame, +        ret = glusterd_submit_request (peerinfo->rpc, &req, dummy_frame,                                         peerinfo->mgmt, GD_MGMT_STAGE_OP,                                         NULL,                                         gd_xdr_from_mgmt_stage_op_req, @@ -1399,7 +1482,7 @@ glusterd3_1_commit_op (call_frame_t *frame, xlator_t *this,          if (!dummy_frame)                  goto out; -        ret = glusterd_submit_request (peerinfo, &req, dummy_frame, +        ret = glusterd_submit_request (peerinfo->rpc, &req, dummy_frame,                                         peerinfo->mgmt, GD_MGMT_COMMIT_OP,                                         NULL,                                         gd_xdr_from_mgmt_commit_op_req, @@ -1413,6 +1496,118 @@ out:          return ret;  } +int32_t +glusterd_start_brick_disconnect_timer (glusterd_op_brick_rsp_ctx_t *ev_ctx) +{ +        struct timeval       timeout = {0, }; +        int32_t              ret = -1; +        xlator_t             *this = NULL; +        glusterd_brickinfo_t *brickinfo = NULL; + +        timeout.tv_sec  = 5; +        timeout.tv_usec = 0; +        brickinfo = ev_ctx->brickinfo; +        GF_ASSERT (brickinfo); +        this = THIS; +        GF_ASSERT (this); + +        brickinfo->timer = gf_timer_call_after (this->ctx, timeout, +                                                glusterd_op_brick_disconnect, +                                                (void *) ev_ctx); + +        ret = 0; + +        return ret; +} + +int32_t +glusterd3_1_brick_op_cbk (struct rpc_req *req, struct iovec *iov, +                          int count, void *myframe) +{ +        gd1_mgmt_brick_op_rsp         rsp   = {0}; +        int                           ret   = -1; +        int32_t                       op_ret = -1; +        glusterd_op_sm_event_type_t   event_type = GD_OP_EVENT_NONE; +        call_frame_t                  *frame = NULL; +        glusterd_op_brick_rsp_ctx_t   *ev_ctx = NULL; +        int32_t                       op = -1; +        dict_t                        *dict = NULL; + +        GF_ASSERT (req); +        frame = myframe; + +        if (-1 == req->rpc_status) { +                rsp.op_ret   = -1; +                rsp.op_errno = EINVAL; +                rsp.op_errstr = "error"; +		event_type = GD_OP_EVENT_RCVD_RJT; +                goto out; +        } + +        ret =  gd_xdr_to_mgmt_brick_op_rsp (*iov, &rsp); +        if (ret < 0) { +                gf_log ("", GF_LOG_ERROR, "error"); +                rsp.op_ret   = -1; +                rsp.op_errno = EINVAL; +                rsp.op_errstr = "error"; +		event_type = GD_OP_EVENT_RCVD_RJT; +                goto out; +        } + +        if (rsp.output.output_len) { +                /* Unserialize the dictionary */ +                dict  = dict_new (); + +                ret = dict_unserialize (rsp.output.output_val, +                                        rsp.output.output_len, +                                        &dict); +                if (ret < 0) { +                        gf_log ("glusterd", GF_LOG_ERROR, +                                "failed to " +                                "unserialize rsp-buffer to dictionary"); +			event_type = GD_OP_EVENT_RCVD_RJT; +                        goto out; +                } else { +                        dict->extra_stdfree = rsp.output.output_val; +                } +        } + +        op_ret = rsp.op_ret; + +out: +        ev_ctx = GF_CALLOC (1, sizeof (*ev_ctx), gf_gld_mt_brick_rsp_ctx_t); +        GF_ASSERT (ev_ctx); +        if (op_ret) { +                event_type = GD_OP_EVENT_RCVD_RJT; +                ev_ctx->op_ret = op_ret; +                ev_ctx->op_errstr = gf_strdup(rsp.op_errstr); +        } else { +                event_type = GD_OP_EVENT_RCVD_ACC; +        } +        ev_ctx->brickinfo = frame->cookie; +        ev_ctx->rsp_dict  = dict; +        ev_ctx->commit_ctx = frame->local; +        op = glusterd_op_get_op (); +        if ((op == GD_OP_STOP_VOLUME) || +           (op == GD_OP_REMOVE_BRICK)) { +                ret = glusterd_start_brick_disconnect_timer (ev_ctx); +        } else { +                ret = glusterd_op_sm_inject_event (event_type, ev_ctx); +                if (!ret) { +                        glusterd_friend_sm (); +                        glusterd_op_sm (); +                } +        } + +        if (ret && dict) +                dict_unref (dict); +        if (rsp.op_errstr && strcmp (rsp.op_errstr, "error")) +                free (rsp.op_errstr); //malloced by xdr +        GLUSTERD_STACK_DESTROY (frame); +        return ret; +} + +  struct rpc_clnt_procedure glusterd3_1_clnt_mgmt_actors[GD_MGMT_MAXVALUE] = {          [GD_MGMT_NULL]        = {"NULL", NULL },          [GD_MGMT_PROBE_QUERY]  = { "PROBE_QUERY",  glusterd3_1_probe}, @@ -1425,6 +1620,11 @@ struct rpc_clnt_procedure glusterd3_1_clnt_mgmt_actors[GD_MGMT_MAXVALUE] = {          [GD_MGMT_FRIEND_UPDATE]  = { "FRIEND_UPDATE",  glusterd3_1_friend_update},  }; +struct rpc_clnt_procedure glusterd3_1_fs_mgmt_actors[GD_MGMT_MAXVALUE] = { +        [GD_MGMT_NULL]        = {"NULL", NULL }, +        [GD_MGMT_BRICK_OP] = {"BRICK_OP", glusterd3_1_brick_op}, +}; +  struct rpc_clnt_program glusterd3_1_mgmt_prog = {          .progname  = "Mgmt 3.1",          .prognum   = GLUSTERD1_MGMT_PROGRAM, @@ -1452,3 +1652,88 @@ struct rpc_clnt_program gd_clnt_mgmt_prog = {          .numproc   = GD_MGMT_PROCCNT,          .proctable = gd_clnt_mgmt_actors,  }; + +struct rpc_clnt_program glusterd_glusterfs_3_1_mgmt_prog = { +        .progname  = "GlusterFS Mops", +        .prognum   = GLUSTERFS_PROGRAM, +        .progver   = GLUSTERFS_VERSION, +        .proctable = glusterd3_1_fs_mgmt_actors, +        .numproc   = GLUSTERFS_PROCCNT, +}; + +int32_t +glusterd3_1_brick_op (call_frame_t *frame, xlator_t *this, +                      void *data) +{ +        gd1_mgmt_brick_op_req           *req = NULL; +        int                             ret = 0; +        glusterd_conf_t                 *priv = NULL; +        call_frame_t                    *dummy_frame = NULL; +        char                            *op_errstr = NULL; +        int                             pending_bricks = 0; +        glusterd_pending_node_t         *pending_brick; +        glusterd_brickinfo_t            *brickinfo = NULL; +        glusterd_req_ctx_t               *req_ctx = NULL; + +        if (!this) { +                ret = -1; +                goto out; +        } +        priv = this->private; +        GF_ASSERT (priv); + +        req_ctx = data; +        GF_ASSERT (req_ctx); +        INIT_LIST_HEAD (&opinfo.pending_bricks); +        ret = glusterd_op_bricks_select (req_ctx->op, req_ctx->dict, &op_errstr); + +        if (ret) { +                gf_log ("", GF_LOG_ERROR, "Brick Op failed"); +                opinfo.op_errstr = op_errstr; +                goto out; +        } + +        list_for_each_entry (pending_brick, &opinfo.pending_bricks, list) { +                dummy_frame = create_frame (this, this->ctx->pool); +                brickinfo = pending_brick->node; + +                if (!dummy_frame) +                        continue; +                if (glusterd_is_brick_started (brickinfo)) +                        continue; + +                ret = glusterd_brick_op_build_payload (req_ctx->op, brickinfo, +                                                (gd1_mgmt_brick_op_req **)&req); + +                if (ret) +                        goto out; + +                dummy_frame->local = data; +                dummy_frame->cookie = brickinfo; +                ret = glusterd_submit_request (brickinfo->rpc, req, dummy_frame, +                                               &glusterd_glusterfs_3_1_mgmt_prog, +                                               req->op, NULL, +                                               gd_xdr_from_mgmt_brick_op_req, +                                               this, glusterd3_1_brick_op_cbk); +                if (req) { +                        if (req->input.input_val) +                                GF_FREE (req->input.input_val); +                        GF_FREE (req); +                        req = NULL; +                } +                if (!ret) +                        pending_bricks++; +        } + +        gf_log ("glusterd", GF_LOG_DEBUG, "Sent op req to %d bricks", +                                            pending_bricks); +        opinfo.brick_pending_count = pending_bricks; + +out: +        if (ret) { +                glusterd_op_sm_inject_event (GD_OP_EVENT_RCVD_RJT, data); +                opinfo.op_ret = ret; +        } +        gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret); +        return ret; +} diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c index cb38ddf88f6..458cd6c5888 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -23,7 +23,6 @@  #endif  #include <inttypes.h> -  #include "globals.h"  #include "glusterfs.h"  #include "compat.h" @@ -33,6 +32,7 @@  #include "timer.h"  #include "defaults.h"  #include "compat.h" +#include "md5.h"  #include "compat-errno.h"  #include "statedump.h"  #include "glusterd-mem-types.h" @@ -63,6 +63,7 @@  #define MOUNTV3_VERSION 3  #define MOUNTV1_VERSION 1 +char    *glusterd_sock_dir = "/tmp";  static glusterd_lock_t lock;  static int32_t @@ -303,7 +304,7 @@ glusterd_get_uuid (uuid_t *uuid)  }  int -glusterd_submit_request (glusterd_peerinfo_t *peerinfo, void *req, +glusterd_submit_request (struct rpc_clnt *rpc, void *req,                           call_frame_t *frame, rpc_clnt_prog_t *prog,                           int procnum, struct iobref *iobref,                           gd_serialize_t sfunc, xlator_t *this, @@ -315,7 +316,7 @@ glusterd_submit_request (glusterd_peerinfo_t *peerinfo, void *req,          char                    new_iobref = 0, start_ping = 0;          struct iovec            iov         = {0, }; -        GF_ASSERT (peerinfo); +        GF_ASSERT (rpc);          GF_ASSERT (this);          iobuf = iobuf_get (this->ctx->iobuf_pool); @@ -347,18 +348,18 @@ glusterd_submit_request (glusterd_peerinfo_t *peerinfo, void *req,                  count = 1;          }          /* Send the msg */ -        ret = rpc_clnt_submit (peerinfo->rpc, prog, procnum, cbkfn, +        ret = rpc_clnt_submit (rpc, prog, procnum, cbkfn,                                 &iov, count,                                 NULL, 0, iobref, frame, NULL, 0, NULL, 0, NULL);          if (ret == 0) { -                pthread_mutex_lock (&peerinfo->rpc->conn.lock); +                pthread_mutex_lock (&rpc->conn.lock);                  { -                        if (!peerinfo->rpc->conn.ping_started) { +                        if (!rpc->conn.ping_started) {                                  start_ping = 1;                          }                  } -                pthread_mutex_unlock (&peerinfo->rpc->conn.lock); +                pthread_mutex_unlock (&rpc->conn.lock);          }          if (start_ping) @@ -375,7 +376,6 @@ out:          return ret;  } -  struct iobuf *  glusterd_serialize_reply (rpcsvc_request_t *req, void *arg,                            gd_serialize_t sfunc, struct iovec *outmsg) @@ -901,6 +901,37 @@ out:          return ret;  } +void +glusterd_set_brick_socket_filepath (glusterd_volinfo_t *volinfo, +                                    glusterd_brickinfo_t *brickinfo, +                                    char *sockpath, size_t len) +{ +        char                    export_path[PATH_MAX] = {0,}; +        char                    sock_filepath[PATH_MAX] = {0,}; +        char                    md5_sum[MD5_DIGEST_LEN*2+1] = {0,}; +        char                    volume_dir[PATH_MAX] = {0,}; +        xlator_t                *this = NULL; +        glusterd_conf_t         *priv = NULL; +        int                     expected_file_len = 0; + +        expected_file_len = strlen (glusterd_sock_dir) + strlen ("/") + +                            MD5_DIGEST_LEN*2 + strlen (".socket") + 1; +        GF_ASSERT (len >= expected_file_len); +        this = THIS; +        GF_ASSERT (this); + +        priv = this->private; + +        GLUSTERD_GET_VOLUME_DIR (volume_dir, volinfo, priv); +        GLUSTERD_REMOVE_SLASH_FROM_PATH (brickinfo->path, export_path); +        snprintf (sock_filepath, PATH_MAX, "%s/run/%s-%s", +                  volume_dir, brickinfo->hostname, export_path); +        _get_md5_str (md5_sum, sizeof (md5_sum), +                              (uint8_t*)sock_filepath, strlen (sock_filepath)); + +        snprintf (sockpath, len, "%s/%s.socket", glusterd_sock_dir, md5_sum); +} +  int32_t  glusterd_volume_start_glusterfs (glusterd_volinfo_t  *volinfo,                                   glusterd_brickinfo_t  *brickinfo) @@ -918,6 +949,9 @@ glusterd_volume_start_glusterfs (glusterd_volinfo_t  *volinfo,          int                     port = 0;          FILE                    *file = NULL;          gf_boolean_t            is_locked = _gf_false; +        dict_t                  *options = NULL; +        char                    socketpath[PATH_MAX] = {0}; +        struct rpc_clnt         *rpc = NULL;          GF_ASSERT (volinfo);          GF_ASSERT (brickinfo); @@ -937,6 +971,8 @@ glusterd_volume_start_glusterfs (glusterd_volinfo_t  *volinfo,                  goto out;          } +        glusterd_set_brick_socket_filepath (volinfo, brickinfo, socketpath, +                                            sizeof (socketpath));          GLUSTERD_GET_BRICK_PIDFILE (pidfile, path, brickinfo->hostname,                                      brickinfo->path); @@ -948,7 +984,7 @@ glusterd_volume_start_glusterfs (glusterd_volinfo_t  *volinfo,                          gf_log ("", GF_LOG_NORMAL, "brick %s:%s "                                  "already started", brickinfo->hostname,                                  brickinfo->path); -                        goto out; +                        goto connect;                  }          } @@ -964,7 +1000,7 @@ glusterd_volume_start_glusterfs (glusterd_volinfo_t  *volinfo,                                  gf_log ("", GF_LOG_NORMAL, "brick %s:%s "                                          "already started", brickinfo->hostname,                                          brickinfo->path); -                                goto out; +                                goto connect;                          } else if (0 == ret) {                                  is_locked = _gf_true;                          } @@ -998,9 +1034,9 @@ glusterd_volume_start_glusterfs (glusterd_volinfo_t  *volinfo,          snprintf (cmd_str, 8192,                    "%s/sbin/glusterfsd --xlator-option %s-server.listen-port=%d " -                  "-s localhost --volfile-id %s -p %s --brick-name %s " +                  "-s localhost --volfile-id %s -p %s -S %s --brick-name %s "                    "--brick-port %d -l %s", GFS_PREFIX, volinfo->volname, -                  port, volfile, pidfile, brickinfo->path, port, +                  port, volfile, pidfile, socketpath, brickinfo->path, port,                    brickinfo->logfile);  	gf_log ("",GF_LOG_DEBUG,"Starting GlusterFS Command Executed: \n %s \n", cmd_str); @@ -1010,6 +1046,19 @@ glusterd_volume_start_glusterfs (glusterd_volinfo_t  *volinfo,                  //pmap_registry_bind (THIS, port, brickinfo->path);                  brickinfo->port = port;          } + +connect: +        if (brickinfo->rpc == NULL) { +                ret = rpc_clnt_transport_unix_options_build (&options, socketpath); +                if (ret) +                        goto out; +                ret = glusterd_rpc_create (&rpc, options, +                                           glusterd_brick_rpc_notify, +                                           brickinfo); +                if (ret) +                        goto out; +                brickinfo->rpc = rpc; +        }  out:          if (is_locked && file)                  lockf (fileno (file), F_ULOCK, 0); @@ -1019,6 +1068,36 @@ out:  }  int32_t +glusterd_brick_unlink_socket_file (glusterd_volinfo_t *volinfo, +                                   glusterd_brickinfo_t *brickinfo) +{ +        char                    path[PATH_MAX] = {0,}; +        char                    socketpath[PATH_MAX] = {0}; +        xlator_t                *this = NULL; +        glusterd_conf_t         *priv = NULL; +        int                     ret = 0; + +        GF_ASSERT (volinfo); +        GF_ASSERT (brickinfo); + +        this = THIS; +        GF_ASSERT (this); + +        priv = this->private; +        GLUSTERD_GET_VOLUME_DIR (path, volinfo, priv); +        glusterd_set_brick_socket_filepath (volinfo, brickinfo, socketpath, +                                            sizeof (socketpath)); +        ret = unlink (socketpath); +        if (ret && (ENOENT == errno)) { +                ret = 0; +        } else { +                gf_log ("glusterd", GF_LOG_ERROR, "Failed to remove %s" +                        " error: %s", socketpath, strerror (errno)); +        } + +        return ret; +} +int32_t  glusterd_volume_stop_glusterfs (glusterd_volinfo_t  *volinfo,                                  glusterd_brickinfo_t   *brickinfo)  { @@ -1026,6 +1105,7 @@ glusterd_volume_stop_glusterfs (glusterd_volinfo_t  *volinfo,          glusterd_conf_t         *priv = NULL;          char                    pidfile[PATH_MAX] = {0,};          char                    path[PATH_MAX] = {0,}; +        int                     ret = 0;          GF_ASSERT (volinfo);          GF_ASSERT (brickinfo); @@ -1035,11 +1115,19 @@ glusterd_volume_stop_glusterfs (glusterd_volinfo_t  *volinfo,          priv = this->private; +        if (brickinfo->rpc) { +                rpc_clnt_unref (brickinfo->rpc); +                brickinfo->rpc = NULL; +        }          GLUSTERD_GET_VOLUME_DIR (path, volinfo, priv);          GLUSTERD_GET_BRICK_PIDFILE (pidfile, path, brickinfo->hostname,                                      brickinfo->path); -        return glusterd_service_stop ("brick", pidfile, SIGTERM, _gf_false); +        ret = glusterd_service_stop ("brick", pidfile, SIGTERM, _gf_false); +        if (ret == 0) { +                ret = glusterd_brick_unlink_socket_file (volinfo, brickinfo); +        } +        return ret;  }  int32_t @@ -1920,7 +2008,6 @@ glusterd_brick_start (glusterd_volinfo_t *volinfo,                  goto out;          } -  out:          gf_log ("", GF_LOG_DEBUG, "returning %d ", ret);          return ret; @@ -1982,6 +2069,13 @@ glusterd_set_brick_status (glusterd_brickinfo_t  *brickinfo,  {          GF_ASSERT (brickinfo);          brickinfo->status = status; +        if (GF_BRICK_STARTED == status) { +                gf_log ("glusterd", GF_LOG_DEBUG, "Setting brick %s:%s status " +                        "to started", brickinfo->hostname, brickinfo->path); +        } else { +                gf_log ("glusterd", GF_LOG_DEBUG, "Setting brick %s:%s status " +                        "to stopped", brickinfo->hostname, brickinfo->path); +        }  }  int @@ -2676,3 +2770,38 @@ glusterd_peer_destroy (glusterd_peerinfo_t *peerinfo)  out:          return ret;  } + +int +glusterd_remove_pending_entry (struct list_head *list, void *elem) +{ +        glusterd_pending_node_t *pending_node = NULL; +        glusterd_pending_node_t *tmp = NULL; +        int                     ret = -1; + +        list_for_each_entry_safe (pending_node, tmp, list, list) { +                if (elem == pending_node->node) { +                        list_del_init (&pending_node->list); +                        GF_FREE (pending_node); +                        ret = 0; +                        goto out; +                } +        } +out: +        gf_log ("", GF_LOG_DEBUG, "returning %d", ret); +        return ret; + +} + +int +glusterd_clear_pending_nodes (struct list_head *list) +{ +        glusterd_pending_node_t *pending_node = NULL; +        glusterd_pending_node_t *tmp = NULL; + +        list_for_each_entry_safe (pending_node, tmp, list, list) { +                list_del_init (&pending_node->list); +                GF_FREE (pending_node); +        } + +        return 0; +} diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h index 79b2454c085..a903cf8d3a8 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.h +++ b/xlators/mgmt/glusterd/src/glusterd-utils.h @@ -70,12 +70,11 @@ glusterd_submit_reply (rpcsvc_request_t *req, void *arg,                         struct iobref *iobref, gd_serialize_t sfunc);  int -glusterd_submit_request (glusterd_peerinfo_t *peerinfo, void *req, -                         call_frame_t *frame, struct rpc_clnt_program *prog, +glusterd_submit_request (struct rpc_clnt *rpc, void *req, +                         call_frame_t *frame, rpc_clnt_prog_t *prog,                           int procnum, struct iobref *iobref,                           gd_serialize_t sfunc, xlator_t *this,                           fop_cbk_fn_t cbkfn); -  int32_t  glusterd_volinfo_new (glusterd_volinfo_t **volinfo); @@ -252,4 +251,8 @@ glusterd_sm_tr_log_delete (glusterd_sm_tr_log_t *log);  int  glusterd_sm_tr_log_add_to_dict (dict_t *dict,                                  glusterd_sm_tr_log_t *circular_log); +int +glusterd_remove_pending_entry (struct list_head *list, void *elem); +int +glusterd_clear_pending_nodes (struct list_head *list);  #endif diff --git a/xlators/mgmt/glusterd/src/glusterd.c b/xlators/mgmt/glusterd/src/glusterd.c index 675713585d5..732a9a3e2b5 100644 --- a/xlators/mgmt/glusterd/src/glusterd.c +++ b/xlators/mgmt/glusterd/src/glusterd.c @@ -53,6 +53,7 @@ extern struct rpcsvc_program gd_svc_cli_prog;  extern struct rpcsvc_program gluster_handshake_prog;  extern struct rpcsvc_program gluster_pmap_prog;  extern glusterd_op_info_t opinfo; +extern struct rpc_clnt_program glusterd_glusterfs_3_1_mgmt_prog;  rpcsvc_cbk_program_t glusterd_cbk_prog = {          .progname  = "Gluster Callback", @@ -391,6 +392,7 @@ init (xlator_t *this)          INIT_LIST_HEAD (&conf->volumes);          pthread_mutex_init (&conf->mutex, NULL);          conf->rpc = rpc; +        conf->gfs_mgmt = &glusterd_glusterfs_3_1_mgmt_prog;          strncpy (conf->workdir, dirname, PATH_MAX);          INIT_LIST_HEAD (&conf->xprt_list); diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h index 2b02a513981..a38c9a799e8 100644 --- a/xlators/mgmt/glusterd/src/glusterd.h +++ b/xlators/mgmt/glusterd/src/glusterd.h @@ -73,6 +73,7 @@ typedef enum glusterd_op_ {          GD_OP_LOG_LOCATE,          GD_OP_LOG_ROTATE,          GD_OP_GSYNC_SET, +        GD_OP_PROFILE_VOLUME,          GD_OP_MAX,  } glusterd_op_t; @@ -104,6 +105,7 @@ typedef struct {          glusterd_store_handle_t *handle;          gf_timer_t *timer;          glusterd_sm_tr_log_t op_sm_log; +        struct rpc_clnt_program *gfs_mgmt;  } glusterd_conf_t;  typedef enum gf_brick_status { @@ -120,7 +122,9 @@ struct glusterd_brickinfo {          char   *logfile;          gf_boolean_t signed_in;          glusterd_store_handle_t *shandle; -        gf_brick_status_t status;  +        gf_brick_status_t status; +        struct rpc_clnt *rpc; +        gf_timer_t *timer;  };  typedef struct glusterd_brickinfo glusterd_brickinfo_t; @@ -205,6 +209,11 @@ struct glusterd_volinfo_ {  typedef struct glusterd_volinfo_ glusterd_volinfo_t; +typedef struct glusterd_pending_node_ { +        void   *node; +        struct list_head list; +} glusterd_pending_node_t; +  enum glusterd_op_ret {          GLUSTERD_CONNECTION_AWAITED = 100,  }; @@ -326,10 +335,6 @@ int32_t  glusterd_create_volume (rpcsvc_request_t *req, dict_t *dict);  int -glusterd_rpc_notify (struct rpc_clnt *rpc, void *mydata, -                     rpc_clnt_event_t event, -                     void *data); -int  glusterd_handle_incoming_friend_req (rpcsvc_request_t *req);  int @@ -408,9 +413,6 @@ glusterd_handle_cli_get_volume (rpcsvc_request_t *req);  int32_t  glusterd_get_volumes (rpcsvc_request_t *req, dict_t *dict, int32_t flags); -int32_t -glusterd_add_brick (rpcsvc_request_t *req, dict_t *dict); -  int  glusterd_handle_add_brick (rpcsvc_request_t *req); @@ -470,9 +472,6 @@ glusterd_xfer_cli_deprobe_resp (rpcsvc_request_t *req, int32_t op_ret,  int  glusterd_fetchspec_notify (xlator_t *this); -int32_t -glusterd_sync_volume (rpcsvc_request_t *req, dict_t *ctx); -  int  glusterd_add_volume_detail_to_dict (glusterd_volinfo_t *volinfo,                                      dict_t  *volumes, int   count); @@ -490,4 +489,21 @@ glusterd_peer_handshake (xlator_t *this, struct rpc_clnt *rpc,  int  glusterd_validate_reconfopts (glusterd_volinfo_t *volinfo, dict_t *val_dict, char **op_errstr); +int +glusterd_handle_cli_profile_volume (rpcsvc_request_t *req); + +int32_t +glusterd_set_volume (rpcsvc_request_t *req, dict_t *dict); +int +glusterd_peer_rpc_notify (struct rpc_clnt *rpc, void *mydata, +                          rpc_clnt_event_t event, +                          void *data); +int +glusterd_brick_rpc_notify (struct rpc_clnt *rpc, void *mydata, +                          rpc_clnt_event_t event, void *data); + +int +glusterd_rpc_create (struct rpc_clnt **rpc, dict_t *options, +                     rpc_clnt_notify_t notify_fn, void *notify_data); +  #endif  | 
