diff options
-rw-r--r-- | cli/src/cli-cmd-volume.c | 50 | ||||
-rw-r--r-- | cli/src/cli3_1-cops.c | 54 | ||||
-rw-r--r-- | glusterfsd/src/glusterfsd-mgmt.c | 8 | ||||
-rw-r--r-- | glusterfsd/src/glusterfsd.c | 2 | ||||
-rw-r--r-- | rpc/rpc-lib/src/protocol-common.h | 2 | ||||
-rw-r--r-- | rpc/xdr/src/cli1-xdr.c | 39 | ||||
-rw-r--r-- | rpc/xdr/src/cli1-xdr.h | 25 | ||||
-rw-r--r-- | rpc/xdr/src/cli1.c | 28 | ||||
-rw-r--r-- | rpc/xdr/src/cli1.h | 10 | ||||
-rw-r--r-- | rpc/xdr/src/cli1.x | 18 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-handler.c | 142 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-op-sm.c | 430 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-op-sm.h | 3 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-sm.c | 77 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.c | 71 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.h | 15 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd.h | 12 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd3_1-mops.c | 49 |
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[] = { |