summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cli/src/cli-cmd-parser.c43
-rw-r--r--cli/src/cli3_1-cops.c2
-rw-r--r--rpc/xdr/src/cli1-xdr.c2
-rw-r--r--rpc/xdr/src/cli1-xdr.h1
-rw-r--r--rpc/xdr/src/cli1.x1
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-handler.c116
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-op-sm.c1
7 files changed, 159 insertions, 7 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c
index 48c4a4fd9ef..f43349416be 100644
--- a/cli/src/cli-cmd-parser.c
+++ b/cli/src/cli-cmd-parser.c
@@ -439,6 +439,10 @@ cli_cmd_volume_remove_brick_parse (const char **words, int wordcount,
int count = 0;
char key[50];
int brick_count = 0, brick_index = 0;
+ int32_t tmp_index = 0;
+ int32_t j = 0;
+ char *tmp_brick = NULL;
+ char *tmp_brick1 = NULL;
GF_ASSERT (words);
GF_ASSERT (options);
@@ -495,6 +499,25 @@ cli_cmd_volume_remove_brick_parse (const char **words, int wordcount,
if (ret)
goto out;
+ tmp_index = brick_index;
+ tmp_brick = GF_MALLOC(2048 * sizeof(*tmp_brick), gf_common_mt_char);
+
+ if (!tmp_brick) {
+ gf_log ("",GF_LOG_ERROR,"cli_cmd_volume_remove_brick_parse: "
+ "Unable to get memory");
+ ret = -1;
+ goto out;
+ }
+
+ tmp_brick1 = GF_MALLOC(2048 * sizeof(*tmp_brick1), gf_common_mt_char);
+
+ if (!tmp_brick1) {
+ gf_log ("",GF_LOG_ERROR,"cli_cmd_volume_remove_brick_parse: "
+ "Unable to get memory");
+ ret = -1;
+ goto out;
+ }
+
while (brick_index < wordcount) {
delimiter = strchr(words[brick_index], ':');
if (!delimiter || delimiter == words[brick_index]
@@ -504,7 +527,20 @@ cli_cmd_volume_remove_brick_parse (const char **words, int wordcount,
ret = -1;
goto out;
}
-
+ j = tmp_index;
+ strcpy(tmp_brick, words[brick_index]);
+ while ( j < brick_index) {
+ strcpy(tmp_brick1, words[j]);
+ if (!(strcmp (tmp_brick, tmp_brick1))) {
+ gf_log("",GF_LOG_ERROR, "Duplicate bricks"
+ " found %s", words[brick_index]);
+ cli_out("Duplicate bricks found %s",
+ words[brick_index]);
+ ret = -1;
+ goto out;
+ }
+ j++;
+ }
snprintf (key, 50, "brick%d", ++brick_count);
ret = dict_set_str (dict, key, (char *)words[brick_index++]);
@@ -526,6 +562,11 @@ out:
dict_destroy (dict);
}
+ if (tmp_brick)
+ GF_FREE (tmp_brick);
+ if (tmp_brick1)
+ GF_FREE (tmp_brick1);
+
return ret;
}
diff --git a/cli/src/cli3_1-cops.c b/cli/src/cli3_1-cops.c
index 6971a242d91..e4b41c4db3a 100644
--- a/cli/src/cli3_1-cops.c
+++ b/cli/src/cli3_1-cops.c
@@ -704,6 +704,8 @@ gf_cli3_1_remove_brick_cbk (struct rpc_req *req, struct iovec *iov,
gf_log ("cli", GF_LOG_NORMAL, "Received resp to remove brick");
cli_out ("Remove Brick %s", (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 c0d488e7f9d..22c00f2f797 100644
--- a/rpc/xdr/src/cli1-xdr.c
+++ b/rpc/xdr/src/cli1-xdr.c
@@ -415,6 +415,8 @@ xdr_gf1_cli_remove_brick_rsp (XDR *xdrs, gf1_cli_remove_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 64bae26f4ef..6f2f8d3e116 100644
--- a/rpc/xdr/src/cli1-xdr.h
+++ b/rpc/xdr/src/cli1-xdr.h
@@ -250,6 +250,7 @@ struct gf1_cli_remove_brick_rsp {
int op_ret;
int op_errno;
char *volname;
+ char *op_errstr;
};
typedef struct gf1_cli_remove_brick_rsp gf1_cli_remove_brick_rsp;
diff --git a/rpc/xdr/src/cli1.x b/rpc/xdr/src/cli1.x
index 0c4cbf83359..9912f750b3c 100644
--- a/rpc/xdr/src/cli1.x
+++ b/rpc/xdr/src/cli1.x
@@ -169,6 +169,7 @@ struct gf1_cli_get_vol_rsp {
int op_ret;
int op_errno;
string volname<>;
+ string op_errstr<>;
} ;
struct gf1_cli_replace_brick_req {
diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c
index 7ecebd051c0..fd90161f84c 100644
--- a/xlators/mgmt/glusterd/src/glusterd-handler.c
+++ b/xlators/mgmt/glusterd/src/glusterd-handler.c
@@ -1525,6 +1525,17 @@ glusterd_handle_remove_brick (rpcsvc_request_t *req)
char key[256] = {0,};
char *brick_list = NULL;
int i = 1;
+ glusterd_volinfo_t *volinfo = NULL;
+ glusterd_brickinfo_t *brickinfo = NULL;
+ int32_t pos = 0;
+ int32_t sub_volume = 0;
+ int32_t sub_volume_start = 0;
+ int32_t sub_volume_end = 0;
+ glusterd_brickinfo_t *tmp = NULL;
+ int32_t err_ret = 0;
+ char *err_str = NULL;
+ gf1_cli_remove_brick_rsp rsp = {0,};
+ void *cli_rsp = NULL;
GF_ASSERT (req);
@@ -1557,6 +1568,39 @@ glusterd_handle_remove_brick (rpcsvc_request_t *req)
gf_log ("", GF_LOG_ERROR, "Unable to get count");
goto out;
}
+
+ err_str = GF_MALLOC (2048 * sizeof(*err_str),gf_common_mt_char);
+
+ if (!err_str) {
+ gf_log ("",GF_LOG_ERROR,"glusterd_handle_remove_brick: "
+ "Unable to get memory");
+ ret = -1;
+ goto out;
+ }
+
+ ret = glusterd_volinfo_find (cli_req.volname, &volinfo);
+ if (ret) {
+ snprintf (err_str, 2048, "volname %s not found",
+ cli_req.volname);
+ gf_log ("", GF_LOG_ERROR, "%s", err_str);
+ err_ret = 1;
+ goto out;
+ }
+
+ if ((volinfo->type == GF_CLUSTER_TYPE_REPLICATE) &&
+ !(volinfo->brick_count <= volinfo->sub_count)) {
+ if (volinfo->sub_count && (count % volinfo->sub_count != 0)) {
+ snprintf (err_str, 2048, "Remove brick incorrect"
+ " brick count of %d for replica %d",
+ count, volinfo->sub_count);
+ gf_log ("", GF_LOG_ERROR, "%s", err_str);
+ err_ret = 1;
+ ret = -1;
+ goto out;
+ }
+
+ }
+
brick_list = GF_MALLOC (120000 * sizeof(brick_list),gf_common_mt_char);
if (!brick_list) {
@@ -1565,7 +1609,8 @@ glusterd_handle_remove_brick (rpcsvc_request_t *req)
ret = -1;
goto out;
}
- strcpy(brick_list, " ");
+
+ strcpy (brick_list, " ");
while ( i <= count) {
snprintf (key, 256, "brick%d", i);
ret = dict_get_str (dict, key, &brick);
@@ -1573,24 +1618,83 @@ glusterd_handle_remove_brick (rpcsvc_request_t *req)
gf_log ("", GF_LOG_ERROR, "Unable to get %s", key);
goto out;
}
- gf_log ("", GF_LOG_DEBUG, "Remove brick count %i brick: %s",
+ gf_log ("", GF_LOG_DEBUG, "Remove brick count %d brick: %s",
i, brick);
- strcat (brick_list, brick);
- strcat (brick_list, " ");
+ ret = glusterd_brickinfo_get(brick, volinfo, &brickinfo);
+ if (ret) {
+ snprintf(err_str, 2048," Incorrect brick %s for volname"
+ " %s", brick, cli_req.volname);
+ gf_log ("", GF_LOG_ERROR, "%s", err_str);
+ err_ret = 1;
+ goto out;
+ }
+ strcat(brick_list, brick);
+ strcat(brick_list, " ");
+
i++;
+ if ((volinfo->type != GF_CLUSTER_TYPE_REPLICATE) ||
+ (volinfo->brick_count <= volinfo->sub_count))
+ continue;
+
+ pos = 0;
+ list_for_each_entry (tmp, &volinfo->bricks, brick_list) {
+
+ if ((!strcmp (tmp->hostname,brickinfo->hostname)) &&
+ !strcmp (tmp->path, brickinfo->path)) {
+ gf_log ("", GF_LOG_NORMAL, "Found brick");
+ if (!sub_volume && volinfo->sub_count) {
+ sub_volume = (pos / volinfo->
+ sub_count) + 1;
+ sub_volume_start = volinfo->sub_count *
+ (sub_volume - 1);
+ sub_volume_end = (volinfo->sub_count *
+ sub_volume) -1 ;
+ } else {
+ if (pos < sub_volume_start ||
+ pos >sub_volume_end) {
+ ret = -1;
+ snprintf(err_str, 2048,"Bricks"
+ " not from same subvol"
+ " for replica");
+ gf_log ("",GF_LOG_ERROR,
+ "%s", err_str);
+ err_ret = 1;
+ goto out;
+ }
+ }
+ break;
+ }
+ pos++;
+ }
}
-// strcat(brick_list,"\n");
gf_cmd_log ("Volume remove-brick","volname:%s count:%d bricks:%s",
cli_req.volname, count, brick_list);
ret = glusterd_remove_brick (req, dict);
out:
- gf_cmd_log ("Volume remove-brick","on %s %s",cli_req.volname,
+ gf_cmd_log ("Volume remove-brick","on volname:%s %s",cli_req.volname,
(ret) ? "FAILED" : "SUCCESS");
+ if (err_ret) {
+ rsp.op_ret = -1;
+ rsp.op_errno = 0;
+ rsp.volname = "";
+ rsp.op_errstr = err_str;
+ cli_rsp = &rsp;
+ glusterd_submit_reply(req, cli_rsp, NULL, 0, NULL,
+ gf_xdr_serialize_cli_remove_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
+
+ }
if (brick_list)
GF_FREE (brick_list);
+ if (err_str)
+ GF_FREE (err_str);
return ret;
}
diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
index ea3e59b68fb..59dae198c6a 100644
--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c
+++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
@@ -2889,6 +2889,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_remove_brick_rsp;
break;