diff options
Diffstat (limited to 'xlators/mgmt/glusterd/src/glusterd-rpc-ops.c')
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-rpc-ops.c | 1826 |
1 files changed, 834 insertions, 992 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c index aa493bd76..d5200a4ae 100644 --- a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c @@ -1,22 +1,12 @@ /* - Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com> - This file is part of GlusterFS. - - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. -*/ + Copyright (c) 2010-2012 Red Hat, Inc. <http://www.redhat.com> + This file is part of GlusterFS. + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. +*/ #ifndef _CONFIG_H #define _CONFIG_H @@ -43,11 +33,9 @@ extern glusterd_op_info_t opinfo; +extern uuid_t global_txn_id; int32_t -glusterd3_1_brick_op (call_frame_t *frame, xlator_t *this, - void *data); -int32_t glusterd_op_send_cli_response (glusterd_op_t op, int32_t op_ret, int32_t op_errno, rpcsvc_request_t *req, void *op_ctx, char *op_errstr) @@ -58,421 +46,177 @@ glusterd_op_send_cli_response (glusterd_op_t op, int32_t op_ret, char *free_ptr = NULL; glusterd_conf_t *conf = NULL; xdrproc_t xdrproc = NULL; + char *errstr = NULL; + int32_t status = 0; + int32_t count = 0; + gf_cli_rsp rsp = {0,}; + xlator_t *this = NULL; - GF_ASSERT (THIS); - - conf = THIS->private; + this = THIS; + GF_ASSERT (this); + conf = this->private; GF_ASSERT (conf); - switch (op) { - case GD_OP_CREATE_VOLUME: - { - gf1_cli_create_vol_rsp rsp = {0,}; - rsp.op_ret = op_ret; - rsp.op_errno = op_errno; - rsp.volname = ""; - if (op_errstr) - rsp.op_errstr = op_errstr; - else - rsp.op_errstr = ""; - cli_rsp = &rsp; - xdrproc = (xdrproc_t)xdr_gf1_cli_create_vol_rsp; - break; - } + ctx = op_ctx; - case GD_OP_START_VOLUME: + switch (op) { + case GD_OP_REMOVE_BRICK: { - gf1_cli_start_vol_rsp rsp = {0,}; - rsp.op_ret = op_ret; - rsp.op_errno = op_errno; - rsp.volname = ""; - if (op_errstr) - rsp.op_errstr = op_errstr; - else - rsp.op_errstr = ""; - cli_rsp = &rsp; - xdrproc = (xdrproc_t) xdr_gf1_cli_start_vol_rsp; + if (ctx) + ret = dict_get_str (ctx, "errstr", &errstr); break; } - - case GD_OP_STOP_VOLUME: + case GD_OP_RESET_VOLUME: { - gf1_cli_stop_vol_rsp rsp = {0,}; - rsp.op_ret = op_ret; - rsp.op_errno = op_errno; - rsp.volname = ""; - if (op_errstr) - rsp.op_errstr = op_errstr; - else - rsp.op_errstr = ""; - cli_rsp = &rsp; - xdrproc = (xdrproc_t) xdr_gf1_cli_stop_vol_rsp; + if (op_ret && !op_errstr) + errstr = "Error while resetting options"; break; } - - case GD_OP_DELETE_VOLUME: + case GD_OP_REBALANCE: + case GD_OP_DEFRAG_BRICK_VOLUME: { - gf1_cli_delete_vol_rsp rsp = {0,}; - rsp.op_ret = op_ret; - rsp.op_errno = op_errno; - rsp.volname = ""; - if (op_errstr) - rsp.op_errstr = op_errstr; - else - rsp.op_errstr = ""; - cli_rsp = &rsp; - xdrproc = (xdrproc_t) xdr_gf1_cli_delete_vol_rsp; + if (ctx) { + ret = dict_get_int32 (ctx, "status", &status); + if (ret) { + gf_log (this->name, GF_LOG_TRACE, + "failed to get status"); + } + } break; } - - case GD_OP_DEFRAG_VOLUME: + case GD_OP_GSYNC_CREATE: + case GD_OP_GSYNC_SET: { - gf1_cli_defrag_vol_rsp rsp = {0,}; - rsp.op_ret = op_ret; - rsp.op_errno = op_errno; - //rsp.volname = ""; - cli_rsp = &rsp; - xdrproc = (xdrproc_t) xdr_gf1_cli_defrag_vol_rsp; - break; - } + if (ctx) { + ret = dict_get_str (ctx, "errstr", &errstr); + ret = dict_set_str (ctx, "glusterd_workdir", conf->workdir); + /* swallow error here, that will be re-triggered in cli */ - case GD_OP_ADD_BRICK: - { - gf1_cli_add_brick_rsp rsp = {0,}; - rsp.op_ret = op_ret; - rsp.op_errno = op_errno; - rsp.volname = ""; - if (op_errstr) - rsp.op_errstr = op_errstr; - else - rsp.op_errstr = ""; - cli_rsp = &rsp; - xdrproc = (xdrproc_t) xdr_gf1_cli_add_brick_rsp; - break; - } + } + break; - case GD_OP_REMOVE_BRICK: - { - gf1_cli_remove_brick_rsp rsp = {0,}; - ctx = op_ctx; - if (ctx && - dict_get_str (ctx, "errstr", &rsp.op_errstr)) - rsp.op_errstr = ""; - rsp.op_ret = op_ret; - rsp.op_errno = op_errno; - rsp.volname = ""; - cli_rsp = &rsp; - xdrproc = (xdrproc_t) xdr_gf1_cli_remove_brick_rsp; - break; } - - case GD_OP_REPLACE_BRICK: + case GD_OP_QUOTA: { - gf1_cli_replace_brick_rsp rsp = {0,}; - ctx = op_ctx; - if (ctx && - dict_get_str (ctx, "status-reply", &rsp.status)) - rsp.status = ""; - rsp.op_ret = op_ret; - rsp.op_errno = op_errno; - if (op_errstr) - rsp.op_errstr = op_errstr; - else - rsp.op_errstr = ""; - rsp.volname = ""; - cli_rsp = &rsp; - xdrproc = (xdrproc_t) xdr_gf1_cli_replace_brick_rsp; + if (ctx && !op_errstr) { + ret = dict_get_str (ctx, "errstr", &errstr); + } break; } - - case GD_OP_SET_VOLUME: + case GD_OP_PROFILE_VOLUME: { - gf1_cli_set_vol_rsp rsp = {0,}; - rsp.op_ret = op_ret; - rsp.op_errno = op_errno; - rsp.volname = ""; - ctx = op_ctx; - - if (op_errstr) - rsp.op_errstr = op_errstr; - else - rsp.op_errstr = ""; - if (ctx) { - ret = dict_allocate_and_serialize (ctx, - &rsp.dict.dict_val, - (size_t*)&rsp.dict.dict_len); - if (ret == 0) - free_ptr = rsp.dict.dict_val; + if (ctx && dict_get_int32 (ctx, "count", &count)) { + ret = dict_set_int32 (ctx, "count", 0); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "failed to set count in dictionary"); + } } - - cli_rsp = &rsp; - xdrproc = (xdrproc_t) xdr_gf1_cli_set_vol_rsp; break; } - - case GD_OP_RESET_VOLUME: + case GD_OP_START_BRICK: + case GD_OP_STOP_BRICK: { - gf_log ("", GF_LOG_DEBUG, "Return value to CLI"); - gf1_cli_reset_vol_rsp rsp = {0,}; - rsp.op_ret = op_ret; - rsp.op_errno = 1; - rsp.volname = ""; - if (op_errstr) - rsp.op_errstr = op_errstr; - else - rsp.op_errstr = "Error while resetting options"; - cli_rsp = &rsp; - xdrproc = (xdrproc_t) xdr_gf1_cli_reset_vol_rsp; + gf_log (this->name, GF_LOG_DEBUG, "op '%s' not supported", + gd_op_list[op]); break; } - - case GD_OP_LOG_FILENAME: + case GD_OP_NONE: + case GD_OP_MAX: { - gf1_cli_log_filename_rsp rsp = {0,}; - rsp.op_ret = op_ret; - rsp.op_errno = op_errno; - if (op_errstr) - rsp.errstr = op_errstr; - else - rsp.errstr = ""; - cli_rsp = &rsp; - xdrproc = (xdrproc_t) xdr_gf1_cli_log_filename_rsp; + gf_log (this->name, GF_LOG_ERROR, "invalid operation"); break; } + case GD_OP_CREATE_VOLUME: + case GD_OP_START_VOLUME: + case GD_OP_STOP_VOLUME: + case GD_OP_DELETE_VOLUME: + case GD_OP_DEFRAG_VOLUME: + case GD_OP_ADD_BRICK: case GD_OP_LOG_ROTATE: - { - gf1_cli_log_rotate_rsp rsp = {0,}; - rsp.op_ret = op_ret; - rsp.op_errno = op_errno; - if (op_errstr) - rsp.errstr = op_errstr; - else - rsp.errstr = ""; - cli_rsp = &rsp; - xdrproc = (xdrproc_t) xdr_gf1_cli_log_rotate_rsp; - break; - } case GD_OP_SYNC_VOLUME: + case GD_OP_STATEDUMP_VOLUME: + case GD_OP_REPLACE_BRICK: + case GD_OP_STATUS_VOLUME: + case GD_OP_SET_VOLUME: + case GD_OP_LIST_VOLUME: + case GD_OP_CLEARLOCKS_VOLUME: + case GD_OP_HEAL_VOLUME: + case GD_OP_SNAP: { - 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; - xdrproc = (xdrproc_t) xdr_gf1_cli_sync_volume_rsp; + /*nothing specific to be done*/ break; } - case GD_OP_GSYNC_SET: + case GD_OP_COPY_FILE: { - int type = 0; - char *str = NULL; - gf1_cli_gsync_set_rsp rsp = {0,}; - - ctx = op_ctx; - rsp.op_ret = op_ret; - rsp.op_errno = op_errno; - rsp.op_errstr = ""; - if (ctx) { - ret = dict_get_str (ctx, "errstr", &str); - if (ret == 0) - rsp.op_errstr = str; - ret = dict_get_int32 (ctx, "type", &type); - if (ret == 0) - rsp.type = type; - ret = dict_set_str (ctx, "glusterd_workdir", conf->workdir); - /* swallow error here, that will be re-triggered in cli */ - - ret = dict_allocate_and_serialize (ctx, - &rsp.dict.dict_val, - (size_t*)&rsp.dict.dict_len); - - if (ret == 0) - free_ptr = rsp.dict.dict_val; - - } - if (op_errstr) - rsp.op_errstr = op_errstr; - cli_rsp = &rsp; - xdrproc = (xdrproc_t) xdr_gf1_cli_gsync_set_rsp; - break; + if (ctx) + ret = dict_get_str (ctx, "errstr", &errstr); + break; } - case GD_OP_RENAME_VOLUME: - case GD_OP_START_BRICK: - case GD_OP_STOP_BRICK: - case GD_OP_LOG_LOCATE: + case GD_OP_SYS_EXEC: { - gf_log ("", GF_LOG_DEBUG, "not supported op %d", op); - break; + if (ctx) { + ret = dict_get_str (ctx, "errstr", &errstr); + ret = dict_set_str (ctx, "glusterd_workdir", + conf->workdir); + } + break; } - case GD_OP_PROFILE_VOLUME: - { - gf1_cli_stats_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 = ""; - ctx = op_ctx; - dict_allocate_and_serialize (ctx, - &rsp.stats_info.stats_info_val, - (size_t*)&rsp.stats_info.stats_info_len); - free_ptr = rsp.stats_info.stats_info_val; - cli_rsp = &rsp; - xdrproc = (xdrproc_t) xdr_gf1_cli_stats_volume_rsp; - break; } - case GD_OP_QUOTA: - { - int32_t type; - char *str = NULL; - char *errstr = NULL; - gf1_cli_quota_rsp rsp = {0,}; - - rsp.op_ret = op_ret; - rsp.op_errno = op_errno; - rsp.volname = ""; - - ctx = op_ctx; - - if (op_errstr) - rsp.op_errstr = op_errstr; - else { - ret = dict_get_str (ctx, "errstr", &errstr); - if (ret == 0) - rsp.op_errstr = errstr; - else - rsp.op_errstr = ""; - } - - rsp.limit_list = ""; - - if (op_ret == 0 && ctx) { - ret = dict_get_str (ctx, "volname", &str); - if (ret == 0) - rsp.volname = str; + rsp.op_ret = op_ret; + rsp.op_errno = errno; + if (errstr) + rsp.op_errstr = errstr; + else if (op_errstr) + rsp.op_errstr = op_errstr; - ret = dict_get_int32 (ctx, "type", &type); - if (ret == 0) - rsp.type = type; - else - rsp.type = 0; - - if (type == GF_QUOTA_OPTION_TYPE_LIST) { - ret = dict_get_str (ctx,"limit_list", &str); - - if (ret == 0) - rsp.limit_list = str; - } - } - cli_rsp = &rsp; - xdrproc = (xdrproc_t) xdr_gf1_cli_quota_rsp; - break; - } + if (!rsp.op_errstr) + rsp.op_errstr = ""; - case GD_OP_LOG_LEVEL: - { - gf1_cli_log_level_rsp rsp = {0,}; - rsp.op_ret = op_ret; - rsp.op_errno = op_errno; - if (op_errstr) - rsp.op_errstr = op_errstr; + if (ctx) { + ret = dict_allocate_and_serialize (ctx, &rsp.dict.dict_val, + &rsp.dict.dict_len); + if (ret < 0 ) + gf_log (this->name, GF_LOG_ERROR, "failed to " + "serialize buffer"); else - rsp.op_errstr = ""; - - cli_rsp = &rsp; - xdrproc = (xdrproc_t) xdr_gf1_cli_log_level_rsp; - break; + free_ptr = rsp.dict.dict_val; } + /* needed by 'rebalance status' */ + if (status) + rsp.op_errno = status; - case GD_OP_STATUS_VOLUME: - { - gf1_cli_status_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 = ""; - ctx = op_ctx; - dict_allocate_and_serialize (ctx, - &rsp.dict.dict_val, - (size_t*)&rsp.dict.dict_len); - free_ptr = rsp.dict.dict_val; - cli_rsp = &rsp; - xdrproc = (xdrproc_t) xdr_gf1_cli_status_volume_rsp; - break; - } - case GD_OP_REBALANCE: - { - gf2_cli_defrag_vol_rsp rsp = {0,}; - int32_t status = 0; - - ctx = op_ctx; - rsp.op_ret = op_ret; - rsp.op_errno = op_errno; - rsp.volname = ""; - if (op_errstr) - rsp.op_errstr = op_errstr; - else - rsp.op_errstr = ""; + cli_rsp = &rsp; + xdrproc = (xdrproc_t) xdr_gf_cli_rsp; - if (ctx) { - ret = dict_get_uint64 (ctx, "files", &rsp.files); - if (ret) { - gf_log (THIS->name, GF_LOG_DEBUG, - "failed to get the file count"); - } - ret = dict_get_uint64 (ctx, "size", &rsp.size); - if (ret) { - gf_log (THIS->name, GF_LOG_DEBUG, - "failed to get the size of migration"); - } - ret = dict_get_uint64 (ctx, "lookups", &rsp.lookedup_files); - if (ret) { - gf_log (THIS->name, GF_LOG_DEBUG, - "failed to get lookuped file count"); - } + glusterd_to_cli (req, cli_rsp, NULL, 0, NULL, + xdrproc, ctx); + ret = 0; - ret = dict_get_int32 (ctx, "status", &status); - if (ret) { - gf_log (THIS->name, GF_LOG_TRACE, - "failed to get status"); - } - } - /* needed by 'rebalance status' */ - if (status) - rsp.op_errno = status; + GF_FREE (free_ptr); + gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret); + return ret; +} - cli_rsp = &rsp; - xdrproc = (xdrproc_t)xdr_gf2_cli_defrag_vol_rsp; - break; - } - case GD_OP_NONE: - case GD_OP_MAX: - { - gf_log ("", GF_LOG_ERROR, "invalid operation %d", op); - break; - } - } +int +glusterd_big_locked_cbk (struct rpc_req *req, struct iovec *iov, + int count, void *myframe, fop_cbk_fn_t fn) +{ + glusterd_conf_t *priv = THIS->private; + int ret = -1; - ret = glusterd_submit_reply (req, cli_rsp, NULL, 0, NULL, - xdrproc); + synclock_lock (&priv->big_lock); + ret = fn (req, iov, count, myframe); + synclock_unlock (&priv->big_lock); - if (free_ptr) - GF_FREE (free_ptr); - gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); return ret; } int -glusterd3_1_probe_cbk (struct rpc_req *req, struct iovec *iov, +__glusterd_probe_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { gd1_mgmt_probe_rsp rsp = {{0},}; @@ -505,7 +249,9 @@ glusterd3_1_probe_cbk (struct rpc_req *req, struct iovec *iov, if (ctx->req) { glusterd_xfer_cli_probe_resp (ctx->req, rsp.op_ret, rsp.op_errno, - ctx->hostname, ctx->port); + rsp.op_errstr, + ctx->hostname, ctx->port, + ctx->dict); } glusterd_destroy_probe_ctx (ctx); @@ -518,6 +264,31 @@ glusterd3_1_probe_cbk (struct rpc_req *req, struct iovec *iov, GF_ASSERT (0); } + if (strncasecmp (rsp.hostname, peerinfo->hostname, 1024)) { + gf_log (THIS->name, GF_LOG_INFO, "Host: %s with uuid: %s " + "already present in cluster with alias hostname: %s", + rsp.hostname, uuid_utoa (rsp.uuid), peerinfo->hostname); + + ctx = ((call_frame_t *)myframe)->local; + ((call_frame_t *)myframe)->local = NULL; + + GF_ASSERT (ctx); + + rsp.op_errno = GF_PROBE_FRIEND; + if (ctx->req) { + glusterd_xfer_cli_probe_resp (ctx->req, rsp.op_ret, + rsp.op_errno, + rsp.op_errstr, + ctx->hostname, ctx->port, + ctx->dict); + } + + glusterd_destroy_probe_ctx (ctx); + (void) glusterd_friend_remove (NULL, rsp.hostname); + ret = rsp.op_ret; + goto out; + } + uuid_copy (peerinfo->uuid, rsp.uuid); ret = glusterd_friend_sm_new_event @@ -543,14 +314,22 @@ glusterd3_1_probe_cbk (struct rpc_req *req, struct iovec *iov, gf_log ("glusterd", GF_LOG_INFO, "Received resp to probe req"); out: - if (rsp.hostname) - free (rsp.hostname);//malloced by xdr + free (rsp.hostname);//malloced by xdr GLUSTERD_STACK_DESTROY (((call_frame_t *)myframe)); return ret; } int -glusterd3_1_friend_add_cbk (struct rpc_req * req, struct iovec *iov, +glusterd_probe_cbk (struct rpc_req *req, struct iovec *iov, + int count, void *myframe) +{ + return glusterd_big_locked_cbk (req, iov, count, myframe, + __glusterd_probe_cbk); +} + + +int +__glusterd_friend_add_cbk (struct rpc_req * req, struct iovec *iov, int count, void *myframe) { gd1_mgmt_friend_rsp rsp = {{0},}; @@ -627,23 +406,31 @@ out: GF_ASSERT (ctx); - if (ctx->req)//reverse probe doesnt have req + if (ctx->req)//reverse probe doesn't have req ret = glusterd_xfer_cli_probe_resp (ctx->req, op_ret, op_errno, - ctx->hostname, ctx->port); + NULL, ctx->hostname, + ctx->port, ctx->dict); if (!ret) { glusterd_friend_sm (); glusterd_op_sm (); } if (ctx) glusterd_destroy_probe_ctx (ctx); - if (rsp.hostname) - free (rsp.hostname);//malloced by xdr + free (rsp.hostname);//malloced by xdr GLUSTERD_STACK_DESTROY (((call_frame_t *)myframe)); return ret; } int -glusterd3_1_friend_remove_cbk (struct rpc_req * req, struct iovec *iov, +glusterd_friend_add_cbk (struct rpc_req *req, struct iovec *iov, + int count, void *myframe) +{ + return glusterd_big_locked_cbk (req, iov, count, myframe, + __glusterd_friend_add_cbk); +} + +int +__glusterd_friend_remove_cbk (struct rpc_req * req, struct iovec *iov, int count, void *myframe) { gd1_mgmt_friend_rsp rsp = {{0},}; @@ -655,6 +442,7 @@ glusterd3_1_friend_remove_cbk (struct rpc_req * req, struct iovec *iov, int32_t op_ret = -1; int32_t op_errno = -1; glusterd_probe_ctx_t *ctx = NULL; + gf_boolean_t move_sm_now = _gf_true; conf = THIS->private; GF_ASSERT (conf); @@ -666,6 +454,7 @@ glusterd3_1_friend_remove_cbk (struct rpc_req * req, struct iovec *iov, if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = EINVAL; + move_sm_now = _gf_false; goto inject; } @@ -709,16 +498,17 @@ inject: if (ret) goto respond; - glusterd_friend_sm (); - glusterd_op_sm (); - + /*friend_sm would be moved on CLNT_DISCONNECT, consequently + cleaning up peerinfo. Else, we run the risk of triggering + a clnt_destroy within saved_frames_unwind. + */ op_ret = 0; respond: - ret = glusterd_xfer_cli_deprobe_resp (ctx->req, op_ret, op_errno, - ctx->hostname); - if (!ret) { + ret = glusterd_xfer_cli_deprobe_resp (ctx->req, op_ret, op_errno, NULL, + ctx->hostname, ctx->dict); + if (!ret && move_sm_now) { glusterd_friend_sm (); glusterd_op_sm (); } @@ -728,37 +518,62 @@ respond: glusterd_destroy_probe_ctx (ctx); } - if (rsp.hostname) - free (rsp.hostname);//malloced by xdr + free (rsp.hostname);//malloced by xdr GLUSTERD_STACK_DESTROY (((call_frame_t *)myframe)); return ret; } +int +glusterd_friend_remove_cbk (struct rpc_req *req, struct iovec *iov, + int count, void *myframe) +{ + return glusterd_big_locked_cbk (req, iov, count, myframe, + __glusterd_friend_remove_cbk); +} + int32_t -glusterd3_1_friend_update_cbk (struct rpc_req *req, struct iovec *iov, +__glusterd_friend_update_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { - int ret = -1; - int32_t op_ret = 0; - char str[50] = {0,}; + int ret = -1; + gd1_mgmt_friend_update_rsp rsp = {{0}, }; + xlator_t *this = NULL; GF_ASSERT (req); + this = THIS; if (-1 == req->rpc_status) { + gf_log (this->name, GF_LOG_ERROR, "RPC Error"); goto out; } - gf_log ("glusterd", GF_LOG_INFO, - "Received %s from uuid: %s", - (op_ret)?"RJT":"ACC", str); + ret = xdr_to_generic (*iov, &rsp, + (xdrproc_t)xdr_gd1_mgmt_friend_update_rsp); + if (ret < 0) { + gf_log (this->name, GF_LOG_ERROR, "Failed to serialize friend" + " update repsonse"); + goto out; + } + ret = 0; out: + gf_log (this->name, GF_LOG_INFO, "Received %s from uuid: %s", + (ret)?"RJT":"ACC", uuid_utoa (rsp.uuid)); + GLUSTERD_STACK_DESTROY (((call_frame_t *)myframe)); return ret; } +int +glusterd_friend_update_cbk (struct rpc_req *req, struct iovec *iov, + int count, void *myframe) +{ + return glusterd_big_locked_cbk (req, iov, count, myframe, + __glusterd_friend_update_cbk); +} + int32_t -glusterd3_1_cluster_lock_cbk (struct rpc_req *req, struct iovec *iov, +__glusterd_cluster_lock_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { gd1_mgmt_cluster_lock_rsp rsp = {{0},}; @@ -766,7 +581,11 @@ glusterd3_1_cluster_lock_cbk (struct rpc_req *req, struct iovec *iov, int32_t op_ret = -1; glusterd_op_sm_event_type_t event_type = GD_OP_EVENT_NONE; glusterd_peerinfo_t *peerinfo = NULL; + xlator_t *this = NULL; + uuid_t *txn_id = &global_txn_id; + this = THIS; + GF_ASSERT (this); GF_ASSERT (req); if (-1 == req->rpc_status) { @@ -777,7 +596,8 @@ glusterd3_1_cluster_lock_cbk (struct rpc_req *req, struct iovec *iov, ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gd1_mgmt_cluster_lock_rsp); if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); + gf_log (this->name, GF_LOG_ERROR, "Failed to decode lock " + "response received from peer"); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; @@ -786,25 +606,28 @@ glusterd3_1_cluster_lock_cbk (struct rpc_req *req, struct iovec *iov, out: op_ret = rsp.op_ret; - gf_log ("glusterd", GF_LOG_INFO, - "Received %s from uuid: %s", - (op_ret)?"RJT":"ACC", uuid_utoa (rsp.uuid)); + gf_log (this->name, (op_ret) ? GF_LOG_ERROR : GF_LOG_DEBUG, + "Received lock %s from uuid: %s", (op_ret) ? "RJT" : "ACC", + uuid_utoa (rsp.uuid)); ret = glusterd_friend_find (rsp.uuid, NULL, &peerinfo); if (ret) { - gf_log ("", GF_LOG_CRITICAL, "Lock response received from " - "unknown peer: %s", uuid_utoa (rsp.uuid)); + gf_log (this->name, GF_LOG_CRITICAL, "Lock response received " + "from unknown peer: %s", uuid_utoa (rsp.uuid)); } if (op_ret) { event_type = GD_OP_EVENT_RCVD_RJT; opinfo.op_ret = op_ret; + opinfo.op_errstr = gf_strdup ("Another transaction could be in " + "progress. Please try again after" + " sometime."); } else { event_type = GD_OP_EVENT_RCVD_ACC; } - ret = glusterd_op_sm_inject_event (event_type, NULL); + ret = glusterd_op_sm_inject_event (event_type, txn_id, NULL); if (!ret) { glusterd_friend_sm (); @@ -816,16 +639,27 @@ out: } int32_t -glusterd3_1_cluster_unlock_cbk (struct rpc_req *req, struct iovec *iov, - int count, void *myframe) +glusterd_cluster_lock_cbk (struct rpc_req *req, struct iovec *iov, + int count, void *myframe) { - gd1_mgmt_cluster_lock_rsp rsp = {{0},}; + return glusterd_big_locked_cbk (req, iov, count, myframe, + __glusterd_cluster_lock_cbk); +} + +static int32_t +glusterd_mgmt_v3_lock_peers_cbk_fn (struct rpc_req *req, struct iovec *iov, + int count, void *myframe) +{ + gd1_mgmt_v3_lock_rsp rsp = {{0},}; int ret = -1; int32_t op_ret = -1; glusterd_op_sm_event_type_t event_type = GD_OP_EVENT_NONE; glusterd_peerinfo_t *peerinfo = NULL; + xlator_t *this = NULL; + uuid_t *txn_id = NULL; - + this = THIS; + GF_ASSERT (this); GF_ASSERT (req); if (-1 == req->rpc_status) { @@ -834,9 +668,12 @@ glusterd3_1_cluster_unlock_cbk (struct rpc_req *req, struct iovec *iov, goto out; } - ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gd1_mgmt_cluster_unlock_rsp); + ret = xdr_to_generic (*iov, &rsp, + (xdrproc_t)xdr_gd1_mgmt_v3_lock_rsp); if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); + gf_log (this->name, GF_LOG_ERROR, + "Failed to decode mgmt_v3 lock " + "response received from peer"); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; @@ -845,25 +682,30 @@ glusterd3_1_cluster_unlock_cbk (struct rpc_req *req, struct iovec *iov, out: op_ret = rsp.op_ret; - gf_log ("glusterd", GF_LOG_INFO, - "Received %s from uuid: %s", - (op_ret)?"RJT":"ACC", uuid_utoa (rsp.uuid)); + txn_id = &rsp.txn_id; - ret = glusterd_friend_find (rsp.uuid, NULL, &peerinfo); + gf_log (this->name, (op_ret) ? GF_LOG_ERROR : GF_LOG_DEBUG, + "Received mgmt_v3 lock %s from uuid: %s", + (op_ret) ? "RJT" : "ACC", uuid_utoa (rsp.uuid)); + ret = glusterd_friend_find (rsp.uuid, NULL, &peerinfo); if (ret) { - gf_log ("", GF_LOG_CRITICAL, "Unlock response received from " - "unknown peer %s", uuid_utoa (rsp.uuid)); + gf_log (this->name, GF_LOG_CRITICAL, + "mgmt_v3 lock response received " + "from unknown peer: %s", uuid_utoa (rsp.uuid)); } if (op_ret) { event_type = GD_OP_EVENT_RCVD_RJT; opinfo.op_ret = op_ret; + opinfo.op_errstr = gf_strdup ("Another transaction could be in " + "progress. Please try again after" + " sometime."); } else { event_type = GD_OP_EVENT_RCVD_ACC; } - ret = glusterd_op_sm_inject_event (event_type, NULL); + ret = glusterd_op_sm_inject_event (event_type, txn_id, NULL); if (!ret) { glusterd_friend_sm (); @@ -874,197 +716,167 @@ out: return ret; } -static int32_t -glusterd_append_gsync_status (dict_t *dst, dict_t *src) +int32_t +glusterd_mgmt_v3_lock_peers_cbk (struct rpc_req *req, struct iovec *iov, + int count, void *myframe) { - int ret = 0; - char *stop_msg = NULL; - - ret = dict_get_str (src, "gsync-status", &stop_msg); - if (ret) { - ret = 0; - goto out; - } - - ret = dict_set_dynstr (dst, "gsync-status", gf_strdup (stop_msg)); - if (ret) { - gf_log ("glusterd", GF_LOG_WARNING, "Unable to set the stop" - "message in the ctx dictionary"); - goto out; - } - - ret = 0; - out: - gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret); - return ret; - + return glusterd_big_locked_cbk (req, iov, count, myframe, + glusterd_mgmt_v3_lock_peers_cbk_fn); } static int32_t -glusterd_append_status_dicts (dict_t *dst, dict_t *src) +glusterd_mgmt_v3_unlock_peers_cbk_fn (struct rpc_req *req, struct iovec *iov, + int count, void *myframe) { - int dst_count = 0; - int src_count = 0; - int i = 0; - int ret = 0; - char mst[PATH_MAX] = {0,}; - char slv[PATH_MAX] = {0, }; - char sts[PATH_MAX] = {0, }; - char *mst_val = NULL; - char *slv_val = NULL; - char *sts_val = NULL; - - GF_ASSERT (dst); - - if (src == NULL) - goto out; + gd1_mgmt_v3_unlock_rsp rsp = {{0},}; + int ret = -1; + int32_t op_ret = -1; + glusterd_op_sm_event_type_t event_type = GD_OP_EVENT_NONE; + glusterd_peerinfo_t *peerinfo = NULL; + xlator_t *this = NULL; + uuid_t *txn_id = NULL; - ret = dict_get_int32 (dst, "gsync-count", &dst_count); - if (ret) - dst_count = 0; + this = THIS; + GF_ASSERT (this); + GF_ASSERT (req); - ret = dict_get_int32 (src, "gsync-count", &src_count); - if (ret || !src_count) { - gf_log ("", GF_LOG_DEBUG, "Source brick empty"); - ret = 0; + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = EINVAL; goto out; } - for (i = 1; i <= src_count; i++) { - snprintf (mst, sizeof(mst), "master%d", i); - snprintf (slv, sizeof(slv), "slave%d", i); - snprintf (sts, sizeof(sts), "status%d", i); + ret = xdr_to_generic (*iov, &rsp, + (xdrproc_t)xdr_gd1_mgmt_v3_unlock_rsp); + if (ret < 0) { + gf_log (this->name, GF_LOG_ERROR, + "Failed to decode mgmt_v3 unlock " + "response received from peer"); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } - ret = dict_get_str (src, mst, &mst_val); - if (ret) - goto out; +out: + op_ret = rsp.op_ret; - ret = dict_get_str (src, slv, &slv_val); - if (ret) - goto out; + txn_id = &rsp.txn_id; - ret = dict_get_str (src, sts, &sts_val); - if (ret) - goto out; + gf_log (this->name, (op_ret) ? GF_LOG_ERROR : GF_LOG_DEBUG, + "Received mgmt_v3 unlock %s from uuid: %s", + (op_ret) ? "RJT" : "ACC", + uuid_utoa (rsp.uuid)); - snprintf (mst, sizeof(mst), "master%d", i+dst_count); - snprintf (slv, sizeof(slv), "slave%d", i+dst_count); - snprintf (sts, sizeof(sts), "status%d", i+dst_count); + ret = glusterd_friend_find (rsp.uuid, NULL, &peerinfo); - ret = dict_set_dynstr (dst, mst, gf_strdup (mst_val)); - if (ret) - goto out; + if (ret) { + gf_log (this->name, GF_LOG_CRITICAL, + "mgmt_v3 unlock response received " + "from unknown peer: %s", uuid_utoa (rsp.uuid)); + } - ret = dict_set_dynstr (dst, slv, gf_strdup (slv_val)); - if (ret) - goto out; + if (op_ret) { + event_type = GD_OP_EVENT_RCVD_RJT; + opinfo.op_ret = op_ret; + opinfo.op_errstr = gf_strdup ("Another transaction could be in " + "progress. Please try again after" + " sometime."); + } else { + event_type = GD_OP_EVENT_RCVD_ACC; + } - ret = dict_set_dynstr (dst, sts, gf_strdup (sts_val)); - if (ret) - goto out; + ret = glusterd_op_sm_inject_event (event_type, txn_id, NULL); + if (!ret) { + glusterd_friend_sm (); + glusterd_op_sm (); } - ret = dict_set_int32 (dst, "gsync-count", dst_count+src_count); - - out: - gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); + GLUSTERD_STACK_DESTROY (((call_frame_t *)myframe)); return ret; - } -static int32_t -glusterd_gsync_use_rsp_dict (dict_t *rsp_dict, char *op_errstr) +int32_t +glusterd_mgmt_v3_unlock_peers_cbk (struct rpc_req *req, struct iovec *iov, + int count, void *myframe) { - dict_t *ctx = NULL; - int ret = 0; + return glusterd_big_locked_cbk (req, iov, count, myframe, + glusterd_mgmt_v3_unlock_peers_cbk_fn); +} - ctx = glusterd_op_get_ctx (); - if (!ctx) { - gf_log ("", GF_LOG_ERROR, - "Operation Context is not present"); - GF_ASSERT (0); - } +int32_t +__glusterd_cluster_unlock_cbk (struct rpc_req *req, struct iovec *iov, + int count, void *myframe) +{ + gd1_mgmt_cluster_lock_rsp rsp = {{0},}; + int ret = -1; + int32_t op_ret = -1; + glusterd_op_sm_event_type_t event_type = GD_OP_EVENT_NONE; + glusterd_peerinfo_t *peerinfo = NULL; + xlator_t *this = NULL; + uuid_t *txn_id = &global_txn_id; - if (rsp_dict) { - ret = glusterd_append_status_dicts (ctx, rsp_dict); - if (ret) - goto out; + this = THIS; + GF_ASSERT (this); + GF_ASSERT (req); - ret = glusterd_append_gsync_status (ctx, rsp_dict); - if (ret) - goto out; - } - if (strcmp ("", op_errstr)) { - ret = dict_set_dynstr (ctx, "errstr", gf_strdup(op_errstr)); - if (ret) - goto out; + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; } - ret = 0; - out: - gf_log ("", GF_LOG_DEBUG, "Returning %d ", ret); - return ret; -} -static int32_t -glusterd_rb_use_rsp_dict (dict_t *rsp_dict) -{ - int32_t src_port = 0; - int32_t dst_port = 0; - int ret = 0; - dict_t *ctx = NULL; - - - ctx = glusterd_op_get_ctx (); - if (!ctx) { - gf_log ("", GF_LOG_ERROR, - "Operation Context is not present"); - GF_ASSERT (0); + ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gd1_mgmt_cluster_unlock_rsp); + if (ret < 0) { + gf_log (this->name, GF_LOG_ERROR, "Failed to decode unlock " + "response received from peer"); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; } - if (rsp_dict) { - ret = dict_get_int32 (rsp_dict, "src-brick-port", &src_port); - if (ret == 0) { - gf_log ("", GF_LOG_DEBUG, - "src-brick-port=%d found", src_port); - } +out: + op_ret = rsp.op_ret; - ret = dict_get_int32 (rsp_dict, "dst-brick-port", &dst_port); - if (ret == 0) { - gf_log ("", GF_LOG_DEBUG, - "dst-brick-port=%d found", dst_port); - } + gf_log (this->name, (op_ret) ? GF_LOG_ERROR : GF_LOG_DEBUG, + "Received unlock %s from uuid: %s", + (op_ret)?"RJT":"ACC", uuid_utoa (rsp.uuid)); + + ret = glusterd_friend_find (rsp.uuid, NULL, &peerinfo); + if (ret) { + gf_log (this->name, GF_LOG_CRITICAL, "Unlock response received " + "from unknown peer %s", uuid_utoa (rsp.uuid)); } - if (src_port) { - ret = dict_set_int32 (ctx, "src-brick-port", - src_port); - if (ret) { - gf_log ("", GF_LOG_DEBUG, - "Could not set src-brick"); - goto out; - } + if (op_ret) { + event_type = GD_OP_EVENT_RCVD_RJT; + opinfo.op_ret = op_ret; + } else { + event_type = GD_OP_EVENT_RCVD_ACC; } - if (dst_port) { - ret = dict_set_int32 (ctx, "dst-brick-port", - dst_port); - if (ret) { - gf_log ("", GF_LOG_DEBUG, - "Could not set dst-brick"); - goto out; - } + ret = glusterd_op_sm_inject_event (event_type, txn_id, NULL); + if (!ret) { + glusterd_friend_sm (); + glusterd_op_sm (); } -out: + GLUSTERD_STACK_DESTROY (((call_frame_t *)myframe)); return ret; +} +int32_t +glusterd_cluster_unlock_cbk (struct rpc_req *req, struct iovec *iov, + int count, void *myframe) +{ + return glusterd_big_locked_cbk (req, iov, count, myframe, + __glusterd_cluster_unlock_cbk); } int32_t -glusterd3_1_stage_op_cbk (struct rpc_req *req, struct iovec *iov, +__glusterd_stage_op_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { gd1_mgmt_stage_op_rsp rsp = {{0},}; @@ -1075,22 +887,32 @@ glusterd3_1_stage_op_cbk (struct rpc_req *req, struct iovec *iov, dict_t *dict = NULL; char err_str[2048] = {0}; char *peer_str = NULL; + xlator_t *this = NULL; + uuid_t *txn_id = NULL; + this = THIS; + GF_ASSERT (this); GF_ASSERT (req); if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = EINVAL; - rsp.op_errstr = "error"; + /* use standard allocation because to keep uniformity + in freeing it */ + rsp.op_errstr = strdup ("error"); goto out; } ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gd1_mgmt_stage_op_rsp); if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); + gf_log (this->name, GF_LOG_ERROR, "Failed to decode stage " + "response received from peer"); rsp.op_ret = -1; rsp.op_errno = EINVAL; - rsp.op_errstr = "error"; + /* use standard allocation because to keep uniformity + in freeing it */ + rsp.op_errstr = strdup ("Failed to decode stage response " + "received from peer."); goto out; } @@ -1102,7 +924,7 @@ glusterd3_1_stage_op_cbk (struct rpc_req *req, struct iovec *iov, rsp.dict.dict_len, &dict); if (ret < 0) { - gf_log ("glusterd", GF_LOG_ERROR, + gf_log (this->name, GF_LOG_ERROR, "failed to " "unserialize rsp-buffer to dictionary"); event_type = GD_OP_EVENT_RCVD_RJT; @@ -1115,15 +937,19 @@ glusterd3_1_stage_op_cbk (struct rpc_req *req, struct iovec *iov, out: op_ret = rsp.op_ret; - gf_log ("glusterd", GF_LOG_INFO, - "Received %s from uuid: %s", - (op_ret)?"RJT":"ACC", uuid_utoa (rsp.uuid)); + gf_log (this->name, (op_ret) ? GF_LOG_ERROR : GF_LOG_DEBUG, + "Received stage %s from uuid: %s", + (op_ret) ? "RJT" : "ACC", uuid_utoa (rsp.uuid)); + + ret = dict_get_bin (dict, "transaction_id", (void **)&txn_id); + + gf_log ("", GF_LOG_DEBUG, "transaction ID = %s", uuid_utoa (*txn_id)); ret = glusterd_friend_find (rsp.uuid, NULL, &peerinfo); if (ret) { - gf_log ("", GF_LOG_CRITICAL, "Stage response received from " - "unknown peer: %s", uuid_utoa (rsp.uuid)); + gf_log (this->name, GF_LOG_CRITICAL, "Stage response received " + "from unknown peer: %s", uuid_utoa (rsp.uuid)); } if (op_ret) { @@ -1136,12 +962,11 @@ out: peer_str = peerinfo->hostname; else peer_str = uuid_utoa (rsp.uuid); - snprintf (err_str, sizeof (err_str), "Operation failed " - "on %s", peer_str); + snprintf (err_str, sizeof (err_str), + OPERRSTR_STAGE_FAIL, peer_str); opinfo.op_errstr = gf_strdup (err_str); } if (!opinfo.op_errstr) { - gf_log ("", GF_LOG_ERROR, "memory allocation failed"); ret = -1; goto out; } @@ -1151,219 +976,39 @@ out: switch (rsp.op) { case GD_OP_REPLACE_BRICK: - glusterd_rb_use_rsp_dict (dict); + glusterd_rb_use_rsp_dict (NULL, dict); break; } - ret = glusterd_op_sm_inject_event (event_type, NULL); + ret = glusterd_op_sm_inject_event (event_type, txn_id, NULL); if (!ret) { glusterd_friend_sm (); glusterd_op_sm (); } - if (rsp.op_errstr && strcmp (rsp.op_errstr, "error")) - free (rsp.op_errstr); //malloced by xdr + free (rsp.op_errstr); //malloced by xdr if (dict) { if (!dict->extra_stdfree && rsp.dict.dict_val) free (rsp.dict.dict_val); //malloced by xdr dict_unref (dict); } else { - if (rsp.dict.dict_val) - free (rsp.dict.dict_val); //malloced by xdr + free (rsp.dict.dict_val); //malloced by xdr } GLUSTERD_STACK_DESTROY (((call_frame_t *)myframe)); return ret; } -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; - -} - -void -_profile_volume_add_friend_rsp (dict_t *this, char *key, data_t *value, - void *data) -{ - char new_key[256] = {0}; - glusterd_pr_brick_rsp_conv_t *rsp_ctx = NULL; - data_t *new_value = NULL; - int brick_count = 0; - char brick_key[256]; - - if (strcmp (key, "count") == 0) - return; - sscanf (key, "%d%s", &brick_count, brick_key); - rsp_ctx = data; - new_value = data_copy (value); - GF_ASSERT (new_value); - snprintf (new_key, sizeof (new_key), "%d%s", - rsp_ctx->count + brick_count, brick_key); - dict_set (rsp_ctx->dict, new_key, new_value); -} - -int -glusterd_profile_volume_use_rsp_dict (dict_t *rsp_dict) -{ - int ret = 0; - glusterd_pr_brick_rsp_conv_t rsp_ctx = {0}; - int32_t brick_count = 0; - int32_t count = 0; - dict_t *ctx_dict = NULL; - glusterd_op_t op = GD_OP_NONE; - - GF_ASSERT (rsp_dict); - - ret = dict_get_int32 (rsp_dict, "count", &brick_count); - if (ret) { - ret = 0; //no bricks in the rsp - goto out; - } - - op = glusterd_op_get_op (); - GF_ASSERT (GD_OP_PROFILE_VOLUME == op); - ctx_dict = glusterd_op_get_ctx (); - - ret = dict_get_int32 (ctx_dict, "count", &count); - rsp_ctx.count = count; - rsp_ctx.dict = ctx_dict; - dict_foreach (rsp_dict, _profile_volume_add_friend_rsp, &rsp_ctx); - dict_del (ctx_dict, "count"); - ret = dict_set_int32 (ctx_dict, "count", count + brick_count); -out: - return ret; -} - -void -glusterd_volume_status_add_peer_rsp (dict_t *this, char *key, data_t *value, - void *data) -{ - glusterd_status_rsp_conv_t *rsp_ctx = NULL; - data_t *new_value = NULL; - int32_t ret = 0; - - if (strcmp (key, "count") == 0) - return; - - rsp_ctx = data; - new_value = data_copy (value); - GF_ASSERT (new_value); - - ret = dict_set (rsp_ctx->dict, key, new_value); - if (ret) - gf_log ("", GF_LOG_ERROR, "Unable to set key: %s in dict", - key); - - return; -} - -int -glusterd_volume_status_use_rsp_dict (dict_t *rsp_dict) -{ - int ret = 0; - glusterd_status_rsp_conv_t rsp_ctx = {0}; - int32_t brick_count = 0; - int32_t count = 0; - dict_t *ctx_dict = NULL; - glusterd_op_t op = GD_OP_NONE; - - GF_ASSERT (rsp_dict); - - ret = dict_get_int32 (rsp_dict, "count", &brick_count); - if (ret) { - ret = 0; //no bricks in the rsp - goto out; - } - - op = glusterd_op_get_op (); - GF_ASSERT (GD_OP_STATUS_VOLUME == op); - ctx_dict = glusterd_op_get_ctx (op); - - ret = dict_get_int32 (ctx_dict, "count", &count); - rsp_ctx.count = count; - rsp_ctx.dict = ctx_dict; - dict_foreach (rsp_dict, glusterd_volume_status_add_peer_rsp, &rsp_ctx); - dict_del (ctx_dict, "count"); - ret = dict_get_int32 (ctx_dict, "count", &brick_count); - ret = dict_set_int32 (ctx_dict, "count", count + brick_count); -out: - return ret; -} - -int -glusterd_volume_rebalance_use_rsp_dict (dict_t *rsp_dict) +int32_t +glusterd_stage_op_cbk (struct rpc_req *req, struct iovec *iov, + int count, void *myframe) { - int ret = 0; - dict_t *ctx_dict = NULL; - glusterd_op_t op = GD_OP_NONE; - uint64_t value = 0; - int32_t value32 = 0; - - GF_ASSERT (rsp_dict); - - op = glusterd_op_get_op (); - GF_ASSERT (GD_OP_REBALANCE == op); - - ctx_dict = glusterd_op_get_ctx (op); - - if (!ctx_dict) - goto out; - - ret = dict_get_uint64 (rsp_dict, "files", &value); - if (!ret) { - ret = dict_set_uint64 (ctx_dict, "files", value); - if (ret) { - gf_log (THIS->name, GF_LOG_DEBUG, - "failed to set the file count"); - } - } - - ret = dict_get_uint64 (rsp_dict, "size", &value); - if (!ret) { - ret = dict_set_uint64 (ctx_dict, "size", value); - if (ret) { - gf_log (THIS->name, GF_LOG_DEBUG, - "failed to set the size of migration"); - } - } - - ret = dict_get_uint64 (rsp_dict, "lookups", &value); - if (!ret) { - ret = dict_set_uint64 (ctx_dict, "lookups", value); - if (ret) { - gf_log (THIS->name, GF_LOG_DEBUG, - "failed to set lookuped file count"); - } - } - - ret = dict_get_int32 (rsp_dict, "status", &value32); - if (!ret) { - ret = dict_set_int32 (ctx_dict, "status", value32); - if (ret) { - gf_log (THIS->name, GF_LOG_DEBUG, - "failed to set status"); - } - } - -out: - return ret; + return glusterd_big_locked_cbk (req, iov, count, myframe, + __glusterd_stage_op_cbk); } - int32_t -glusterd3_1_commit_op_cbk (struct rpc_req *req, struct iovec *iov, +__glusterd_commit_op_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { gd1_mgmt_commit_op_rsp rsp = {{0},}; @@ -1374,24 +1019,34 @@ glusterd3_1_commit_op_cbk (struct rpc_req *req, struct iovec *iov, dict_t *dict = NULL; char err_str[2048] = {0}; char *peer_str = NULL; + xlator_t *this = NULL; + uuid_t *txn_id = NULL; + this = THIS; + GF_ASSERT (this); GF_ASSERT (req); if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = EINVAL; - rsp.op_errstr = "error"; + /* use standard allocation because to keep uniformity + in freeing it */ + rsp.op_errstr = strdup ("error"); event_type = GD_OP_EVENT_RCVD_RJT; goto out; } ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gd1_mgmt_commit_op_rsp); if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); + gf_log (this->name, GF_LOG_ERROR, "Failed to decode commit " + "response received from peer"); rsp.op_ret = -1; rsp.op_errno = EINVAL; - rsp.op_errstr = "error"; + /* use standard allocation because to keep uniformity + in freeing it */ + rsp.op_errstr = strdup ("Failed to decode commit response " + "received from peer."); event_type = GD_OP_EVENT_RCVD_RJT; goto out; } @@ -1404,7 +1059,7 @@ glusterd3_1_commit_op_cbk (struct rpc_req *req, struct iovec *iov, rsp.dict.dict_len, &dict); if (ret < 0) { - gf_log ("glusterd", GF_LOG_ERROR, + gf_log (this->name, GF_LOG_ERROR, "failed to " "unserialize rsp-buffer to dictionary"); event_type = GD_OP_EVENT_RCVD_RJT; @@ -1416,15 +1071,20 @@ glusterd3_1_commit_op_cbk (struct rpc_req *req, struct iovec *iov, op_ret = rsp.op_ret; - gf_log ("glusterd", GF_LOG_INFO, - "Received %s from uuid: %s", + gf_log (this->name, (op_ret) ? GF_LOG_ERROR : GF_LOG_DEBUG, + "Received commit %s from uuid: %s", (op_ret)?"RJT":"ACC", uuid_utoa (rsp.uuid)); + ret = dict_get_bin (dict, "transaction_id", (void **)&txn_id); + + gf_log ("", GF_LOG_DEBUG, "transaction ID = %s", uuid_utoa (*txn_id)); + ret = glusterd_friend_find (rsp.uuid, NULL, &peerinfo); if (ret) { - gf_log ("", GF_LOG_CRITICAL, "Commit response received from " - "unknown peer: %s", uuid_utoa (rsp.uuid)); + gf_log (this->name, GF_LOG_CRITICAL, "Commit response for " + "'Volume %s' received from unknown peer: %s", + gd_op_list[opinfo.op], uuid_utoa (rsp.uuid)); } if (op_ret) { @@ -1437,12 +1097,11 @@ glusterd3_1_commit_op_cbk (struct rpc_req *req, struct iovec *iov, peer_str = peerinfo->hostname; else peer_str = uuid_utoa (rsp.uuid); - snprintf (err_str, sizeof (err_str), "Operation failed " - "on %s", peer_str); + snprintf (err_str, sizeof (err_str), + OPERRSTR_COMMIT_FAIL, peer_str); opinfo.op_errstr = gf_strdup (err_str); } if (!opinfo.op_errstr) { - gf_log ("", GF_LOG_ERROR, "memory allocation failed"); ret = -1; goto out; } @@ -1450,36 +1109,44 @@ glusterd3_1_commit_op_cbk (struct rpc_req *req, struct iovec *iov, event_type = GD_OP_EVENT_RCVD_ACC; switch (rsp.op) { case GD_OP_REPLACE_BRICK: - ret = glusterd_rb_use_rsp_dict (dict); + ret = glusterd_rb_use_rsp_dict (NULL, dict); if (ret) goto out; break; case GD_OP_SYNC_VOLUME: - ret = glusterd_sync_use_rsp_dict (dict); + ret = glusterd_sync_use_rsp_dict (NULL, dict); if (ret) goto out; break; case GD_OP_PROFILE_VOLUME: - ret = glusterd_profile_volume_use_rsp_dict (dict); + ret = glusterd_profile_volume_use_rsp_dict (NULL, dict); if (ret) goto out; break; case GD_OP_GSYNC_SET: - ret = glusterd_gsync_use_rsp_dict (dict, rsp.op_errstr); + ret = glusterd_gsync_use_rsp_dict (NULL, dict, rsp.op_errstr); if (ret) goto out; break; case GD_OP_STATUS_VOLUME: - ret = glusterd_volume_status_use_rsp_dict (dict); + ret = glusterd_volume_status_copy_to_op_ctx_dict (NULL, dict); if (ret) goto out; + break; case GD_OP_REBALANCE: - ret = glusterd_volume_rebalance_use_rsp_dict (dict); + case GD_OP_DEFRAG_BRICK_VOLUME: + ret = glusterd_volume_rebalance_use_rsp_dict (NULL, dict); + if (ret) + goto out; + break; + + case GD_OP_HEAL_VOLUME: + ret = glusterd_volume_heal_use_rsp_dict (NULL, dict); if (ret) goto out; @@ -1491,7 +1158,7 @@ glusterd3_1_commit_op_cbk (struct rpc_req *req, struct iovec *iov, } out: - ret = glusterd_op_sm_inject_event (event_type, NULL); + ret = glusterd_op_sm_inject_event (event_type, txn_id, NULL); if (!ret) { glusterd_friend_sm (); @@ -1500,17 +1167,22 @@ out: if (dict) dict_unref (dict); - if (rsp.op_errstr && strcmp (rsp.op_errstr, "error")) - free (rsp.op_errstr); //malloced by xdr + free (rsp.op_errstr); //malloced by xdr GLUSTERD_STACK_DESTROY (((call_frame_t *)myframe)); return ret; } - +int32_t +glusterd_commit_op_cbk (struct rpc_req *req, struct iovec *iov, + int count, void *myframe) +{ + return glusterd_big_locked_cbk (req, iov, count, myframe, + __glusterd_commit_op_cbk); +} int32_t -glusterd3_1_probe (call_frame_t *frame, xlator_t *this, - void *data) +glusterd_rpc_probe (call_frame_t *frame, xlator_t *this, + void *data) { gd1_mgmt_probe_req req = {{0},}; int ret = 0; @@ -1540,26 +1212,25 @@ glusterd3_1_probe (call_frame_t *frame, xlator_t *this, if (ret) goto out; - uuid_copy (req.uuid, priv->uuid); + uuid_copy (req.uuid, MY_UUID); req.hostname = gf_strdup (hostname); req.port = port; - ret = glusterd_submit_request (peerinfo->rpc, &req, frame, peerinfo->mgmt, - GD_MGMT_PROBE_QUERY, - NULL, this, glusterd3_1_probe_cbk, + ret = glusterd_submit_request (peerinfo->rpc, &req, frame, peerinfo->peer, + GLUSTERD_PROBE_QUERY, + NULL, this, glusterd_probe_cbk, (xdrproc_t)xdr_gd1_mgmt_probe_req); out: - if (req.hostname) - GF_FREE (req.hostname); + GF_FREE (req.hostname); gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret); return ret; } int32_t -glusterd3_1_friend_add (call_frame_t *frame, xlator_t *this, - void *data) +glusterd_rpc_friend_add (call_frame_t *frame, xlator_t *this, + void *data) { gd1_mgmt_friend_req req = {{0},}; int ret = 0; @@ -1585,24 +1256,23 @@ glusterd3_1_friend_add (call_frame_t *frame, xlator_t *this, if (ret) goto out; - uuid_copy (req.uuid, priv->uuid); + uuid_copy (req.uuid, MY_UUID); req.hostname = peerinfo->hostname; req.port = peerinfo->port; ret = dict_allocate_and_serialize (vols, &req.vols.vols_val, - (size_t *)&req.vols.vols_len); + &req.vols.vols_len); if (ret) goto out; - ret = glusterd_submit_request (peerinfo->rpc, &req, frame, peerinfo->mgmt, - GD_MGMT_FRIEND_ADD, - NULL, this, glusterd3_1_friend_add_cbk, + ret = glusterd_submit_request (peerinfo->rpc, &req, frame, peerinfo->peer, + GLUSTERD_FRIEND_ADD, + NULL, this, glusterd_friend_add_cbk, (xdrproc_t)xdr_gd1_mgmt_friend_req); out: - if (req.vols.vols_val) - GF_FREE (req.vols.vols_val); + GF_FREE (req.vols.vols_val); if (vols) dict_unref (vols); @@ -1612,8 +1282,8 @@ out: } int32_t -glusterd3_1_friend_remove (call_frame_t *frame, xlator_t *this, - void *data) +glusterd_rpc_friend_remove (call_frame_t *frame, xlator_t *this, + void *data) { gd1_mgmt_friend_req req = {{0},}; int ret = 0; @@ -1633,12 +1303,12 @@ glusterd3_1_friend_remove (call_frame_t *frame, xlator_t *this, peerinfo = event->peerinfo; - uuid_copy (req.uuid, priv->uuid); + uuid_copy (req.uuid, MY_UUID); req.hostname = peerinfo->hostname; req.port = peerinfo->port; - ret = glusterd_submit_request (peerinfo->rpc, &req, frame, peerinfo->mgmt, - GD_MGMT_FRIEND_REMOVE, NULL, - this, glusterd3_1_friend_remove_cbk, + ret = glusterd_submit_request (peerinfo->rpc, &req, frame, peerinfo->peer, + GLUSTERD_FRIEND_REMOVE, NULL, + this, glusterd_friend_remove_cbk, (xdrproc_t)xdr_gd1_mgmt_friend_req); out: @@ -1648,15 +1318,13 @@ out: int32_t -glusterd3_1_friend_update (call_frame_t *frame, xlator_t *this, - void *data) +glusterd_rpc_friend_update (call_frame_t *frame, xlator_t *this, + void *data) { gd1_mgmt_friend_update req = {{0},}; int ret = 0; glusterd_conf_t *priv = NULL; dict_t *friends = NULL; - char *dict_buf = NULL; - size_t len = -1; call_frame_t *dummy_frame = NULL; glusterd_peerinfo_t *peerinfo = NULL; @@ -1671,32 +1339,29 @@ glusterd3_1_friend_update (call_frame_t *frame, xlator_t *this, if (ret) goto out; - ret = dict_allocate_and_serialize (friends, &dict_buf, (size_t *)&len); + ret = dict_allocate_and_serialize (friends, &req.friends.friends_val, + &req.friends.friends_len); if (ret) goto out; - req.friends.friends_val = dict_buf; - req.friends.friends_len = len; - - uuid_copy (req.uuid, priv->uuid); + uuid_copy (req.uuid, MY_UUID); dummy_frame = create_frame (this, this->ctx->pool); ret = glusterd_submit_request (peerinfo->rpc, &req, dummy_frame, - peerinfo->mgmt, - GD_MGMT_FRIEND_UPDATE, NULL, - this, glusterd3_1_friend_update_cbk, + peerinfo->peer, + GLUSTERD_FRIEND_UPDATE, NULL, + this, glusterd_friend_update_cbk, (xdrproc_t)xdr_gd1_mgmt_friend_update); out: - if (req.friends.friends_val) - GF_FREE (req.friends.friends_val); + GF_FREE (req.friends.friends_val); gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret); return ret; } int32_t -glusterd3_1_cluster_lock (call_frame_t *frame, xlator_t *this, +glusterd_cluster_lock (call_frame_t *frame, xlator_t *this, void *data) { gd1_mgmt_cluster_lock_req req = {{0},}; @@ -1720,17 +1385,145 @@ glusterd3_1_cluster_lock (call_frame_t *frame, xlator_t *this, goto out; ret = glusterd_submit_request (peerinfo->rpc, &req, dummy_frame, - peerinfo->mgmt, GD_MGMT_CLUSTER_LOCK, + peerinfo->mgmt, GLUSTERD_MGMT_CLUSTER_LOCK, NULL, - this, glusterd3_1_cluster_lock_cbk, + this, glusterd_cluster_lock_cbk, (xdrproc_t)xdr_gd1_mgmt_cluster_lock_req); out: - gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret); + gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret); return ret; } int32_t -glusterd3_1_cluster_unlock (call_frame_t *frame, xlator_t *this, +glusterd_mgmt_v3_lock_peers (call_frame_t *frame, xlator_t *this, + void *data) +{ + gd1_mgmt_v3_lock_req req = {{0},}; + int ret = -1; + glusterd_peerinfo_t *peerinfo = NULL; + glusterd_conf_t *priv = NULL; + call_frame_t *dummy_frame = NULL; + dict_t *dict = NULL; + uuid_t *txn_id = NULL; + + if (!this) + goto out; + + dict = data; + + priv = this->private; + GF_ASSERT (priv); + + ret = dict_get_ptr (dict, "peerinfo", VOID (&peerinfo)); + if (ret) + goto out; + + //peerinfo should not be in payload + dict_del (dict, "peerinfo"); + + glusterd_get_uuid (&req.uuid); + + ret = dict_allocate_and_serialize (dict, &req.dict.dict_val, + &req.dict.dict_len); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to serialize dict " + "to request buffer"); + goto out; + } + + /* Sending valid transaction ID to peers */ + ret = dict_get_bin (dict, "transaction_id", + (void **)&txn_id); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "Failed to get transaction id."); + goto out; + } else { + gf_log (this->name, GF_LOG_DEBUG, + "Transaction_id = %s", uuid_utoa (*txn_id)); + uuid_copy (req.txn_id, *txn_id); + } + + dummy_frame = create_frame (this, this->ctx->pool); + if (!dummy_frame) + goto out; + + ret = glusterd_submit_request (peerinfo->rpc, &req, dummy_frame, + peerinfo->mgmt_v3, + GLUSTERD_MGMT_V3_LOCK, NULL, + this, glusterd_mgmt_v3_lock_peers_cbk, + (xdrproc_t)xdr_gd1_mgmt_v3_lock_req); +out: + gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret); + return ret; +} + +int32_t +glusterd_mgmt_v3_unlock_peers (call_frame_t *frame, xlator_t *this, + void *data) +{ + gd1_mgmt_v3_unlock_req req = {{0},}; + int ret = -1; + glusterd_peerinfo_t *peerinfo = NULL; + glusterd_conf_t *priv = NULL; + call_frame_t *dummy_frame = NULL; + dict_t *dict = NULL; + uuid_t *txn_id = NULL; + + if (!this) + goto out; + + dict = data; + + priv = this->private; + GF_ASSERT (priv); + + ret = dict_get_ptr (dict, "peerinfo", VOID (&peerinfo)); + if (ret) + goto out; + + //peerinfo should not be in payload + dict_del (dict, "peerinfo"); + + glusterd_get_uuid (&req.uuid); + + ret = dict_allocate_and_serialize (dict, &req.dict.dict_val, + &req.dict.dict_len); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to serialize dict " + "to request buffer"); + goto out; + } + + /* Sending valid transaction ID to peers */ + ret = dict_get_bin (dict, "transaction_id", + (void **)&txn_id); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "Failed to get transaction id."); + goto out; + } else { + gf_log (this->name, GF_LOG_DEBUG, + "Transaction_id = %s", uuid_utoa (*txn_id)); + uuid_copy (req.txn_id, *txn_id); + } + + dummy_frame = create_frame (this, this->ctx->pool); + if (!dummy_frame) + goto out; + + ret = glusterd_submit_request (peerinfo->rpc, &req, dummy_frame, + peerinfo->mgmt_v3, + GLUSTERD_MGMT_V3_UNLOCK, NULL, + this, glusterd_mgmt_v3_unlock_peers_cbk, + (xdrproc_t)xdr_gd1_mgmt_v3_unlock_req); +out: + gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret); + return ret; +} + +int32_t +glusterd_cluster_unlock (call_frame_t *frame, xlator_t *this, void *data) { gd1_mgmt_cluster_lock_req req = {{0},}; @@ -1754,17 +1547,17 @@ glusterd3_1_cluster_unlock (call_frame_t *frame, xlator_t *this, goto out; ret = glusterd_submit_request (peerinfo->rpc, &req, dummy_frame, - peerinfo->mgmt, GD_MGMT_CLUSTER_UNLOCK, + peerinfo->mgmt, GLUSTERD_MGMT_CLUSTER_UNLOCK, NULL, - this, glusterd3_1_cluster_unlock_cbk, + this, glusterd_cluster_unlock_cbk, (xdrproc_t)xdr_gd1_mgmt_cluster_unlock_req); out: - gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret); + gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret); return ret; } int32_t -glusterd3_1_stage_op (call_frame_t *frame, xlator_t *this, +glusterd_stage_op (call_frame_t *frame, xlator_t *this, void *data) { gd1_mgmt_stage_op_req req = {{0,},}; @@ -1794,40 +1587,35 @@ glusterd3_1_stage_op (call_frame_t *frame, xlator_t *this, glusterd_get_uuid (&req.uuid); req.op = glusterd_op_get_op (); - if (GD_OP_DELETE_VOLUME == req.op) { - ret = dict_get_str (dict, "volname", &req.buf.buf_val); - if (ret) - goto out; - req.buf.buf_len = strlen (req.buf.buf_val); - is_alloc = _gf_false; - } else { - ret = dict_allocate_and_serialize (dict, &req.buf.buf_val, - (size_t *)&req.buf.buf_len); - - if (ret) - goto out; + ret = dict_allocate_and_serialize (dict, &req.buf.buf_val, + &req.buf.buf_len); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to serialize dict " + "to request buffer"); + goto out; } + dummy_frame = create_frame (this, this->ctx->pool); if (!dummy_frame) goto out; ret = glusterd_submit_request (peerinfo->rpc, &req, dummy_frame, - peerinfo->mgmt, GD_MGMT_STAGE_OP, + peerinfo->mgmt, GLUSTERD_MGMT_STAGE_OP, NULL, - this, glusterd3_1_stage_op_cbk, + this, glusterd_stage_op_cbk, (xdrproc_t)xdr_gd1_mgmt_stage_op_req); out: if ((_gf_true == is_alloc) && req.buf.buf_val) GF_FREE (req.buf.buf_val); - gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret); + gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret); return ret; } int32_t -glusterd3_1_commit_op (call_frame_t *frame, xlator_t *this, +glusterd_commit_op (call_frame_t *frame, xlator_t *this, void *data) { gd1_mgmt_commit_op_req req = {{0,},}; @@ -1856,18 +1644,12 @@ glusterd3_1_commit_op (call_frame_t *frame, xlator_t *this, glusterd_get_uuid (&req.uuid); req.op = glusterd_op_get_op (); - if (GD_OP_DELETE_VOLUME == req.op) { - ret = dict_get_str (dict, "volname", &req.buf.buf_val); - if (ret) - goto out; - req.buf.buf_len = strlen (req.buf.buf_val); - is_alloc = _gf_false; - } else { - ret = dict_allocate_and_serialize (dict, &req.buf.buf_val, - (size_t *)&req.buf.buf_len); - - if (ret) - goto out; + ret = dict_allocate_and_serialize (dict, &req.buf.buf_val, + &req.buf.buf_len); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to serialize dict to " + "request buffer"); + goto out; } dummy_frame = create_frame (this, this->ctx->pool); @@ -1875,45 +1657,21 @@ glusterd3_1_commit_op (call_frame_t *frame, xlator_t *this, goto out; ret = glusterd_submit_request (peerinfo->rpc, &req, dummy_frame, - peerinfo->mgmt, GD_MGMT_COMMIT_OP, + peerinfo->mgmt, GLUSTERD_MGMT_COMMIT_OP, NULL, - this, glusterd3_1_commit_op_cbk, + this, glusterd_commit_op_cbk, (xdrproc_t)xdr_gd1_mgmt_commit_op_req); out: if ((_gf_true == is_alloc) && req.buf.buf_val) GF_FREE (req.buf.buf_val); - gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret); + gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret); return ret; } int32_t -glusterd_start_brick_disconnect_timer (glusterd_op_brick_rsp_ctx_t *ev_ctx) -{ - struct timeval timeout = {0, }; - int32_t ret = -1; - xlator_t *this = NULL; - glusterd_brickinfo_t *brickinfo = NULL; - - timeout.tv_sec = 5; - timeout.tv_usec = 0; - brickinfo = ev_ctx->brickinfo; - GF_ASSERT (brickinfo); - this = THIS; - GF_ASSERT (this); - - brickinfo->timer = gf_timer_call_after (this->ctx, timeout, - glusterd_op_brick_disconnect, - (void *) ev_ctx); - - ret = 0; - - return ret; -} - -int32_t -glusterd3_1_brick_op_cbk (struct rpc_req *req, struct iovec *iov, +__glusterd_brick_op_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { gd1_mgmt_brick_op_rsp rsp = {0}; @@ -1922,26 +1680,37 @@ glusterd3_1_brick_op_cbk (struct rpc_req *req, struct iovec *iov, glusterd_op_sm_event_type_t event_type = GD_OP_EVENT_NONE; call_frame_t *frame = NULL; glusterd_op_brick_rsp_ctx_t *ev_ctx = NULL; - int32_t op = -1; dict_t *dict = NULL; + int index = 0; + glusterd_req_ctx_t *req_ctx = NULL; + glusterd_pending_node_t *node = NULL; + xlator_t *this = NULL; + uuid_t *txn_id = &global_txn_id; + + this = THIS; + GF_ASSERT (this); GF_ASSERT (req); frame = myframe; + req_ctx = frame->local; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = EINVAL; - rsp.op_errstr = "error"; + /* use standard allocation because to keep uniformity + in freeing it */ + rsp.op_errstr = strdup ("error"); event_type = GD_OP_EVENT_RCVD_RJT; goto out; } ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gd1_mgmt_brick_op_rsp); if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); + gf_log (this->name, GF_LOG_ERROR, "Failed to decode brick op " + "response received"); rsp.op_ret = -1; rsp.op_errno = EINVAL; - rsp.op_errstr = strdup ("Unable to decode response"); + rsp.op_errstr = strdup ("Unable to decode brick op response"); event_type = GD_OP_EVENT_RCVD_RJT; goto out; } @@ -1954,8 +1723,7 @@ glusterd3_1_brick_op_cbk (struct rpc_req *req, struct iovec *iov, rsp.output.output_len, &dict); if (ret < 0) { - gf_log ("glusterd", GF_LOG_ERROR, - "failed to " + gf_log (this->name, GF_LOG_ERROR, "Failed to " "unserialize rsp-buffer to dictionary"); event_type = GD_OP_EVENT_RCVD_RJT; goto out; @@ -1966,7 +1734,25 @@ glusterd3_1_brick_op_cbk (struct rpc_req *req, struct iovec *iov, op_ret = rsp.op_ret; + /* Add index to rsp_dict for GD_OP_STATUS_VOLUME */ + if (GD_OP_STATUS_VOLUME == req_ctx->op) { + node = frame->cookie; + index = node->index; + ret = dict_set_int32 (dict, "index", index); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "Error setting index on brick status rsp dict"); + rsp.op_ret = -1; + event_type = GD_OP_EVENT_RCVD_RJT; + goto out; + } + } out: + + ret = dict_get_bin (req_ctx->dict, "transaction_id", (void **)&txn_id); + + gf_log ("", GF_LOG_DEBUG, "transaction ID = %s", uuid_utoa (*txn_id)); + ev_ctx = GF_CALLOC (1, sizeof (*ev_ctx), gf_gld_mt_brick_rsp_ctx_t); GF_ASSERT (ev_ctx); if (op_ret) { @@ -1976,96 +1762,46 @@ out: } else { event_type = GD_OP_EVENT_RCVD_ACC; } - ev_ctx->brickinfo = frame->cookie; + ev_ctx->pending_node = frame->cookie; ev_ctx->rsp_dict = dict; ev_ctx->commit_ctx = frame->local; - op = glusterd_op_get_op (); - if ((op == GD_OP_STOP_VOLUME) || - (op == GD_OP_REMOVE_BRICK)) { - ret = glusterd_start_brick_disconnect_timer (ev_ctx); - } else { - ret = glusterd_op_sm_inject_event (event_type, ev_ctx); - if (!ret) { - glusterd_friend_sm (); - glusterd_op_sm (); - } + ret = glusterd_op_sm_inject_event (event_type, txn_id, ev_ctx); + if (!ret) { + glusterd_friend_sm (); + glusterd_op_sm (); } if (ret && dict) dict_unref (dict); - if (rsp.op_errstr && strcmp (rsp.op_errstr, "error")) - free (rsp.op_errstr); //malloced by xdr + free (rsp.op_errstr); //malloced by xdr GLUSTERD_STACK_DESTROY (frame); return ret; } - -struct rpc_clnt_procedure glusterd3_1_clnt_mgmt_actors[GD_MGMT_MAXVALUE] = { - [GD_MGMT_NULL] = {"NULL", NULL }, - [GD_MGMT_PROBE_QUERY] = { "PROBE_QUERY", glusterd3_1_probe}, - [GD_MGMT_FRIEND_ADD] = { "FRIEND_ADD", glusterd3_1_friend_add }, - [GD_MGMT_CLUSTER_LOCK] = {"CLUSTER_LOCK", glusterd3_1_cluster_lock}, - [GD_MGMT_CLUSTER_UNLOCK] = {"CLUSTER_UNLOCK", glusterd3_1_cluster_unlock}, - [GD_MGMT_STAGE_OP] = {"STAGE_OP", glusterd3_1_stage_op}, - [GD_MGMT_COMMIT_OP] = {"COMMIT_OP", glusterd3_1_commit_op}, - [GD_MGMT_FRIEND_REMOVE] = { "FRIEND_REMOVE", glusterd3_1_friend_remove}, - [GD_MGMT_FRIEND_UPDATE] = { "FRIEND_UPDATE", glusterd3_1_friend_update}, -}; - -struct rpc_clnt_procedure glusterd3_1_fs_mgmt_actors[GD_MGMT_MAXVALUE] = { - [GD_MGMT_NULL] = {"NULL", NULL }, - [GD_MGMT_BRICK_OP] = {"BRICK_OP", glusterd3_1_brick_op}, -}; - -struct rpc_clnt_program glusterd3_1_mgmt_prog = { - .progname = "Mgmt 3.1", - .prognum = GLUSTERD1_MGMT_PROGRAM, - .progver = GLUSTERD1_MGMT_VERSION, - .proctable = glusterd3_1_clnt_mgmt_actors, - .numproc = GLUSTERD1_MGMT_PROCCNT, -}; - -struct rpc_clnt_procedure gd_clnt_mgmt_actors[GLUSTERD_MGMT_MAXVALUE] = { - [GLUSTERD_MGMT_NULL] = {"NULL", NULL }, - [GLUSTERD_MGMT_PROBE_QUERY] = {"PROBE_QUERY", glusterd3_1_probe}, - [GLUSTERD_MGMT_FRIEND_ADD] = {"FRIEND_ADD", glusterd3_1_friend_add}, - [GLUSTERD_MGMT_CLUSTER_LOCK] = {"CLUSTER_LOCK", glusterd3_1_cluster_lock}, - [GLUSTERD_MGMT_CLUSTER_UNLOCK] = {"CLUSTER_UNLOCK", glusterd3_1_cluster_unlock}, - [GLUSTERD_MGMT_STAGE_OP] = {"STAGE_OP", glusterd3_1_stage_op}, - [GLUSTERD_MGMT_COMMIT_OP] = {"COMMIT_OP", glusterd3_1_commit_op}, - [GLUSTERD_MGMT_FRIEND_REMOVE] = {"FRIEND_REMOVE", glusterd3_1_friend_remove}, - [GLUSTERD_MGMT_FRIEND_UPDATE] = {"FRIEND_UPDATE", glusterd3_1_friend_update}, -}; - -struct rpc_clnt_program gd_clnt_mgmt_prog = { - .progname = "glusterd clnt mgmt", - .prognum = GD_MGMT_PROGRAM, - .progver = GD_MGMT_VERSION, - .numproc = GD_MGMT_PROCCNT, - .proctable = gd_clnt_mgmt_actors, -}; - -struct rpc_clnt_program glusterd_glusterfs_3_1_mgmt_prog = { - .progname = "GlusterFS Mops", - .prognum = GLUSTERFS_PROGRAM, - .progver = GLUSTERFS_VERSION, - .proctable = glusterd3_1_fs_mgmt_actors, - .numproc = GLUSTERFS_PROCCNT, -}; +int32_t +glusterd_brick_op_cbk (struct rpc_req *req, struct iovec *iov, + int count, void *myframe) +{ + return glusterd_big_locked_cbk (req, iov, count, myframe, + __glusterd_brick_op_cbk); +} int32_t -glusterd3_1_brick_op (call_frame_t *frame, xlator_t *this, +glusterd_brick_op (call_frame_t *frame, xlator_t *this, void *data) { + gd1_mgmt_brick_op_req *req = NULL; int ret = 0; glusterd_conf_t *priv = NULL; call_frame_t *dummy_frame = NULL; char *op_errstr = NULL; int pending_bricks = 0; - glusterd_pending_node_t *pending_brick; - glusterd_brickinfo_t *brickinfo = NULL; - glusterd_req_ctx_t *req_ctx = NULL; + glusterd_pending_node_t *pending_node; + glusterd_req_ctx_t *req_ctx = NULL; + struct rpc_clnt *rpc = NULL; + dict_t *op_ctx = NULL; + uuid_t *txn_id = &global_txn_id; if (!this) { ret = -1; @@ -2077,40 +1813,85 @@ glusterd3_1_brick_op (call_frame_t *frame, xlator_t *this, req_ctx = data; GF_ASSERT (req_ctx); INIT_LIST_HEAD (&opinfo.pending_bricks); - ret = glusterd_op_bricks_select (req_ctx->op, req_ctx->dict, &op_errstr); + ret = glusterd_op_bricks_select (req_ctx->op, req_ctx->dict, &op_errstr, + &opinfo.pending_bricks, NULL); if (ret) { - gf_log ("", GF_LOG_ERROR, "Brick Op failed"); + gf_log (this->name, GF_LOG_ERROR, "Failed to select bricks " + "while performing brick op during 'Volume %s'", + gd_op_list[opinfo.op]); opinfo.op_errstr = op_errstr; goto out; } - list_for_each_entry (pending_brick, &opinfo.pending_bricks, list) { - dummy_frame = create_frame (this, this->ctx->pool); - brickinfo = pending_brick->node; + ret = dict_get_bin (req_ctx->dict, "transaction_id", (void **)&txn_id); + + gf_log ("", GF_LOG_DEBUG, "transaction ID = %s", uuid_utoa (*txn_id)); + + list_for_each_entry (pending_node, &opinfo.pending_bricks, list) { + dummy_frame = create_frame (this, this->ctx->pool); if (!dummy_frame) continue; - if (_gf_false == glusterd_is_brick_started (brickinfo)) - continue; - ret = glusterd_brick_op_build_payload (req_ctx->op, brickinfo, - (gd1_mgmt_brick_op_req **)&req, - req_ctx->dict); + if ((pending_node->type == GD_NODE_NFS) || + ((pending_node->type == GD_NODE_SHD) && + (req_ctx->op == GD_OP_STATUS_VOLUME))) + ret = glusterd_node_op_build_payload + (req_ctx->op, + (gd1_mgmt_brick_op_req **)&req, + req_ctx->dict); + else { + ret = glusterd_brick_op_build_payload + (req_ctx->op, pending_node->node, + (gd1_mgmt_brick_op_req **)&req, + req_ctx->dict); - if (ret) - goto out; + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to " + "build brick op payload during " + "'Volume %s'", gd_op_list[req_ctx->op]); + goto out; + } + } dummy_frame->local = data; - dummy_frame->cookie = brickinfo; - ret = glusterd_submit_request (brickinfo->rpc, req, dummy_frame, - &glusterd_glusterfs_3_1_mgmt_prog, + dummy_frame->cookie = pending_node; + + rpc = glusterd_pending_node_get_rpc (pending_node); + if (!rpc) { + if (pending_node->type == GD_NODE_REBALANCE) { + opinfo.brick_pending_count = 0; + ret = 0; + if (req) { + GF_FREE (req->input.input_val); + GF_FREE (req); + req = NULL; + } + GLUSTERD_STACK_DESTROY (dummy_frame); + + op_ctx = glusterd_op_get_ctx (); + if (!op_ctx) + goto out; + glusterd_defrag_volume_node_rsp (req_ctx->dict, + NULL, op_ctx); + + goto out; + } + + ret = -1; + gf_log (this->name, GF_LOG_ERROR, "Brick Op failed " + "due to rpc failure."); + goto out; + } + + ret = glusterd_submit_request (rpc, req, dummy_frame, + priv->gfs_mgmt, req->op, NULL, - this, glusterd3_1_brick_op_cbk, + this, glusterd_brick_op_cbk, (xdrproc_t)xdr_gd1_mgmt_brick_op_req); if (req) { - if (req->input.input_val) - GF_FREE (req->input.input_val); + GF_FREE (req->input.input_val); GF_FREE (req); req = NULL; } @@ -2118,15 +1899,76 @@ glusterd3_1_brick_op (call_frame_t *frame, xlator_t *this, pending_bricks++; } - gf_log ("glusterd", GF_LOG_DEBUG, "Sent op req to %d bricks", - pending_bricks); + gf_log (this->name, GF_LOG_DEBUG, "Sent brick op req for operation " + "'Volume %s' to %d bricks", gd_op_list[req_ctx->op], + pending_bricks); opinfo.brick_pending_count = pending_bricks; out: if (ret) { - glusterd_op_sm_inject_event (GD_OP_EVENT_RCVD_RJT, data); + glusterd_op_sm_inject_event (GD_OP_EVENT_RCVD_RJT, + txn_id, data); opinfo.op_ret = ret; } - gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret); + gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret); return ret; } + +struct rpc_clnt_procedure gd_brick_actors[GLUSTERD_BRICK_MAXVALUE] = { + [GLUSTERD_BRICK_NULL] = {"NULL", NULL }, + [GLUSTERD_BRICK_OP] = {"BRICK_OP", glusterd_brick_op}, +}; + +struct rpc_clnt_procedure gd_peer_actors[GLUSTERD_FRIEND_MAXVALUE] = { + [GLUSTERD_FRIEND_NULL] = {"NULL", NULL }, + [GLUSTERD_PROBE_QUERY] = {"PROBE_QUERY", glusterd_rpc_probe}, + [GLUSTERD_FRIEND_ADD] = {"FRIEND_ADD", glusterd_rpc_friend_add}, + [GLUSTERD_FRIEND_REMOVE] = {"FRIEND_REMOVE", glusterd_rpc_friend_remove}, + [GLUSTERD_FRIEND_UPDATE] = {"FRIEND_UPDATE", glusterd_rpc_friend_update}, +}; + +struct rpc_clnt_procedure gd_mgmt_actors[GLUSTERD_MGMT_MAXVALUE] = { + [GLUSTERD_MGMT_NULL] = {"NULL", NULL }, + [GLUSTERD_MGMT_CLUSTER_LOCK] = {"CLUSTER_LOCK", glusterd_cluster_lock}, + [GLUSTERD_MGMT_CLUSTER_UNLOCK] = {"CLUSTER_UNLOCK", glusterd_cluster_unlock}, + [GLUSTERD_MGMT_STAGE_OP] = {"STAGE_OP", glusterd_stage_op}, + [GLUSTERD_MGMT_COMMIT_OP] = {"COMMIT_OP", glusterd_commit_op}, +}; + +struct rpc_clnt_procedure gd_mgmt_v3_actors[GLUSTERD_MGMT_V3_MAXVALUE] = { + [GLUSTERD_MGMT_V3_NULL] = {"NULL", NULL }, + [GLUSTERD_MGMT_V3_LOCK] = {"MGMT_V3_LOCK", glusterd_mgmt_v3_lock_peers}, + [GLUSTERD_MGMT_V3_UNLOCK] = {"MGMT_V3_UNLOCK", glusterd_mgmt_v3_unlock_peers}, +}; + +struct rpc_clnt_program gd_mgmt_prog = { + .progname = "glusterd mgmt", + .prognum = GD_MGMT_PROGRAM, + .progver = GD_MGMT_VERSION, + .proctable = gd_mgmt_actors, + .numproc = GLUSTERD_MGMT_MAXVALUE, +}; + +struct rpc_clnt_program gd_brick_prog = { + .progname = "brick operations", + .prognum = GD_BRICK_PROGRAM, + .progver = GD_BRICK_VERSION, + .proctable = gd_brick_actors, + .numproc = GLUSTERD_BRICK_MAXVALUE, +}; + +struct rpc_clnt_program gd_peer_prog = { + .progname = "Peer mgmt", + .prognum = GD_FRIEND_PROGRAM, + .progver = GD_FRIEND_VERSION, + .proctable = gd_peer_actors, + .numproc = GLUSTERD_FRIEND_MAXVALUE, +}; + +struct rpc_clnt_program gd_mgmt_v3_prog = { + .progname = "glusterd mgmt v3", + .prognum = GD_MGMT_V3_PROGRAM, + .progver = GD_MGMT_V3_VERSION, + .proctable = gd_mgmt_v3_actors, + .numproc = GLUSTERD_MGMT_V3_MAXVALUE, +}; |
