From 26cc6b015bb29f942194d1ca2a3dd21d5483d829 Mon Sep 17 00:00:00 2001 From: Vijay Bellur Date: Tue, 27 Jul 2010 08:48:49 +0000 Subject: DVM: Changes for remove brick Signed-off-by: Vijay Bellur Signed-off-by: Anand V. Avati BUG: 1220 () URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=1220 --- cli/src/cli-cmd.c | 2 +- xlators/mgmt/glusterd/src/glusterd-handler.c | 56 ++++++ xlators/mgmt/glusterd/src/glusterd-op-sm.c | 271 +++++++++++++++++++++++++++ xlators/mgmt/glusterd/src/glusterd-op-sm.h | 14 ++ xlators/mgmt/glusterd/src/glusterd-utils.c | 37 ++++ xlators/mgmt/glusterd/src/glusterd-utils.h | 4 + xlators/mgmt/glusterd/src/glusterd.h | 6 + xlators/mgmt/glusterd/src/glusterd3_1-mops.c | 6 +- 8 files changed, 394 insertions(+), 2 deletions(-) diff --git a/cli/src/cli-cmd.c b/cli/src/cli-cmd.c index 043cb91d7e4..c88d3fe8505 100644 --- a/cli/src/cli-cmd.c +++ b/cli/src/cli-cmd.c @@ -41,7 +41,7 @@ static pthread_cond_t conn = PTHREAD_COND_INITIALIZER; static pthread_mutex_t conn_mutex = PTHREAD_MUTEX_INITIALIZER; int cli_op_ret = 0; -int connected = 1; +int connected = 0; int cli_cmd_process (struct cli_state *state, int argc, char **argv) diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c index c1ab571197b..8fe0b31a6cb 100644 --- a/xlators/mgmt/glusterd/src/glusterd-handler.c +++ b/xlators/mgmt/glusterd/src/glusterd-handler.c @@ -815,6 +815,44 @@ out: return ret; } +int +glusterd_handle_remove_brick (rpcsvc_request_t *req) +{ + int32_t ret = -1; + gf1_cli_remove_brick_req cli_req = {0,}; + dict_t *dict = NULL; + + GF_ASSERT (req); + + if (!gf_xdr_to_cli_remove_brick_req (req->msg[0], &cli_req)) { + //failed to decode msg; + req->rpc_err = GARBAGE_ARGS; + goto out; + } + + gf_log ("glusterd", GF_LOG_NORMAL, "Received rem brick req"); + + if (cli_req.bricks.bricks_len) { + /* Unserialize the dictionary */ + dict = dict_new (); + + ret = dict_unserialize (cli_req.bricks.bricks_val, + cli_req.bricks.bricks_len, + &dict); + if (ret < 0) { + gf_log ("glusterd", GF_LOG_ERROR, + "failed to " + "unserialize req-buffer to dictionary"); + goto out; + } + } + + ret = glusterd_remove_brick (req, dict); + +out: + return ret; +} + int glusterd_op_lock_send_resp (rpcsvc_request_t *req, int32_t status) { @@ -1586,6 +1624,24 @@ glusterd_add_brick (rpcsvc_request_t *req, dict_t *dict) return ret; } +int32_t +glusterd_remove_brick (rpcsvc_request_t *req, dict_t *dict) +{ + int32_t ret = -1; + + GF_ASSERT (req); + GF_ASSERT (dict); + + glusterd_op_set_op (GD_OP_REMOVE_BRICK); + + glusterd_op_set_ctx (GD_OP_REMOVE_BRICK, dict); + 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 0871dfedc19..1a954cce2e8 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c @@ -90,7 +90,15 @@ glusterd_op_get_len (glusterd_op_t op) ret = dict_serialized_length (dict); return ret; } + + case GD_OP_REMOVE_BRICK: + { + dict_t *dict = glusterd_op_get_ctx (op); + ret = dict_serialized_length (dict); + return ret; + } break; + break; default: GF_ASSERT (op); @@ -202,6 +210,20 @@ glusterd_op_build_payload (glusterd_op_t op, gd1_mgmt_stage_op_req **req) } 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; + default: break; } @@ -510,6 +532,52 @@ out: return ret; } +static int +glusterd_op_stage_remove_brick (gd1_mgmt_stage_op_req *req) +{ + int ret = 0; + dict_t *dict = NULL; + char *volname = NULL; + gf_boolean_t exists = _gf_false; + + 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, "volname", &volname); + + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to get volume name"); + goto out; + } + + exists = glusterd_check_volume_exists (volname); + + if (!exists) { + gf_log ("", GF_LOG_ERROR, "Volume with name: %s exists", + volname); + ret = -1; + goto out; + } else { + ret = 0; + } + +out: + gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); + + return ret; +} + + static int glusterd_op_create_volume (gd1_mgmt_stage_op_req *req) { @@ -758,6 +826,126 @@ out: return ret; } +static int +glusterd_op_remove_brick (gd1_mgmt_stage_op_req *req) +{ + int ret = 0; + dict_t *dict = NULL; + char *volname = NULL; + glusterd_conf_t *priv = NULL; + glusterd_volinfo_t *volinfo = NULL; + glusterd_brickinfo_t *brickinfo = NULL; + xlator_t *this = NULL; + char *brick = NULL; + int32_t count = 0; + int32_t i = 1; + gf_boolean_t glfs_stopped = _gf_false; + int32_t mybrick = 0; + char key[256] = {0,}; + char *dup_brick = 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, "volname", &volname); + + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to get volume name"); + goto out; + } + + ret = glusterd_volinfo_find (volname, &volinfo); + + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to allocate memory"); + goto out; + } + + + ret = dict_get_int32 (dict, "count", &count); + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to get count"); + goto out; + } + + + while ( i <= count) { + snprintf (key, 256, "brick%d", i); + ret = dict_get_str (dict, key, &brick); + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to get %s", key); + goto out; + } + dup_brick = gf_strdup (brick); + + ret = glusterd_brickinfo_get (dup_brick, volinfo, &brickinfo); + if (ret) + goto out; + + + ret = glusterd_resolve_brick (brickinfo); + + if (ret) + goto out; + + if (!uuid_compare (brickinfo->uuid, priv->uuid)) { + ret = + glusterd_volume_create_generate_volfiles (volinfo); + if (ret) + goto out; + + gf_log ("", GF_LOG_NORMAL, "About to stop glusterfs" + " for brick %s:%s", brickinfo->hostname, + brickinfo->path); + ret = glusterd_volume_stop_glusterfs + (volinfo, brickinfo, mybrick); + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to start " + "glusterfs, ret: %d", ret); + goto out; + } + glusterd_brickinfo_delete (brickinfo); + glfs_stopped = _gf_true; + mybrick++; + } + + i++; + } + + if (!glfs_stopped) { + ret = glusterd_volume_create_generate_volfiles (volinfo); + if (ret) + goto out; + } + +/* ret = glusterd_ha_update_volume (volinfo); + + if (ret) + goto out; +*/ + + +out: + return ret; +} + + static int glusterd_op_delete_volume (gd1_mgmt_stage_op_req *req) { @@ -1225,6 +1413,17 @@ glusterd_op_send_cli_response (int32_t op, int32_t op_ret, sfunc = gf_xdr_serialize_cli_add_brick_rsp; break; } + + case GD_MGMT_CLI_REMOVE_BRICK: + { + gf1_cli_remove_brick_rsp rsp = {0,}; + rsp.op_ret = op_ret; + rsp.op_errno = op_errno; + rsp.volname = ""; + cli_rsp = &rsp; + sfunc = gf_xdr_serialize_cli_remove_brick_rsp; + break; + } } @@ -1246,6 +1445,7 @@ glusterd_op_txn_complete () { int32_t ret = -1; glusterd_conf_t *priv = NULL; + int32_t op = -1; priv = THIS->private; GF_ASSERT (priv); @@ -1265,6 +1465,16 @@ glusterd_op_txn_complete () opinfo.op_ret = 0; opinfo.op_errno = 0; + + op = glusterd_op_get_op (); + + if (op != -1) { + glusterd_op_clear_pending_op (op); + glusterd_op_clear_commit_op (op); + glusterd_op_clear_op (op); + glusterd_op_clear_ctx (op); + } + out: pthread_mutex_unlock (&opinfo.lock); gf_log ("glusterd", GF_LOG_NORMAL, "Returning %d", ret); @@ -1395,6 +1605,10 @@ glusterd_op_stage_validate (gd1_mgmt_stage_op_req *req) ret = glusterd_op_stage_add_brick (req); break; + case GD_OP_REMOVE_BRICK: + ret = glusterd_op_stage_remove_brick (req); + break; + default: gf_log ("", GF_LOG_ERROR, "Unknown op %d", req->op); @@ -1433,6 +1647,11 @@ glusterd_op_commit_perform (gd1_mgmt_stage_op_req *req) case GD_OP_ADD_BRICK: ret = glusterd_op_add_brick (req); break; + + case GD_OP_REMOVE_BRICK: + ret = glusterd_op_remove_brick (req); + break; + default: gf_log ("", GF_LOG_ERROR, "Unknown op %d", req->op); @@ -1694,6 +1913,28 @@ glusterd_op_set_op (glusterd_op_t op) } +int32_t +glusterd_op_get_op () +{ + + int i = 0; + int32_t ret = 0; + + for ( i = 0; i < GD_OP_MAX; i++) { + if (opinfo.op[i]) + break; + } + + if ( i == GD_OP_MAX) + ret = -1; + else + ret = i; + + return ret; + +} + + int32_t glusterd_op_set_cli_op (gf_mgmt_procnum op) { @@ -1747,6 +1988,19 @@ glusterd_op_clear_commit_op (glusterd_op_t op) } +int32_t +glusterd_op_clear_op (glusterd_op_t op) +{ + + GF_ASSERT (op < GD_OP_MAX); + GF_ASSERT (op > GD_OP_NONE); + + opinfo.op[op] = 0; + + return 0; + +} + int32_t glusterd_op_set_ctx (glusterd_op_t op, void *ctx) { @@ -1760,6 +2014,23 @@ glusterd_op_set_ctx (glusterd_op_t op, void *ctx) } +int32_t +glusterd_op_clear_ctx (glusterd_op_t op) +{ + + void *ctx = NULL; + + GF_ASSERT (op < GD_OP_MAX); + GF_ASSERT (op > GD_OP_NONE); + + ctx = opinfo.op_ctx[op]; + + if (ctx) + GF_FREE (ctx); + + return 0; + +} void * glusterd_op_get_ctx (glusterd_op_t op) diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.h b/xlators/mgmt/glusterd/src/glusterd-op-sm.h index 4a619ba3ad2..1bcfbb5bfb1 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.h +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.h @@ -198,4 +198,18 @@ glusterd_op_set_cli_op (gf_mgmt_procnum op); int32_t glusterd_op_send_cli_response (int32_t op, int32_t op_ret, int32_t op_errno, rpcsvc_request_t *req); +int32_t +glusterd_op_get_op (); + +int32_t +glusterd_op_clear_pending_op (glusterd_op_t op); + +int32_t +glusterd_op_clear_commit_op (glusterd_op_t op); + +int32_t +glusterd_op_clear_op (glusterd_op_t op); + +int32_t +glusterd_op_clear_ctx (glusterd_op_t op); #endif diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c index fb76d1f0305..1d4a8d2ec69 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -625,6 +625,43 @@ out: } +int32_t +glusterd_brickinfo_get (char *brick, glusterd_volinfo_t *volinfo, + glusterd_brickinfo_t **brickinfo) +{ + int32_t ret = -1; + char *hostname = NULL; + char *path = NULL; + glusterd_brickinfo_t *tmp = NULL; + + GF_ASSERT (brick); + GF_ASSERT (brickinfo); + GF_ASSERT (volinfo); + + gf_log ("", GF_LOG_NORMAL, "brick: %s", brick); + + hostname = strtok (brick, ":"); + path = strtok (NULL, ":"); + + GF_ASSERT (hostname); + GF_ASSERT (path); + + list_for_each_entry (tmp, &volinfo->bricks, brick_list) { + + if ((!strcmp (tmp->hostname, hostname)) && + !strcmp (tmp->path, path)) { + gf_log ("", GF_LOG_NORMAL, "Found brick"); + ret = 0; + break; + } + } + + *brickinfo = tmp; + + gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); + return ret; +} + int32_t glusterd_friend_cleanup (glusterd_peerinfo_t *peerinfo) { diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h index 39a0cdb197f..fc8b33ab1b9 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.h +++ b/xlators/mgmt/glusterd/src/glusterd-utils.h @@ -111,4 +111,8 @@ glusterd_brickinfo_delete (glusterd_brickinfo_t *brickinfo); gf_boolean_t glusterd_is_cli_op_req (int32_t op); + +int32_t +glusterd_brickinfo_get (char *brick, glusterd_volinfo_t *volinfo, + glusterd_brickinfo_t **brickinfo); #endif diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h index 5fccc0199bd..6446f2fc111 100644 --- a/xlators/mgmt/glusterd/src/glusterd.h +++ b/xlators/mgmt/glusterd/src/glusterd.h @@ -218,4 +218,10 @@ glusterd_add_brick (rpcsvc_request_t *req, dict_t *dict); int glusterd_handle_add_brick (rpcsvc_request_t *req); + +int +glusterd_handle_remove_brick (rpcsvc_request_t *req); + +int32_t +glusterd_remove_brick (rpcsvc_request_t *req, dict_t *dict); #endif diff --git a/xlators/mgmt/glusterd/src/glusterd3_1-mops.c b/xlators/mgmt/glusterd/src/glusterd3_1-mops.c index 9b44465cf23..1a2cb7449c6 100644 --- a/xlators/mgmt/glusterd/src/glusterd3_1-mops.c +++ b/xlators/mgmt/glusterd/src/glusterd3_1-mops.c @@ -1169,6 +1169,9 @@ glusterd_handle_rpc_msg (rpcsvc_request_t *req) ret = glusterd_handle_add_brick (req); break; + case GD_MGMT_CLI_REMOVE_BRICK: + ret = glusterd_handle_remove_brick (req); + break; default: GF_ASSERT (0); } @@ -1204,7 +1207,8 @@ rpcsvc_actor_t glusterd1_mgmt_actors[] = { [GD_MGMT_CLI_STOP_VOLUME] = { "STOP_VOLUME", GD_MGMT_CLI_STOP_VOLUME, glusterd_handle_rpc_msg, NULL, NULL}, [GD_MGMT_CLI_DELETE_VOLUME] = { "DELETE_VOLUME", GD_MGMT_CLI_DELETE_VOLUME, glusterd_handle_rpc_msg, NULL, NULL}, [GD_MGMT_CLI_GET_VOLUME] = { "GET_VOLUME", GD_MGMT_CLI_GET_VOLUME, glusterd_handle_rpc_msg, NULL, NULL}, - [GD_MGMT_CLI_ADD_BRICK] = { "GET_VOLUME", GD_MGMT_CLI_ADD_BRICK, glusterd_handle_rpc_msg, NULL, NULL}, + [GD_MGMT_CLI_ADD_BRICK] = { "ADD_BRICK", GD_MGMT_CLI_ADD_BRICK, glusterd_handle_rpc_msg, NULL, NULL}, + [GD_MGMT_CLI_REMOVE_BRICK] = { "REMOVE_BRICK", GD_MGMT_CLI_REMOVE_BRICK, glusterd_handle_rpc_msg, NULL, NULL}, }; /*rpcsvc_actor_t glusterd1_mgmt_actors[] = { -- cgit