summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cli/src/cli-rpc-ops.c50
-rw-r--r--rpc/xdr/src/cli1-xdr.c21
-rw-r--r--rpc/xdr/src/cli1-xdr.h13
-rw-r--r--rpc/xdr/src/cli1-xdr.x11
-rw-r--r--rpc/xdr/src/cli1.c15
-rw-r--r--rpc/xdr/src/cli1.h6
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-handler.c2
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-rebalance.c393
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.h3
9 files changed, 412 insertions, 102 deletions
diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c
index c2373e2a576..4e713eef52a 100644
--- a/cli/src/cli-rpc-ops.c
+++ b/cli/src/cli-rpc-ops.c
@@ -777,18 +777,18 @@ int
gf_cli3_1_defrag_volume_cbk (struct rpc_req *req, struct iovec *iov,
int count, void *myframe)
{
- gf1_cli_defrag_vol_rsp rsp = {0,};
- cli_local_t *local = NULL;
- char *volname = NULL;
- call_frame_t *frame = NULL;
- int cmd = 0;
- int ret = 0;
+ gf2_cli_defrag_vol_rsp rsp = {0,};
+ cli_local_t *local = NULL;
+ char *volname = NULL;
+ call_frame_t *frame = NULL;
+ int cmd = 0;
+ int ret = 0;
if (-1 == req->rpc_status) {
goto out;
}
- ret = gf_xdr_to_cli_defrag_vol_rsp (*iov, &rsp);
+ ret = gf_xdr_to_cli_defrag_vol_rsp_v2 (*iov, &rsp);
if (ret < 0) {
gf_log ("", GF_LOG_ERROR, "error");
goto out;
@@ -804,24 +804,34 @@ gf_cli3_1_defrag_volume_cbk (struct rpc_req *req, struct iovec *iov,
cmd = local->u.defrag_vol.cmd;
}
if (cmd == GF_DEFRAG_CMD_START) {
- cli_out ("starting rebalance on volume %s has been %s", volname,
- (rsp.op_ret) ? "unsuccessful": "successful");
- if (rsp.op_ret && rsp.op_errno == EEXIST)
- cli_out ("Rebalance already started on volume %s",
- volname);
+ if (rsp.op_ret && strcmp (rsp.op_errstr, ""))
+ cli_out (rsp.op_errstr);
+ else
+ cli_out ("starting rebalance on volume %s has been %s",
+ volname, (rsp.op_ret) ? "unsuccessful":
+ "successful");
}
if (cmd == GF_DEFRAG_CMD_STOP) {
- if (rsp.op_ret == -1)
- cli_out ("rebalance volume %s stop failed", volname);
- else
+ if (rsp.op_ret == -1) {
+ if (strcmp (rsp.op_errstr, ""))
+ cli_out (rsp.op_errstr);
+ else
+ cli_out ("rebalance volume %s stop failed",
+ volname);
+ } else {
cli_out ("stopped rebalance process of volume %s \n"
"(after rebalancing %"PRId64" files totaling "
"%"PRId64" bytes)", volname, rsp.files, rsp.size);
+ }
}
if (cmd == GF_DEFRAG_CMD_STATUS) {
- if (rsp.op_ret == -1)
- cli_out ("failed to get the status of rebalance process");
- else {
+ if (rsp.op_ret == -1) {
+ if (strcmp (rsp.op_errstr, ""))
+ cli_out (rsp.op_errstr);
+ else
+ cli_out ("failed to get the status of "
+ "rebalance process");
+ } else {
char *status = "unknown";
if (rsp.op_errno == 0)
status = "not started";
@@ -856,6 +866,10 @@ gf_cli3_1_defrag_volume_cbk (struct rpc_req *req, struct iovec *iov,
ret = rsp.op_ret;
out:
+ if (rsp.op_errstr)
+ free (rsp.op_errstr); //malloced by xdr
+ if (rsp.volname)
+ free (rsp.volname); //malloced by xdr
cli_cmd_broadcast_response (ret);
return ret;
}
diff --git a/rpc/xdr/src/cli1-xdr.c b/rpc/xdr/src/cli1-xdr.c
index 453513aa335..d9640f5b070 100644
--- a/rpc/xdr/src/cli1-xdr.c
+++ b/rpc/xdr/src/cli1-xdr.c
@@ -387,6 +387,27 @@ xdr_gf1_cli_defrag_vol_rsp (XDR *xdrs, gf1_cli_defrag_vol_rsp *objp)
}
bool_t
+xdr_gf2_cli_defrag_vol_rsp (XDR *xdrs, gf2_cli_defrag_vol_rsp *objp)
+{
+
+ if (!xdr_int (xdrs, &objp->op_ret))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->op_errno))
+ return FALSE;
+ if (!xdr_string (xdrs, &objp->op_errstr, ~0))
+ return FALSE;
+ if (!xdr_string (xdrs, &objp->volname, ~0))
+ return FALSE;
+ if (!xdr_u_quad_t (xdrs, &objp->files))
+ return FALSE;
+ if (!xdr_u_quad_t (xdrs, &objp->size))
+ return FALSE;
+ if (!xdr_u_quad_t (xdrs, &objp->lookedup_files))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
xdr_gf1_cli_add_brick_req (XDR *xdrs, gf1_cli_add_brick_req *objp)
{
diff --git a/rpc/xdr/src/cli1-xdr.h b/rpc/xdr/src/cli1-xdr.h
index 302b1f8ab8f..2e37e1bc2bc 100644
--- a/rpc/xdr/src/cli1-xdr.h
+++ b/rpc/xdr/src/cli1-xdr.h
@@ -240,6 +240,17 @@ struct gf1_cli_defrag_vol_rsp {
};
typedef struct gf1_cli_defrag_vol_rsp gf1_cli_defrag_vol_rsp;
+struct gf2_cli_defrag_vol_rsp {
+ int op_ret;
+ int op_errno;
+ char *op_errstr;
+ char *volname;
+ u_quad_t files;
+ u_quad_t size;
+ u_quad_t lookedup_files;
+};
+typedef struct gf2_cli_defrag_vol_rsp gf2_cli_defrag_vol_rsp;
+
struct gf1_cli_add_brick_req {
char *volname;
int count;
@@ -454,6 +465,7 @@ extern bool_t xdr_gf1_cli_rename_vol_req (XDR *, gf1_cli_rename_vol_req*);
extern bool_t xdr_gf1_cli_rename_vol_rsp (XDR *, gf1_cli_rename_vol_rsp*);
extern bool_t xdr_gf1_cli_defrag_vol_req (XDR *, gf1_cli_defrag_vol_req*);
extern bool_t xdr_gf1_cli_defrag_vol_rsp (XDR *, gf1_cli_defrag_vol_rsp*);
+extern bool_t xdr_gf2_cli_defrag_vol_rsp (XDR *, gf2_cli_defrag_vol_rsp*);
extern bool_t xdr_gf1_cli_add_brick_req (XDR *, gf1_cli_add_brick_req*);
extern bool_t xdr_gf1_cli_add_brick_rsp (XDR *, gf1_cli_add_brick_rsp*);
extern bool_t xdr_gf1_cli_remove_brick_req (XDR *, gf1_cli_remove_brick_req*);
@@ -505,6 +517,7 @@ extern bool_t xdr_gf1_cli_rename_vol_req ();
extern bool_t xdr_gf1_cli_rename_vol_rsp ();
extern bool_t xdr_gf1_cli_defrag_vol_req ();
extern bool_t xdr_gf1_cli_defrag_vol_rsp ();
+extern bool_t xdr_gf2_cli_defrag_vol_rsp ();
extern bool_t xdr_gf1_cli_add_brick_req ();
extern bool_t xdr_gf1_cli_add_brick_rsp ();
extern bool_t xdr_gf1_cli_remove_brick_req ();
diff --git a/rpc/xdr/src/cli1-xdr.x b/rpc/xdr/src/cli1-xdr.x
index 0e18c6ab922..c5bd82965b7 100644
--- a/rpc/xdr/src/cli1-xdr.x
+++ b/rpc/xdr/src/cli1-xdr.x
@@ -165,6 +165,17 @@ struct gf1_cli_get_vol_rsp {
unsigned hyper lookedup_files;
} ;
+
+ struct gf2_cli_defrag_vol_rsp {
+ int op_ret;
+ int op_errno;
+ string op_errstr<>;
+ string volname<>;
+ unsigned hyper files;
+ unsigned hyper size;
+ unsigned hyper lookedup_files;
+} ;
+
struct gf1_cli_add_brick_req {
string volname<>;
int count;
diff --git a/rpc/xdr/src/cli1.c b/rpc/xdr/src/cli1.c
index 7bdfd033261..db678267803 100644
--- a/rpc/xdr/src/cli1.c
+++ b/rpc/xdr/src/cli1.c
@@ -302,6 +302,21 @@ gf_xdr_to_cli_defrag_vol_rsp (struct iovec inmsg, void *args)
}
ssize_t
+gf_xdr_serialize_cli_defrag_vol_rsp_v2 (struct iovec outmsg, void *rsp)
+{
+ return xdr_serialize_generic (outmsg, (void *)rsp,
+ (xdrproc_t)xdr_gf2_cli_defrag_vol_rsp);
+
+}
+
+ssize_t
+gf_xdr_to_cli_defrag_vol_rsp_v2 (struct iovec inmsg, void *args)
+{
+ return xdr_to_generic (inmsg, (void *)args,
+ (xdrproc_t)xdr_gf2_cli_defrag_vol_rsp);
+}
+
+ssize_t
gf_xdr_to_cli_defrag_vol_req (struct iovec inmsg, void *args)
{
return xdr_to_generic (inmsg, (void *)args,
diff --git a/rpc/xdr/src/cli1.h b/rpc/xdr/src/cli1.h
index 7e80a18cb78..2b7c2c65c0f 100644
--- a/rpc/xdr/src/cli1.h
+++ b/rpc/xdr/src/cli1.h
@@ -138,6 +138,12 @@ ssize_t
gf_xdr_to_cli_defrag_vol_rsp (struct iovec inmsg, void *args);
ssize_t
+gf_xdr_serialize_cli_defrag_vol_rsp_v2 (struct iovec outmsg, void *rsp);
+
+ssize_t
+gf_xdr_to_cli_defrag_vol_rsp_v2 (struct iovec inmsg, void *args);
+
+ssize_t
gf_xdr_serialize_cli_add_brick_rsp (struct iovec outmsg, void *rsp);
ssize_t
diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c
index efba9e202c7..68cdb6fc3a7 100644
--- a/xlators/mgmt/glusterd/src/glusterd-handler.c
+++ b/xlators/mgmt/glusterd/src/glusterd-handler.c
@@ -3532,7 +3532,7 @@ struct rpcsvc_program gd_svc_mgmt_prog = {
rpcsvc_actor_t gd_svc_cli_actors[] = {
[GLUSTER_CLI_PROBE] = { "CLI_PROBE", GLUSTER_CLI_PROBE, glusterd_handle_cli_probe, NULL, NULL},
[GLUSTER_CLI_CREATE_VOLUME] = { "CLI_CREATE_VOLUME", GLUSTER_CLI_CREATE_VOLUME, glusterd_handle_create_volume, NULL,NULL},
- [GLUSTER_CLI_DEFRAG_VOLUME] = { "CLI_DEFRAG_VOLUME", GLUSTER_CLI_DEFRAG_VOLUME, glusterd_handle_defrag_volume, NULL,NULL},
+ [GLUSTER_CLI_DEFRAG_VOLUME] = { "CLI_DEFRAG_VOLUME", GLUSTER_CLI_DEFRAG_VOLUME, glusterd_handle_defrag_volume_v2, NULL,NULL},
[GLUSTER_CLI_DEPROBE] = { "FRIEND_REMOVE", GLUSTER_CLI_DEPROBE, glusterd_handle_cli_deprobe, NULL, NULL},
[GLUSTER_CLI_LIST_FRIENDS] = { "LIST_FRIENDS", GLUSTER_CLI_LIST_FRIENDS, glusterd_handle_cli_list_friends, NULL, NULL},
[GLUSTER_CLI_START_VOLUME] = { "START_VOLUME", GLUSTER_CLI_START_VOLUME, glusterd_handle_cli_start_volume, NULL, NULL},
diff --git a/xlators/mgmt/glusterd/src/glusterd-rebalance.c b/xlators/mgmt/glusterd/src/glusterd-rebalance.c
index a8a063706fb..c1dbead2eed 100644
--- a/xlators/mgmt/glusterd/src/glusterd-rebalance.c
+++ b/xlators/mgmt/glusterd/src/glusterd-rebalance.c
@@ -108,25 +108,27 @@ gf_glusterd_rebalance_move_data (glusterd_volinfo_t *volinfo, const char *dir)
while (1) {
ret = read (src_fd, defrag->databuf, 131072);
if (!ret || (ret < 0)) {
- close (dst_fd);
- close (src_fd);
break;
}
ret = write (dst_fd, defrag->databuf, ret);
if (ret < 0) {
- close (dst_fd);
- close (src_fd);
break;
}
}
ret = stat (full_path, &new_stbuf);
- if (ret < 0)
+ if (ret < 0) {
+ close (dst_fd);
+ close (src_fd);
continue;
+ }
/* No need to rebalance, if there is some
activity on source file */
- if (new_stbuf.st_mtime != stbuf.st_mtime)
+ if (new_stbuf.st_mtime != stbuf.st_mtime) {
+ close (dst_fd);
+ close (src_fd);
continue;
+ }
ret = fchmod (dst_fd, stbuf.st_mode);
if (ret) {
@@ -152,6 +154,9 @@ gf_glusterd_rebalance_move_data (glusterd_volinfo_t *volinfo, const char *dir)
UNLOCK (&defrag->lock);
}
+ close (dst_fd);
+ close (src_fd);
+
if (volinfo->defrag_status == GF_DEFRAG_STATUS_STOPED) {
closedir (fd);
ret = -1;
@@ -329,22 +334,77 @@ out:
}
int
-glusterd_defrag_stop (glusterd_volinfo_t *volinfo,
- gf1_cli_defrag_vol_rsp *rsp)
+glusterd_defrag_stop_validate (glusterd_volinfo_t *volinfo,
+ char *op_errstr, size_t len)
+{
+ int ret = -1;
+ if (glusterd_is_defrag_on (volinfo) == 0) {
+ snprintf (op_errstr, len, "Rebalance on %s is either Completed "
+ "or not yet started", volinfo->volname);
+ goto out;
+ }
+ ret = 0;
+out:
+ gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int
+glusterd_defrag_stop (glusterd_volinfo_t *volinfo, u_quad_t *files,
+ u_quad_t *size, char *op_errstr, size_t len)
{
/* TODO: set a variaeble 'stop_defrag' here, it should be checked
in defrag loop */
- if (!volinfo || !volinfo->defrag)
+ int ret = -1;
+ GF_ASSERT (volinfo);
+ GF_ASSERT (files);
+ GF_ASSERT (size);
+ GF_ASSERT (op_errstr);
+
+ ret = glusterd_defrag_stop_validate (volinfo, op_errstr, len);
+ if (ret)
+ goto out;
+ if (!volinfo || !volinfo->defrag) {
+ ret = -1;
goto out;
+ }
LOCK (&volinfo->defrag->lock);
{
volinfo->defrag_status = GF_DEFRAG_STATUS_STOPED;
- rsp->files = volinfo->defrag->total_files;
- rsp->size = volinfo->defrag->total_data;
+ *files = volinfo->defrag->total_files;
+ *size = volinfo->defrag->total_data;
}
UNLOCK (&volinfo->defrag->lock);
+ ret = 0;
+out:
+ gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int
+glusterd_defrag_status_get_v2 (glusterd_volinfo_t *volinfo,
+ gf2_cli_defrag_vol_rsp *rsp)
+{
+ if (!volinfo)
+ goto out;
+
+ if (volinfo->defrag) {
+ LOCK (&volinfo->defrag->lock);
+ {
+ rsp->files = volinfo->defrag->total_files;
+ rsp->size = volinfo->defrag->total_data;
+ rsp->lookedup_files = volinfo->defrag->num_files_lookedup;
+ }
+ UNLOCK (&volinfo->defrag->lock);
+ } else {
+ rsp->files = volinfo->rebalance_files;
+ rsp->size = volinfo->rebalance_data;
+ rsp->lookedup_files = volinfo->lookedup_files;
+ }
+
+ rsp->op_errno = volinfo->defrag_status;
rsp->op_ret = 0;
out:
return 0;
@@ -377,16 +437,167 @@ out:
return 0;
}
+void
+glusterd_rebalance_cmd_attempted_log (int cmd, char *volname)
+{
+ switch (cmd) {
+ case GF_DEFRAG_CMD_START:
+ gf_cmd_log ("Volume rebalance"," on volname: %s "
+ "cmd: start, attempted", volname);
+ break;
+ case GF_DEFRAG_CMD_STOP:
+ gf_cmd_log ("Volume rebalance"," on volname: %s "
+ "cmd: stop, attempted", volname);
+ break;
+ default:
+ break;
+ }
+ gf_log ("glusterd", GF_LOG_NORMAL, "Received rebalance volume %s on %s",
+ (cmd == GF_DEFRAG_CMD_START)?"start":(cmd == GF_DEFRAG_CMD_STOP)?"stop":"status"
+ , volname);
+}
+
+void
+glusterd_rebalance_cmd_log (int cmd, char *volname, int status)
+{
+ if (cmd != GF_DEFRAG_CMD_STATUS) {
+ gf_cmd_log ("volume rebalance"," on volname: %s %d %s",
+ volname, cmd, ((status)?"FAILED":"SUCCESS"));
+ }
+}
+
int
-glusterd_handle_defrag_volume (rpcsvc_request_t *req)
+glusterd_defrag_start_validate (glusterd_volinfo_t *volinfo, char *op_errstr,
+ size_t len)
{
- int32_t ret = -1;
- gf1_cli_defrag_vol_req cli_req = {0,};
- glusterd_conf_t *priv = NULL;
- char cmd_str[4096] = {0,};
- glusterd_volinfo_t *volinfo = NULL;
+ int ret = -1;
+
+ if (glusterd_is_defrag_on (volinfo)) {
+ gf_log ("glusterd", GF_LOG_DEBUG,
+ "rebalance on volume %s already started",
+ volinfo->volname);
+ snprintf (op_errstr, len, "Rebalance on %s is already started",
+ volinfo->volname);
+ goto out;
+ }
+
+ if (glusterd_is_rb_started (volinfo) ||
+ glusterd_is_rb_paused (volinfo)) {
+ gf_log ("glusterd", GF_LOG_DEBUG,
+ "Replace brick is in progress on volume %s",
+ volinfo->volname);
+ snprintf (op_errstr, len, "Replace brick is in progress on "
+ "volume %s", volinfo->volname);
+ goto out;
+ }
+ ret = 0;
+out:
+ gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int
+glusterd_handle_defrag_start (glusterd_volinfo_t *volinfo, char *op_errstr,
+ size_t len)
+{
+ int ret = -1;
glusterd_defrag_info_t *defrag = NULL;
- gf1_cli_defrag_vol_rsp rsp = {0,};
+ char cmd_str[4096] = {0,};
+ glusterd_conf_t *priv = NULL;
+
+ priv = THIS->private;
+
+ GF_ASSERT (volinfo);
+ GF_ASSERT (op_errstr);
+
+ ret = glusterd_defrag_start_validate (volinfo, op_errstr, len);
+ if (ret)
+ goto out;
+ if (!volinfo->defrag)
+ volinfo->defrag = GF_CALLOC (1, sizeof (glusterd_defrag_info_t),
+ gf_gld_mt_defrag_info);
+ if (!volinfo->defrag)
+ goto out;
+
+ defrag = volinfo->defrag;
+
+ LOCK_INIT (&defrag->lock);
+ snprintf (defrag->mount, 1024, "%s/mount/%s",
+ priv->workdir, volinfo->volname);
+ /* Create a directory, mount glusterfs over it, start glusterfs-defrag */
+ snprintf (cmd_str, sizeof (cmd_str), "mkdir -p %s", defrag->mount);
+ ret = system (cmd_str);
+
+ if (ret) {
+ gf_log("glusterd", GF_LOG_DEBUG, "command: %s failed", cmd_str);
+ goto out;
+ }
+
+ snprintf (cmd_str, sizeof (cmd_str), "%s/sbin/glusterfs -s localhost "
+ "--volfile-id %s --volume-name %s-quick-read "
+ "--xlator-option *dht.unhashed-sticky-bit=yes "
+ "--xlator-option *dht.use-readdirp=yes "
+ "--xlator-option *dht.lookup-unhashed=yes %s",
+ GFS_PREFIX, volinfo->volname, volinfo->volname,
+ defrag->mount);
+ ret = gf_system (cmd_str);
+ if (ret) {
+ gf_log("glusterd", GF_LOG_DEBUG, "command: %s failed", cmd_str);
+ goto out;
+ }
+
+ volinfo->defrag_status = GF_DEFRAG_STATUS_STARTED;
+
+ ret = pthread_create (&defrag->th, NULL, glusterd_defrag_start,
+ volinfo);
+ if (ret) {
+ snprintf (cmd_str, sizeof (cmd_str), "umount -l %s", defrag->mount);
+ if (system (cmd_str))
+ gf_log("glusterd", GF_LOG_DEBUG, "command: %s "
+ "failed", cmd_str);
+ }
+out:
+ gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int
+glusterd_rebalance_cmd_validate (int cmd, char *volname,
+ glusterd_volinfo_t **volinfo,
+ char *op_errstr, size_t len)
+{
+ int ret = -1;
+
+ if (glusterd_volinfo_find(volname, volinfo)) {
+ gf_log ("glusterd", GF_LOG_ERROR, "Received rebalance on invalid"
+ " volname %s", volname);
+ snprintf (op_errstr, len, "Volume %s does not exist",
+ volname);
+ goto out;
+ }
+
+ if ((*volinfo)->status != GLUSTERD_STATUS_STARTED) {
+ gf_log ("glusterd", GF_LOG_ERROR, "Received rebalance on stopped"
+ " volname %s", volname);
+ snprintf (op_errstr, len, "Volume %s needs to "
+ "be started to perform rebalance", volname);
+ goto out;
+ }
+ ret = 0;
+out:
+ gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int
+glusterd_handle_defrag_volume_v2 (rpcsvc_request_t *req)
+{
+ int32_t ret = -1;
+ gf1_cli_defrag_vol_req cli_req = {0,};
+ glusterd_volinfo_t *volinfo = NULL;
+ gf2_cli_defrag_vol_rsp rsp = {0,};
+ char msg[2048] = {0};
+ glusterd_conf_t *priv = NULL;
GF_ASSERT (req);
@@ -409,88 +620,105 @@ glusterd_handle_defrag_volume (rpcsvc_request_t *req)
default:
break;
}
+
gf_log ("glusterd", GF_LOG_NORMAL, "Received rebalance volume %s on %s",
- (cli_req.cmd == GF_DEFRAG_CMD_START)?"start":(cli_req.cmd == GF_DEFRAG_CMD_STOP)?"stop":"status"
- , cli_req.volname);
+ ((cli_req.cmd == GF_DEFRAG_CMD_START) ? "start" :
+ (cli_req.cmd == GF_DEFRAG_CMD_STOP) ? "stop" : "status"),
+ cli_req.volname);
+
+ glusterd_rebalance_cmd_attempted_log (cli_req.cmd, cli_req.volname);
rsp.volname = cli_req.volname;
rsp.op_ret = -1;
- if (glusterd_volinfo_find(cli_req.volname, &volinfo)) {
- gf_log ("glusterd", GF_LOG_NORMAL, "Received rebalance on invalid"
- " volname %s", cli_req.volname);
- goto out;
- }
+ rsp.op_errstr = msg;
- if (volinfo->status != GLUSTERD_STATUS_STARTED) {
- gf_log ("glusterd", GF_LOG_NORMAL, "Received rebalance on stopped"
- " volname %s", cli_req.volname);
+ ret = glusterd_rebalance_cmd_validate (cli_req.cmd, cli_req.volname,
+ &volinfo, msg, sizeof (msg));
+ if (ret)
goto out;
- }
-
switch (cli_req.cmd) {
case GF_DEFRAG_CMD_START:
- {
- if (volinfo->defrag) {
- gf_log ("glusterd", GF_LOG_DEBUG,
- "rebalance on volume %s already started",
- cli_req.volname);
- rsp.op_errno = EEXIST;
- goto out;
- }
+ ret = glusterd_handle_defrag_start (volinfo, msg, sizeof (msg));
+ rsp.op_ret = ret;
+ break;
+ case GF_DEFRAG_CMD_STOP:
+ ret = glusterd_defrag_stop (volinfo, &rsp.files, &rsp.size,
+ msg, sizeof (msg));
+ rsp.op_ret = ret;
+ break;
+ case GF_DEFRAG_CMD_STATUS:
+ ret = glusterd_defrag_status_get_v2 (volinfo, &rsp);
+ break;
+ default:
+ break;
+ }
+ glusterd_rebalance_cmd_log (cli_req.cmd, cli_req.volname, rsp.op_ret);
+out:
- if (glusterd_is_rb_started (volinfo) ||
- glusterd_is_rb_paused (volinfo)) {
- gf_log ("glusterd", GF_LOG_DEBUG,
- "Replace brick is in progress on volume %s",
- cli_req.volname);
- goto out;
- }
- volinfo->defrag = GF_CALLOC (1, sizeof (glusterd_defrag_info_t),
- gf_gld_mt_defrag_info);
- if (!volinfo->defrag)
- goto out;
+ ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
+ gf_xdr_serialize_cli_defrag_vol_rsp_v2);
+ if (cli_req.volname)
+ free (cli_req.volname);//malloced by xdr
- defrag = volinfo->defrag;
+ return 0;
+}
- LOCK_INIT (&defrag->lock);
- snprintf (defrag->mount, 1024, "%s/mount/%s",
- priv->workdir, cli_req.volname);
- /* Create a directory, mount glusterfs over it, start glusterfs-defrag */
- snprintf (cmd_str, 4096, "mkdir -p %s", defrag->mount);
- ret = system (cmd_str);
+int
+glusterd_handle_defrag_volume (rpcsvc_request_t *req)
+{
+ int32_t ret = -1;
+ gf1_cli_defrag_vol_req cli_req = {0,};
+ glusterd_conf_t *priv = NULL;
+ char cmd_str[4096] = {0,};
+ glusterd_volinfo_t *volinfo = NULL;
+ gf1_cli_defrag_vol_rsp rsp = {0,};
+ char msg[2048] = {0};
- if (ret) {
- gf_log("glusterd", GF_LOG_DEBUG, "command: %s failed", cmd_str);
- goto out;
- }
+ GF_ASSERT (req);
- snprintf (cmd_str, 4096, "%s/sbin/glusterfs -s localhost "
- "--volfile-id %s --volume-name %s-quick-read "
- "--xlator-option *dht.unhashed-sticky-bit=yes "
- "--xlator-option *dht.use-readdirp=yes "
- "--xlator-option *dht.lookup-unhashed=yes %s",
- GFS_PREFIX, cli_req.volname, cli_req.volname,
- defrag->mount);
- ret = gf_system (cmd_str);
- if (ret) {
- gf_log("glusterd", GF_LOG_DEBUG, "command: %s failed", cmd_str);
- goto out;
- }
+ priv = THIS->private;
- volinfo->defrag_status = GF_DEFRAG_STATUS_STARTED;
- rsp.op_ret = 0;
+ if (!gf_xdr_to_cli_defrag_vol_req (req->msg[0], &cli_req)) {
+ //failed to decode msg;
+ req->rpc_err = GARBAGE_ARGS;
+ goto out;
+ }
- ret = pthread_create (&defrag->th, NULL, glusterd_defrag_start,
- volinfo);
- if (ret) {
- snprintf (cmd_str, 1024, "umount -l %s", defrag->mount);
- ret = system (cmd_str);
- rsp.op_ret = -1;
- }
+ switch (cli_req.cmd) {
+ case GF_DEFRAG_CMD_START:
+ gf_cmd_log ("Volume rebalance"," on volname: %s "
+ "cmd: start, attempted", cli_req.volname);
+ break;
+ case GF_DEFRAG_CMD_STOP:
+ gf_cmd_log ("Volume rebalance"," on volname: %s "
+ "cmd: stop, attempted", cli_req.volname);
+ break;
+ default:
+ break;
+ }
+ gf_log ("glusterd", GF_LOG_NORMAL, "Received rebalance volume %s on %s",
+ ((cli_req.cmd == GF_DEFRAG_CMD_START) ? "start" :
+ (cli_req.cmd == GF_DEFRAG_CMD_STOP) ? "stop" : "status"),
+ cli_req.volname);
+
+ rsp.volname = cli_req.volname;
+ rsp.op_ret = -1;
+
+ ret = glusterd_rebalance_cmd_validate (cli_req.cmd, cli_req.volname,
+ &volinfo, msg, sizeof (msg));
+ if (ret)
+ goto out;
+ switch (cli_req.cmd) {
+ case GF_DEFRAG_CMD_START:
+ {
+ ret = glusterd_handle_defrag_start (volinfo, msg, sizeof (msg));
+ rsp.op_ret = ret;
break;
}
case GF_DEFRAG_CMD_STOP:
- ret = glusterd_defrag_stop (volinfo, &rsp);
+ ret = glusterd_defrag_stop (volinfo, &rsp.files, &rsp.size,
+ msg, sizeof (msg));
+ rsp.op_ret = ret;
break;
case GF_DEFRAG_CMD_STATUS:
ret = glusterd_defrag_status_get (volinfo, &rsp);
@@ -508,7 +736,6 @@ glusterd_handle_defrag_volume (rpcsvc_request_t *req)
}
out:
-
ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
gf_xdr_serialize_cli_defrag_vol_rsp);
if (cli_req.volname)
diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h
index d98ddb1c6b7..06f35479c35 100644
--- a/xlators/mgmt/glusterd/src/glusterd.h
+++ b/xlators/mgmt/glusterd/src/glusterd.h
@@ -354,6 +354,9 @@ int
glusterd_handle_defrag_volume (rpcsvc_request_t *req);
int
+glusterd_handle_defrag_volume_v2 (rpcsvc_request_t *req);
+
+int
glusterd_xfer_cli_probe_resp (rpcsvc_request_t *req, int32_t op_ret,
int32_t op_errno, char *hostname, int port);