diff options
| -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 8b2404012..1421157c8 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 d6e1a35d6..22159025e 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 77fb3852b..728c79095 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 ce16b666f..64112c179 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 c6fd14f3b..55060bf69 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 ffb8ab2cf..d33831472 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 07c6b060f..0306fdd18 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 c7eb7d15a..cb8acbeb7 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 d72ecadd2..ed824cc6a 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;  | 
