diff options
author | Pranith Kumar K <pranithk@gluster.com> | 2010-08-28 06:02:54 +0000 |
---|---|---|
committer | Vijay Bellur <vijay@dev.gluster.com> | 2010-08-28 04:56:11 -0700 |
commit | 157560b6dce9cf790e8405ce895d80f4efab1539 (patch) | |
tree | 61059f04be060b47cdbd148d6b1dc8aaa6b2e582 | |
parent | 48055db6c1b8e669e6c83cc3e579569f05629026 (diff) |
cli, mgmt/glusterd: added volume stop <VOLNAME> force functionality
Signed-off-by: Pranith Kumar K <pranithk@gluster.com>
Signed-off-by: Vijay Bellur <vijay@dev.gluster.com>
BUG: 1361 ()
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=1361
-rw-r--r-- | cli/src/cli-cmd-volume.c | 32 | ||||
-rw-r--r-- | cli/src/cli.h | 1 | ||||
-rw-r--r-- | cli/src/cli3_1-cops.c | 6 | ||||
-rw-r--r-- | rpc/xdr/src/cli1-xdr.c | 20 | ||||
-rw-r--r-- | rpc/xdr/src/cli1-xdr.h | 19 | ||||
-rw-r--r-- | rpc/xdr/src/cli1.x | 11 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-handler.c | 22 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-op-sm.c | 101 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-op-sm.h | 1 |
9 files changed, 161 insertions, 52 deletions
diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c index 8b240401297..1421157c89a 100644 --- a/cli/src/cli-cmd-volume.c +++ b/cli/src/cli-cmd-volume.c @@ -31,6 +31,7 @@ #include "cli.h" #include "cli-cmd.h" #include "cli-mem-types.h" +#include "cli1-xdr.h" extern struct rpc_clnt *global_rpc; @@ -49,7 +50,7 @@ cli_cmd_volume_start_usage () void cli_cmd_volume_stop_usage () { - cli_out ("Usage: volume stop <VOLNAME>"); + cli_out ("Usage: volume stop <VOLNAME> [force]"); } void @@ -212,29 +213,42 @@ cli_cmd_volume_stop_cbk (struct cli_state *state, struct cli_cmd_word *word, int ret = -1; rpc_clnt_procedure_t *proc = NULL; call_frame_t *frame = NULL; - char *volname = NULL; - + int flags = 0; + gf1_cli_stop_vol_req req = {0,}; frame = create_frame (THIS, THIS->ctx->pool); if (!frame) goto out; - if (wordcount != 3) { + if (wordcount < 3 || wordcount > 4) { cli_cmd_volume_stop_usage (); goto out; } - volname = (char *)words[2]; + req.volname = (char *)words[2]; + if (!req.volname) + goto out; + if (wordcount == 4) { + if (!strcmp("force", words[3])) { + flags |= GF_CLI_FLAG_OP_FORCE; + } else { + ret = -1; + cli_cmd_volume_stop_usage (); + goto out; + } + } + + req.flags = flags; proc = &cli_rpc_prog->proctable[GF1_CLI_STOP_VOLUME]; if (proc->fn) { - ret = proc->fn (frame, THIS, volname); + ret = proc->fn (frame, THIS, &req); } out: - if (!proc && ret && volname) - cli_out ("Stopping Volume %s failed", volname); + if (!proc && ret && req.volname) + cli_out ("Stopping Volume %s failed", req.volname); return ret; } @@ -519,7 +533,7 @@ struct cli_cmd volume_cmds[] = { cli_cmd_volume_start_cbk, "start volume specified by <VOLNAME>"}, - { "volume stop <VOLNAME>", + { "volume stop <VOLNAME> [force]", cli_cmd_volume_stop_cbk, "stop volume specified by <VOLNAME>"}, diff --git a/cli/src/cli.h b/cli/src/cli.h index d6e1a35d6e3..22159025e5e 100644 --- a/cli/src/cli.h +++ b/cli/src/cli.h @@ -110,6 +110,7 @@ struct cli_local { struct { char *volname; + int flags; } stop_vol; struct { diff --git a/cli/src/cli3_1-cops.c b/cli/src/cli3_1-cops.c index 77fb3852ba5..728c79095b8 100644 --- a/cli/src/cli3_1-cops.c +++ b/cli/src/cli3_1-cops.c @@ -1095,12 +1095,12 @@ gf_cli3_1_stop_volume (call_frame_t *frame, xlator_t *this, goto out; } - req.volname = data; - + req = *((gf1_cli_stop_vol_req*)data); local = cli_local_get (); if (local) { - local->u.stop_vol.volname = data; + local->u.stop_vol.volname = req.volname; + local->u.stop_vol.flags = req.flags; frame->local = local; } diff --git a/rpc/xdr/src/cli1-xdr.c b/rpc/xdr/src/cli1-xdr.c index ce16b666f1f..64112c1797a 100644 --- a/rpc/xdr/src/cli1-xdr.c +++ b/rpc/xdr/src/cli1-xdr.c @@ -62,6 +62,15 @@ xdr_gf1_cli_get_volume (XDR *xdrs, gf1_cli_get_volume *objp) } bool_t +xdr_gf1_cli_op_flags (XDR *xdrs, gf1_cli_op_flags *objp) +{ + + if (!xdr_enum (xdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +bool_t xdr_gf1_cli_probe_req (XDR *xdrs, gf1_cli_probe_req *objp) { @@ -76,7 +85,7 @@ bool_t xdr_gf1_cli_probe_rsp (XDR *xdrs, gf1_cli_probe_rsp *objp) { - register int32_t *buf; + register int32_t *buf; if (xdrs->x_op == XDR_ENCODE) { buf = XDR_INLINE (xdrs, 3 * BYTES_PER_XDR_UNIT); @@ -224,9 +233,8 @@ xdr_gf1_cli_create_vol_rsp (XDR *xdrs, gf1_cli_create_vol_rsp *objp) return FALSE; if (!xdr_string (xdrs, &objp->volname, ~0)) return FALSE; - if (!xdr_string (xdrs, &objp->op_errstr, ~0)) - return FALSE; - + if (!xdr_string (xdrs, &objp->op_errstr, ~0)) + return FALSE; return TRUE; } @@ -280,6 +288,8 @@ xdr_gf1_cli_stop_vol_req (XDR *xdrs, gf1_cli_stop_vol_req *objp) if (!xdr_string (xdrs, &objp->volname, ~0)) return FALSE; + if (!xdr_int (xdrs, &objp->flags)) + return FALSE; return TRUE; } @@ -375,7 +385,7 @@ xdr_gf1_cli_add_brick_rsp (XDR *xdrs, gf1_cli_add_brick_rsp *objp) return FALSE; if (!xdr_string (xdrs, &objp->volname, ~0)) return FALSE; - if (!xdr_string (xdrs, &objp->op_errstr, ~0)) + if (!xdr_string (xdrs, &objp->op_errstr, ~0)) return FALSE; return TRUE; } diff --git a/rpc/xdr/src/cli1-xdr.h b/rpc/xdr/src/cli1-xdr.h index c6fd14f3ba8..55060bf693d 100644 --- a/rpc/xdr/src/cli1-xdr.h +++ b/rpc/xdr/src/cli1-xdr.h @@ -26,8 +26,7 @@ #ifndef _CLI1_H_RPCGEN #define _CLI1_H_RPCGEN -//#include <rpc/rpc.h> -#include <rpc/xdr.h> +#include <rpc/rpc.h> #ifdef __cplusplus @@ -62,6 +61,11 @@ enum gf1_cli_get_volume { }; typedef enum gf1_cli_get_volume gf1_cli_get_volume; +enum gf1_cli_op_flags { + GF_CLI_FLAG_OP_FORCE = 1, +}; +typedef enum gf1_cli_op_flags gf1_cli_op_flags; + struct gf1_cli_probe_req { char *hostname; int port; @@ -172,6 +176,7 @@ typedef struct gf1_cli_start_vol_rsp gf1_cli_start_vol_rsp; struct gf1_cli_stop_vol_req { char *volname; + int flags; }; typedef struct gf1_cli_stop_vol_req gf1_cli_stop_vol_req; @@ -196,7 +201,7 @@ struct gf1_cli_rename_vol_rsp { typedef struct gf1_cli_rename_vol_rsp gf1_cli_rename_vol_rsp; struct gf1_cli_defrag_vol_req { - int cmd; + int cmd; char *volname; }; typedef struct gf1_cli_defrag_vol_req gf1_cli_defrag_vol_req; @@ -205,9 +210,9 @@ struct gf1_cli_defrag_vol_rsp { int op_ret; int op_errno; char *volname; - u_quad_t files; - u_quad_t size; - u_quad_t lookedup_files; + u_quad_t files; + u_quad_t size; + u_quad_t lookedup_files; }; typedef struct gf1_cli_defrag_vol_rsp gf1_cli_defrag_vol_rsp; @@ -288,6 +293,7 @@ extern bool_t xdr_gf1_cluster_type (XDR *, gf1_cluster_type*); extern bool_t xdr_gf1_cli_replace_op (XDR *, gf1_cli_replace_op*); extern bool_t xdr_gf1_cli_friends_list (XDR *, gf1_cli_friends_list*); extern bool_t xdr_gf1_cli_get_volume (XDR *, gf1_cli_get_volume*); +extern bool_t xdr_gf1_cli_op_flags (XDR *, gf1_cli_op_flags*); extern bool_t xdr_gf1_cli_probe_req (XDR *, gf1_cli_probe_req*); extern bool_t xdr_gf1_cli_probe_rsp (XDR *, gf1_cli_probe_rsp*); extern bool_t xdr_gf1_cli_deprobe_req (XDR *, gf1_cli_deprobe_req*); @@ -322,6 +328,7 @@ extern bool_t xdr_gf1_cluster_type (); extern bool_t xdr_gf1_cli_replace_op (); extern bool_t xdr_gf1_cli_friends_list (); extern bool_t xdr_gf1_cli_get_volume (); +extern bool_t xdr_gf1_cli_op_flags (); extern bool_t xdr_gf1_cli_probe_req (); extern bool_t xdr_gf1_cli_probe_rsp (); extern bool_t xdr_gf1_cli_deprobe_req (); diff --git a/rpc/xdr/src/cli1.x b/rpc/xdr/src/cli1.x index ffb8ab2cfd3..d3383147268 100644 --- a/rpc/xdr/src/cli1.x +++ b/rpc/xdr/src/cli1.x @@ -7,7 +7,7 @@ enum gf1_cli_replace_op { GF_REPLACE_OP_NONE = 0, GF_REPLACE_OP_START, - GF_REPLACE_OP_STOP, + GF_REPLACE_OP_COMMIT, GF_REPLACE_OP_PAUSE, GF_REPLACE_OP_ABORT, GF_REPLACE_OP_STATUS @@ -21,6 +21,10 @@ enum gf1_cli_get_volume { GF_CLI_GET_VOLUME_ALL = 1 } ; +enum gf1_cli_op_flags { + GF_CLI_FLAG_OP_FORCE = 1 +}; + struct gf1_cli_probe_req { string hostname<>; int port; @@ -103,6 +107,7 @@ struct gf1_cli_get_vol_rsp { struct gf1_cli_stop_vol_req { string volname<>; + int flags; } ; @@ -125,6 +130,7 @@ struct gf1_cli_get_vol_rsp { } ; struct gf1_cli_defrag_vol_req { + int cmd; string volname<>; } ; @@ -132,6 +138,9 @@ struct gf1_cli_get_vol_rsp { int op_ret; int op_errno; string volname<>; + unsigned hyper files; + unsigned hyper size; + unsigned hyper lookedup_files; } ; struct gf1_cli_add_brick_req { diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c index 07c6b060fae..0306fdd18ac 100644 --- a/xlators/mgmt/glusterd/src/glusterd-handler.c +++ b/xlators/mgmt/glusterd/src/glusterd-handler.c @@ -1129,7 +1129,6 @@ glusterd_handle_cli_stop_volume (rpcsvc_request_t *req) { int32_t ret = -1; gf1_cli_stop_vol_req cli_req = {0,}; - int32_t flags = 0; GF_ASSERT (req); @@ -1142,7 +1141,7 @@ glusterd_handle_cli_stop_volume (rpcsvc_request_t *req) gf_log ("glusterd", GF_LOG_NORMAL, "Received stop vol req" "for volume %s", cli_req.volname); - ret = glusterd_stop_volume (req, cli_req.volname, flags); + ret = glusterd_stop_volume (req, cli_req.volname, cli_req.flags); out: return ret; @@ -2174,18 +2173,29 @@ out: int32_t glusterd_stop_volume (rpcsvc_request_t *req, char *volname, int flags) { - int32_t ret = -1; - glusterd_op_stop_volume_ctx_t *ctx = NULL; + int32_t ret = -1; + dict_t *ctx = NULL; + char *dup_volname = NULL; GF_ASSERT (req); GF_ASSERT (volname); - ctx = GF_CALLOC (1, sizeof (*ctx), gf_gld_mt_stop_volume_ctx_t); + ctx = dict_new (); if (!ctx) goto out; - strncpy (ctx->volume_name, volname, GD_VOLUME_NAME_MAX); + dup_volname = gf_strdup(volname); + if (!dup_volname) + goto out; + + ret = dict_set_str (ctx, "volname", dup_volname); + if (ret) + goto out; + + ret = dict_set_int32 (ctx, "flags", flags); + if (ret) + goto out; glusterd_op_set_op (GD_OP_STOP_VOLUME); diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c index c7eb7d15ad2..cb8acbeb798 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c @@ -179,13 +179,20 @@ glusterd_op_build_payload (glusterd_op_t op, gd1_mgmt_stage_op_req **req) case GD_OP_STOP_VOLUME: { - glusterd_op_stop_volume_ctx_t *ctx = NULL; - ctx = glusterd_op_get_ctx (op); - GF_ASSERT (ctx); - stage_req->buf.buf_len = - strlen (ctx->volume_name); - stage_req->buf.buf_val = - gf_strdup (ctx->volume_name); + dict_t *dict = NULL; + dict = glusterd_op_get_ctx (op); + if (!dict) { + gf_log ("", GF_LOG_ERROR, "Null Context for " + "stop volume"); + ret = -1; + goto out; + } + ret = dict_allocate_and_serialize (dict, + &stage_req->buf.buf_val, + (size_t *)&stage_req->buf.buf_len); + if (ret) { + goto out; + } } break; @@ -264,7 +271,7 @@ glusterd_op_stage_create_volume (gd1_mgmt_stage_op_req *req) gf_boolean_t exists = _gf_false; char *bricks = NULL; char *brick_list = NULL; - glusterd_brickinfo_t *brick_info = NULL; + glusterd_brickinfo_t *brick_info = NULL; int32_t brick_count = 0; int32_t i = 0; struct stat st_buf = {0,}; @@ -385,16 +392,53 @@ out: } static int +glusterd_op_stop_volume_args_get (gd1_mgmt_stage_op_req *req, + dict_t *dict, char** volname, + int *flags) +{ + int ret = -1; + + if (!req || !dict || !volname || !flags) + goto out; + + ret = dict_unserialize (req->buf.buf_val, req->buf.buf_len, &dict); + + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to unserialize dict"); + goto out; + } + + ret = dict_get_str (dict, "volname", volname); + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to get volume name"); + goto out; + } + + ret = dict_get_int32 (dict, "flags", flags); + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to get flags"); + goto out; + } +out: + return ret; +} +static int glusterd_op_stage_stop_volume (gd1_mgmt_stage_op_req *req) { - int ret = 0; - char volname[1024] = {0,}; + int ret = -1; + dict_t *dict = NULL; + char *volname = NULL; + int flags = 0; gf_boolean_t exists = _gf_false; glusterd_volinfo_t *volinfo = NULL; - GF_ASSERT (req); + dict = dict_new (); + if (!dict) + goto out; - strncpy (volname, req->buf.buf_val, req->buf.buf_len); + ret = glusterd_op_stop_volume_args_get (req, dict, &volname, &flags); + if (ret) + goto out; exists = glusterd_check_volume_exists (volname); @@ -411,16 +455,21 @@ glusterd_op_stage_stop_volume (gd1_mgmt_stage_op_req *req) if (ret) goto out; - ret = glusterd_is_volume_started (volinfo); + if (!(flags & GF_CLI_FLAG_OP_FORCE)) { + ret = glusterd_is_volume_started (volinfo); - if (ret) { - gf_log ("", GF_LOG_ERROR, "Volume %s has not been started", - volname); - goto out; + if (ret) { + gf_log ("", GF_LOG_ERROR, "Volume %s " + "has not been started", volname); + goto out; + } } out: + if (dict) + dict_unref (dict); + gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); return ret; @@ -1986,21 +2035,27 @@ static int glusterd_op_stop_volume (gd1_mgmt_stage_op_req *req) { int ret = 0; - char volname[1024] = {0,}; + int flags = 0; + char *volname = NULL; glusterd_conf_t *priv = NULL; glusterd_volinfo_t *volinfo = NULL; glusterd_brickinfo_t *brickinfo = NULL; xlator_t *this = NULL; int32_t mybrick = 0; - - GF_ASSERT (req); + dict_t *dict = NULL; this = THIS; GF_ASSERT (this); priv = this->private; GF_ASSERT (priv); - strncpy (volname, req->buf.buf_val, req->buf.buf_len); + dict = dict_new (); + if (!dict) + goto out; + + ret = glusterd_op_stop_volume_args_get (req, dict, &volname, &flags); + if (ret) + goto out; ret = glusterd_volinfo_find (volname, &volinfo); @@ -2026,6 +2081,10 @@ glusterd_op_stop_volume (gd1_mgmt_stage_op_req *req) glusterd_set_volume_status (volinfo, GLUSTERD_STATUS_STOPPED); out: + if (flags & GF_CLI_FLAG_OP_FORCE) + ret = 0; + if (dict) + dict_unref (dict); return ret; } diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.h b/xlators/mgmt/glusterd/src/glusterd-op-sm.h index d72ecadd2c2..ed824cc6a9a 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.h +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.h @@ -128,7 +128,6 @@ struct glusterd_op_start_volume_ctx_ { }; typedef struct glusterd_op_start_volume_ctx_ glusterd_op_start_volume_ctx_t; -typedef struct glusterd_op_start_volume_ctx_ glusterd_op_stop_volume_ctx_t; typedef struct glusterd_op_start_volume_ctx_ glusterd_op_delete_volume_ctx_t; |