summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cli/src/cli-cmd-volume.c54
-rw-r--r--cli/src/cli.h1
-rw-r--r--cli/src/cli3_1-cops.c78
-rw-r--r--extras/glusterfs-defrag.in7
-rw-r--r--rpc/xdr/src/cli1-xdr.c8
-rw-r--r--rpc/xdr/src/cli1-xdr.h4
-rw-r--r--rpc/xdr/src/cli1.h4
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-handler.c309
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-mem-types.h1
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.h37
-rw-r--r--xlators/mgmt/glusterd/src/glusterd3_1-mops.c2
11 files changed, 440 insertions, 65 deletions
diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c
index 22844c500ae..63c15473072 100644
--- a/cli/src/cli-cmd-volume.c
+++ b/cli/src/cli-cmd-volume.c
@@ -219,8 +219,7 @@ cli_cmd_volume_rename_cbk (struct cli_state *state, struct cli_cmd_word *word,
goto out;
dict = dict_new ();
-
- if (dict)
+ if (!dict)
goto out;
GF_ASSERT (words[2]);
@@ -254,34 +253,57 @@ out:
return ret;
}
+void
+cli_cmd_volume_defrag_usage ()
+{
+ cli_out ("Usage: volume rebalance <volname> <start|stop|status>");
+}
int
cli_cmd_volume_defrag_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;
- char *volname = NULL;
-
+ int ret = -1;
+ rpc_clnt_procedure_t *proc = NULL;
+ call_frame_t *frame = NULL;
+ dict_t *dict = NULL;
frame = create_frame (THIS, THIS->ctx->pool);
if (!frame)
goto out;
+ dict = dict_new ();
+ if (!dict)
+ goto out;
+
+ GF_ASSERT (words[2]);
+
+ if (!(words[3])) {
+ cli_cmd_volume_defrag_usage();
+ goto out;
+ }
//TODO: Build validation here
- volname = (char *)words[2];
- GF_ASSERT (volname);
+ ret = dict_set_str (dict, "volname", (char *)words[2]);
+ if (ret)
+ goto out;
+
+ ret = dict_set_str (dict, "command", (char *)words[3]);
+ if (ret)
+ goto out;
proc = &cli_rpc_prog->proctable[GF1_CLI_DEFRAG_VOLUME];
if (proc->fn) {
- ret = proc->fn (frame, THIS, volname);
+ ret = proc->fn (frame, THIS, dict);
}
out:
- if (!proc && ret)
- cli_out ("Defrag of Volume %s failed", volname);
+ if (!proc && ret) {
+ if (dict)
+ dict_destroy (dict);
+
+ cli_out ("Defrag of Volume %s failed", (char *)words[2]);
+ }
return 0;
}
@@ -438,7 +460,13 @@ struct cli_cmd volume_cmds[] = {
{ "volume remove-brick <VOLNAME> [(replica <COUNT>)|(stripe <COUNT>)] <BRICK> ...",
cli_cmd_volume_remove_brick_cbk },
- { "volume defrag <VOLNAME>",
+ { "volume rebalance <VOLNAME> start",
+ cli_cmd_volume_defrag_cbk },
+
+ { "volume rebalance <VOLNAME> stop",
+ cli_cmd_volume_defrag_cbk },
+
+ { "volume rebalance <VOLNAME> status",
cli_cmd_volume_defrag_cbk },
{ "volume replace-brick <VOLNAME> (<BRICK> <NEW-BRICK>)|pause|abort|start|status",
diff --git a/cli/src/cli.h b/cli/src/cli.h
index 7b2de667358..36ac7214bfd 100644
--- a/cli/src/cli.h
+++ b/cli/src/cli.h
@@ -123,6 +123,7 @@ struct cli_local {
struct {
char *volname;
+ int cmd;
} defrag_vol;
struct {
diff --git a/cli/src/cli3_1-cops.c b/cli/src/cli3_1-cops.c
index 210c881b61b..de3aa6ed2dd 100644
--- a/cli/src/cli3_1-cops.c
+++ b/cli/src/cli3_1-cops.c
@@ -500,11 +500,12 @@ 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,};
- int ret = 0;
- cli_local_t *local = NULL;
- char *volname = NULL;
- call_frame_t *frame = NULL;
+ 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;
if (-1 == req->rpc_status) {
goto out;
@@ -521,12 +522,34 @@ gf_cli3_1_defrag_volume_cbk (struct rpc_req *req, struct iovec *iov,
if (frame)
local = frame->local;
- if (local)
- volname = local->u.start_vol.volname;
+ if (local) {
+ volname = local->u.defrag_vol.volname;
+ cmd = local->u.defrag_vol.cmd;
+ }
+ if (cmd == GF_DEFRAG_CMD_START) {
+ cli_out ("starting defrag 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 ("'defrag volume %s stop' failed", volname);
+ else
+ cli_out ("stopped defrag 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 defrag process");
+ else {
+ cli_out ("rebalanced %"PRId64" files of size %"PRId64
+ " (total files scanned %"PRId64")",
+ rsp.files, rsp.size, rsp.lookedup_files);
+ }
+ }
- gf_log ("cli", GF_LOG_NORMAL, "Received resp to probe");
- cli_out ("Defrag of volume %s has been %s", volname,
- (rsp.op_ret) ? "unsuccessful": "successful");
+ if (volname)
+ GF_FREE (volname);
ret = rsp.op_ret;
@@ -1074,23 +1097,48 @@ int32_t
gf_cli3_1_defrag_volume (call_frame_t *frame, xlator_t *this,
void *data)
{
- gf1_cli_defrag_vol_req req = {0,};
- int ret = 0;
- cli_local_t *local = NULL;
+ gf1_cli_defrag_vol_req req = {0,};
+ int ret = 0;
+ cli_local_t *local = NULL;
+ char *volname = NULL;
+ char *cmd_str = NULL;
+ dict_t *dict = NULL;
if (!frame || !this || !data) {
ret = -1;
goto out;
}
+ dict = data;
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret)
+ gf_log ("", GF_LOG_DEBUG, "error");
+
+ ret = dict_get_str (dict, "command", &cmd_str);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG, "error");
+ goto out;
+ }
+
+ if (strncasecmp (cmd_str, "start", 6) == 0) {
+ req.cmd = GF_DEFRAG_CMD_START;
+ } else if (strncasecmp (cmd_str, "stop", 5) == 0) {
+ req.cmd = GF_DEFRAG_CMD_STOP;
+ } else if (strncasecmp (cmd_str, "status", 7) == 0) {
+ req.cmd = GF_DEFRAG_CMD_STATUS;
+ }
+
+
local = cli_local_get ();
if (local) {
- local->u.defrag_vol.volname = data;
+ local->u.defrag_vol.volname = gf_strdup (volname);
+ local->u.defrag_vol.cmd = req.cmd;
frame->local = local;
}
- req.volname = data;
+ req.volname = volname;
ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
GD_MGMT_CLI_DEFRAG_VOLUME, NULL,
diff --git a/extras/glusterfs-defrag.in b/extras/glusterfs-defrag.in
index 8bdaf3d8252..68a393f1c3a 100644
--- a/extras/glusterfs-defrag.in
+++ b/extras/glusterfs-defrag.in
@@ -12,7 +12,10 @@
set -e;
-added_bricks="node1:/gfs/export1"
+#
+#added_bricks="node1:/gfs/export1"
+#
+added_bricks=""
CP="cp"
MV="mv"
@@ -53,6 +56,8 @@ relocate_file()
return;
fi
+ size=$(stat -c '%s' "$path");
+
# If there are some entries in added_bricks, then check
# if the link file is present on those nodes, if not,
# set flag=1, so full defrag happens
diff --git a/rpc/xdr/src/cli1-xdr.c b/rpc/xdr/src/cli1-xdr.c
index 32e42c21ce4..3dddde15f56 100644
--- a/rpc/xdr/src/cli1-xdr.c
+++ b/rpc/xdr/src/cli1-xdr.c
@@ -301,6 +301,8 @@ bool_t
xdr_gf1_cli_defrag_vol_req (XDR *xdrs, gf1_cli_defrag_vol_req *objp)
{
+ if (!xdr_int (xdrs, &objp->cmd))
+ return FALSE;
if (!xdr_string (xdrs, &objp->volname, ~0))
return FALSE;
return TRUE;
@@ -316,6 +318,12 @@ xdr_gf1_cli_defrag_vol_rsp (XDR *xdrs, gf1_cli_defrag_vol_rsp *objp)
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;
}
diff --git a/rpc/xdr/src/cli1-xdr.h b/rpc/xdr/src/cli1-xdr.h
index 3580ebb766d..ed45d89a728 100644
--- a/rpc/xdr/src/cli1-xdr.h
+++ b/rpc/xdr/src/cli1-xdr.h
@@ -175,6 +175,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;
char *volname;
};
typedef struct gf1_cli_defrag_vol_req gf1_cli_defrag_vol_req;
@@ -183,6 +184,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;
};
typedef struct gf1_cli_defrag_vol_rsp gf1_cli_defrag_vol_rsp;
diff --git a/rpc/xdr/src/cli1.h b/rpc/xdr/src/cli1.h
index 73f9f8d7b41..578b8225c73 100644
--- a/rpc/xdr/src/cli1.h
+++ b/rpc/xdr/src/cli1.h
@@ -25,6 +25,10 @@
#include "cli1-xdr.h"
+#define GF_DEFRAG_CMD_START 1
+#define GF_DEFRAG_CMD_STOP 2
+#define GF_DEFRAG_CMD_STATUS 3
+
ssize_t
gf_xdr_serialize_cli_probe_rsp (struct iovec outmsg, void *rsp);
diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c
index a8b334c3dd9..ce4c661826e 100644
--- a/xlators/mgmt/glusterd/src/glusterd-handler.c
+++ b/xlators/mgmt/glusterd/src/glusterd-handler.c
@@ -594,7 +594,203 @@ out:
return ret;
}
+int
+glusterd_check_and_rebalance (glusterd_volinfo_t *volinfo, char *dir)
+{
+ int ret = -1;
+ int dst_fd = -1;
+ int src_fd = -1;
+ DIR *fd = NULL;
+ glusterd_defrag_info_t *defrag = NULL;
+ struct dirent *entry = NULL;
+ struct stat stbuf = {0,};
+ struct stat new_stbuf = {0,};
+ char full_path[1024] = {0,};
+ char tmp_filename[1024] = {0,};
+ char value[128] = {0,};
+
+ defrag = volinfo->defrag;
+ if (!defrag)
+ goto out;
+
+ fd = opendir (dir);
+ if (!fd)
+ goto out;
+
+ do {
+ entry = readdir (fd);
+ if (!entry)
+ break;
+
+ if (!strcmp (entry->d_name, ".") || !strcmp (entry->d_name, ".."))
+ continue;
+
+ snprintf (full_path, 1024, "%s/%s", dir, entry->d_name);
+
+ ret = stat (full_path, &stbuf);
+ if (ret == -1)
+ continue;
+
+ if (S_ISDIR (stbuf.st_mode)) {
+ //getfattr -n trusted.distribute.fix.layout "$path" ;
+ getxattr (full_path, "trusted.distribute.fix.layout",
+ &value, 128);
+
+ ret = glusterd_check_and_rebalance (volinfo, full_path);
+ }
+ if (S_ISREG (stbuf.st_mode) && ((stbuf.st_mode & 01000) == 01000)) {
+ /* TODO: run the defrag */
+ snprintf (tmp_filename, 1024, "%s/.%s.gfs%zu", dir,
+ entry->d_name, stbuf.st_size);
+
+ dst_fd = creat (tmp_filename, (stbuf.st_mode & ~01000));
+ if (dst_fd == -1)
+ continue;
+
+ src_fd = open (full_path, O_RDONLY);
+ if (src_fd == -1) {
+ close (dst_fd);
+ continue;
+ }
+
+ 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)
+ continue;
+ if (new_stbuf.st_mtime != stbuf.st_mtime)
+ continue;
+
+ ret = rename (tmp_filename, full_path);
+ if (ret != -1) {
+ LOCK (&defrag->lock);
+ {
+ defrag->total_files += 1;
+ defrag->total_data += stbuf.st_size;
+ }
+ UNLOCK (&defrag->lock);
+ }
+ }
+ ret = 0;
+
+ LOCK (&defrag->lock);
+ {
+ if (S_ISREG (stbuf.st_mode))
+ defrag->num_files_lookedup += 1;
+ if (volinfo->defrag_status == GF_DEFRAG_STATUS_STOPED)
+ ret = 1;
+ }
+ UNLOCK (&defrag->lock);
+ if (ret)
+ break;
+
+ /* Write the full 'glusterfs-defrag' here */
+
+ } while (1);
+
+ closedir (fd);
+
+ if (!entry)
+ ret = 0;
+out:
+ return ret;
+}
+
+void *
+glusterd_defrag_start (void *data)
+{
+ glusterd_volinfo_t *volinfo = data;
+ glusterd_defrag_info_t *defrag = NULL;
+ char cmd_str[1024] = {0,};
+ int ret = -1;
+
+ /* TODO: make it more generic.. */
+ defrag = volinfo->defrag;
+ if (!defrag)
+ goto out;
+
+ ret = glusterd_check_and_rebalance (volinfo, defrag->mount);
+
+ /* TODO: This should run in a thread, and finish the thread when
+ the task is complete. While defrag is running, keep updating
+ files */
+
+ volinfo->defrag_status = GF_DEFRAG_STATUS_COMPLETE;
+ volinfo->rebalance_files = defrag->total_files;
+ volinfo->rebalance_data = defrag->total_data;
+ volinfo->lookedup_files = defrag->num_files_lookedup;
+out:
+ gf_log ("defrag", GF_LOG_NORMAL, "defrag on %s complete",
+ defrag->mount);
+
+ snprintf (cmd_str, 1024, "umount %s", defrag->mount);
+ system (cmd_str);
+ volinfo->defrag = NULL;
+ LOCK_DESTROY (&defrag->lock);
+ GF_FREE (defrag);
+
+ return NULL;
+}
+
+int
+glusterd_defrag_stop (glusterd_volinfo_t *volinfo,
+ gf1_cli_defrag_vol_rsp *rsp)
+{
+ /* TODO: set a variaeble 'stop_defrag' here, it should be checked
+ in defrag loop */
+ if (!volinfo || !volinfo->defrag)
+ 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;
+ }
+ UNLOCK (&volinfo->defrag->lock);
+ rsp->op_ret = 0;
+out:
+ return 0;
+}
+
+int
+glusterd_defrag_status_get (glusterd_volinfo_t *volinfo,
+ gf1_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_ret = 0;
+out:
+ return 0;
+}
int
glusterd_handle_defrag_volume (rpcsvc_request_t *req)
@@ -603,7 +799,9 @@ glusterd_handle_defrag_volume (rpcsvc_request_t *req)
gf1_cli_defrag_vol_req cli_req = {0,};
glusterd_conf_t *priv = NULL;
char cmd_str[4096] = {0,};
- glusterd_volinfo_t *tmp_volinfo = NULL;
+ glusterd_volinfo_t *volinfo = NULL;
+ glusterd_defrag_info_t *defrag = NULL;
+ gf1_cli_defrag_vol_rsp rsp = {0,};
GF_ASSERT (req);
@@ -617,46 +815,87 @@ glusterd_handle_defrag_volume (rpcsvc_request_t *req)
gf_log ("glusterd", GF_LOG_NORMAL, "Received defrag volume on %s",
cli_req.volname);
- if (glusterd_volinfo_find(cli_req.volname, &tmp_volinfo)) {
- gf_log ("glusterd", GF_LOG_NORMAL, "Received defrag on invalid"
- " volname %s", cli_req.volname);
- goto out;
- }
-
- glusterd_op_set_op (GD_OP_DEFRAG_VOLUME);
+ rsp.volname = cli_req.volname;
+ rsp.op_ret = -1;
+ if (glusterd_volinfo_find(cli_req.volname, &volinfo)) {
+ gf_log ("glusterd", GF_LOG_NORMAL, "Received defrag on invalid"
+ " volname %s", cli_req.volname);
+ goto out;
+ }
- glusterd_op_set_ctx (GD_OP_DEFRAG_VOLUME, cli_req.volname);
+ if (volinfo->status != GLUSTERD_STATUS_STARTED) {
+ gf_log ("glusterd", GF_LOG_NORMAL, "Received defrag on stopped"
+ " volname %s", cli_req.volname);
+ goto out;
+ }
- /* TODO: make it more generic.. */
- /* Create a directory, mount glusterfs over it, start glusterfs-defrag */
- snprintf (cmd_str, 4096, "mkdir -p %s/mount/%s",
- priv->workdir, cli_req.volname);
- ret = system (cmd_str);
-
- if (ret) {
- gf_log("glusterd", GF_LOG_DEBUG, "command: %s failed", cmd_str);
- goto out;
- }
-
- snprintf (cmd_str, 4096, "glusterfs -f %s/vols/%s/%s-tcp.vol "
- "--xlator-option dht0.unhashed-sticky-bit=yes "
- "--xlator-option dht0.lookup-unhashed=on %s/mount/%s",
- priv->workdir, cli_req.volname, cli_req.volname,
- priv->workdir, cli_req.volname);
- ret = system (cmd_str);
+ switch (cli_req.cmd) {
+ case GF_DEFRAG_CMD_START:
+ {
+ if (volinfo->defrag) {
+ gf_log ("glusterd", GF_LOG_DEBUG,
+ "defrag on volume %s already started",
+ cli_req.volname);
+ goto out;
+ }
- if (ret) {
- gf_log("glusterd", GF_LOG_DEBUG, "command: %s failed", cmd_str);
- goto out;
- }
+ 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, 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);
+
+ if (ret) {
+ gf_log("glusterd", GF_LOG_DEBUG, "command: %s failed", cmd_str);
+ goto out;
+ }
- snprintf (cmd_str, 4096, "glusterfs-defrag %s/mount/%s",
- priv->workdir, cli_req.volname);
- ret = system (cmd_str);
+ snprintf (cmd_str, 4096, "glusterfs -f %s/vols/%s/%s-tcp.vol "
+ "--xlator-option dht0.unhashed-sticky-bit=yes "
+ "--xlator-option dht0.lookup-unhashed=yes "
+ "--volume-name quickread %s",
+ priv->workdir, cli_req.volname, cli_req.volname,
+ defrag->mount);
+ ret = system (cmd_str);
- if (ret)
- gf_log("glusterd", GF_LOG_DEBUG, "command: %s failed",cmd_str);
+ if (ret) {
+ gf_log("glusterd", GF_LOG_DEBUG, "command: %s failed", cmd_str);
+ goto out;
+ }
+ rsp.op_ret = 0;
+ 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;
+ }
+ break;
+ }
+ case GF_DEFRAG_CMD_STOP:
+ ret = glusterd_defrag_stop (volinfo, &rsp);
+ break;
+ case GF_DEFRAG_CMD_STATUS:
+ ret = glusterd_defrag_status_get (volinfo, &rsp);
+ break;
+ default:
+ break;
+ }
+ if (ret)
+ gf_log("glusterd", GF_LOG_DEBUG, "command: %s failed",cmd_str);
out:
+
+ ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
+ gf_xdr_serialize_cli_defrag_vol_rsp);
+
return ret;
}
diff --git a/xlators/mgmt/glusterd/src/glusterd-mem-types.h b/xlators/mgmt/glusterd/src/glusterd-mem-types.h
index 8df94163d61..a5d7c4f27f2 100644
--- a/xlators/mgmt/glusterd/src/glusterd-mem-types.h
+++ b/xlators/mgmt/glusterd/src/glusterd-mem-types.h
@@ -54,6 +54,7 @@ enum gf_gld_mem_types_ {
gf_gld_mt_ifreq,
gf_gld_mt_store_handle_t,
gf_gld_mt_store_iter_t,
+ gf_gld_mt_defrag_info,
gf_gld_mt_end
};
#endif
diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h
index 368c0a6847a..dce3275e73c 100644
--- a/xlators/mgmt/glusterd/src/glusterd.h
+++ b/xlators/mgmt/glusterd/src/glusterd.h
@@ -25,7 +25,10 @@
#include "config.h"
#endif
+#include <sys/types.h>
+#include <dirent.h>
#include <pthread.h>
+
#include "uuid.h"
#include "rpc-clnt.h"
@@ -84,6 +87,33 @@ struct glusterd_brickinfo {
typedef struct glusterd_brickinfo glusterd_brickinfo_t;
+struct gf_defrag_brickinfo_ {
+ char *name;
+ int files;
+ int size;
+};
+
+typedef enum gf_defrag_status_ {
+ GF_DEFRAG_STATUS_NOT_STARTED,
+ GF_DEFRAG_STATUS_STARTED,
+ GF_DEFRAG_STATUS_STOPED,
+ GF_DEFRAG_STATUS_COMPLETE,
+} gf_defrag_status_t;
+
+struct glusterd_defrag_info_ {
+ uint64_t total_files;
+ uint64_t total_data;
+ uint64_t num_files_lookedup;
+ gf_lock_t lock;
+ pthread_t th;
+ char mount[1024];
+ char databuf[131072];
+ struct gf_defrag_brickinfo_ *bricks; /* volinfo->brick_count */
+};
+
+
+typedef struct glusterd_defrag_info_ glusterd_defrag_info_t;
+
struct glusterd_volinfo_ {
char volname[GLUSTERD_MAX_VOLUME_NAME];
int type;
@@ -94,6 +124,13 @@ struct glusterd_volinfo_ {
int sub_count;
int port;
glusterd_store_handle_t *shandle;
+
+ /* Defrag/rebalance related */
+ gf_defrag_status_t defrag_status;
+ uint64_t rebalance_files;
+ uint64_t rebalance_data;
+ uint64_t lookedup_files;
+ glusterd_defrag_info_t *defrag;
};
typedef struct glusterd_volinfo_ glusterd_volinfo_t;
diff --git a/xlators/mgmt/glusterd/src/glusterd3_1-mops.c b/xlators/mgmt/glusterd/src/glusterd3_1-mops.c
index 86d09194e11..59933e8ac7d 100644
--- a/xlators/mgmt/glusterd/src/glusterd3_1-mops.c
+++ b/xlators/mgmt/glusterd/src/glusterd3_1-mops.c
@@ -1199,7 +1199,7 @@ rpcsvc_actor_t glusterd1_mgmt_actors[] = {
[GD_MGMT_COMMIT_OP] = { "COMMIT_OP", GD_MGMT_COMMIT_OP, glusterd_handle_rpc_msg, NULL, NULL},
[GD_MGMT_CLI_PROBE] = { "CLI_PROBE", GD_MGMT_CLI_PROBE, glusterd_handle_rpc_msg, NULL, NULL},
[GD_MGMT_CLI_CREATE_VOLUME] = { "CLI_CREATE_VOLUME", GD_MGMT_CLI_CREATE_VOLUME, glusterd_handle_rpc_msg, NULL,NULL},
- [GD_MGMT_CLI_DEFRAG_VOLUME] = { "CLI_DEFRAG_VOLUME", GD_MGMT_CLI_DEFRAG_VOLUME, glusterd_handle_rpc_msg, NULL,NULL},
+ [GD_MGMT_CLI_DEFRAG_VOLUME] = { "CLI_DEFRAG_VOLUME", GD_MGMT_CLI_DEFRAG_VOLUME, glusterd_handle_defrag_volume, NULL,NULL},
[GD_MGMT_CLI_DEPROBE] = { "FRIEND_REMOVE", GD_MGMT_CLI_DEPROBE, glusterd_handle_rpc_msg, NULL, NULL},
[GD_MGMT_CLI_LIST_FRIENDS] = { "LIST_FRIENDS", GD_MGMT_CLI_LIST_FRIENDS, glusterd_handle_rpc_msg, NULL, NULL},
[GD_MGMT_CLI_START_VOLUME] = { "START_VOLUME", GD_MGMT_CLI_START_VOLUME, glusterd_handle_rpc_msg, NULL, NULL},