summaryrefslogtreecommitdiffstats
path: root/xlators/mgmt
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/mgmt')
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-handler.c56
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-op-sm.c112
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.c34
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.h2
4 files changed, 153 insertions, 51 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c
index 0c33b6590a3..4d9a662b36a 100644
--- a/xlators/mgmt/glusterd/src/glusterd-handler.c
+++ b/xlators/mgmt/glusterd/src/glusterd-handler.c
@@ -1126,8 +1126,6 @@ glusterd_handle_create_volume (rpcsvc_request_t *req)
gf1_cli_create_vol_rsp rsp = {0,};
glusterd_conf_t *priv = NULL;
int err_ret = 0;
- glusterd_brickinfo_t *tmpbrkinfo = NULL;
- glusterd_volinfo_t *volinfo = NULL;
xlator_t *this = NULL;
char *free_ptr = NULL;
char *trans_type = NULL;
@@ -1137,10 +1135,10 @@ glusterd_handle_create_volume (rpcsvc_request_t *req)
GF_ASSERT (req);
this = THIS;
- priv = this->private;
-
GF_ASSERT(this);
+ priv = this->private;
+
if (!gf_xdr_to_cli_create_vol_req (req->msg[0], &cli_req)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
@@ -1250,22 +1248,12 @@ glusterd_handle_create_volume (rpcsvc_request_t *req)
goto out;
}
brick_validation:
- list_for_each_entry (volinfo, &priv->volumes, vol_list) {
-
- list_for_each_entry (tmpbrkinfo, &volinfo->bricks,
- brick_list) {
-
- if ((!strcmp(brickinfo->hostname, tmpbrkinfo->
- hostname) && !strcmp(brickinfo->path,
- tmpbrkinfo->path))) {
- snprintf(err_str, 1048, "Brick %s already"
- " in use", brick);
- gf_log ("glusterd", GF_LOG_ERROR, "%s",
- err_str);
- err_ret = 1;
- goto out;
- }
- }
+ err_ret = glusterd_is_exisiting_brick (brickinfo->hostname,
+ brickinfo->path);
+ if (err_ret) {
+ snprintf(err_str, 1048, "Brick: %s already in use",
+ brick);
+ goto out;
}
}
ret = glusterd_create_volume (req, dict);
@@ -1406,18 +1394,16 @@ glusterd_handle_add_brick (rpcsvc_request_t *req)
char err_str[1048];
gf1_cli_add_brick_rsp rsp = {0,};
glusterd_volinfo_t *volinfo = NULL;
- glusterd_brickinfo_t *tmpbrkinfo = NULL;
int32_t err_ret = 0;
- glusterd_volinfo_t *tmpvolinfo = NULL;
glusterd_conf_t *priv = NULL;
xlator_t *this = NULL;
char *free_ptr = NULL;
this = THIS;
- priv = this->private;
-
GF_ASSERT(this);
+ priv = this->private;
+
GF_ASSERT (req);
if (!gf_xdr_to_cli_add_brick_req (req->msg[0], &cli_req)) {
@@ -1544,22 +1530,12 @@ brick_val:
goto out;
}
brick_validation:
- list_for_each_entry (tmpvolinfo, &priv->volumes, vol_list) {
-
- list_for_each_entry (tmpbrkinfo, &tmpvolinfo->bricks,
- brick_list) {
-
- if ((!strcmp(brickinfo->hostname, tmpbrkinfo->
- hostname) && !strcmp(brickinfo->path,
- tmpbrkinfo->path))) {
- snprintf(err_str, 1048, "Brick %s already"
- "in use", brick);
- gf_log ("glusterd", GF_LOG_ERROR, "%s",
- err_str);
- err_ret = 1;
- goto out;
- }
- }
+ err_ret = glusterd_is_exisiting_brick (brickinfo->hostname,
+ brickinfo->path);
+ if (err_ret) {
+ snprintf(err_str, 1048, "Brick: %s already in use",
+ brick);
+ goto out;
}
}
diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
index 4506b3a6885..b8d2778e39a 100644
--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c
+++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
@@ -753,16 +753,22 @@ out:
}
static int
-glusterd_op_stage_replace_brick (gd1_mgmt_stage_op_req *req)
+glusterd_op_stage_replace_brick (gd1_mgmt_stage_op_req *req, char **op_errstr)
{
int ret = 0;
dict_t *dict = NULL;
char *src_brick = NULL;
char *dst_brick = NULL;
char *volname = NULL;
+ gf1_cli_replace_op replace_op = 0;
glusterd_volinfo_t *volinfo = NULL;
glusterd_brickinfo_t *src_brickinfo = NULL;
- gf_boolean_t exists = _gf_false;
+ char *host = NULL;
+ char *path = NULL;
+ char msg[2048] = {0};
+ char *dup_dstbrick = NULL;
+ glusterd_peerinfo_t *peerinfo = NULL;
+ struct stat st_buf = {0,};
GF_ASSERT (req);
@@ -804,36 +810,116 @@ glusterd_op_stage_replace_brick (gd1_mgmt_stage_op_req *req)
goto out;
}
+ ret = dict_get_int32 (dict, "operation", (int32_t *)&replace_op);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "dict get on replace-brick operation failed");
+ goto out;
+ }
+
ret = glusterd_volinfo_find (volname, &volinfo);
if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to allocate memory");
+ snprintf (msg, sizeof (msg), "volume: %s does not exist",
+ volname);
+ *op_errstr = gf_strdup (msg);
+ goto out;
+ }
+
+ if (GLUSTERD_STATUS_STARTED != volinfo->status) {
+ ret = -1;
+ snprintf (msg, sizeof (msg), "volume: %s is not started",
+ volname);
+ *op_errstr = gf_strdup (msg);
goto out;
}
ret = glusterd_brickinfo_get (src_brick, volinfo,
&src_brickinfo);
if (ret) {
- gf_log ("", GF_LOG_DEBUG, "Unable to get src-brickinfo");
+ snprintf (msg, sizeof (msg), "brick: %s does not exist in "
+ "volume: %s", src_brick, volname);
+ *op_errstr = gf_strdup (msg);
goto out;
}
if (!glusterd_is_local_addr (src_brickinfo->hostname)) {
gf_log ("", GF_LOG_DEBUG,
"I AM THE SOURCE HOST");
- exists = glusterd_check_volume_exists (volname);
+ }
- if (!exists) {
- gf_log ("", GF_LOG_ERROR, "Volume with name: %s "
- "does not exist",
- volname);
+ dup_dstbrick = gf_strdup (dst_brick);
+ if (!dup_dstbrick) {
+ ret = -1;
+ gf_log ("", GF_LOG_ERROR, "Memory allocation failed");
+ goto out;
+ }
+ host = strtok (dup_dstbrick, ":");
+ path = strtok (NULL, ":");
+
+ if (!host || !path) {
+ gf_log ("", GF_LOG_ERROR,
+ "dst brick %s is not of form <HOSTNAME>:<export-dir>",
+ dst_brick);
+ ret = -1;
+ goto out;
+ }
+ if (glusterd_is_exisiting_brick (host, path)) {
+ snprintf(msg, sizeof(msg), "Brick: %s:%s already in use",
+ host, path);
+ *op_errstr = gf_strdup (msg);
+ ret = -1;
+ goto out;
+ }
+
+ if (!glusterd_is_local_addr (host)) {
+ ret = stat (path, &st_buf);
+ if (ret == -1) {
+ snprintf (msg, sizeof (msg) ,"path: %s for brick: %s"
+ " does not exist", path, dst_brick);
+ gf_log ("glusterd", GF_LOG_ERROR, "%s", msg);
+ *op_errstr = gf_strdup (msg);
+ goto out;
+ }
+ if (!S_ISDIR (st_buf.st_mode)) {
+ snprintf (msg, sizeof (msg), "Volume name %s, brick"
+ ": %s, path %s is not a directory", volname,
+ dst_brick, path);
+ gf_log ("glusterd", GF_LOG_ERROR,
+ "%s", msg);
+ *op_errstr = gf_strdup (msg);
+ ret = -1;
+ goto out;
+ }
+ } else {
+ ret = glusterd_friend_find (NULL, host, &peerinfo);
+ if (ret) {
+ snprintf (msg, sizeof (msg), "%s, is not a friend",
+ host);
+ *op_errstr = gf_strdup (msg);
+ goto out;
+ }
+
+ if (!peerinfo->connected) {
+ snprintf (msg, sizeof (msg), "%s, is not connected at "
+ "the moment", host);
+ *op_errstr = gf_strdup (msg);
ret = -1;
goto out;
}
- }
+ if (GD_FRIEND_STATE_BEFRIENDED != peerinfo->state.state) {
+ snprintf (msg, sizeof (msg), "%s, is not befriended "
+ "at the moment", host);
+ *op_errstr = gf_strdup (msg);
+ ret = -1;
+ goto out;
+ }
+ }
ret = 0;
out:
+ if (dup_dstbrick)
+ GF_FREE (dup_dstbrick);
if (dict)
dict_unref (dict);
gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
@@ -3657,6 +3743,10 @@ glusterd_op_send_cli_response (int32_t op, int32_t op_ret,
rsp.status = "";
rsp.op_ret = op_ret;
rsp.op_errno = op_errno;
+ if (op_errstr)
+ rsp.op_errstr = op_errstr;
+ else
+ rsp.op_errstr = "";
rsp.volname = "";
cli_rsp = &rsp;
sfunc = gf_xdr_serialize_cli_replace_brick_rsp;
@@ -3949,7 +4039,7 @@ glusterd_op_stage_validate (gd1_mgmt_stage_op_req *req, char **op_errstr)
break;
case GD_OP_REPLACE_BRICK:
- ret = glusterd_op_stage_replace_brick (req);
+ ret = glusterd_op_stage_replace_brick (req, op_errstr);
break;
case GD_OP_SET_VOLUME:
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
index 358d6ffe46f..e3592891b18 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
@@ -1716,3 +1716,37 @@ glusterd_volume_count_get (void)
return ret;
}
+
+int
+glusterd_is_exisiting_brick (char *hostname, char *path)
+{
+ glusterd_brickinfo_t *tmpbrkinfo = NULL;
+ glusterd_volinfo_t *volinfo = NULL;
+ glusterd_conf_t *priv = NULL;
+ xlator_t *this = NULL;
+ int ret = 0;
+
+ GF_ASSERT (hostname);
+ GF_ASSERT (path);
+
+ this = THIS;
+ GF_ASSERT (this);
+
+ priv = this->private;
+ list_for_each_entry (volinfo, &priv->volumes, vol_list) {
+
+ list_for_each_entry (tmpbrkinfo, &volinfo->bricks,
+ brick_list) {
+
+ if ((!strcmp(hostname, tmpbrkinfo-> hostname)
+ && !strcmp(path, tmpbrkinfo->path))) {
+ gf_log ("glusterd", GF_LOG_ERROR, "Brick %s:%s"
+ " already in use", hostname, path);
+ ret = 1;
+ goto out;
+ }
+ }
+ }
+out:
+ return ret;
+}
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h
index e03968dfeeb..72715a0f5df 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.h
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.h
@@ -158,4 +158,6 @@ glusterd_volume_count_get (void);
int32_t
glusterd_add_volume_to_dict (glusterd_volinfo_t *volinfo,
dict_t *dict, int32_t count);
+int
+glusterd_is_exisiting_brick (char *hostname, char *path);
#endif