From 7c7219fd881dd6485fbad2e80121a3c2dffd6d9b Mon Sep 17 00:00:00 2001 From: shishir gowda Date: Wed, 25 Aug 2010 06:16:46 +0000 Subject: Cli volume create validation Signed-off-by: shishir gowda Signed-off-by: Anand V. Avati BUG: 1185 () URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=1185 --- cli/src/cli3_1-cops.c | 2 + rpc/xdr/src/cli1-xdr.c | 3 + rpc/xdr/src/cli1-xdr.h | 1 + rpc/xdr/src/cli1.x | 1 + xlators/mgmt/glusterd/src/glusterd-handler.c | 102 +++++++++++++++++++++++++++ xlators/mgmt/glusterd/src/glusterd-op-sm.c | 6 ++ xlators/mgmt/glusterd/src/glusterd-op-sm.h | 4 ++ 7 files changed, 119 insertions(+) diff --git a/cli/src/cli3_1-cops.c b/cli/src/cli3_1-cops.c index 1bb70689e..7200800d6 100644 --- a/cli/src/cli3_1-cops.c +++ b/cli/src/cli3_1-cops.c @@ -393,6 +393,8 @@ gf_cli3_1_create_volume_cbk (struct rpc_req *req, struct iovec *iov, gf_log ("cli", GF_LOG_NORMAL, "Received resp to create volume"); cli_out ("Creation of volume %s has been %s", volname, (rsp.op_ret) ? "unsuccessful": "successful"); + if (rsp.op_ret && rsp.op_errstr) + cli_out ("%s", rsp.op_errstr); ret = rsp.op_ret; diff --git a/rpc/xdr/src/cli1-xdr.c b/rpc/xdr/src/cli1-xdr.c index a64ca3000..b850bde10 100644 --- a/rpc/xdr/src/cli1-xdr.c +++ b/rpc/xdr/src/cli1-xdr.c @@ -224,6 +224,9 @@ xdr_gf1_cli_create_vol_rsp (XDR *xdrs, gf1_cli_create_vol_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 f8c3e5889..77dbfb80a 100644 --- a/rpc/xdr/src/cli1-xdr.h +++ b/rpc/xdr/src/cli1-xdr.h @@ -142,6 +142,7 @@ struct gf1_cli_create_vol_rsp { int op_ret; int op_errno; char *volname; + char *op_errstr; }; typedef struct gf1_cli_create_vol_rsp gf1_cli_create_vol_rsp; diff --git a/rpc/xdr/src/cli1.x b/rpc/xdr/src/cli1.x index 8f0dfc3c0..6ca60020f 100644 --- a/rpc/xdr/src/cli1.x +++ b/rpc/xdr/src/cli1.x @@ -77,6 +77,7 @@ struct gf1_cli_get_vol_rsp { int op_ret; int op_errno; string volname<>; + string op_errstr<>; } ; struct gf1_cli_delete_vol_req { diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c index 463213ec1..fb5a0df03 100644 --- a/xlators/mgmt/glusterd/src/glusterd-handler.c +++ b/xlators/mgmt/glusterd/src/glusterd-handler.c @@ -952,9 +952,22 @@ glusterd_handle_create_volume (rpcsvc_request_t *req) int32_t ret = -1; gf1_cli_create_vol_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_create_vol_rsp rsp = {0,}; GF_ASSERT (req); + if (!gf_xdr_to_cli_create_vol_req (req->msg[0], &cli_req)) { //failed to decode msg; req->rpc_err = GARBAGE_ARGS; @@ -978,6 +991,95 @@ glusterd_handle_create_volume (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 already exists", + volname); + rsp.op_ret = -1; + rsp.op_errno = 0; + rsp.volname = ""; + snprintf(err_str, 1048, "Volname %s already exists", + volname); + rsp.op_errstr = err_str; + cli_rsp = &rsp; + glusterd_submit_reply(req, cli_rsp, NULL, 0, NULL, + gf_xdr_serialize_cli_create_vol_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; + } + + 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_create_vol_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_create_vol_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_create_volume (req, dict); out: diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c index 720e7921d..5d3323f0d 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c @@ -2352,6 +2352,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_create_vol_rsp; break; @@ -3055,3 +3056,8 @@ glusterd_op_sm_init () INIT_LIST_HEAD (&gd_op_sm_queue); return 0; } + +int32_t +glusterd_opinfo_unlock(){ + return (pthread_mutex_unlock(&opinfo.lock)); +} diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.h b/xlators/mgmt/glusterd/src/glusterd-op-sm.h index 535d57b8b..afb134637 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.h +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.h @@ -212,4 +212,8 @@ glusterd_op_clear_op (glusterd_op_t op); int32_t glusterd_op_clear_ctx (glusterd_op_t op); + +int32_t +glusterd_opinfo_unlock(); + #endif -- cgit