summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPranith Kumar K <pranithk@gluster.com>2010-08-28 06:02:54 +0000
committerVijay Bellur <vijay@dev.gluster.com>2010-08-28 04:56:11 -0700
commit157560b6dce9cf790e8405ce895d80f4efab1539 (patch)
tree61059f04be060b47cdbd148d6b1dc8aaa6b2e582
parent48055db6c1b8e669e6c83cc3e579569f05629026 (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.c32
-rw-r--r--cli/src/cli.h1
-rw-r--r--cli/src/cli3_1-cops.c6
-rw-r--r--rpc/xdr/src/cli1-xdr.c20
-rw-r--r--rpc/xdr/src/cli1-xdr.h19
-rw-r--r--rpc/xdr/src/cli1.x11
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-handler.c22
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-op-sm.c101
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-op-sm.h1
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;