diff options
| author | Kaushal M <kaushal@redhat.com> | 2014-02-11 10:07:24 +0530 | 
|---|---|---|
| committer | Vijay Bellur <vbellur@redhat.com> | 2014-04-29 09:37:32 -0700 | 
| commit | 5e4a5a4c27f120102d4c2e3c7d558a20d838cf24 (patch) | |
| tree | 9819acc18296b122a06dd3a53a16d20f80b86f81 | |
| parent | 16e71bf8b76eb421e30f5fe239601ba85710c983 (diff) | |
cli: Add a cli command to enable/disable barrier
This patch adds a new
 'gluster volume barrier <VOLNAME> {enable|disable}'
cli command. This helps in testing the brick op code path when testing
the barrier xlator.
This patch can be reverted later if not required for end users.
Change-Id: Icd86a2d13e7f276dda1ecbb2593d60638ece7dcd
BUG: 1060002
Signed-off-by: Kaushal M <kaushal@redhat.com>
Reviewed-on: http://review.gluster.org/6958
Reviewed-by: Krishnan Parthasarathi <kparthas@redhat.com>
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Vijay Bellur <vbellur@redhat.com>
| -rw-r--r-- | cli/src/cli-cmd-volume.c | 57 | ||||
| -rw-r--r-- | cli/src/cli-rpc-ops.c | 63 | ||||
| -rw-r--r-- | rpc/rpc-lib/src/protocol-common.h | 1 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-brick-ops.c | 101 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-handler.c | 63 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-op-sm.c | 9 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-volgen.c | 20 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-volgen.h | 2 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd.h | 3 | 
9 files changed, 316 insertions, 3 deletions
diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c index 53c94c68779..83b923e360a 100644 --- a/cli/src/cli-cmd-volume.c +++ b/cli/src/cli-cmd-volume.c @@ -2264,6 +2264,60 @@ out:          return ret;  } +int +cli_cmd_volume_barrier_cbk (struct cli_state *state, struct cli_cmd_word *word, +                            const char **words, int wordcount) +{ +        int ret = -1; +        rpc_clnt_procedure_t *proc = NULL; +        call_frame_t *frame = NULL; +        dict_t *options = NULL; +        int sent = 0; +        int parse_error = 0; +        cli_local_t *local = NULL; + +        frame = create_frame (THIS, THIS->ctx->pool); +        if (!frame) +                goto out; + +        if (wordcount != 4) { +                cli_usage_out (word->pattern); +                parse_error = 1; +                goto out; +        } + +        options = dict_new(); +        if (!options) { +                ret = -1; +                goto out; +        } +        ret = dict_set_str(options, "volname", (char *)words[2]); +        if (ret) +                goto out; + +        ret = dict_set_str (options, "barrier", (char *)words[3]); +        if (ret) +                goto out; + +        proc = &cli_rpc_prog->proctable[GLUSTER_CLI_BARRIER_VOLUME]; + +        CLI_LOCAL_INIT (local, words, frame, options); + +        if (proc->fn) +                ret = proc->fn (frame, THIS, options); + +out: +        if (ret) { +                cli_cmd_sent_status_get (&sent); +                if ((sent == 0) && (parse_error == 0)) +                        cli_err ("Volume barrier failed"); +        } +        CLI_STACK_DESTROY (frame); +        if (options) +                dict_unref (options); + +        return ret; +}  struct cli_cmd volume_cmds[] = {          { "volume info [all|<VOLNAME>]",            cli_cmd_volume_info_cbk, @@ -2387,6 +2441,9 @@ struct cli_cmd volume_cmds[] = {            cli_cmd_volume_clearlocks_cbk,            "Clear locks held on path"          }, +        {"volume barrier <VOLNAME> {enable|disable}", +         cli_cmd_volume_barrier_cbk, +         "Barrier/unbarrier file operations on a volume"},          { NULL, NULL, NULL }  }; diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c index 8481d468cfa..987f9f16f48 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -8657,6 +8657,68 @@ out:          return ret;  } +int32_t +gf_cli_barrier_volume_cbk (struct rpc_req *req, struct iovec *iov, +                                  int count, void *myframe) +{ +        gf_cli_rsp                      rsp = {0,}; +        int                             ret = -1; +        dict_t                          *dict = NULL; + +        if (-1 == req->rpc_status) +                goto out; +        ret = xdr_to_generic (*iov, &rsp, +                              (xdrproc_t)xdr_gf_cli_rsp); +        if (ret < 0) { +                gf_log (((call_frame_t *) myframe)->this->name, GF_LOG_ERROR, +                        "Failed to decode xdr response"); +                goto out; +        } +        gf_log ("cli", GF_LOG_DEBUG, "Received response to barrier"); + +        if (rsp.op_ret) { +                if (rsp.op_errstr && (strlen (rsp.op_errstr) > 1)) { +                        cli_err ("volume barrier: command unsuccessful : %s", +                                 rsp.op_errstr); +                } else { +                        cli_err ("volume barrier: command unsuccessful"); +                } +        } else { +                cli_out ("volume barrier: command successful"); +        } +        ret = rsp.op_ret; + +out: +        if (dict) +                dict_unref (dict); +        free (rsp.op_errstr); +        free (rsp.dict.dict_val); +        cli_cmd_broadcast_response (ret); +        return ret; +} +int +gf_cli_barrier_volume (call_frame_t *frame, xlator_t *this, void *data) +{ +        gf_cli_req                      req = {{0,}}; +        dict_t                          *options = NULL; +        int                             ret = -1; + +        if (!frame || !this || !data) +                goto out; + +        options = data; + +        ret = cli_to_glusterd (&req, frame, gf_cli_barrier_volume_cbk, +                               (xdrproc_t) xdr_gf_cli_req, options, +                               GLUSTER_CLI_BARRIER_VOLUME, this, cli_rpc_prog, +                               NULL); +out: +        gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret); + +        GF_FREE (req.dict.dict_val); +        return ret; +} +  int  cli_to_glusterd (gf_cli_req *req, call_frame_t *frame,                   fop_cbk_fn_t cbkfn, xdrproc_t xdrproc, dict_t *dict, @@ -8769,6 +8831,7 @@ struct rpc_clnt_procedure gluster_cli_actors[GLUSTER_CLI_MAXVALUE] = {          [GLUSTER_CLI_COPY_FILE]        = {"COPY_FILE", gf_cli_copy_file},          [GLUSTER_CLI_SYS_EXEC]         = {"SYS_EXEC", gf_cli_sys_exec},          [GLUSTER_CLI_SNAP]             = {"SNAP", gf_cli_snapshot}, +        [GLUSTER_CLI_BARRIER_VOLUME]   = {"BARRIER VOLUME", gf_cli_barrier_volume},  };  struct rpc_clnt_program cli_prog = { diff --git a/rpc/rpc-lib/src/protocol-common.h b/rpc/rpc-lib/src/protocol-common.h index 25b0085b37f..634fff8f760 100644 --- a/rpc/rpc-lib/src/protocol-common.h +++ b/rpc/rpc-lib/src/protocol-common.h @@ -170,6 +170,7 @@ enum gluster_cli_procnum {          GLUSTER_CLI_COPY_FILE,          GLUSTER_CLI_SYS_EXEC,          GLUSTER_CLI_SNAP, +        GLUSTER_CLI_BARRIER_VOLUME,          GLUSTER_CLI_MAXVALUE,  }; diff --git a/xlators/mgmt/glusterd/src/glusterd-brick-ops.c b/xlators/mgmt/glusterd/src/glusterd-brick-ops.c index 1804dd02e9a..e2e01672893 100644 --- a/xlators/mgmt/glusterd/src/glusterd-brick-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-brick-ops.c @@ -2008,3 +2008,104 @@ out:          return ret;  } + +int +glusterd_op_stage_barrier (dict_t *dict, char **op_errstr) +{ +        int                  ret         = -1; +        xlator_t             *this       = NULL; +        char                 *volname    = NULL; +        glusterd_volinfo_t   *vol        = NULL; + +        GF_ASSERT (dict); +        this = THIS; +        GF_ASSERT (this); + +        ret = dict_get_str (dict, "volname", &volname); +        if (ret) { +                gf_log (this->name, GF_LOG_ERROR, "Volname not present in " +                        "dict"); +                goto out; +        } + +        ret = glusterd_volinfo_find (volname, &vol); +        if (ret) { +                gf_asprintf (op_errstr, "Volume %s does not exist", volname); +                gf_log (this->name, GF_LOG_ERROR, "%s", *op_errstr); +                goto out; +        } + +        if (!glusterd_is_volume_started (vol)) { +                gf_asprintf (op_errstr, "Volume %s is not started", volname); +                ret = -1; +                goto out; +        } + +        ret = dict_get_str_boolean (dict, "barrier", -1); +        if (ret == -1) { +                gf_asprintf (op_errstr, "Barrier op for volume %s not present " +                             "in dict", volname); +                gf_log (this->name, GF_LOG_ERROR, "%s", *op_errstr); +                goto out; +        } +        ret = 0; +out: +        gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret); +        return ret; +} + +int +glusterd_op_barrier (dict_t *dict, char **op_errstr) +{ +        int                  ret         = -1; +        xlator_t             *this       = NULL; +        char                 *volname    = NULL; +        glusterd_volinfo_t   *vol        = NULL; +        char                 *barrier_op = NULL; + +        GF_ASSERT (dict); +        this = THIS; +        GF_ASSERT (this); + +        ret = dict_get_str (dict, "volname", &volname); +        if (ret) { +                gf_log (this->name, GF_LOG_ERROR, "Volname not present in " +                        "dict"); +                goto out; +        } + +        ret = glusterd_volinfo_find (volname, &vol); +        if (ret) { +                gf_asprintf (op_errstr, "Volume %s does not exist", volname); +                gf_log (this->name, GF_LOG_ERROR, "%s", *op_errstr); +                goto out; +        } + +        ret = dict_get_str (dict, "barrier", &barrier_op); +        if (ret) { +                gf_asprintf (op_errstr, "Barrier op for volume %s not present " +                             "in dict", volname); +                gf_log (this->name, GF_LOG_ERROR, "%s", *op_errstr); +                goto out; +        } + +        ret = dict_set_dynstr_with_alloc (vol->dict, "features.barrier", +                                          barrier_op); +        if (ret) { +                gf_log (this->name, GF_LOG_ERROR, "Failed to set barrier op in" +                        " volume option dict"); +                goto out; +        } + +        gd_update_volume_op_versions (vol); +        ret = glusterd_create_volfiles (vol); +        if (ret) { +                gf_log (this->name, GF_LOG_ERROR, "Failed to create volfiles"); +                goto out; +        } +        ret = glusterd_store_volinfo (vol, GLUSTERD_VOLINFO_VER_AC_INCREMENT); + +out: +        gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret); +        return ret; +} diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c index b8202b233cd..c840803fbf0 100644 --- a/xlators/mgmt/glusterd/src/glusterd-handler.c +++ b/xlators/mgmt/glusterd/src/glusterd-handler.c @@ -3948,6 +3948,68 @@ out:  }  static int +__glusterd_handle_barrier (rpcsvc_request_t *req) +{ +        int          ret     = -1; +        xlator_t     *this   = NULL; +        gf_cli_req   cli_req = {{0,}}; +        dict_t       *dict   = NULL; +        char *volname = NULL; + +        GF_ASSERT (req); +        this = THIS; +        GF_ASSERT(this); + +        ret = xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req); +        if (ret < 0) { +                req->rpc_err = GARBAGE_ARGS; +                goto out; +        } + +        if (!cli_req.dict.dict_len) { +                ret = -1; +                goto out; +        } + +        dict = dict_new(); +        if (!dict) { +                ret = -1; +                goto out; +        } +        ret = dict_unserialize (cli_req.dict.dict_val, cli_req.dict.dict_len, +                                &dict); +        if (ret < 0) { +                gf_log (this->name, GF_LOG_ERROR, "Failed to unserialize " +                        "request dictionary."); +                goto out; +        } + +        ret = dict_get_str (dict, "volname", &volname); +        if (ret) { +                gf_log (this->name, GF_LOG_ERROR, "Volname not present in " +                        "dict"); +                goto out; +        } +        gf_log (this->name, GF_LOG_INFO, "Recieved barrier volume request for " +                "volume %s", volname); + +        ret = glusterd_op_begin_synctask (req, GD_OP_BARRIER, dict); + +out: +        if (ret) { +                ret = glusterd_op_send_cli_response (GD_OP_BARRIER, ret, 0, req, +                                                     dict, "Operation failed"); +        } +        free (cli_req.dict.dict_val); +        return ret; +} + +int +glusterd_handle_barrier (rpcsvc_request_t *req) +{ +        return glusterd_big_locked_handler (req, __glusterd_handle_barrier); +} +static int  get_brickinfo_from_brickid (char *brickid, glusterd_brickinfo_t **brickinfo)  {          glusterd_volinfo_t      *volinfo    = NULL; @@ -4356,6 +4418,7 @@ rpcsvc_actor_t gd_svc_cli_actors[] = {          [GLUSTER_CLI_COPY_FILE]          = {"COPY_FILE",          GLUSTER_CLI_COPY_FILE,        glusterd_handle_copy_file,             NULL, 0, DRC_NA},          [GLUSTER_CLI_SYS_EXEC]           = {"SYS_EXEC",           GLUSTER_CLI_SYS_EXEC,         glusterd_handle_sys_exec,              NULL, 0, DRC_NA},          [GLUSTER_CLI_SNAP]               = {"SNAP",               GLUSTER_CLI_SNAP,             glusterd_handle_snapshot,              NULL, 0, DRC_NA}, +        [GLUSTER_CLI_BARRIER_VOLUME] = {"BARRIER_VOLUME", GLUSTER_CLI_BARRIER_VOLUME, glusterd_handle_barrier, NULL, 0, DRC_NA},  };  struct rpcsvc_program gd_svc_cli_prog = { diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c index baf54def971..ca9bfbadff8 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c @@ -3222,6 +3222,7 @@ glusterd_op_build_payload (dict_t **req, char **op_errstr, dict_t *op_ctx)                  case GD_OP_STATEDUMP_VOLUME:                  case GD_OP_CLEARLOCKS_VOLUME:                  case GD_OP_DEFRAG_BRICK_VOLUME: +                case GD_OP_BARRIER:                          {                                  ret = dict_get_str (dict, "volname", &volname);                                  if (ret) { @@ -4677,6 +4678,10 @@ glusterd_op_stage_validate (glusterd_op_t op, dict_t *dict, char **op_errstr,                          ret = glusterd_op_stage_sys_exec (dict, op_errstr);                          break; +                case GD_OP_BARRIER: +                        ret = glusterd_op_stage_barrier (dict, op_errstr); +                        break; +                  default:                          gf_log (this->name, GF_LOG_ERROR, "Unknown op %s",                                  gd_op_list[op]); @@ -4788,6 +4793,10 @@ glusterd_op_commit_perform (glusterd_op_t op, dict_t *dict, char **op_errstr,                          ret = glusterd_op_sys_exec (dict, op_errstr, rsp_dict);                          break; +                case GD_OP_BARRIER: +                        ret = glusterd_op_barrier (dict, op_errstr); +                        break; +                  default:                          gf_log (this->name, GF_LOG_ERROR, "Unknown op %s",                                  gd_op_list[op]); diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.c b/xlators/mgmt/glusterd/src/glusterd-volgen.c index ae095bf7c63..6ce38e91b5b 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volgen.c +++ b/xlators/mgmt/glusterd/src/glusterd-volgen.c @@ -3656,7 +3656,7 @@ glusterd_create_rb_volfiles (glusterd_volinfo_t *volinfo,  }  int -glusterd_create_volfiles_and_notify_services (glusterd_volinfo_t *volinfo) +glusterd_create_volfiles (glusterd_volinfo_t *volinfo)  {          int        ret  = -1;          xlator_t  *this = NULL; @@ -3678,11 +3678,25 @@ glusterd_create_volfiles_and_notify_services (glusterd_volinfo_t *volinfo)          }          ret = generate_client_volfiles (volinfo, GF_CLIENT_OTHER); -        if (ret) { +        if (ret)                  gf_log (this->name, GF_LOG_ERROR,                          "Could not generate client volfiles"); + +out: +        return ret; +} + +int +glusterd_create_volfiles_and_notify_services (glusterd_volinfo_t *volinfo) +{ +        int        ret  = -1; +        xlator_t  *this = NULL; + +        this = THIS; + +        ret = glusterd_create_volfiles (volinfo); +        if (ret)                  goto out; -        }          ret = glusterd_fetchspec_notify (this); diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.h b/xlators/mgmt/glusterd/src/glusterd-volgen.h index ef92087fc74..dab5e1ff03d 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volgen.h +++ b/xlators/mgmt/glusterd/src/glusterd-volgen.h @@ -114,6 +114,8 @@ struct volopt_map_entry {  int glusterd_create_rb_volfiles (glusterd_volinfo_t *volinfo,                                   glusterd_brickinfo_t *brickinfo); +int glusterd_create_volfiles (glusterd_volinfo_t *volinfo); +  int glusterd_create_volfiles_and_notify_services (glusterd_volinfo_t *volinfo);  void glusterd_get_nfs_filepath (char *filename); diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h index e4e29ad9c62..9e3eb417929 100644 --- a/xlators/mgmt/glusterd/src/glusterd.h +++ b/xlators/mgmt/glusterd/src/glusterd.h @@ -922,6 +922,9 @@ int glusterd_op_stage_clearlocks_volume (dict_t *dict, char **op_errstr);  int glusterd_op_clearlocks_volume (dict_t *dict, char **op_errstr,                                     dict_t *rsp_dict); +int glusterd_op_stage_barrier (dict_t *dict, char **op_errstr); +int glusterd_op_barrier (dict_t *dict, char **op_errstr); +  /* misc */  void glusterd_do_replace_brick (void *data);  int glusterd_op_perform_remove_brick (glusterd_volinfo_t  *volinfo, char *brick,  | 
