summaryrefslogtreecommitdiffstats
path: root/xlators/mgmt
diff options
context:
space:
mode:
authorPranith Kumar K <pranithk@gluster.com>2010-09-20 09:54:12 +0000
committerVijay Bellur <vijay@dev.gluster.com>2010-09-20 10:33:38 -0700
commitad234382336a6f2dafb4cb698dfabbf7957b498b (patch)
tree8cb8c47abb63ea4a5647a5524b688f298017aae9 /xlators/mgmt
parente71b50e49612af4e76510b0c2a6f0519adfd852d (diff)
cli, mgmt/glusterd: volume sync command
Signed-off-by: Pranith Kumar K <pranithk@gluster.com> Signed-off-by: Vijay Bellur <vijay@dev.gluster.com> BUG: 1310 () URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=1310
Diffstat (limited to 'xlators/mgmt')
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-handler.c142
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-op-sm.c430
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-op-sm.h3
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-sm.c77
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.c71
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.h15
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.h12
-rw-r--r--xlators/mgmt/glusterd/src/glusterd3_1-mops.c49
8 files changed, 583 insertions, 216 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c
index bc015293f..da9eca021 100644
--- a/xlators/mgmt/glusterd/src/glusterd-handler.c
+++ b/xlators/mgmt/glusterd/src/glusterd-handler.c
@@ -297,7 +297,7 @@ out:
return ret;
}
-static int
+int
glusterd_add_volume_detail_to_dict (glusterd_volinfo_t *volinfo,
dict_t *volumes, int count)
{
@@ -2013,6 +2013,108 @@ out:
return ret;
}
+int
+glusterd_handle_sync_volume (rpcsvc_request_t *req)
+{
+ int32_t ret = -1;
+ gf1_cli_sync_volume_req cli_req = {0,};
+ dict_t *dict = NULL;
+ gf1_cli_sync_volume_rsp cli_rsp = {0.};
+ char msg[2048] = {0,};
+ gf_boolean_t free_hostname = _gf_true;
+ gf_boolean_t free_volname = _gf_true;
+ glusterd_volinfo_t *volinfo = NULL;
+
+ GF_ASSERT (req);
+
+ if (!gf_xdr_to_cli_sync_volume_req (req->msg[0], &cli_req)) {
+ //failed to decode msg;
+ req->rpc_err = GARBAGE_ARGS;
+ goto out;
+ }
+ gf_log ("glusterd", GF_LOG_NORMAL, "Received volume sync req "
+ "for volume %s",
+ (cli_req.flags & GF_CLI_SYNC_ALL) ? "all" : cli_req.volname);
+
+ dict = dict_new ();
+ if (!dict) {
+ gf_log ("", GF_LOG_ERROR, "Can't allocate sync vol dict");
+ goto out;
+ }
+
+ if (!glusterd_is_local_addr (cli_req.hostname)) {
+ ret = -1;
+ snprintf (msg, sizeof (msg), "sync from localhost"
+ " not allowed");
+ goto out;
+ }
+
+ ret = dict_set_dynmstr (dict, "hostname", cli_req.hostname);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "hostname set failed");
+ snprintf (msg, sizeof (msg), "hostname set failed");
+ goto out;
+ } else {
+ free_hostname = _gf_false;
+ }
+
+ ret = dict_set_int32 (dict, "flags", cli_req.flags);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "volume flags set failed");
+ snprintf (msg, sizeof (msg), "volume flags set failed");
+ goto out;
+ }
+
+ if (!cli_req.flags) {
+ ret = glusterd_volinfo_find (cli_req.volname, &volinfo);
+ if (!ret) {
+ snprintf (msg, sizeof (msg), "please delete the "
+ "volume: %s before sync", cli_req.volname);
+ ret = -1;
+ goto out;
+ }
+
+ ret = dict_set_dynmstr (dict, "volname", cli_req.volname);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "volume name set failed");
+ snprintf (msg, sizeof (msg), "volume name set failed");
+ goto out;
+ } else {
+ free_volname = _gf_false;
+ }
+ } else {
+ free_volname = _gf_false;
+ if (glusterd_volume_count_get ()) {
+ snprintf (msg, sizeof (msg), "please delete all the "
+ "volumes before full sync");
+ ret = -1;
+ goto out;
+ }
+ }
+
+ ret = glusterd_sync_volume (req, dict);
+
+out:
+ if (ret) {
+ cli_rsp.op_ret = -1;
+ cli_rsp.op_errstr = msg;
+ glusterd_submit_reply(req, &cli_rsp, NULL, 0, NULL,
+ gf_xdr_from_cli_sync_volume_rsp);
+ if (free_hostname && cli_req.hostname)
+ free (cli_req.hostname);
+ if (free_volname && cli_req.volname)
+ free (cli_req.volname);
+ if (dict)
+ dict_unref (dict);
+ if (!glusterd_opinfo_unlock())
+ gf_log ("glusterd", GF_LOG_ERROR, "Unlock on "
+ "opinfo failed");
+
+ ret = 0; //sent error to cli, prevent second reply
+ }
+
+ return ret;
+}
int
glusterd_op_lock_send_resp (rpcsvc_request_t *req, int32_t status)
@@ -2156,9 +2258,9 @@ out:
int
glusterd_op_commit_send_resp (rpcsvc_request_t *req,
- int32_t op, int32_t status, char *op_errstr)
+ int32_t op, int32_t status, char *op_errstr,
+ dict_t *rsp_dict)
{
- dict_t *rsp_dict = NULL;
gd1_mgmt_commit_op_rsp rsp = {{0}, };
int ret = -1;
@@ -2172,18 +2274,14 @@ glusterd_op_commit_send_resp (rpcsvc_request_t *req,
else
rsp.op_errstr = "";
- rsp_dict = dict_new ();
- if (!rsp_dict) {
- gf_log ("", GF_LOG_DEBUG,
- "Out of memory");
- ret = -1;
- goto out;
- }
-
- if (op == GD_OP_REPLACE_BRICK) {
+ switch (op) {
+ case GD_OP_REPLACE_BRICK:
ret = glusterd_fill_rb_commit_rsp (rsp_dict);
if (ret)
goto out;
+ break;
+ default:
+ break;
}
ret = dict_allocate_and_serialize (rsp_dict,
@@ -2203,8 +2301,6 @@ glusterd_op_commit_send_resp (rpcsvc_request_t *req,
"Responded to commit, ret: %d", ret);
out:
- if (rsp_dict)
- dict_unref (rsp_dict);
if (rsp.dict.dict_val)
GF_FREE (rsp.dict.dict_val);
return ret;
@@ -3084,6 +3180,24 @@ glusterd_log_rotate (rpcsvc_request_t *req, dict_t *dict)
return ret;
}
+int32_t
+glusterd_sync_volume (rpcsvc_request_t *req, dict_t *ctx)
+{
+ int32_t ret = -1;
+
+ GF_ASSERT (req);
+ GF_ASSERT (ctx);
+
+ glusterd_op_set_op (GD_OP_SYNC_VOLUME);
+ glusterd_op_set_ctx (GD_OP_SYNC_VOLUME, ctx);
+ glusterd_op_set_ctx_free (GD_OP_SYNC_VOLUME, _gf_true);
+ glusterd_op_set_req (req);
+
+ ret = glusterd_op_txn_begin ();
+
+ return ret;
+}
+
int32_t
glusterd_list_friends (rpcsvc_request_t *req, dict_t *dict, int32_t flags)
diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
index 651cb22e0..a6c1c779a 100644
--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c
+++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
@@ -84,7 +84,7 @@ glusterd_destroy_commit_ctx (glusterd_op_commit_ctx_t *ctx)
GF_FREE (ctx);
}
-static void
+void
glusterd_set_volume_status (glusterd_volinfo_t *volinfo,
glusterd_volume_status status)
{
@@ -99,6 +99,27 @@ glusterd_is_volume_started (glusterd_volinfo_t *volinfo)
return (!(volinfo->status == GLUSTERD_STATUS_STARTED));
}
+gf_boolean_t
+glusterd_are_all_volumes_stopped ()
+{
+ glusterd_conf_t *priv = NULL;
+ xlator_t *this = NULL;
+ glusterd_volinfo_t *voliter = NULL;
+
+ this = THIS;
+ GF_ASSERT (this);
+ priv = this->private;
+ GF_ASSERT (priv);
+
+ list_for_each_entry (voliter, &priv->volumes, vol_list) {
+ if (voliter->status == GLUSTERD_STATUS_STARTED)
+ return _gf_false;
+ }
+
+ return _gf_true;
+
+}
+
static int
glusterd_op_get_len (glusterd_op_t op)
{
@@ -158,6 +179,7 @@ glusterd_op_build_payload (glusterd_op_t op, gd1_mgmt_stage_op_req **req)
int len = 0;
int ret = -1;
gd1_mgmt_stage_op_req *stage_req = NULL;
+ void *ctx = NULL;
GF_ASSERT (op < GD_OP_MAX);
GF_ASSERT (op > GD_OP_NONE);
@@ -178,12 +200,18 @@ glusterd_op_build_payload (glusterd_op_t op, gd1_mgmt_stage_op_req **req)
stage_req->op = op;
//stage_req->buf.buf_len = len;
+ ctx = (void*)glusterd_op_get_ctx (op);
+ if (!ctx) {
+ gf_log ("", GF_LOG_ERROR, "Null Context for "
+ "op %d", op);
+ ret = -1;
+ goto out;
+ }
+
switch (op) {
case GD_OP_CREATE_VOLUME:
{
- dict_t *dict = NULL;
- dict = glusterd_op_get_ctx (op);
- GF_ASSERT (dict);
+ dict_t *dict = ctx;
++glusterfs_port;
ret = dict_set_int32 (dict, "port", glusterfs_port);
ret = dict_allocate_and_serialize (dict,
@@ -197,124 +225,36 @@ glusterd_op_build_payload (glusterd_op_t op, gd1_mgmt_stage_op_req **req)
case GD_OP_START_VOLUME:
{
- glusterd_op_start_volume_ctx_t *ctx = NULL;
- ctx = glusterd_op_get_ctx (op);
- GF_ASSERT (ctx);
+ glusterd_op_start_volume_ctx_t *ctx1 = ctx;
stage_req->buf.buf_len =
- strlen (ctx->volume_name);
+ strlen (ctx1->volume_name);
stage_req->buf.buf_val =
- gf_strdup (ctx->volume_name);
- }
- break;
-
- case GD_OP_STOP_VOLUME:
- {
- 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;
- }
+ gf_strdup (ctx1->volume_name);
}
break;
case GD_OP_DELETE_VOLUME:
{
- glusterd_op_delete_volume_ctx_t *ctx = NULL;
- ctx = glusterd_op_get_ctx (op);
- GF_ASSERT (ctx);
+ glusterd_op_delete_volume_ctx_t *ctx1 = ctx;
stage_req->buf.buf_len =
- strlen (ctx->volume_name);
+ strlen (ctx1->volume_name);
stage_req->buf.buf_val =
- gf_strdup (ctx->volume_name);
+ gf_strdup (ctx1->volume_name);
}
break;
+ case GD_OP_STOP_VOLUME:
case GD_OP_ADD_BRICK:
- {
- dict_t *dict = NULL;
- dict = glusterd_op_get_ctx (op);
- GF_ASSERT (dict);
- ret = dict_allocate_and_serialize (dict,
- &stage_req->buf.buf_val,
- (size_t *)&stage_req->buf.buf_len);
- if (ret) {
- goto out;
- }
- }
- break;
-
case GD_OP_REPLACE_BRICK:
- {
- dict_t *dict = NULL;
- dict = glusterd_op_get_ctx (op);
- GF_ASSERT (dict);
- ret = dict_allocate_and_serialize (dict,
- &stage_req->buf.buf_val,
- (size_t *)&stage_req->buf.buf_len);
- if (ret) {
- goto out;
- }
- }
- break;
-
case GD_OP_SET_VOLUME:
- {
- dict_t *dict = NULL;
- dict = glusterd_op_get_ctx (op);
- GF_ASSERT (dict);
- ret = dict_allocate_and_serialize (dict,
- &stage_req->buf.buf_val,
- (size_t *)&stage_req->buf.buf_len);
- if (ret) {
- goto out;
- }
- }
- break;
-
case GD_OP_REMOVE_BRICK:
- {
- dict_t *dict = NULL;
- dict = glusterd_op_get_ctx (op);
- GF_ASSERT (dict);
- ret = dict_allocate_and_serialize (dict,
- &stage_req->buf.buf_val,
- (size_t *)&stage_req->buf.buf_len);
- if (ret) {
- goto out;
- }
- }
- break;
-
case GD_OP_LOG_FILENAME:
- {
- dict_t *dict = NULL;
- dict = glusterd_op_get_ctx (op);
- GF_ASSERT (dict);
- ret = dict_allocate_and_serialize (dict,
- &stage_req->buf.buf_val,
- (size_t *)&stage_req->buf.buf_len);
- if (ret) {
- goto out;
- }
- }
- break;
-
case GD_OP_LOG_ROTATE:
+ case GD_OP_SYNC_VOLUME:
{
- dict_t *dict = NULL;
- dict = glusterd_op_get_ctx (op);
- GF_ASSERT (dict);
+ dict_t *dict = ctx;
ret = dict_allocate_and_serialize (dict,
- &stage_req->buf.buf_val,
+ &stage_req->buf.buf_val,
(size_t *)&stage_req->buf.buf_len);
if (ret) {
goto out;
@@ -334,31 +274,6 @@ out:
}
static int
-glusterd_check_generate_start_nfs (glusterd_volinfo_t *volinfo)
-{
- int ret = -1;
-
- if (!volinfo) {
- gf_log ("", GF_LOG_ERROR, "Invalid Arguments");
- goto out;
- }
-
- ret = volgen_generate_nfs_volfile (volinfo);
- if (ret)
- goto out;
-
- if (glusterd_is_nfs_started ()) {
- ret = glusterd_nfs_server_stop ();
- if (ret)
- goto out;
- }
-
- ret = glusterd_nfs_server_start ();
-out:
- return ret;
-}
-
-static int
glusterd_op_stage_create_volume (gd1_mgmt_stage_op_req *req, char **op_errstr)
{
int ret = 0;
@@ -455,8 +370,9 @@ glusterd_op_stage_create_volume (gd1_mgmt_stage_op_req *req, char **op_errstr)
snprintf (cmd_str, 1024, "%s", brick_info->path);
ret = glusterd_resolve_brick (brick_info);
if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR,
- "cannot resolve brick");
+ gf_log ("glusterd", GF_LOG_ERROR, "cannot resolve "
+ "brick: %s:%s", brick_info->hostname,
+ brick_info->path);
goto out;
}
@@ -466,7 +382,7 @@ glusterd_op_stage_create_volume (gd1_mgmt_stage_op_req *req, char **op_errstr)
snprintf (msg, 2048,"Volume name %s, brick"
": %s:%s, path %s not present", volname,
brick_info->hostname, brick_info->path, brick_info->path);
- gf_log ("glusterd",GF_LOG_ERROR, "%s", msg);
+ gf_log ("glusterd",GF_LOG_ERROR, "%s", msg);
*op_errstr = gf_strdup (msg);
goto out;
}
@@ -722,7 +638,7 @@ glusterd_op_stage_add_brick (gd1_mgmt_stage_op_req *req, char **op_errstr)
struct stat st_buf = {0,};
char cmd_str[1024];
glusterd_conf_t *priv = NULL;
- char msg[2048];
+ char msg[2048] = {0,};
GF_ASSERT (req);
@@ -928,7 +844,7 @@ out:
static int
glusterd_op_stage_log_filename (gd1_mgmt_stage_op_req *req)
{
- int ret = 0;
+ int ret = -1;
dict_t *dict = NULL;
char *volname = NULL;
gf_boolean_t exists = _gf_false;
@@ -970,7 +886,7 @@ out:
static int
glusterd_op_stage_log_rotate (gd1_mgmt_stage_op_req *req)
{
- int ret = 0;
+ int ret = -1;
dict_t *dict = NULL;
char *volname = NULL;
gf_boolean_t exists = _gf_false;
@@ -1134,7 +1050,7 @@ glusterd_check_option_exists(char *optstring)
static int
glusterd_op_stage_remove_brick (gd1_mgmt_stage_op_req *req)
{
- int ret = 0;
+ int ret = -1;
dict_t *dict = NULL;
char *volname = NULL;
glusterd_volinfo_t *volinfo = NULL;
@@ -1203,6 +1119,80 @@ out:
}
static int
+glusterd_op_stage_sync_volume (gd1_mgmt_stage_op_req *req, char **op_errstr)
+{
+ int ret = -1;
+ dict_t *dict = NULL;
+ char *volname = NULL;
+ char *hostname = NULL;
+ gf_boolean_t exists = _gf_false;
+ glusterd_peerinfo_t *peerinfo = NULL;
+ char msg[2048] = {0,};
+
+ GF_ASSERT (req);
+
+ dict = dict_new ();
+ if (!dict)
+ 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, "hostname", &hostname);
+ if (ret) {
+ snprintf (msg, sizeof (msg), "hostname couldn't be "
+ "retrieved from msg");
+ *op_errstr = gf_strdup (msg);
+ goto out;
+ }
+
+ ret = glusterd_is_local_addr (hostname);
+ if (ret) {
+ ret = glusterd_friend_find (NULL, hostname, &peerinfo);
+ if (ret) {
+ snprintf (msg, sizeof (msg), "%s, is not a friend",
+ hostname);
+ *op_errstr = gf_strdup (msg);
+ goto out;
+ }
+
+ if (!peerinfo->connected) {
+ snprintf (msg, sizeof (msg), "%s, is not connected at "
+ "the moment", hostname);
+ *op_errstr = gf_strdup (msg);
+ ret = -1;
+ goto out;
+ }
+ } else {
+
+ //volname is not present in case of sync all
+ ret = dict_get_str (dict, "volname", &volname);
+ if (!ret) {
+ exists = glusterd_check_volume_exists (volname);
+ if (!exists) {
+ snprintf (msg, sizeof (msg), "volume: %s, "
+ "doesn't exist", volname);
+ *op_errstr = gf_strdup (msg);
+ ret = -1;
+ goto out;
+ }
+ } else {
+ ret = 0;
+ }
+ }
+
+out:
+ if (dict)
+ dict_unref (dict);
+ gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+
+ return ret;
+}
+
+static int
glusterd_op_create_volume (gd1_mgmt_stage_op_req *req, char **op_errstr)
{
int ret = 0;
@@ -2390,7 +2380,7 @@ glusterd_op_set_volume (gd1_mgmt_stage_op_req *req)
dict = dict_new ();
if (!dict)
goto out;
-
+
ret = dict_unserialize (req->buf.buf_val, req->buf.buf_len, &dict);
if (ret) {
@@ -2454,9 +2444,9 @@ glusterd_op_set_volume (gd1_mgmt_stage_op_req *req)
ret = -1;
goto out;
}
-
-
+
+
gf_log ("", GF_LOG_DEBUG, "Received set volume command");
@@ -2469,7 +2459,7 @@ out:
static int
glusterd_op_remove_brick (gd1_mgmt_stage_op_req *req)
{
- int ret = 0;
+ int ret = -1;
dict_t *dict = NULL;
char *volname = NULL;
glusterd_conf_t *priv = NULL;
@@ -2642,18 +2632,17 @@ glusterd_op_start_volume (gd1_mgmt_stage_op_req *req, char **op_errstr)
{
int ret = 0;
char volname[1024] = {0,};
- glusterd_conf_t *priv = NULL;
glusterd_volinfo_t *volinfo = NULL;
+ glusterd_conf_t *priv = NULL;
glusterd_brickinfo_t *brickinfo = NULL;
xlator_t *this = NULL;
int32_t mybrick = 0;
- GF_ASSERT (req);
-
this = THIS;
GF_ASSERT (this);
priv = this->private;
GF_ASSERT (priv);
+ GF_ASSERT (req);
strncpy (volname, req->buf.buf_val, req->buf.buf_len);
@@ -2661,8 +2650,18 @@ glusterd_op_start_volume (gd1_mgmt_stage_op_req *req, char **op_errstr)
if (ret)
goto out;
-
list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
+ if (uuid_is_null (brickinfo->uuid)) {
+ ret = glusterd_resolve_brick (brickinfo);
+ if (ret) {
+ gf_log ("glusterd", GF_LOG_ERROR,
+ "cannot resolve brick: %s:%s",
+ brickinfo->hostname, brickinfo->path);
+ goto out;
+ }
+
+ }
+
if (!uuid_compare (brickinfo->uuid, priv->uuid)) {
gf_log ("", GF_LOG_NORMAL, "About to start glusterfs"
" for brick %s:%s", brickinfo->hostname,
@@ -2697,7 +2696,7 @@ out:
static int
glusterd_op_log_filename (gd1_mgmt_stage_op_req *req)
{
- int ret = 0;
+ int ret = -1;
dict_t *dict = NULL;
glusterd_conf_t *priv = NULL;
glusterd_volinfo_t *volinfo = NULL;
@@ -2785,7 +2784,7 @@ out:
static int
glusterd_op_log_rotate (gd1_mgmt_stage_op_req *req)
{
- int ret = 0;
+ int ret = -1;
dict_t *dict = NULL;
glusterd_conf_t *priv = NULL;
glusterd_volinfo_t *volinfo = NULL;
@@ -2901,10 +2900,10 @@ glusterd_op_stop_volume (gd1_mgmt_stage_op_req *req)
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;
dict_t *dict = NULL;
+ glusterd_brickinfo_t *brickinfo = NULL;
+ int32_t mybrick = 0;
this = THIS;
GF_ASSERT (this);
@@ -2925,6 +2924,16 @@ glusterd_op_stop_volume (gd1_mgmt_stage_op_req *req)
goto out;
list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
+ if (uuid_is_null (brickinfo->uuid)) {
+ ret = glusterd_resolve_brick (brickinfo);
+ if (ret) {
+ gf_log ("glusterd", GF_LOG_ERROR,
+ "cannot resolve brick: %s:%s",
+ brickinfo->hostname, brickinfo->path);
+ goto out;
+ }
+
+ }
if (!uuid_compare (brickinfo->uuid, priv->uuid)) {
gf_log ("", GF_LOG_NORMAL, "About to stop glusterfs"
" for brick %s:%s", brickinfo->hostname,
@@ -2957,7 +2966,6 @@ glusterd_op_stop_volume (gd1_mgmt_stage_op_req *req)
} else {
ret = glusterd_check_generate_start_nfs (volinfo);
}
-
out:
if (flags & GF_CLI_FLAG_OP_FORCE)
ret = 0;
@@ -2967,6 +2975,91 @@ out:
}
static int
+glusterd_op_sync_volume (gd1_mgmt_stage_op_req *req, char **op_errstr,
+ dict_t *rsp_dict)
+{
+ int ret = -1;
+ dict_t *dict = NULL;
+ char *volname = NULL;
+ char *hostname = NULL;
+ char msg[2048] = {0,};
+ int count = 1;
+ int vol_count = 0;
+ glusterd_conf_t *priv = NULL;
+ glusterd_volinfo_t *volinfo = NULL;
+ xlator_t *this = NULL;
+
+ GF_ASSERT (req);
+ this = THIS;
+ GF_ASSERT (this);
+ priv = this->private;
+ GF_ASSERT (priv);
+
+
+ dict = dict_new ();
+ if (!dict)
+ 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, "hostname", &hostname);
+ if (ret) {
+ snprintf (msg, sizeof (msg), "hostname couldn't be "
+ "retrieved from msg");
+ *op_errstr = gf_strdup (msg);
+ goto out;
+ }
+
+ if (glusterd_is_local_addr (hostname)) {
+ ret = 0;
+ goto out;
+ }
+
+ //volname is not present in case of sync all
+ ret = dict_get_str (dict, "volname", &volname);
+ if (!ret) {
+ ret = glusterd_volinfo_find (volname, &volinfo);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Volume with name: %s "
+ "not exists", volname);
+ goto out;
+ }
+ }
+
+ if (!rsp_dict) {
+ //this should happen only on source
+ ret = 0;
+ goto out;
+ }
+
+ if (volname) {
+ ret = glusterd_add_volume_to_dict (volinfo, rsp_dict,
+ 1);
+ vol_count = 1;
+ } else {
+ list_for_each_entry (volinfo, &priv->volumes, vol_list) {
+ ret = glusterd_add_volume_to_dict (volinfo,
+ rsp_dict, count);
+ if (ret)
+ goto out;
+
+ vol_count = count++;
+ }
+ }
+ ret = dict_set_int32 (rsp_dict, "count", vol_count);
+out:
+ if (dict)
+ dict_unref (dict);
+ gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+
+ return ret;
+}
+
+static int
glusterd_op_ac_none (glusterd_op_sm_event_t *event, void *ctx)
{
int ret = 0;
@@ -3475,6 +3568,19 @@ glusterd_op_send_cli_response (int32_t op, int32_t op_ret,
sfunc = gf_xdr_serialize_cli_log_rotate_rsp;
break;
}
+ case GD_MGMT_CLI_SYNC_VOLUME:
+ {
+ gf1_cli_sync_volume_rsp rsp = {0,};
+ rsp.op_ret = op_ret;
+ rsp.op_errno = op_errno;
+ if (op_errstr)
+ rsp.op_errstr = op_errstr;
+ else
+ rsp.op_errstr = "";
+ cli_rsp = &rsp;
+ sfunc = gf_xdr_from_cli_sync_volume_rsp;
+ break;
+ }
}
ret = glusterd_submit_reply (req, cli_rsp, NULL, 0, NULL,
@@ -3635,6 +3741,7 @@ glusterd_op_ac_commit_op (glusterd_op_sm_event_t *event, void *ctx)
glusterd_op_commit_ctx_t *commit_ctx = NULL;
int32_t status = 0;
char *op_errstr = NULL;
+ dict_t *rsp_dict = NULL;
GF_ASSERT (ctx);
@@ -3642,14 +3749,27 @@ glusterd_op_ac_commit_op (glusterd_op_sm_event_t *event, void *ctx)
req = &commit_ctx->stage_req;
- status = glusterd_op_commit_perform (req, &op_errstr);
+ rsp_dict = dict_new ();
+ if (!rsp_dict) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Out of memory");
+ ret = -1;
+ goto out;
+ }
+
+
+ status = glusterd_op_commit_perform (req, &op_errstr, rsp_dict);
if (status) {
gf_log ("", GF_LOG_ERROR, "Commit failed: %d", status);
}
- ret = glusterd_op_commit_send_resp (commit_ctx->req, req->op, status, op_errstr);
+ ret = glusterd_op_commit_send_resp (commit_ctx->req, req->op, status,
+ op_errstr, rsp_dict);
+out:
+ if (rsp_dict)
+ dict_unref (rsp_dict);
if (op_errstr && (strcmp (op_errstr, "")))
GF_FREE (op_errstr);
@@ -3723,6 +3843,10 @@ glusterd_op_stage_validate (gd1_mgmt_stage_op_req *req, char **op_errstr)
ret = glusterd_op_stage_log_rotate (req);
break;
+ case GD_OP_SYNC_VOLUME:
+ ret = glusterd_op_stage_sync_volume (req, op_errstr);
+ break;
+
default:
gf_log ("", GF_LOG_ERROR, "Unknown op %d",
req->op);
@@ -3735,7 +3859,8 @@ glusterd_op_stage_validate (gd1_mgmt_stage_op_req *req, char **op_errstr)
int32_t
-glusterd_op_commit_perform (gd1_mgmt_stage_op_req *req, char **op_errstr)
+glusterd_op_commit_perform (gd1_mgmt_stage_op_req *req, char **op_errstr,
+ dict_t *rsp_dict)
{
int ret = -1;
@@ -3782,6 +3907,10 @@ glusterd_op_commit_perform (gd1_mgmt_stage_op_req *req, char **op_errstr)
ret = glusterd_op_log_rotate (req);
break;
+ case GD_OP_SYNC_VOLUME:
+ ret = glusterd_op_sync_volume (req, op_errstr, rsp_dict);
+ break;
+
default:
gf_log ("", GF_LOG_ERROR, "Unknown op %d",
req->op);
@@ -4191,6 +4320,7 @@ glusterd_op_free_ctx (glusterd_op_t op, void *ctx, gf_boolean_t ctx_free)
case GD_OP_REPLACE_BRICK:
case GD_OP_LOG_FILENAME:
case GD_OP_LOG_ROTATE:
+ case GD_OP_SYNC_VOLUME:
dict_unref (ctx);
break;
case GD_OP_DELETE_VOLUME:
diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.h b/xlators/mgmt/glusterd/src/glusterd-op-sm.h
index e14f00759..2f39d24f7 100644
--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.h
+++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.h
@@ -196,7 +196,8 @@ int32_t
glusterd_op_stage_validate (gd1_mgmt_stage_op_req *req, char **op_errstr);
int32_t
-glusterd_op_commit_perform (gd1_mgmt_stage_op_req *req, char **op_errstr);
+glusterd_op_commit_perform (gd1_mgmt_stage_op_req *req, char **op_errstr,
+ dict_t* dict);
void *
glusterd_op_get_ctx (glusterd_op_t op);
diff --git a/xlators/mgmt/glusterd/src/glusterd-sm.c b/xlators/mgmt/glusterd/src/glusterd-sm.c
index 602494b14..025fee775 100644
--- a/xlators/mgmt/glusterd/src/glusterd-sm.c
+++ b/xlators/mgmt/glusterd/src/glusterd-sm.c
@@ -620,6 +620,60 @@ glusterd_destroy_friend_event_context (glusterd_friend_sm_event_t *event)
}
int
+glusterd_check_and_add_friend (glusterd_friend_sm_event_t *event)
+{
+ rpcsvc_request_t *req = NULL;
+ glusterd_peerinfo_t *peerinfo = NULL;
+ glusterd_friend_sm_event_type_t event_type = 0;
+ glusterd_friend_req_ctx_t *fr_ctx = NULL;
+ glusterd_probe_ctx_t *pb_ctx = NULL;
+ gf_boolean_t add_friend = _gf_false;
+ char rhost[UNIX_PATH_MAX + 1] = {0};
+ char *host_str = NULL;
+ int port = 6969; //TODO, use standard
+ int ret = 0;
+
+ peerinfo = event->peerinfo;
+ event_type = event->event;
+
+ if (!peerinfo &&
+ (GD_FRIEND_EVENT_PROBE == event_type)) {
+ add_friend = _gf_true;
+ pb_ctx = event->ctx;
+ req = pb_ctx->req;
+ }
+ if (!peerinfo &&
+ (GD_FRIEND_EVENT_RCVD_FRIEND_REQ == event_type)) {
+ add_friend = _gf_true;
+ fr_ctx = event->ctx;
+ req = fr_ctx->req;
+ }
+ if (add_friend) {
+ if (req) {
+ ret = glusterd_remote_hostname_get (req, rhost,
+ sizeof (rhost));
+ if (!ret)
+ host_str = rhost;
+ }
+ ret = glusterd_friend_add ((const char*)host_str, port,
+ GD_FRIEND_STATE_DEFAULT,
+ NULL, NULL, &peerinfo, 0);
+ if (ret) {
+ gf_log ("glusterd", GF_LOG_ERROR, "Unable to add peer, "
+ "ret = %d", ret);
+ ret = 1;
+ goto out;
+ }
+ GF_ASSERT (peerinfo);
+ event->peerinfo = peerinfo;
+ }
+ ret = 0;
+
+out:
+ return ret;
+}
+
+int
glusterd_friend_sm ()
{
glusterd_friend_sm_event_t *event = NULL;
@@ -629,32 +683,21 @@ glusterd_friend_sm ()
glusterd_sm_t *state = NULL;
glusterd_peerinfo_t *peerinfo = NULL;
glusterd_friend_sm_event_type_t event_type = 0;
- int port = 6969; //TODO, use standard
gf_boolean_t is_await_conn = _gf_false;
+ int loop = 0;
while (!list_empty (&gd_friend_sm_queue)) {
list_for_each_entry_safe (event, tmp, &gd_friend_sm_queue, list) {
list_del_init (&event->list);
- peerinfo = event->peerinfo;
event_type = event->event;
- if (!peerinfo &&
- (GD_FRIEND_EVENT_PROBE == event_type ||
- GD_FRIEND_EVENT_RCVD_FRIEND_REQ == event_type)) {
- ret = glusterd_friend_add (NULL, port,
- GD_FRIEND_STATE_DEFAULT,
- NULL, NULL, &peerinfo, 0);
-
- if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR, "Unable to add peer, "
- "ret = %d", ret);
- continue;
- }
- GF_ASSERT (peerinfo);
- event->peerinfo = peerinfo;
- }
+ loop = glusterd_check_and_add_friend (event);
+ if (loop)
+ continue;
+
+ peerinfo = event->peerinfo;
if (!peerinfo)
goto out;
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
index 017ab6873..358d6ffe4 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
@@ -1000,6 +1000,7 @@ glusterd_is_cli_op_req (int32_t op)
case GD_MGMT_CLI_LOG_FILENAME:
case GD_MGMT_CLI_LOG_LOCATE:
case GD_MGMT_CLI_LOG_ROTATE:
+ case GD_MGMT_CLI_SYNC_VOLUME:
return _gf_true;
break;
}
@@ -1452,7 +1453,6 @@ out:
return ret;
}
-
int32_t
glusterd_import_friend_volumes (dict_t *vols)
{
@@ -1470,7 +1470,6 @@ glusterd_import_friend_volumes (dict_t *vols)
ret = glusterd_import_friend_volume (vols, i);
if (ret)
goto out;
-
i++;
}
@@ -1645,27 +1644,6 @@ glusterd_nfs_server_stop ()
return glusterd_service_stop ("nfsd", pidfile, SIGTERM, _gf_false);
}
-gf_boolean_t
-glusterd_are_all_volumes_stopped ()
-{
- glusterd_conf_t *priv = NULL;
- xlator_t *this = NULL;
- glusterd_volinfo_t *voliter = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- list_for_each_entry (voliter, &priv->volumes, vol_list) {
- if (voliter->status == GLUSTERD_STATUS_STARTED)
- return _gf_false;
- }
-
- return _gf_true;
-
-}
-
int
glusterd_remote_hostname_get (rpcsvc_request_t *req, char *remote_host, int len)
{
@@ -1691,3 +1669,50 @@ glusterd_remote_hostname_get (rpcsvc_request_t *req, char *remote_host, int len)
return 0;
}
+int
+glusterd_check_generate_start_nfs (glusterd_volinfo_t *volinfo)
+{
+ int ret = -1;
+
+ if (!volinfo) {
+ gf_log ("", GF_LOG_ERROR, "Invalid Arguments");
+ goto out;
+ }
+
+ ret = volgen_generate_nfs_volfile (volinfo);
+ if (ret)
+ goto out;
+
+ if (glusterd_is_nfs_started ()) {
+ ret = glusterd_nfs_server_stop ();
+ if (ret)
+ goto out;
+ }
+
+ ret = glusterd_nfs_server_start ();
+out:
+ return ret;
+}
+
+int
+glusterd_volume_count_get (void)
+{
+ glusterd_volinfo_t *tmp_volinfo = NULL;
+ int32_t ret = 0;
+ xlator_t *this = NULL;
+ glusterd_conf_t *priv = NULL;
+
+ this = THIS;
+ GF_ASSERT (this);
+
+ priv = this->private;
+
+ list_for_each_entry (tmp_volinfo, &priv->volumes, vol_list) {
+ ret++;
+ }
+
+
+ gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+
+}
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h
index a74fa871f..e03968dfe 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.h
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.h
@@ -143,10 +143,19 @@ glusterd_nfs_server_stop ();
int
glusterd_file_copy (int out, int in);
-gf_boolean_t
-glusterd_are_all_volumes_stopped ();
-
int
glusterd_remote_hostname_get (rpcsvc_request_t *req,
char *remote_host, int len);
+int32_t
+glusterd_import_friend_volumes (dict_t *vols);
+void
+glusterd_set_volume_status (glusterd_volinfo_t *volinfo,
+ glusterd_volume_status status);
+int
+glusterd_check_generate_start_nfs (glusterd_volinfo_t *volinfo);
+int32_t
+glusterd_volume_count_get (void);
+int32_t
+glusterd_add_volume_to_dict (glusterd_volinfo_t *volinfo,
+ dict_t *dict, int32_t count);
#endif
diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h
index cfa229301..48d78bc33 100644
--- a/xlators/mgmt/glusterd/src/glusterd.h
+++ b/xlators/mgmt/glusterd/src/glusterd.h
@@ -296,7 +296,8 @@ glusterd_xfer_cli_probe_resp (rpcsvc_request_t *req, int32_t op_ret,
int
glusterd_op_commit_send_resp (rpcsvc_request_t *req,
- int32_t op, int32_t status, char *op_errstr);
+ int32_t op, int32_t status, char *op_errstr,
+ dict_t *rsp_dict);
int
glusterd_xfer_friend_remove_resp (rpcsvc_request_t *req, char *hostname, int port);
@@ -365,8 +366,12 @@ glusterd_handle_log_locate (rpcsvc_request_t *req);
int
glusterd_handle_log_rotate (rpcsvc_request_t *req);
+int
+glusterd_handle_sync_volume (rpcsvc_request_t *req);
+
int32_t
glusterd_log_filename (rpcsvc_request_t *req, dict_t *dict);
+
int32_t
glusterd_log_rotate (rpcsvc_request_t *req, dict_t *dict);
@@ -386,4 +391,9 @@ glusterd_xfer_cli_deprobe_resp (rpcsvc_request_t *req, int32_t op_ret,
int
glusterd_fetchspec_notify (xlator_t *this);
+int32_t
+glusterd_sync_volume (rpcsvc_request_t *req, dict_t *ctx);
+int
+glusterd_add_volume_detail_to_dict (glusterd_volinfo_t *volinfo,
+ dict_t *volumes, int count);
#endif
diff --git a/xlators/mgmt/glusterd/src/glusterd3_1-mops.c b/xlators/mgmt/glusterd/src/glusterd3_1-mops.c
index 244b71009..99b5f7b4e 100644
--- a/xlators/mgmt/glusterd/src/glusterd3_1-mops.c
+++ b/xlators/mgmt/glusterd/src/glusterd3_1-mops.c
@@ -553,6 +553,23 @@ out:
}
static int32_t
+glusterd_sync_use_rsp_dict (dict_t *rsp_dict)
+{
+ int ret = 0;
+
+ GF_ASSERT (rsp_dict);
+
+ if (!rsp_dict) {
+ goto out;
+ }
+
+ ret = glusterd_import_friend_volumes (rsp_dict);
+out:
+ return ret;
+
+}
+
+static int32_t
glusterd_rb_use_rsp_dict (dict_t *rsp_dict)
{
int32_t src_port = 0;
@@ -663,10 +680,19 @@ glusterd3_1_commit_op_cbk (struct rpc_req *req, struct iovec *iov,
goto out;
}
} else {
- if (rsp.op == GD_OP_REPLACE_BRICK) {
+ switch (rsp.op) {
+ case GD_OP_REPLACE_BRICK:
ret = glusterd_rb_use_rsp_dict (dict);
if (ret)
goto out;
+ break;
+ case GD_OP_SYNC_VOLUME:
+ ret = glusterd_sync_use_rsp_dict (dict);
+ if (ret)
+ goto out;
+ break;
+ default:
+ break;
}
event_type = GD_OP_EVENT_RCVD_ACC;
}
@@ -956,7 +982,8 @@ glusterd3_1_cluster_lock (call_frame_t *frame, xlator_t *this,
list_for_each_entry (peerinfo, &priv->peers, uuid_list) {
GF_ASSERT (peerinfo);
- if (peerinfo->state.state != GD_FRIEND_STATE_BEFRIENDED)
+ if ((peerinfo->state.state != GD_FRIEND_STATE_BEFRIENDED) &&
+ (glusterd_op_get_op() != GD_OP_SYNC_VOLUME))
continue;
dummy_frame = create_frame (this, this->ctx->pool);
@@ -1007,7 +1034,8 @@ glusterd3_1_cluster_unlock (call_frame_t *frame, xlator_t *this,
list_for_each_entry (peerinfo, &priv->peers, uuid_list) {
GF_ASSERT (peerinfo);
- if (peerinfo->state.state != GD_FRIEND_STATE_BEFRIENDED)
+ if ((peerinfo->state.state != GD_FRIEND_STATE_BEFRIENDED) &&
+ (glusterd_op_get_op() != GD_OP_SYNC_VOLUME))
continue;
dummy_frame = create_frame (this, this->ctx->pool);
@@ -1091,7 +1119,8 @@ glusterd3_1_stage_op (call_frame_t *frame, xlator_t *this,
list_for_each_entry (peerinfo, &priv->peers, uuid_list) {
GF_ASSERT (peerinfo);
- if (peerinfo->state.state != GD_FRIEND_STATE_BEFRIENDED)
+ if ((peerinfo->state.state != GD_FRIEND_STATE_BEFRIENDED) &&
+ (glusterd_op_get_op() != GD_OP_SYNC_VOLUME))
continue;
dummy_frame = create_frame (this, this->ctx->pool);
@@ -1171,7 +1200,8 @@ glusterd3_1_commit_op (call_frame_t *frame, xlator_t *this,
if (ret)
goto out;
- ret = glusterd_op_commit_perform ((gd1_mgmt_stage_op_req *)req, &op_errstr);
+ ret = glusterd_op_commit_perform ((gd1_mgmt_stage_op_req *)req, &op_errstr,
+ NULL);//rsp_dict invalid for source
if (ret) {
gf_log ("", GF_LOG_ERROR, "Commit failed");
@@ -1182,7 +1212,8 @@ glusterd3_1_commit_op (call_frame_t *frame, xlator_t *this,
list_for_each_entry (peerinfo, &priv->peers, uuid_list) {
GF_ASSERT (peerinfo);
- if (peerinfo->state.state != GD_FRIEND_STATE_BEFRIENDED)
+ if ((peerinfo->state.state != GD_FRIEND_STATE_BEFRIENDED) &&
+ (glusterd_op_get_op() != GD_OP_SYNC_VOLUME))
continue;
dummy_frame = create_frame (this, this->ctx->pool);
@@ -1339,6 +1370,10 @@ glusterd_handle_rpc_msg (rpcsvc_request_t *req)
ret = glusterd_handle_set_volume (req);
break;
+ case GD_MGMT_CLI_SYNC_VOLUME:
+ ret = glusterd_handle_sync_volume (req);
+ break;
+
default:
gf_log("", GF_LOG_ERROR, "Recieved Invalid procnum:%d",
req->procnum);
@@ -1393,7 +1428,7 @@ rpcsvc_actor_t glusterd1_mgmt_actors[] = {
[GD_MGMT_CLI_LOG_LOCATE] = { "LOG LOCATE", GD_MGMT_CLI_LOG_LOCATE, glusterd_handle_log_locate, NULL, NULL},
[GD_MGMT_CLI_LOG_ROTATE] = { "LOG FILENAME", GD_MGMT_CLI_LOG_ROTATE, glusterd_handle_rpc_msg, NULL, NULL},
[GD_MGMT_CLI_SET_VOLUME] = { "SET_VOLUME", GD_MGMT_CLI_SET_VOLUME, glusterd_handle_rpc_msg, NULL, NULL},
-
+ [GD_MGMT_CLI_SYNC_VOLUME] = { "SYNC_VOLUME", GD_MGMT_CLI_SYNC_VOLUME, glusterd_handle_rpc_msg, NULL, NULL},
};
/*rpcsvc_actor_t glusterd1_mgmt_actors[] = {