diff options
author | Amar Tumballi <amar@gluster.com> | 2011-09-09 09:42:51 +0530 |
---|---|---|
committer | Vijay Bellur <vijay@gluster.com> | 2011-09-13 02:10:12 -0700 |
commit | 25daa42911d2ff697880ee29c591cac5f2abebed (patch) | |
tree | 9555284c052e1e205909e91f578a8b46b522ec56 /cli/src/cli-rpc-ops.c | |
parent | 17e57f27c714c94dd5d9fa91650f83d069f2f4e4 (diff) |
support for de-commissioning a node using 'remove-brick'
to achieve this, we now create volume-file with
'decommissioned-nodes' option in distribute volume, then just
perform the rebalance set of operations (with 'force' flag set).
now onwards, the 'remove-brick' (with 'start' option) operation tries
to migrate data from removed bricks to existing bricks.
'remove-brick' also supports similar options as of replace-brick.
* (no options) -> works as 'force', will have the current behavior
of remove-brick, ie., no data-migration, volume changes.
* start (starts remove-brick with data-migration/draining process,
which takes care of migrating data and once complete, will
commit the changes to volume file)
* pause (stop data migration, but keep the volume file intact with
extra options whatever is set)
* abort (stop data-migration, and fall back to old configuration)
* commit (if volume is stopped, commits the changes to volumefile)
* force (stops the data-migration and commits the changes to
volume file)
Change-Id: I3952bcfbe604a0952e68b6accace7014d5e401d3
BUG: 1952
Reviewed-on: http://review.gluster.com/118
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Vijay Bellur <vijay@gluster.com>
Diffstat (limited to 'cli/src/cli-rpc-ops.c')
-rw-r--r-- | cli/src/cli-rpc-ops.c | 160 |
1 files changed, 136 insertions, 24 deletions
diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c index 3d6ce25ef1b..d7a5988f238 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -856,23 +856,36 @@ gf_cli3_1_defrag_volume_cbk (struct rpc_req *req, struct iovec *iov, "rebalance process"); goto done; } - if (rsp.op_errno == 0) + + switch (rsp.op_errno) { + case GF_DEFRAG_STATUS_NOT_STARTED: status = "not started"; - if (rsp.op_errno == 1) + break; + case GF_DEFRAG_STATUS_LAYOUT_FIX_STARTED: status = "step 1: layout fix in progress"; - if (rsp.op_errno == 2) + break; + case GF_DEFRAG_STATUS_MIGRATE_DATA_STARTED: status = "step 2: data migration in progress"; - if (rsp.op_errno == 3) + break; + case GF_DEFRAG_STATUS_STOPPED: status = "stopped"; - if (rsp.op_errno == 4) + break; + case GF_DEFRAG_STATUS_COMPLETE: status = "completed"; - if (rsp.op_errno == 5) + break; + case GF_DEFRAG_STATUS_FAILED: status = "failed"; - if (rsp.op_errno == 6) + break; + case GF_DEFRAG_STATUS_LAYOUT_FIX_COMPLETE: status = "step 1: layout fix complete"; - if (rsp.op_errno == 7) + break; + case GF_DEFRAG_STATUS_MIGRATE_DATA_COMPLETE: status = "step 2: data migration complete"; - + break; + case GF_DEFRAG_STATUS_PAUSED: + status = "paused"; + break; + } if (rsp.files && (rsp.op_errno == 1)) { cli_out ("rebalance %s: fixed layout %"PRId64, status, rsp.files); @@ -1064,6 +1077,87 @@ out: return ret; } +int +gf_cli3_remove_brick_status_cbk (struct rpc_req *req, struct iovec *iov, + int count, void *myframe) +{ + gf2_cli_defrag_vol_rsp rsp = {0,}; + char *status = "unknown"; + int ret = 0; + + if (-1 == req->rpc_status) { + goto out; + } + + ret = xdr_to_generic (*iov, &rsp, + (xdrproc_t)xdr_gf2_cli_defrag_vol_rsp); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "error"); + goto out; + } + + ret = rsp.op_ret; + if (rsp.op_ret == -1) { + if (strcmp (rsp.op_errstr, "")) + cli_out ("%s", rsp.op_errstr); + else + cli_out ("failed to get the status of " + "remove-brick process"); + goto out; + } + + switch (rsp.op_errno) { + case GF_DEFRAG_STATUS_NOT_STARTED: + status = "not started"; + break; + case GF_DEFRAG_STATUS_LAYOUT_FIX_STARTED: + case GF_DEFRAG_STATUS_MIGRATE_DATA_STARTED: + case GF_DEFRAG_STATUS_LAYOUT_FIX_COMPLETE: + status = "in progress"; + break; + case GF_DEFRAG_STATUS_STOPPED: + status = "stopped"; + break; + case GF_DEFRAG_STATUS_COMPLETE: + case GF_DEFRAG_STATUS_MIGRATE_DATA_COMPLETE: + status = "completed"; + break; + case GF_DEFRAG_STATUS_FAILED: + status = "failed"; + break; + case GF_DEFRAG_STATUS_PAUSED: + status = "paused"; + break; + } + + if (rsp.files && (rsp.op_errno == 1)) { + cli_out ("remove-brick %s: fixed layout %"PRId64, + status, rsp.files); + goto out; + } + if (rsp.files && (rsp.op_errno == 6)) { + cli_out ("remove-brick %s: fixed layout %"PRId64, + status, rsp.files); + goto out; + } + if (rsp.files) { + cli_out ("remove-brick %s: decommissioned %"PRId64 + " files of size %"PRId64, status, + rsp.files, rsp.size); + goto out; + } + + cli_out ("remove-brick %s", status); + +out: + if (rsp.op_errstr) + free (rsp.op_errstr); //malloced by xdr + if (rsp.volname) + free (rsp.volname); //malloced by xdr + cli_cmd_broadcast_response (ret); + return ret; +} + int gf_cli3_1_remove_brick_cbk (struct rpc_req *req, struct iovec *iov, @@ -2160,8 +2254,11 @@ gf_cli3_1_remove_brick (call_frame_t *frame, xlator_t *this, void *data) { gf1_cli_remove_brick_req req = {0,}; + gf1_cli_defrag_vol_req status_req = {0,}; int ret = 0; - dict_t *dict = NULL; + dict_t *dict = NULL; + int32_t command = 0; + char *volname = NULL; if (!frame || !this || !data) { ret = -1; @@ -2170,30 +2267,45 @@ gf_cli3_1_remove_brick (call_frame_t *frame, xlator_t *this, dict = data; - ret = dict_get_str (dict, "volname", &req.volname); - + ret = dict_get_str (dict, "volname", &volname); if (ret) goto out; ret = dict_get_int32 (dict, "count", &req.count); - if (ret) goto out; - ret = dict_allocate_and_serialize (dict, - &req.bricks.bricks_val, - (size_t *)&req.bricks.bricks_len); - if (ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "failed to get serialized length of dict"); + ret = dict_get_int32 (dict, "command", &command); + if (ret) goto out; - } - ret = cli_cmd_submit (&req, frame, cli_rpc_prog, - GLUSTER_CLI_REMOVE_BRICK, NULL, - this, gf_cli3_1_remove_brick_cbk, - (xdrproc_t) xdr_gf1_cli_remove_brick_req); + if (command != GF_OP_CMD_STATUS) { + req.volname = volname; + + ret = dict_allocate_and_serialize (dict, + &req.bricks.bricks_val, + (size_t *)&req.bricks.bricks_len); + if (ret < 0) { + gf_log (this->name, GF_LOG_DEBUG, + "failed to get serialized length of dict"); + goto out; + } + + ret = cli_cmd_submit (&req, frame, cli_rpc_prog, + GLUSTER_CLI_REMOVE_BRICK, NULL, + this, gf_cli3_1_remove_brick_cbk, + (xdrproc_t) xdr_gf1_cli_remove_brick_req); + } else { + /* Need rebalance status to e sent :-) */ + status_req.volname = volname; + status_req.cmd = GF_DEFRAG_CMD_STATUS; + ret = cli_cmd_submit (&status_req, frame, cli_rpc_prog, + GLUSTER_CLI_DEFRAG_VOLUME, NULL, + this, gf_cli3_remove_brick_status_cbk, + (xdrproc_t) xdr_gf1_cli_defrag_vol_req); + + } out: gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret); |