diff options
author | shishir gowda <shishirng@gluster.com> | 2010-08-26 03:32:21 +0000 |
---|---|---|
committer | Anand V. Avati <avati@dev.gluster.com> | 2010-08-26 07:30:54 -0700 |
commit | fabb7e5e5dab69689bde255225748f8513a09d84 (patch) | |
tree | 7f7160fa19c105c5830dc7cadd34034f2b2ba70e | |
parent | 33dfb02e92eb64009d353057f567dec02295886c (diff) |
Cli volume add-brick validation
Signed-off-by: shishir gowda <shishirng@gluster.com>
Signed-off-by: Anand V. Avati <avati@dev.gluster.com>
BUG: 1440 (volume add brick validation)
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=1440
-rw-r--r-- | cli/src/cli3_1-cops.c | 2 | ||||
-rw-r--r-- | rpc/xdr/src/cli1-xdr.c | 2 | ||||
-rw-r--r-- | rpc/xdr/src/cli1-xdr.h | 1 | ||||
-rw-r--r-- | rpc/xdr/src/cli1.x | 1 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-handler.c | 134 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-op-sm.c | 1 |
6 files changed, 141 insertions, 0 deletions
diff --git a/cli/src/cli3_1-cops.c b/cli/src/cli3_1-cops.c index 7200800d615..77fb3852ba5 100644 --- a/cli/src/cli3_1-cops.c +++ b/cli/src/cli3_1-cops.c @@ -662,6 +662,8 @@ gf_cli3_1_add_brick_cbk (struct rpc_req *req, struct iovec *iov, cli_out ("Add Brick %s", (rsp.op_ret) ? "unsuccessful": "successful"); + if (rsp.op_ret && rsp.op_errstr) + cli_out ("%s", rsp.op_errstr); ret = rsp.op_ret; out: diff --git a/rpc/xdr/src/cli1-xdr.c b/rpc/xdr/src/cli1-xdr.c index b850bde10f4..ce16b666f1f 100644 --- a/rpc/xdr/src/cli1-xdr.c +++ b/rpc/xdr/src/cli1-xdr.c @@ -375,6 +375,8 @@ xdr_gf1_cli_add_brick_rsp (XDR *xdrs, gf1_cli_add_brick_rsp *objp) return FALSE; if (!xdr_string (xdrs, &objp->volname, ~0)) 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 77dbfb80a0e..c6fd14f3ba8 100644 --- a/rpc/xdr/src/cli1-xdr.h +++ b/rpc/xdr/src/cli1-xdr.h @@ -226,6 +226,7 @@ struct gf1_cli_add_brick_rsp { int op_ret; int op_errno; char *volname; + char *op_errstr; }; typedef struct gf1_cli_add_brick_rsp gf1_cli_add_brick_rsp; diff --git a/rpc/xdr/src/cli1.x b/rpc/xdr/src/cli1.x index 6ca60020f43..ffb8ab2cfd3 100644 --- a/rpc/xdr/src/cli1.x +++ b/rpc/xdr/src/cli1.x @@ -145,6 +145,7 @@ struct gf1_cli_get_vol_rsp { int op_ret; int op_errno; string volname<>; + string op_errstr<>; } ; struct gf1_cli_remove_brick_req { diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c index fb5a0df0338..65791d413c3 100644 --- a/xlators/mgmt/glusterd/src/glusterd-handler.c +++ b/xlators/mgmt/glusterd/src/glusterd-handler.c @@ -1165,6 +1165,19 @@ glusterd_handle_add_brick (rpcsvc_request_t *req) int32_t ret = -1; gf1_cli_add_brick_req cli_req = {0,}; dict_t *dict = NULL; + glusterd_brickinfo_t *brickinfo = NULL; + char *brick = NULL; + char *bricks = NULL; + char *volname = NULL; + int brick_count = 0; + char *tmpptr = NULL; + int i = 0; + glusterd_peerinfo_t *peerinfo = NULL; + char *brick_list = NULL; + void *cli_rsp = NULL; + char err_str[1048]; + gf1_cli_add_brick_rsp rsp = {0,}; + glusterd_volinfo_t *volinfo = NULL; GF_ASSERT (req); @@ -1191,6 +1204,127 @@ glusterd_handle_add_brick (rpcsvc_request_t *req) } } + ret = dict_get_str (dict, "volname", &volname); + + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to get volume name"); + goto out; + } + + if (!(ret = glusterd_check_volume_exists (volname))) { + gf_log ("", GF_LOG_ERROR, "Volname %s does not exist", + volname); + rsp.op_ret = -1; + rsp.op_errno = 0; + rsp.volname = ""; + snprintf(err_str, 1048, "Volname %s does not exist", + volname); + rsp.op_errstr = err_str; + cli_rsp = &rsp; + glusterd_submit_reply(req, cli_rsp, NULL, 0, NULL, + gf_xdr_serialize_cli_add_brick_rsp); + if (!glusterd_opinfo_unlock()) + gf_log ("glusterd", GF_LOG_ERROR, "Unlock on opinfo" + " failed"); + + ret = 0; //sent error to cli, prevent second reply + goto out; + } + + ret = dict_get_int32 (dict, "count", &brick_count); + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to get count"); + goto out; + } + + if (!(ret = glusterd_volinfo_find (volname, &volinfo))) { + if (volinfo->type == GF_CLUSTER_TYPE_NONE) + goto brick_val; + if (!brick_count || !volinfo->sub_count) + goto brick_val; + if ((brick_count % volinfo->sub_count) != 0) { + rsp.op_ret = -1; + rsp.op_errno = -1; + rsp.volname = ""; + snprintf(err_str, 2048, "Incorrect number of bricks" + " supplied %d for type %s with count %d", + brick_count, (volinfo->type == 1)? "STRIPE": + "REPLICATE", volinfo->sub_count); + rsp.op_errstr = err_str; + cli_rsp = &rsp; + glusterd_submit_reply(req, cli_rsp, NULL, 0, NULL, + gf_xdr_serialize_cli_add_brick_rsp); + if (!glusterd_opinfo_unlock()) + gf_log ("glusterd", GF_LOG_ERROR, "Unlock on opinfo" + " failed"); + + ret = 0; //sent error to cli, prevent second reply + goto out; + } + } else { + gf_log("", GF_LOG_ERROR, "Unable to get volinfo for volname" + " %s", volname); + goto out; + } + +brick_val: + ret = dict_get_str (dict, "bricks", &bricks); + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to get bricks"); + goto out; + } + + if (bricks) + brick_list = gf_strdup (bricks); + + while ( i < brick_count) { + i++; + brick= strtok_r (brick_list, " \n", &tmpptr); + brick_list = tmpptr; + ret = glusterd_brickinfo_from_brick (brick, &brickinfo); + if (ret) + goto out; + if(!(ret = glusterd_is_local_addr(brickinfo->hostname))) + continue; //localhost, continue without validation + ret = glusterd_friend_find_by_hostname(brickinfo->hostname, + &peerinfo); + if (ret) { + rsp.op_ret = -1; + rsp.op_errno = 0; + rsp.volname = ""; + snprintf(err_str, 1048, "Host %s not a friend", + brickinfo->hostname); + rsp.op_errstr = err_str; + cli_rsp = &rsp; + glusterd_submit_reply(req, cli_rsp, NULL, 0, NULL, + gf_xdr_serialize_cli_add_brick_rsp); + if (!glusterd_opinfo_unlock()) + gf_log ("glusterd", GF_LOG_ERROR, "Unlock on " + "opinfo failed"); + + ret = 0; //sent error to cli, prevent second reply + goto out; + } + if ((!peerinfo->connected) && + (peerinfo->state.state != GD_FRIEND_STATE_BEFRIENDED)) { + rsp.op_ret = -1; + rsp.op_errno = 0; + rsp.volname = ""; + snprintf(err_str, 1048, "Host %s not connected", + brickinfo->hostname); + rsp.op_errstr = err_str; + cli_rsp = &rsp; + glusterd_submit_reply(req, cli_rsp, NULL, 0, NULL, + gf_xdr_serialize_cli_add_brick_rsp); + if (!glusterd_opinfo_unlock()) + gf_log ("glusterd", GF_LOG_ERROR, "Unlock on " + "opinfo failed"); + + ret = 0; //sent error to cli, prevent second reply + goto out; + } + } + ret = glusterd_add_brick (req, dict); out: diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c index 5d3323f0dc7..03c1190a997 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c @@ -2408,6 +2408,7 @@ glusterd_op_send_cli_response (int32_t op, int32_t op_ret, rsp.op_ret = op_ret; rsp.op_errno = op_errno; rsp.volname = ""; + rsp.op_errstr = ""; cli_rsp = &rsp; sfunc = gf_xdr_serialize_cli_add_brick_rsp; break; |