summaryrefslogtreecommitdiffstats
path: root/xlators/mgmt/glusterd/src/glusterd-utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/mgmt/glusterd/src/glusterd-utils.c')
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.c327
1 files changed, 324 insertions, 3 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
index ec371d80815..0011cac0078 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
@@ -5970,7 +5970,7 @@ glusterd_is_defrag_on (glusterd_volinfo_t *volinfo)
int
glusterd_new_brick_validate (char *brick, glusterd_brickinfo_t *brickinfo,
- char *op_errstr, size_t len)
+ char *op_errstr, size_t len, char *op)
{
glusterd_brickinfo_t *newbrickinfo = NULL;
int ret = -1;
@@ -6011,8 +6011,12 @@ glusterd_new_brick_validate (char *brick, glusterd_brickinfo_t *brickinfo,
newbrickinfo->path)) {
snprintf(op_errstr, len, "Brick: %s not available."
" Brick may be containing or be contained "
- "by an existing brick", brick);
- ret = -1;
+ "by an existing brick.", brick);
+ if (op && (!strcmp (op, "GF_RESET_OP_COMMIT") ||
+ !strcmp (op, "GF_RESET_OP_COMMIT_FORCE")))
+ ret = 1;
+ else
+ ret = -1;
goto out;
}
@@ -11458,6 +11462,7 @@ glusterd_disallow_op_for_tier (glusterd_volinfo_t *volinfo, glusterd_op_t op,
switch (op) {
case GD_OP_ADD_BRICK:
case GD_OP_REPLACE_BRICK:
+ case GD_OP_RESET_BRICK:
ret = -1;
gf_msg_debug (this->name, 0, "Operation not "
"permitted on tiered volume %s",
@@ -11708,3 +11713,319 @@ get_last_brick_of_brick_group (glusterd_volinfo_t *volinfo,
return last;
}
+
+int
+glusterd_get_rb_dst_brickinfo (glusterd_volinfo_t *volinfo,
+ glusterd_brickinfo_t **brickinfo)
+{
+ int32_t ret = -1;
+
+ if (!volinfo || !brickinfo)
+ goto out;
+
+ *brickinfo = volinfo->rep_brick.dst_brick;
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+int
+rb_update_dstbrick_port (glusterd_brickinfo_t *dst_brickinfo, dict_t *rsp_dict,
+ dict_t *req_dict)
+{
+ int ret = 0;
+ int dict_ret = 0;
+ int dst_port = 0;
+
+ dict_ret = dict_get_int32 (req_dict, "dst-brick-port", &dst_port);
+ if (!dict_ret)
+ dst_brickinfo->port = dst_port;
+
+ if (gf_is_local_addr (dst_brickinfo->hostname)) {
+ gf_msg ("glusterd", GF_LOG_INFO, 0,
+ GD_MSG_BRK_PORT_NO_ADD_INDO,
+ "adding dst-brick port no %d", dst_port);
+
+ if (rsp_dict) {
+ ret = dict_set_int32 (rsp_dict, "dst-brick-port",
+ dst_brickinfo->port);
+ if (ret) {
+ gf_msg_debug ("glusterd", 0,
+ "Could not set dst-brick port no in rsp dict");
+ goto out;
+ }
+ }
+
+ if (req_dict && !dict_ret) {
+ ret = dict_set_int32 (req_dict, "dst-brick-port",
+ dst_brickinfo->port);
+ if (ret) {
+ gf_msg_debug ("glusterd", 0,
+ "Could not set dst-brick port no");
+ goto out;
+ }
+ }
+ }
+out:
+ return ret;
+}
+
+int
+glusterd_brick_op_prerequisites (dict_t *dict,
+ char **op,
+ glusterd_op_t *gd_op, char **volname,
+ glusterd_volinfo_t **volinfo,
+ char **src_brick, glusterd_brickinfo_t
+ **src_brickinfo, char *pidfile,
+ char **op_errstr, dict_t *rsp_dict)
+{
+ int ret = 0;
+ char msg[2048] = {0};
+ gsync_status_param_t param = {0,};
+ xlator_t *this = NULL;
+ glusterd_conf_t *priv = NULL;
+ glusterd_volinfo_t *v = NULL;
+ glusterd_brickinfo_t *b = NULL;
+
+ this = THIS;
+ GF_ASSERT (this);
+
+ priv = this->private;
+ GF_ASSERT (priv);
+
+ ret = dict_get_str (dict, "operation", op);
+ if (ret) {
+ gf_msg_debug (this->name, 0,
+ "dict get on operation type failed");
+ goto out;
+ }
+
+ *gd_op = gd_cli_to_gd_op (*op);
+ if (*gd_op < 0)
+ goto out;
+
+ ret = dict_get_str (dict, "volname", volname);
+
+ if (ret) {
+ gf_msg (this->name, GF_LOG_ERROR, 0,
+ GD_MSG_DICT_GET_FAILED, "Unable to get volume name");
+ goto out;
+ }
+
+ ret = glusterd_volinfo_find (*volname, volinfo);
+ if (ret) {
+ 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_disallow_op_for_tier (*volinfo, *gd_op, -1);
+ if (ret) {
+ snprintf (msg, sizeof (msg), "%sbrick commands are not "
+ "supported on tiered volume %s",
+ (*gd_op == GD_OP_REPLACE_BRICK) ? "replace-" :
+ "reset-",
+ *volname);
+ *op_errstr = gf_strdup (msg);
+ goto out;
+ }
+
+ /* If geo-rep is configured, for this volume, it should be stopped. */
+ param.volinfo = *volinfo;
+ ret = glusterd_check_geo_rep_running (&param, op_errstr);
+ if (ret || param.is_active) {
+ ret = -1;
+ goto out;
+ }
+
+ if (glusterd_is_defrag_on(*volinfo)) {
+ snprintf (msg, sizeof(msg), "Volume name %s rebalance is in "
+ "progress. Please retry after completion", *volname);
+ gf_msg (this->name, GF_LOG_ERROR, 0,
+ GD_MSG_OIP_RETRY_LATER, "%s", msg);
+ *op_errstr = gf_strdup (msg);
+ ret = -1;
+ goto out;
+ }
+
+ if (dict) {
+ if (!glusterd_is_fuse_available ()) {
+ gf_msg (this->name, GF_LOG_ERROR, 0,
+ (*gd_op == GD_OP_REPLACE_BRICK) ?
+ GD_MSG_RB_CMD_FAIL :
+ GD_MSG_RESET_BRICK_CMD_FAIL,
+ "Unable to open /dev/"
+ "fuse (%s), %s command failed",
+ strerror (errno), gd_rb_op_to_str (*op));
+ snprintf (msg, sizeof(msg), "Fuse unavailable\n "
+ "%s failed", gd_rb_op_to_str (*op));
+ *op_errstr = gf_strdup (msg);
+ ret = -1;
+ goto out;
+ }
+ }
+
+ ret = dict_get_str (dict, "src-brick", src_brick);
+
+ if (ret) {
+ gf_msg (this->name, GF_LOG_ERROR, 0,
+ GD_MSG_DICT_GET_FAILED, "Unable to get src brick");
+ goto out;
+ }
+
+ gf_msg_debug (this->name, 0, "src brick=%s", *src_brick);
+
+ ret = glusterd_volume_brickinfo_get_by_brick (*src_brick, *volinfo,
+ src_brickinfo,
+ _gf_false);
+ if (ret) {
+ snprintf (msg, sizeof (msg), "brick: %s does not exist in "
+ "volume: %s", *src_brick, *volname);
+ *op_errstr = gf_strdup (msg);
+ goto out;
+ }
+
+ if (gf_is_local_addr ((*src_brickinfo)->hostname)) {
+ gf_msg_debug (this->name, 0,
+ "I AM THE SOURCE HOST");
+ if ((*src_brickinfo)->port && rsp_dict) {
+ ret = dict_set_int32 (rsp_dict, "src-brick-port",
+ (*src_brickinfo)->port);
+ if (ret) {
+ gf_msg_debug (this->name, 0,
+ "Could not set src-brick-port=%d",
+ (*src_brickinfo)->port);
+ }
+ }
+
+ v = *volinfo;
+ b = *src_brickinfo;
+ GLUSTERD_GET_BRICK_PIDFILE (pidfile, v, b,
+ priv);
+ }
+
+ ret = 0;
+out:
+ return ret;
+}
+
+int
+glusterd_get_dst_brick_info (char **dst_brick, char *volname, char **op_errstr,
+ glusterd_brickinfo_t **dst_brickinfo, char **host,
+ dict_t *dict, char **dup_dstbrick)
+{
+
+ char *path = NULL;
+ char *c = NULL;
+ char msg[2048] = {0};
+ xlator_t *this = NULL;
+ glusterd_conf_t *priv = NULL;
+ int ret = 0;
+
+ this = THIS;
+ GF_ASSERT (this);
+
+ priv = this->private;
+ GF_ASSERT (priv);
+
+ ret = dict_get_str (dict, "dst-brick", dst_brick);
+
+ if (ret) {
+ gf_msg (this->name, GF_LOG_ERROR, 0,
+ GD_MSG_DICT_GET_FAILED,
+ "Unable to get dest brick.");
+ goto out;
+ }
+
+ gf_msg_debug (this->name, 0, "dst brick=%s", *dst_brick);
+
+ if (!glusterd_store_is_valid_brickpath (volname, *dst_brick) ||
+ !glusterd_is_valid_volfpath (volname, *dst_brick)) {
+ snprintf (msg, sizeof (msg), "brick path %s is too "
+ "long.", *dst_brick);
+ gf_msg (this->name, GF_LOG_ERROR, 0,
+ GD_MSG_BRKPATH_TOO_LONG, "%s", msg);
+ *op_errstr = gf_strdup (msg);
+
+ ret = -1;
+ goto out;
+ }
+
+ *dup_dstbrick = gf_strdup (*dst_brick);
+ if (!*dup_dstbrick) {
+ ret = -1;
+ goto out;
+ }
+
+ /*
+ * IPv4 address contains '.' and ipv6 addresses contains ':'
+ * So finding the last occurance of ':' to
+ * mark the start of brick path
+ */
+ c = strrchr(*dup_dstbrick, ':');
+ if (c != NULL) {
+ c[0] = '\0';
+ *host = *dup_dstbrick;
+ path = c++;
+ }
+
+ if (!host || !path) {
+ gf_msg (this->name, GF_LOG_ERROR, 0,
+ GD_MSG_BAD_FORMAT,
+ "dst brick %s is not of "
+ "form <HOSTNAME>:<export-dir>",
+ *dst_brick);
+ ret = -1;
+ goto out;
+ }
+
+ ret = glusterd_brickinfo_new_from_brick (*dst_brick,
+ dst_brickinfo,
+ _gf_true, NULL);
+ if (ret)
+ goto out;
+
+ ret = 0;
+out:
+ return ret;
+}
+
+glusterd_op_t
+gd_cli_to_gd_op (char *cli_op)
+{
+ if (!strcmp (cli_op, "GF_RESET_OP_START") ||
+ !strcmp(cli_op, "GF_RESET_OP_COMMIT") ||
+ !strcmp (cli_op, "GF_RESET_OP_COMMIT_FORCE")) {
+ return GD_OP_RESET_BRICK;
+ }
+
+ if (!strcmp (cli_op, "GF_REPLACE_OP_COMMIT_FORCE"))
+ return GD_OP_REPLACE_BRICK;
+
+ return -1;
+}
+
+char *
+gd_rb_op_to_str (char *op)
+{
+ if (!strcmp (op, "GF_RESET_OP_START"))
+ return "reset-brick start";
+ if (!strcmp (op, "GF_RESET_OP_COMMIT"))
+ return "reset-brick commit";
+ if (!strcmp (op, "GF_RESET_OP_COMMIT_FORCE"))
+ return "reset-brick commit force";
+ if (!strcmp (op, "GF_REPLACE_OP_COMMIT_FORCE"))
+ return "replace-brick commit force";
+ return NULL;
+}