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 7200800d6..77fb3852b 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 b850bde10..ce16b666f 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 77dbfb80a..c6fd14f3b 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 6ca60020f..ffb8ab2cf 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 fb5a0df03..65791d413 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 5d3323f0d..03c1190a9 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;  | 
