summaryrefslogtreecommitdiffstats
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
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
-rw-r--r--cli/src/cli-cmd-volume.c50
-rw-r--r--cli/src/cli3_1-cops.c54
-rw-r--r--glusterfsd/src/glusterfsd-mgmt.c8
-rw-r--r--glusterfsd/src/glusterfsd.c2
-rw-r--r--rpc/rpc-lib/src/protocol-common.h2
-rw-r--r--rpc/xdr/src/cli1-xdr.c39
-rw-r--r--rpc/xdr/src/cli1-xdr.h25
-rw-r--r--rpc/xdr/src/cli1.c28
-rw-r--r--rpc/xdr/src/cli1.h10
-rw-r--r--rpc/xdr/src/cli1.x18
-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
18 files changed, 810 insertions, 225 deletions
diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c
index fc7fda9dfc2..28104c18704 100644
--- a/cli/src/cli-cmd-volume.c
+++ b/cli/src/cli-cmd-volume.c
@@ -131,6 +131,52 @@ out:
}
+
+void
+cli_cmd_sync_volume_usage ()
+{
+ cli_out ("Usage: volume sync <HOSTNAME> [all|<VOLNAME>]");
+}
+
+int
+cli_cmd_sync_volume_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;
+ gf1_cli_sync_volume_req req = {0,};
+
+ if ((wordcount < 3) || (wordcount > 4)) {
+ cli_cmd_sync_volume_usage ();
+ goto out;
+ }
+
+ if ((wordcount == 3) || !strcmp(words[3], "all")) {
+ req.flags = GF_CLI_SYNC_ALL;
+ req.volname = "";
+ } else {
+ req.volname = (char *)words[3];
+ }
+
+ req.hostname = (char *)words[2];
+
+ proc = &cli_rpc_prog->proctable[GF1_CLI_SYNC_VOLUME];
+
+ frame = create_frame (THIS, THIS->ctx->pool);
+ if (!frame)
+ goto out;
+
+ if (proc->fn) {
+ ret = proc->fn (frame, THIS, &req);
+ }
+
+out:
+ if (ret)
+ cli_out ("Volume sync failed");
+
+ return ret;
+}
void
cli_cmd_volume_create_usage ()
{
@@ -826,6 +872,10 @@ struct cli_cmd volume_cmds[] = {
cli_cmd_log_rotate_cbk,
"rotate the log file for corresponding volume/brick"},
+ { "volume sync <HOSTNAME> [all|<VOLNAME>]",
+ cli_cmd_sync_volume_cbk,
+ "sync the volume information from a peer"},
+
{ NULL, NULL, NULL }
};
diff --git a/cli/src/cli3_1-cops.c b/cli/src/cli3_1-cops.c
index 0898f2b943a..832618c2446 100644
--- a/cli/src/cli3_1-cops.c
+++ b/cli/src/cli3_1-cops.c
@@ -1032,6 +1032,36 @@ out:
return ret;
}
+static int
+gf_cli3_1_sync_volume_cbk (struct rpc_req *req, struct iovec *iov,
+ int count, void *myframe)
+{
+ gf1_cli_sync_volume_rsp rsp = {0,};
+ int ret = -1;
+
+ if (-1 == req->rpc_status) {
+ goto out;
+ }
+
+ ret = gf_xdr_to_cli_sync_volume_rsp (*iov, &rsp);
+ if (ret < 0) {
+ gf_log ("", GF_LOG_ERROR, "error");
+ goto out;
+ }
+
+ gf_log ("cli", GF_LOG_DEBUG, "Received resp to sync");
+ cli_out ("volume sync: %s",
+ (rsp.op_ret) ? "unsuccessful": "successful");
+
+ if (rsp.op_ret && rsp.op_errstr)
+ cli_out (rsp.op_errstr);
+ ret = rsp.op_ret;
+
+out:
+ cli_cmd_broadcast_response (ret);
+ return ret;
+}
+
int
gf_cli3_1_getspec_cbk (struct rpc_req *req, struct iovec *iov,
int count, void *myframe)
@@ -1881,6 +1911,28 @@ out:
}
int32_t
+gf_cli3_1_sync_volume (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ int ret = 0;
+
+ if (!frame || !this || !data) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = cli_cmd_submit ((gf1_cli_sync_volume_req*)data, frame,
+ cli_rpc_prog, GD_MGMT_CLI_SYNC_VOLUME,
+ NULL, gf_xdr_from_cli_sync_volume_req,
+ this, gf_cli3_1_sync_volume_cbk);
+
+out:
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+
+ return ret;
+}
+
+int32_t
gf_cli3_1_getspec (call_frame_t *frame, xlator_t *this,
void *data)
{
@@ -1939,7 +1991,6 @@ out:
return ret;
}
-
struct rpc_clnt_procedure gluster3_1_cli_actors[GF1_CLI_MAXVALUE] = {
[GF1_CLI_NULL] = {"NULL", NULL },
[GF1_CLI_PROBE] = { "PROBE_QUERY", gf_cli3_1_probe},
@@ -1962,6 +2013,7 @@ struct rpc_clnt_procedure gluster3_1_cli_actors[GF1_CLI_MAXVALUE] = {
[GF1_CLI_LOG_ROTATE] = {"LOG ROTATE", gf_cli3_1_log_rotate},
[GF1_CLI_GETSPEC] = {"GETSPEC", gf_cli3_1_getspec},
[GF1_CLI_PMAP_PORTBYBRICK] = {"PMAP PORTBYBRICK", gf_cli3_1_pmap_b2p},
+ [GF1_CLI_SYNC_VOLUME] = {"SYNC_VOLUME", gf_cli3_1_sync_volume},
};
struct rpc_clnt_program cli3_1_prog = {
diff --git a/glusterfsd/src/glusterfsd-mgmt.c b/glusterfsd/src/glusterfsd-mgmt.c
index 6e3cda951aa..d9cc83a8133 100644
--- a/glusterfsd/src/glusterfsd-mgmt.c
+++ b/glusterfsd/src/glusterfsd-mgmt.c
@@ -603,20 +603,20 @@ mgmt_pmap_signout_cbk (struct rpc_req *req, struct iovec *iov, int count,
ret = xdr_to_pmap_signout_rsp (*iov, &rsp);
if (ret < 0) {
- gf_log (frame->this->name, GF_LOG_ERROR, "error");
+ gf_log ("", GF_LOG_ERROR, "error");
rsp.op_ret = -1;
rsp.op_errno = EINVAL;
goto out;
}
if (-1 == rsp.op_ret) {
- gf_log (frame->this->name, GF_LOG_ERROR,
+ gf_log ("", GF_LOG_ERROR,
"failed to register the port with glusterd");
goto out;
}
out:
- if (frame)
- STACK_DESTROY (frame->root);
+// if (frame)
+// STACK_DESTROY (frame->root);
return 0;
}
diff --git a/glusterfsd/src/glusterfsd.c b/glusterfsd/src/glusterfsd.c
index 0fd739cb421..c0cb8a0db5f 100644
--- a/glusterfsd/src/glusterfsd.c
+++ b/glusterfsd/src/glusterfsd.c
@@ -642,7 +642,7 @@ cleanup_and_exit (int signum)
ctx = glusterfs_ctx_get ();
/* TODO: is this the right place? */
- // glusterfs_mgmt_pmap_signout (ctx);
+ glusterfs_mgmt_pmap_signout (ctx);
gf_log ("glusterfsd", GF_LOG_NORMAL, "shutting down");
diff --git a/rpc/rpc-lib/src/protocol-common.h b/rpc/rpc-lib/src/protocol-common.h
index 4b8f113d01e..632c1d42d97 100644
--- a/rpc/rpc-lib/src/protocol-common.h
+++ b/rpc/rpc-lib/src/protocol-common.h
@@ -102,6 +102,7 @@ enum gf_mgmt_procnum_ {
GD_MGMT_CLI_LOG_FILENAME,
GD_MGMT_CLI_LOG_LOCATE,
GD_MGMT_CLI_LOG_ROTATE,
+ GD_MGMT_CLI_SYNC_VOLUME,
GD_MGMT_MAXVALUE,
};
@@ -129,6 +130,7 @@ enum gf_cli_procnum {
GF1_CLI_LOG_ROTATE,
GF1_CLI_GETSPEC,
GF1_CLI_PMAP_PORTBYBRICK,
+ GF1_CLI_SYNC_VOLUME,
GF1_CLI_MAXVALUE,
};
diff --git a/rpc/xdr/src/cli1-xdr.c b/rpc/xdr/src/cli1-xdr.c
index 95c27e99ff1..93f7e76818a 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_sync_volume (XDR *xdrs, gf1_cli_sync_volume *objp)
+{
+
+ if (!xdr_enum (xdrs, (enum_t *) objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
xdr_gf1_cli_op_flags (XDR *xdrs, gf1_cli_op_flags *objp)
{
@@ -279,8 +288,8 @@ xdr_gf1_cli_start_vol_rsp (XDR *xdrs, gf1_cli_start_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;
}
@@ -512,6 +521,19 @@ xdr_gf1_cli_log_locate_req (XDR *xdrs, gf1_cli_log_locate_req *objp)
}
bool_t
+xdr_gf1_cli_sync_volume_req (XDR *xdrs, gf1_cli_sync_volume_req *objp)
+{
+
+ if (!xdr_int (xdrs, &objp->flags))
+ return FALSE;
+ if (!xdr_string (xdrs, &objp->volname, ~0))
+ return FALSE;
+ if (!xdr_string (xdrs, &objp->hostname, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
xdr_gf1_cli_log_locate_rsp (XDR *xdrs, gf1_cli_log_locate_rsp *objp)
{
@@ -547,3 +569,16 @@ xdr_gf1_cli_log_rotate_rsp (XDR *xdrs, gf1_cli_log_rotate_rsp *objp)
return FALSE;
return TRUE;
}
+
+bool_t
+xdr_gf1_cli_sync_volume_rsp (XDR *xdrs, gf1_cli_sync_volume_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;
+ return TRUE;
+}
diff --git a/rpc/xdr/src/cli1-xdr.h b/rpc/xdr/src/cli1-xdr.h
index 1b6145a6752..c6d8e8bf523 100644
--- a/rpc/xdr/src/cli1-xdr.h
+++ b/rpc/xdr/src/cli1-xdr.h
@@ -63,6 +63,11 @@ enum gf1_cli_get_volume {
};
typedef enum gf1_cli_get_volume gf1_cli_get_volume;
+enum gf1_cli_sync_volume {
+ GF_CLI_SYNC_ALL = 1,
+};
+typedef enum gf1_cli_sync_volume gf1_cli_sync_volume;
+
enum gf1_cli_op_flags {
GF_CLI_FLAG_OP_FORCE = 1,
};
@@ -311,6 +316,13 @@ struct gf1_cli_log_locate_req {
};
typedef struct gf1_cli_log_locate_req gf1_cli_log_locate_req;
+struct gf1_cli_sync_volume_req {
+ int flags;
+ char *volname;
+ char *hostname;
+};
+typedef struct gf1_cli_sync_volume_req gf1_cli_sync_volume_req;
+
struct gf1_cli_log_locate_rsp {
int op_ret;
int op_errno;
@@ -331,6 +343,13 @@ struct gf1_cli_log_rotate_rsp {
};
typedef struct gf1_cli_log_rotate_rsp gf1_cli_log_rotate_rsp;
+struct gf1_cli_sync_volume_rsp {
+ int op_ret;
+ int op_errno;
+ char *op_errstr;
+};
+typedef struct gf1_cli_sync_volume_rsp gf1_cli_sync_volume_rsp;
+
/* the xdr functions */
#if defined(__STDC__) || defined(__cplusplus)
@@ -338,6 +357,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_sync_volume (XDR *, gf1_cli_sync_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*);
@@ -370,15 +390,18 @@ extern bool_t xdr_gf1_cli_set_vol_rsp (XDR *, gf1_cli_set_vol_rsp*);
extern bool_t xdr_gf1_cli_log_filename_req (XDR *, gf1_cli_log_filename_req*);
extern bool_t xdr_gf1_cli_log_filename_rsp (XDR *, gf1_cli_log_filename_rsp*);
extern bool_t xdr_gf1_cli_log_locate_req (XDR *, gf1_cli_log_locate_req*);
+extern bool_t xdr_gf1_cli_sync_volume_req (XDR *, gf1_cli_sync_volume_req*);
extern bool_t xdr_gf1_cli_log_locate_rsp (XDR *, gf1_cli_log_locate_rsp*);
extern bool_t xdr_gf1_cli_log_rotate_req (XDR *, gf1_cli_log_rotate_req*);
extern bool_t xdr_gf1_cli_log_rotate_rsp (XDR *, gf1_cli_log_rotate_rsp*);
+extern bool_t xdr_gf1_cli_sync_volume_rsp (XDR *, gf1_cli_sync_volume_rsp*);
#else /* K&R C */
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_sync_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 ();
@@ -411,9 +434,11 @@ extern bool_t xdr_gf1_cli_set_vol_rsp ();
extern bool_t xdr_gf1_cli_log_filename_req ();
extern bool_t xdr_gf1_cli_log_filename_rsp ();
extern bool_t xdr_gf1_cli_log_locate_req ();
+extern bool_t xdr_gf1_cli_sync_volume_req ();
extern bool_t xdr_gf1_cli_log_locate_rsp ();
extern bool_t xdr_gf1_cli_log_rotate_req ();
extern bool_t xdr_gf1_cli_log_rotate_rsp ();
+extern bool_t xdr_gf1_cli_sync_volume_rsp ();
#endif /* K&R C */
diff --git a/rpc/xdr/src/cli1.c b/rpc/xdr/src/cli1.c
index d7ba91aea89..22b74fd7df5 100644
--- a/rpc/xdr/src/cli1.c
+++ b/rpc/xdr/src/cli1.c
@@ -523,3 +523,31 @@ gf_xdr_from_cli_log_rotate_req (struct iovec outmsg, void *req)
return xdr_serialize_generic (outmsg, (void *)req,
(xdrproc_t)xdr_gf1_cli_log_rotate_req);
}
+
+ssize_t
+gf_xdr_to_cli_sync_volume_req (struct iovec inmsg, void *args)
+{
+ return xdr_to_generic (inmsg, (void *)args,
+ (xdrproc_t)xdr_gf1_cli_sync_volume_req);
+}
+
+ssize_t
+gf_xdr_from_cli_sync_volume_req (struct iovec outmsg, void *args)
+{
+ return xdr_serialize_generic (outmsg, (void *)args,
+ (xdrproc_t)xdr_gf1_cli_sync_volume_req);
+}
+
+ssize_t
+gf_xdr_to_cli_sync_volume_rsp (struct iovec inmsg, void *args)
+{
+ return xdr_to_generic (inmsg, (void *)args,
+ (xdrproc_t)xdr_gf1_cli_sync_volume_rsp);
+}
+
+ssize_t
+gf_xdr_from_cli_sync_volume_rsp (struct iovec outmsg, void *args)
+{
+ return xdr_serialize_generic (outmsg, (void *)args,
+ (xdrproc_t)xdr_gf1_cli_sync_volume_rsp);
+}
diff --git a/rpc/xdr/src/cli1.h b/rpc/xdr/src/cli1.h
index 31b2c9b75c6..ee225400145 100644
--- a/rpc/xdr/src/cli1.h
+++ b/rpc/xdr/src/cli1.h
@@ -234,6 +234,16 @@ gf_xdr_to_cli_log_rotate_rsp (struct iovec inmsg, void *args);
ssize_t
gf_xdr_from_cli_log_rotate_req (struct iovec outmsg, void *req);
+ssize_t
+gf_xdr_to_cli_sync_volume_req (struct iovec inmsg, void *args);
+
+ssize_t
+gf_xdr_from_cli_sync_volume_req (struct iovec outmsg, void *args);
+ssize_t
+gf_xdr_to_cli_sync_volume_rsp (struct iovec inmsg, void *args);
+
+ssize_t
+gf_xdr_from_cli_sync_volume_rsp (struct iovec outmsg, void *args);
#endif /* !_CLI1_H */
diff --git a/rpc/xdr/src/cli1.x b/rpc/xdr/src/cli1.x
index 03c175e63c7..3f37f6d75cf 100644
--- a/rpc/xdr/src/cli1.x
+++ b/rpc/xdr/src/cli1.x
@@ -23,6 +23,10 @@ enum gf1_cli_get_volume {
GF_CLI_GET_NEXT_VOLUME
} ;
+enum gf1_cli_sync_volume {
+ GF_CLI_SYNC_ALL = 1
+} ;
+
enum gf1_cli_op_flags {
GF_CLI_FLAG_OP_FORCE = 1
};
@@ -218,6 +222,12 @@ struct gf1_cli_log_locate_req {
string brick<>;
};
+struct gf1_cli_sync_volume_req {
+ int flags;
+ string volname<>;
+ string hostname<>;
+};
+
struct gf1_cli_log_locate_rsp {
int op_ret;
int op_errno;
@@ -230,7 +240,13 @@ struct gf1_cli_log_rotate_req {
};
struct gf1_cli_log_rotate_rsp {
+ int op_ret;
+ int op_errno;
+ string errstr<>;
+};
+
+struct gf1_cli_sync_volume_rsp {
int op_ret;
int op_errno;
- string errstr<>;
+ string op_errstr<>;
};
diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c
index bc015293f4a..da9eca02174 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 651cb22e036..a6c1c779a7f 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 e14f007591e..2f39d24f709 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 602494b1412..025fee7755a 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 017ab687327..358d6ffe46f 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 a74fa871faf..e03968dfeeb 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 cfa22930136..48d78bc339a 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 244b71009e7..99b5f7b4e5d 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[] = {