summaryrefslogtreecommitdiffstats
path: root/xlators/mgmt/glusterd
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/mgmt/glusterd')
-rw-r--r--xlators/mgmt/glusterd/src/Makefile.am3
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-brick-ops.c2
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-handler.c1
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-hooks.c1
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-messages.h29
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-mgmt.c33
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-mgmt.h6
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-op-sm.c1
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-replace-brick.c349
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-reset-brick.c430
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-rpc-ops.c1
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-syncop.c1
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.c327
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.h34
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volume-ops.c2
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.c1
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.h6
17 files changed, 956 insertions, 271 deletions
diff --git a/xlators/mgmt/glusterd/src/Makefile.am b/xlators/mgmt/glusterd/src/Makefile.am
index 23840cdb80e..faee8625d1c 100644
--- a/xlators/mgmt/glusterd/src/Makefile.am
+++ b/xlators/mgmt/glusterd/src/Makefile.am
@@ -16,7 +16,8 @@ glusterd_la_SOURCES = glusterd.c glusterd-handler.c glusterd-sm.c \
glusterd-proc-mgmt.c glusterd-svc-mgmt.c glusterd-shd-svc.c \
glusterd-nfs-svc.c glusterd-quotad-svc.c glusterd-svc-helper.c \
glusterd-conn-helper.c glusterd-snapd-svc.c glusterd-snapd-svc-helper.c \
- glusterd-bitd-svc.c glusterd-scrub-svc.c glusterd-server-quorum.c
+ glusterd-bitd-svc.c glusterd-scrub-svc.c glusterd-server-quorum.c \
+ glusterd-reset-brick.c
glusterd_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \
diff --git a/xlators/mgmt/glusterd/src/glusterd-brick-ops.c b/xlators/mgmt/glusterd/src/glusterd-brick-ops.c
index 7be1d382d5f..8458876f50f 100644
--- a/xlators/mgmt/glusterd/src/glusterd-brick-ops.c
+++ b/xlators/mgmt/glusterd/src/glusterd-brick-ops.c
@@ -1830,7 +1830,7 @@ glusterd_op_stage_add_brick (dict_t *dict, char **op_errstr, dict_t *rsp_dict)
brick_alloc = _gf_true;
ret = glusterd_new_brick_validate (brick, brickinfo, msg,
- sizeof (msg));
+ sizeof (msg), NULL);
if (ret) {
*op_errstr = gf_strdup (msg);
ret = -1;
diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c
index 4a027f4ed7d..18886dc5d15 100644
--- a/xlators/mgmt/glusterd/src/glusterd-handler.c
+++ b/xlators/mgmt/glusterd/src/glusterd-handler.c
@@ -5926,6 +5926,7 @@ rpcsvc_actor_t gd_svc_cli_actors[GLUSTER_CLI_MAXVALUE] = {
[GLUSTER_CLI_GET_VOL_OPT] = {"GET_VOL_OPT", GLUSTER_CLI_GET_VOL_OPT, glusterd_handle_get_vol_opt, NULL, 0, DRC_NA},
[GLUSTER_CLI_BITROT] = {"BITROT", GLUSTER_CLI_BITROT, glusterd_handle_bitrot, NULL, 0, DRC_NA},
[GLUSTER_CLI_GET_STATE] = {"GET_STATE", GLUSTER_CLI_GET_STATE, glusterd_handle_get_state, NULL, 0, DRC_NA},
+ [GLUSTER_CLI_RESET_BRICK] = {"RESET_BRICK", GLUSTER_CLI_RESET_BRICK, glusterd_handle_reset_brick, NULL, 0, DRC_NA},
};
struct rpcsvc_program gd_svc_cli_prog = {
diff --git a/xlators/mgmt/glusterd/src/glusterd-hooks.c b/xlators/mgmt/glusterd/src/glusterd-hooks.c
index 9229da9c45f..77efa6c57b3 100644
--- a/xlators/mgmt/glusterd/src/glusterd-hooks.c
+++ b/xlators/mgmt/glusterd/src/glusterd-hooks.c
@@ -57,6 +57,7 @@ char glusterd_hook_dirnames[GD_OP_MAX][256] =
[GD_OP_LIST_VOLUME] = EMPTY,
[GD_OP_CLEARLOCKS_VOLUME] = EMPTY,
[GD_OP_DEFRAG_BRICK_VOLUME] = EMPTY,
+ [GD_OP_RESET_BRICK] = EMPTY,
};
#undef EMPTY
diff --git a/xlators/mgmt/glusterd/src/glusterd-messages.h b/xlators/mgmt/glusterd/src/glusterd-messages.h
index f0c9ee25ed6..e520c69add2 100644
--- a/xlators/mgmt/glusterd/src/glusterd-messages.h
+++ b/xlators/mgmt/glusterd/src/glusterd-messages.h
@@ -41,7 +41,7 @@
#define GLUSTERD_COMP_BASE GLFS_MSGID_GLUSTERD
-#define GLFS_NUM_MESSAGES 585
+#define GLFS_NUM_MESSAGES 587
#define GLFS_MSGID_END (GLUSTERD_COMP_BASE + GLFS_NUM_MESSAGES + 1)
/* Messaged with message IDs */
@@ -2837,7 +2837,7 @@
* @recommendedaction
*
*/
-#define GD_MSG_NFS_VOL_FILE_GEN_FAIL (GLUSTERD_COMP_BASE + 349)
+#define GD_MSG_GLUSTER_SERVICE_START_FAIL (GLUSTERD_COMP_BASE + 349)
/*!
* @messageid
@@ -2965,7 +2965,7 @@
* @recommendedaction
*
*/
-#define GD_MSG_NFS_SERVER_STOP_FAIL (GLUSTERD_COMP_BASE + 365)
+#define GD_MSG_GLUSTER_SERVICES_STOP_FAIL (GLUSTERD_COMP_BASE + 365)
/*!
* @messageid
@@ -4727,8 +4727,31 @@
* @recommendation
*
*/
+#define GD_MSG_BRICK_CLEANUP_SUCCESS (GLUSTERD_COMP_BASE + 584)
+
+/*!
+ * @messageid
+ * @diagnosis
+ * @recommendation
+ *
+ */
#define GD_MSG_STATE_STR_GET_FAILED (GLUSTERD_COMP_BASE + 585)
+/*!
+ * @messageid
+ * @diagnosis
+ * @recommendedaction
+ *
+ */
+#define GD_MSG_RESET_BRICK_COMMIT_FORCE_REQ_RCVD (GLUSTERD_COMP_BASE + 586)
+
+/*!
+ * @messageid
+ * @diagnosis
+ * @recommendedaction
+ *
+ */
+#define GD_MSG_RESET_BRICK_CMD_FAIL (GLUSTERD_COMP_BASE + 587)
/*------------*/
#define glfs_msg_end_x GLFS_MSGID_END, "Invalid: End of messages"
#endif /* !_GLUSTERD_MESSAGES_H_ */
diff --git a/xlators/mgmt/glusterd/src/glusterd-mgmt.c b/xlators/mgmt/glusterd/src/glusterd-mgmt.c
index 6cc7b84b8b2..a5d22e4e265 100644
--- a/xlators/mgmt/glusterd/src/glusterd-mgmt.c
+++ b/xlators/mgmt/glusterd/src/glusterd-mgmt.c
@@ -189,6 +189,17 @@ gd_mgmt_v3_pre_validate_fn (glusterd_op_t op, dict_t *dict,
}
break;
+ case GD_OP_RESET_BRICK:
+ ret = glusterd_reset_brick_prevalidate (dict, op_errstr,
+ rsp_dict);
+ if (ret) {
+ gf_msg (this->name, GF_LOG_WARNING, 0,
+ GD_MSG_PRE_VALIDATION_FAIL,
+ "Reset brick prevalidation failed.");
+ goto out;
+ }
+ break;
+
default:
break;
}
@@ -298,6 +309,17 @@ gd_mgmt_v3_commit_fn (glusterd_op_t op, dict_t *dict,
break;
}
+ case GD_OP_RESET_BRICK:
+ {
+ ret = glusterd_op_reset_brick (dict, rsp_dict);
+ if (ret) {
+ gf_msg (this->name, GF_LOG_ERROR, 0,
+ GD_MSG_COMMIT_OP_FAIL,
+ "Reset-brick commit failed.");
+ goto out;
+ }
+ break;
+ }
default:
break;
@@ -670,6 +692,16 @@ glusterd_pre_validate_aggr_rsp_dict (glusterd_op_t op,
goto out;
}
break;
+ case GD_OP_RESET_BRICK:
+ ret = glusterd_rb_use_rsp_dict (aggr, rsp);
+ if (ret) {
+ gf_msg (this->name, GF_LOG_ERROR, 0,
+ GD_MSG_PRE_VALIDATION_FAIL,
+ "Failed to aggregate prevalidate "
+ "response dictionaries.");
+ goto out;
+ }
+ break;
default:
ret = -1;
gf_msg (this->name, GF_LOG_ERROR, EINVAL,
@@ -972,6 +1004,7 @@ glusterd_mgmt_v3_build_payload (dict_t **req, char **op_errstr, dict_t *dict,
case GD_OP_START_VOLUME:
case GD_OP_ADD_BRICK:
case GD_OP_REPLACE_BRICK:
+ case GD_OP_RESET_BRICK:
{
ret = dict_get_str (dict, "volname", &volname);
if (ret) {
diff --git a/xlators/mgmt/glusterd/src/glusterd-mgmt.h b/xlators/mgmt/glusterd/src/glusterd-mgmt.h
index bf87ec710f1..2215f178327 100644
--- a/xlators/mgmt/glusterd/src/glusterd-mgmt.h
+++ b/xlators/mgmt/glusterd/src/glusterd-mgmt.h
@@ -74,4 +74,10 @@ glusterd_mgmt_v3_release_peer_locks (glusterd_op_t op, dict_t *dict,
int32_t
glusterd_multiple_mgmt_v3_unlock (dict_t *dict, uuid_t uuid);
+
+int
+glusterd_reset_brick_prevalidate (dict_t *dict, char **op_errstr,
+ dict_t *rsp_dict);
+int
+glusterd_op_reset_brick (dict_t *dict, dict_t *rsp_dict);
#endif /* _GLUSTERD_MGMT_H_ */
diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
index 553b7b4a6cf..dc28a2b9236 100644
--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c
+++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
@@ -4139,6 +4139,7 @@ glusterd_op_build_payload (dict_t **req, char **op_errstr, dict_t *op_ctx)
case GD_OP_BITROT:
case GD_OP_SCRUB_STATUS:
case GD_OP_SCRUB_ONDEMAND:
+ case GD_OP_RESET_BRICK:
{
do_common = _gf_true;
}
diff --git a/xlators/mgmt/glusterd/src/glusterd-replace-brick.c b/xlators/mgmt/glusterd/src/glusterd-replace-brick.c
index 0df5d437ca5..687ff004eb5 100644
--- a/xlators/mgmt/glusterd/src/glusterd-replace-brick.c
+++ b/xlators/mgmt/glusterd/src/glusterd-replace-brick.c
@@ -27,13 +27,6 @@
#include <signal.h>
-#define GLUSTERD_GET_RB_MNTPT(path, len, volinfo) \
- snprintf (path, len, \
- DEFAULT_VAR_RUN_DIRECTORY"/%s-"RB_CLIENT_MOUNTPOINT, \
- volinfo->volname);
-
-extern uuid_t global_txn_id;
-
int
glusterd_mgmt_v3_initiate_replace_brick_cmd_phases (rpcsvc_request_t *req,
glusterd_op_t op,
@@ -46,14 +39,17 @@ __glusterd_handle_replace_brick (rpcsvc_request_t *req)
dict_t *dict = NULL;
char *src_brick = NULL;
char *dst_brick = NULL;
- int32_t op = 0;
+ char *cli_op = NULL;
+ glusterd_op_t op = -1;
char *volname = NULL;
char msg[2048] = {0,};
xlator_t *this = NULL;
+ glusterd_conf_t *conf = NULL;
GF_ASSERT (req);
this = THIS;
GF_ASSERT (this);
+ conf = this->private;
ret = xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req);
if (ret < 0) {
@@ -95,7 +91,7 @@ __glusterd_handle_replace_brick (rpcsvc_request_t *req)
goto out;
}
- ret = dict_get_int32 (dict, "operation", &op);
+ ret = dict_get_str (dict, "operation", &cli_op);
if (ret) {
gf_msg_debug (this->name, 0,
"dict_get on operation failed");
@@ -103,6 +99,19 @@ __glusterd_handle_replace_brick (rpcsvc_request_t *req)
goto out;
}
+ op = gd_cli_to_gd_op (cli_op);
+
+ if (conf->op_version < GD_OP_VERSION_3_9_0 &&
+ strcmp (cli_op, "GF_REPLACE_OP_COMMIT_FORCE")) {
+ snprintf (msg, sizeof (msg), "Cannot execute command. The "
+ "cluster is operating at version %d. reset-brick "
+ "command %s is unavailable in this version.",
+ conf->op_version,
+ gd_rb_op_to_str (cli_op));
+ ret = -1;
+ goto out;
+ }
+
ret = dict_get_str (dict, "src-brick", &src_brick);
if (ret) {
@@ -114,52 +123,60 @@ __glusterd_handle_replace_brick (rpcsvc_request_t *req)
gf_msg_debug (this->name, 0,
"src brick=%s", src_brick);
- ret = dict_get_str (dict, "dst-brick", &dst_brick);
+ if (!strcmp (cli_op, "GF_RESET_OP_COMMIT") ||
+ !strcmp (cli_op, "GF_RESET_OP_COMMIT_FORCE") ||
+ !strcmp (cli_op, "GF_REPLACE_OP_COMMIT_FORCE")) {
+ ret = dict_get_str (dict, "dst-brick", &dst_brick);
- if (ret) {
- snprintf (msg, sizeof (msg), "Failed to get dest brick");
- gf_msg (this->name, GF_LOG_ERROR, 0,
- GD_MSG_DICT_GET_FAILED, "%s", msg);
- goto out;
+ if (ret) {
+ snprintf (msg, sizeof (msg), "Failed to get"
+ "dest brick");
+ gf_msg (this->name, GF_LOG_ERROR, 0,
+ GD_MSG_DICT_GET_FAILED, "%s", msg);
+ goto out;
+ }
+
+ gf_msg_debug (this->name, 0, "dst brick=%s", dst_brick);
}
- gf_msg_debug (this->name, 0, "dst brick=%s", dst_brick);
gf_msg (this->name, GF_LOG_INFO, 0,
- GD_MSG_REPLACE_BRK_COMMIT_FORCE_REQ_RCVD,
- "Received replace brick commit-force "
- "request operation");
+ (op == GD_OP_REPLACE_BRICK) ?
+ GD_MSG_REPLACE_BRK_COMMIT_FORCE_REQ_RCVD :
+ GD_MSG_RESET_BRICK_COMMIT_FORCE_REQ_RCVD,
+ "Received %s request.",
+ gd_rb_op_to_str (cli_op));
+
+ gf_event ((op == GD_OP_REPLACE_BRICK) ? EVENT_BRICK_REPLACE :
+ EVENT_BRICK_RESET, "received %s request. Source bricks %s,"
+ "destination brick %s.", gd_rb_op_to_str (cli_op),
+ src_brick, (dst_brick) ? dst_brick : "");
ret = glusterd_mgmt_v3_initiate_replace_brick_cmd_phases (req,
- GD_OP_REPLACE_BRICK, dict);
+ op, dict);
out:
+ if (ret) {
+ glusterd_op_send_cli_response (op, ret, 0, req,
+ dict, msg);
+ }
+ ret = 0;
free (cli_req.dict.dict_val);//malloced by xdr
return ret;
}
int
-glusterd_handle_replace_brick (rpcsvc_request_t *req)
+glusterd_handle_reset_brick (rpcsvc_request_t *req)
{
return glusterd_big_locked_handler (req,
__glusterd_handle_replace_brick);
}
-static int
-glusterd_get_rb_dst_brickinfo (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t **brickinfo)
+int
+glusterd_handle_replace_brick (rpcsvc_request_t *req)
{
- int32_t ret = -1;
-
- if (!volinfo || !brickinfo)
- goto out;
-
- *brickinfo = volinfo->rep_brick.dst_brick;
-
- ret = 0;
-
-out:
- return ret;
+ return glusterd_big_locked_handler (req,
+ __glusterd_handle_replace_brick);
}
int
@@ -170,21 +187,22 @@ glusterd_op_stage_replace_brick (dict_t *dict, char **op_errstr,
char *src_brick = NULL;
char *dst_brick = NULL;
char *volname = NULL;
- char *replace_op = NULL;
+ char *op = NULL;
+ glusterd_op_t gd_op = -1;
glusterd_volinfo_t *volinfo = NULL;
glusterd_brickinfo_t *src_brickinfo = NULL;
char *host = NULL;
char *path = NULL;
char msg[2048] = {0};
- char *dup_dstbrick = NULL;
glusterd_peerinfo_t *peerinfo = NULL;
glusterd_brickinfo_t *dst_brickinfo = NULL;
glusterd_conf_t *priv = NULL;
char pidfile[PATH_MAX] = {0};
xlator_t *this = NULL;
gf_boolean_t is_force = _gf_false;
- gsync_status_param_t param = {0,};
- char *c = NULL;
+ pid_t pid = -1;
+ uuid_t volume_id = {0,};
+ char *dup_dstbrick = NULL;
this = THIS;
GF_ASSERT (this);
@@ -192,193 +210,41 @@ glusterd_op_stage_replace_brick (dict_t *dict, char **op_errstr,
priv = this->private;
GF_ASSERT (priv);
- 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 = 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);
-
- 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 = dict_get_str (dict, "operation", &replace_op);
- if (ret) {
- gf_msg_debug (this->name, 0,
- "dict get on replace-brick operation failed");
- 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_REPLACE_BRICK, -1);
- if (ret) {
- snprintf (msg, sizeof (msg), "Replace brick commands are not "
- "supported on tiered volume %s", volname);
- *op_errstr = gf_strdup (msg);
- goto out;
- }
-
- 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;
- }
-
- /* 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;
+ ret = glusterd_brick_op_prerequisites (dict, &op, &gd_op,
+ &volname, &volinfo,
+ &src_brick, &src_brickinfo,
+ pidfile,
+ op_errstr, rsp_dict);
+ if (ret)
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);
+ if (strcmp (op, "GF_REPLACE_OP_COMMIT_FORCE")) {
ret = -1;
goto out;
- }
-
- if (!strcmp(replace_op, "GF_REPLACE_OP_COMMIT_FORCE")) {
- is_force = _gf_true;
} else {
- ret = -1;
- goto out;
- }
-
- 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 (dict) {
- if (!glusterd_is_fuse_available ()) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- GD_MSG_RB_CMD_FAIL, "Unable to open /dev/"
- "fuse (%s), replace-brick command failed",
- strerror (errno));
- snprintf (msg, sizeof(msg), "Fuse unavailable\n "
- "Replace-brick failed");
- *op_errstr = gf_strdup (msg);
- ret = -1;
- 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);
- }
- }
-
- GLUSTERD_GET_BRICK_PIDFILE (pidfile, volinfo, src_brickinfo,
- priv);
-
- }
-
- dup_dstbrick = gf_strdup (dst_brick);
- if (!dup_dstbrick) {
- ret = -1;
- gf_msg (this->name, GF_LOG_ERROR, ENOMEM,
- GD_MSG_NO_MEMORY, "Memory allocation failed");
- 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;
- }
+ is_force = _gf_true;
+ }
- ret = glusterd_brickinfo_new_from_brick (dst_brick, &dst_brickinfo,
- _gf_true, NULL);
+ ret = glusterd_get_dst_brick_info (&dst_brick, volname,
+ op_errstr,
+ &dst_brickinfo, &host,
+ dict, &dup_dstbrick);
if (ret)
goto out;
ret = glusterd_new_brick_validate (dst_brick, dst_brickinfo,
- msg, sizeof (msg));
- if (ret) {
+ msg, sizeof (msg), op);
+ /* fail if brick being replaced with itself */
+ if (ret) {
*op_errstr = gf_strdup (msg);
ret = -1;
gf_msg (this->name, GF_LOG_ERROR, 0,
GD_MSG_BRICK_VALIDATE_FAIL, "%s", *op_errstr);
goto out;
- }
+ }
- if (!strcmp(replace_op, "GF_REPLACE_OP_COMMIT_FORCE")) {
-
- volinfo->rep_brick.src_brick = src_brickinfo;
- volinfo->rep_brick.dst_brick = dst_brickinfo;
- }
+ volinfo->rep_brick.src_brick = src_brickinfo;
+ volinfo->rep_brick.dst_brick = dst_brickinfo;
if (glusterd_rb_check_bricks (volinfo, src_brickinfo, dst_brickinfo)) {
@@ -484,48 +350,8 @@ rb_kill_destination_brick (glusterd_volinfo_t *volinfo,
return glusterd_service_stop ("brick", pidfile, SIGTERM, _gf_true);
}
-static int
-rb_update_dstbrick_port (glusterd_brickinfo_t *dst_brickinfo, dict_t *rsp_dict,
- dict_t *req_dict, char *replace_op)
-{
- 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");
-
- 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) {
- 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;
-}
-static int
+int
glusterd_op_perform_replace_brick (glusterd_volinfo_t *volinfo,
char *old_brick, char *new_brick,
dict_t *dict)
@@ -563,6 +389,7 @@ glusterd_op_perform_replace_brick (glusterd_volinfo_t *volinfo,
strncpy (new_brickinfo->brick_id, old_brickinfo->brick_id,
sizeof (new_brickinfo->brick_id));
+ new_brickinfo->port = old_brickinfo->port;
/* A bricks mount dir is required only by snapshots which were
* introduced in gluster-3.6.0
@@ -579,8 +406,8 @@ glusterd_op_perform_replace_brick (glusterd_volinfo_t *volinfo,
sizeof(new_brickinfo->mount_dir));
}
- cds_list_add_tail (&new_brickinfo->brick_list,
- &old_brickinfo->brick_list);
+ cds_list_add (&new_brickinfo->brick_list,
+ &old_brickinfo->brick_list);
volinfo->brick_count++;
@@ -699,11 +526,11 @@ glusterd_op_replace_brick (dict_t *dict, dict_t *rsp_dict)
}
ret = rb_update_dstbrick_port (dst_brickinfo, rsp_dict,
- dict, replace_op);
+ dict);
if (ret)
goto out;
- if (strcmp(replace_op, "GF_REPLACE_OP_COMMIT_FORCE")) {
+ if (strcmp (replace_op, "GF_REPLACE_OP_COMMIT_FORCE")) {
ret = -1;
goto out;
}
@@ -722,8 +549,8 @@ glusterd_op_replace_brick (dict_t *dict, dict_t *rsp_dict)
ret = glusterd_svcs_stop (volinfo);
if (ret) {
gf_msg (this->name, GF_LOG_ERROR, 0,
- GD_MSG_NFS_SERVER_STOP_FAIL,
- "Unable to stop nfs server, ret: %d", ret);
+ GD_MSG_GLUSTER_SERVICES_STOP_FAIL,
+ "Unable to stop gluster services, ret: %d", ret);
}
ret = glusterd_op_perform_replace_brick (volinfo, src_brick,
@@ -732,7 +559,7 @@ glusterd_op_replace_brick (dict_t *dict, dict_t *rsp_dict)
gf_msg (this->name, GF_LOG_CRITICAL, 0,
GD_MSG_BRICK_ADD_FAIL, "Unable to add dst-brick: "
"%s to volume: %s", dst_brick, volinfo->volname);
- (void) glusterd_svcs_manager (volinfo);
+ (void) glusterd_svcs_manager (volinfo);
goto out;
}
@@ -741,8 +568,8 @@ glusterd_op_replace_brick (dict_t *dict, dict_t *rsp_dict)
ret = glusterd_svcs_manager (volinfo);
if (ret) {
gf_msg (this->name, GF_LOG_CRITICAL, 0,
- GD_MSG_NFS_VOL_FILE_GEN_FAIL,
- "Failed to generate nfs volume file");
+ GD_MSG_GLUSTER_SERVICE_START_FAIL,
+ "Failed to start one or more gluster services.");
}
@@ -752,7 +579,7 @@ glusterd_op_replace_brick (dict_t *dict, dict_t *rsp_dict)
volinfo->rep_brick.dst_brick = NULL;
if (!ret)
- ret = glusterd_store_volinfo (volinfo,
+ ret = glusterd_store_volinfo (volinfo,
GLUSTERD_VOLINFO_VER_AC_INCREMENT);
if (ret)
gf_msg (this->name, GF_LOG_ERROR, 0,
diff --git a/xlators/mgmt/glusterd/src/glusterd-reset-brick.c b/xlators/mgmt/glusterd/src/glusterd-reset-brick.c
new file mode 100644
index 00000000000..d1efe0663fb
--- /dev/null
+++ b/xlators/mgmt/glusterd/src/glusterd-reset-brick.c
@@ -0,0 +1,430 @@
+/*
+ Copyright (c) 2016 Red Hat, Inc. <http://www.redhat.com>
+ This file is part of GlusterFS.
+
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
+*/
+#include "common-utils.h"
+#include "cli1-xdr.h"
+#include "xdr-generic.h"
+#include "glusterfs.h"
+#include "glusterd.h"
+#include "glusterd-op-sm.h"
+#include "glusterd-geo-rep.h"
+#include "glusterd-store.h"
+#include "glusterd-utils.h"
+#include "glusterd-svc-mgmt.h"
+#include "glusterd-svc-helper.h"
+#include "glusterd-nfs-svc.h"
+#include "glusterd-volgen.h"
+#include "glusterd-messages.h"
+#include "glusterd-mgmt.h"
+#include "run.h"
+#include "syscall.h"
+
+#include <signal.h>
+
+int
+glusterd_reset_brick_prevalidate (dict_t *dict, char **op_errstr,
+ dict_t *rsp_dict)
+{
+ int ret = 0;
+ int32_t port = 0;
+ char *src_brick = NULL;
+ char *dst_brick = NULL;
+ char *volname = NULL;
+ char *op = NULL;
+ glusterd_op_t gd_op = -1;
+ glusterd_volinfo_t *volinfo = NULL;
+ glusterd_brickinfo_t *src_brickinfo = NULL;
+ char *host = NULL;
+ char msg[2048] = {0};
+ glusterd_peerinfo_t *peerinfo = NULL;
+ glusterd_brickinfo_t *dst_brickinfo = NULL;
+ gf_boolean_t enabled = _gf_false;
+ glusterd_conf_t *priv = NULL;
+ char *savetok = NULL;
+ char pidfile[PATH_MAX] = {0};
+ char *task_id_str = NULL;
+ xlator_t *this = NULL;
+ gf_boolean_t is_force = _gf_false;
+ gsync_status_param_t param = {0,};
+ pid_t pid = -1;
+ uuid_t volume_id = {0,};
+ char *dup_dstbrick = NULL;
+
+ this = THIS;
+ GF_ASSERT (this);
+
+ priv = this->private;
+ GF_ASSERT (priv);
+
+ ret = glusterd_brick_op_prerequisites (dict, &op, &gd_op,
+ &volname, &volinfo,
+ &src_brick, &src_brickinfo,
+ pidfile,
+ op_errstr, rsp_dict);
+ if (ret)
+ goto out;
+
+ if (!strcmp (op, "GF_RESET_OP_START"))
+ goto done;
+
+ if (!strcmp (op, "GF_RESET_OP_COMMIT_FORCE"))
+ is_force = _gf_true;
+
+ ret = glusterd_get_dst_brick_info (&dst_brick, volname,
+ op_errstr,
+ &dst_brickinfo, &host,
+ dict, &dup_dstbrick);
+ if (ret)
+ goto out;
+
+ ret = glusterd_new_brick_validate (dst_brick, dst_brickinfo,
+ msg, sizeof (msg), op);
+ /* if bricks are not same and reset brick was used, fail command.
+ * Only replace brick should be used to replace with new bricks
+ * to the volume.
+ */
+ if (ret == 0) {
+ if (!gf_uuid_compare (MY_UUID, dst_brickinfo->uuid)) {
+ ret = -1;
+ *op_errstr = gf_strdup
+ ("When destination brick is new,"
+ " please use"
+ " gluster volume "
+ "replace-brick <volname> "
+ "<src-brick> <dst-brick> "
+ "commit force");
+ if (*op_errstr)
+ gf_msg (this->name,
+ GF_LOG_ERROR,
+ EPERM,
+ GD_MSG_BRICK_VALIDATE_FAIL,
+ "%s", *op_errstr);
+ goto out;
+ }
+ } else if (ret == 1) {
+ if (gf_is_service_running (pidfile, &pid)) {
+ ret = -1;
+ *op_errstr = gf_strdup
+ ("Source brick"
+ " must be stopped."
+ " Please use "
+ "gluster volume "
+ "reset-brick <volname> "
+ "<dst-brick> start.");
+ if (*op_errstr)
+ gf_msg (this->name,
+ GF_LOG_ERROR,
+ EPERM,
+ GD_MSG_BRICK_VALIDATE_FAIL,
+ "%s", *op_errstr);
+ goto out;
+ }
+ ret = sys_lgetxattr (dst_brickinfo->path,
+ GF_XATTR_VOL_ID_KEY,
+ volume_id, 16);
+ if (gf_uuid_compare (dst_brickinfo->uuid,
+ src_brickinfo->uuid) ||
+ (ret >= 0 && is_force == _gf_false)) {
+ ret = -1;
+ *op_errstr = gf_strdup ("Brick not available."
+ "It may be containing "
+ "or be contained "
+ "by an existing brick."
+ "Use 'force' option to "
+ "override this.");
+ if (*op_errstr)
+ gf_msg (this->name,
+ GF_LOG_ERROR,
+ EPERM,
+ GD_MSG_BRICK_VALIDATE_FAIL,
+ "%s", *op_errstr);
+ goto out;
+ }
+ ret = 0;
+ } else {
+ *op_errstr = gf_strdup (msg);
+ ret = -1;
+ gf_msg (this->name, GF_LOG_ERROR, 0,
+ GD_MSG_BRICK_VALIDATE_FAIL, "%s", *op_errstr);
+ goto out;
+ }
+
+ volinfo->rep_brick.src_brick = src_brickinfo;
+ volinfo->rep_brick.dst_brick = dst_brickinfo;
+
+ if (gf_is_local_addr (host)) {
+ ret = glusterd_validate_and_create_brickpath
+ (dst_brickinfo,
+ volinfo->volume_id,
+ op_errstr, is_force);
+ if (ret)
+ goto out;
+ } else {
+ rcu_read_lock ();
+
+ peerinfo = glusterd_peerinfo_find (NULL, host);
+ if (peerinfo == NULL) {
+ ret = -1;
+ snprintf (msg, sizeof (msg),
+ "%s, is not a friend.",
+ host);
+ *op_errstr = gf_strdup (msg);
+
+ } else if (!peerinfo->connected) {
+ snprintf (msg, sizeof (msg), "%s,"
+ "is not connected at "
+ "the moment.", host);
+ *op_errstr = gf_strdup (msg);
+ ret = -1;
+
+ } else 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;
+ }
+ rcu_read_unlock ();
+
+ if (ret)
+ goto out;
+
+ }
+
+ ret = glusterd_get_brick_mount_dir
+ (dst_brickinfo->path,
+ dst_brickinfo->hostname,
+ dst_brickinfo->mount_dir);
+ if (ret) {
+ gf_msg (this->name, GF_LOG_ERROR, 0,
+ GD_MSG_BRICK_MOUNTDIR_GET_FAIL,
+ "Failed to get brick mount_dir.");
+ goto out;
+ }
+
+ ret = dict_set_dynstr_with_alloc (rsp_dict,
+ "brick1.mount_dir",
+ dst_brickinfo->mount_dir);
+ if (ret) {
+ gf_msg (this->name, GF_LOG_ERROR, 0,
+ GD_MSG_DICT_SET_FAILED,
+ "Failed to set brick1.mount_dir");
+ goto out;
+ }
+
+ ret = dict_set_int32 (rsp_dict, "brick_count", 1);
+ if (ret) {
+ gf_msg (this->name, GF_LOG_ERROR, 0,
+ GD_MSG_DICT_SET_FAILED,
+ "Failed to set local_brick_count.");
+ goto out;
+ }
+
+done:
+ ret = 0;
+out:
+ GF_FREE (dup_dstbrick);
+ gf_msg_debug (this->name, 0, "Returning %d.", ret);
+
+ return ret;
+}
+
+int
+glusterd_op_reset_brick (dict_t *dict, dict_t *rsp_dict)
+{
+ int ret = 0;
+ dict_t *ctx = NULL;
+ char *op = NULL;
+ glusterd_volinfo_t *volinfo = NULL;
+ char *volname = NULL;
+ xlator_t *this = NULL;
+ glusterd_conf_t *priv = NULL;
+ char *src_brick = NULL;
+ char *dst_brick = NULL;
+ glusterd_brickinfo_t *src_brickinfo = NULL;
+ glusterd_brickinfo_t *dst_brickinfo = NULL;
+ char *task_id_str = NULL;
+ char pidfile[PATH_MAX] = {0,};
+
+ 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 failed");
+ 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)
+ 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) {
+ gf_msg_debug (this->name, 0,
+ "Unable to get src-brickinfo");
+ goto out;
+ }
+
+ if (!strcmp (op, "GF_RESET_OP_START")) {
+ (void) glusterd_brick_disconnect (src_brickinfo);
+ GLUSTERD_GET_BRICK_PIDFILE (pidfile, volinfo,
+ src_brickinfo, priv);
+ ret = glusterd_service_stop ("brick", pidfile,
+ SIGTERM, _gf_false);
+ if (ret == 0) {
+ glusterd_set_brick_status (src_brickinfo,
+ GF_BRICK_STOPPED);
+ (void) glusterd_brick_unlink_socket_file
+ (volinfo, src_brickinfo);
+ gf_msg (this->name, GF_LOG_INFO, 0,
+ GD_MSG_BRICK_CLEANUP_SUCCESS,
+ "Brick cleanup successful.");
+ } else {
+ gf_msg (this->name, GF_LOG_CRITICAL, 0,
+ GD_MSG_BRK_CLEANUP_FAIL,
+ "Unable to cleanup src brick");
+ goto out;
+ }
+ goto out;
+ } else if (!strcmp (op, "GF_RESET_OP_COMMIT") ||
+ !strcmp (op, "GF_RESET_OP_COMMIT_FORCE")) {
+ 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 dst brick");
+ goto out;
+ }
+
+ gf_msg_debug (this->name, 0, "dst brick=%s", dst_brick);
+
+ ret = glusterd_get_rb_dst_brickinfo (volinfo,
+ &dst_brickinfo);
+ if (ret) {
+ gf_msg (this->name, GF_LOG_ERROR, 0,
+ GD_MSG_RB_BRICKINFO_GET_FAIL,
+ "Unable to get "
+ "reset brick "
+ "destination brickinfo");
+ goto out;
+ }
+
+ ret = glusterd_resolve_brick (dst_brickinfo);
+ if (ret) {
+ gf_msg_debug (this->name, 0,
+ "Unable to resolve dst-brickinfo");
+ goto out;
+ }
+
+ ret = rb_update_dstbrick_port (dst_brickinfo, rsp_dict,
+ dict);
+ if (ret)
+ goto out;
+
+ if (gf_is_local_addr (dst_brickinfo->hostname)) {
+ gf_msg_debug (this->name, 0, "I AM THE DESTINATION HOST");
+ (void) glusterd_brick_disconnect (src_brickinfo);
+ GLUSTERD_GET_BRICK_PIDFILE (pidfile, volinfo,
+ src_brickinfo, priv);
+ ret = glusterd_service_stop ("brick", pidfile,
+ SIGTERM, _gf_false);
+ if (ret == 0) {
+ glusterd_set_brick_status
+ (src_brickinfo, GF_BRICK_STOPPED);
+ (void) glusterd_brick_unlink_socket_file
+ (volinfo, src_brickinfo);
+ gf_msg (this->name, GF_LOG_INFO, 0,
+ GD_MSG_BRICK_CLEANUP_SUCCESS,
+ "Brick cleanup successful.");
+ } else {
+ gf_msg (this->name, GF_LOG_CRITICAL, 0,
+ GD_MSG_BRK_CLEANUP_FAIL,
+ "Unable to cleanup src brick");
+ goto out;
+ }
+ }
+
+ ret = glusterd_svcs_stop (volinfo);
+ if (ret) {
+ gf_msg (this->name, GF_LOG_ERROR, 0,
+ GD_MSG_GLUSTER_SERVICES_STOP_FAIL,
+ "Unable to stop gluster services, ret: %d",
+ ret);
+ goto out;
+ }
+ ret = glusterd_op_perform_replace_brick (volinfo, src_brick,
+ dst_brick, dict);
+ if (ret) {
+ gf_msg (this->name, GF_LOG_CRITICAL, 0,
+ GD_MSG_BRICK_ADD_FAIL,
+ "Unable to add dst-brick: "
+ "%s to volume: %s", dst_brick,
+ volinfo->volname);
+ (void) glusterd_svcs_manager (volinfo);
+ goto out;
+ }
+
+ volinfo->rebal.defrag_status = 0;
+
+ ret = glusterd_svcs_manager (volinfo);
+ if (ret) {
+ gf_msg (this->name, GF_LOG_CRITICAL, 0,
+ GD_MSG_GLUSTER_SERVICE_START_FAIL,
+ "Failed to start one or more gluster services.");
+ }
+
+
+ ret = glusterd_fetchspec_notify (THIS);
+ glusterd_brickinfo_delete (volinfo->rep_brick.dst_brick);
+ volinfo->rep_brick.src_brick = NULL;
+ volinfo->rep_brick.dst_brick = NULL;
+
+ if (!ret)
+ ret = glusterd_store_volinfo (volinfo,
+ GLUSTERD_VOLINFO_VER_AC_INCREMENT);
+ if (ret) {
+ gf_msg (this->name, GF_LOG_ERROR, 0,
+ GD_MSG_RBOP_STATE_STORE_FAIL,
+ "Couldn't store"
+ " reset brick operation's state.");
+
+ }
+ } else {
+ ret = -1;
+ goto out;
+ }
+
+
+out:
+ return ret;
+}
diff --git a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c
index 03b6e71cd9a..f9e76f3fad5 100644
--- a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c
+++ b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c
@@ -144,6 +144,7 @@ glusterd_op_send_cli_response (glusterd_op_t op, int32_t op_ret,
case GD_OP_BITROT:
case GD_OP_SCRUB_STATUS:
case GD_OP_SCRUB_ONDEMAND:
+ case GD_OP_RESET_BRICK:
{
/*nothing specific to be done*/
break;
diff --git a/xlators/mgmt/glusterd/src/glusterd-syncop.c b/xlators/mgmt/glusterd/src/glusterd-syncop.c
index 70d10208584..2b7a4477fca 100644
--- a/xlators/mgmt/glusterd/src/glusterd-syncop.c
+++ b/xlators/mgmt/glusterd/src/glusterd-syncop.c
@@ -248,6 +248,7 @@ glusterd_syncop_aggr_rsp_dict (glusterd_op_t op, dict_t *aggr, dict_t *rsp)
break;
case GD_OP_REPLACE_BRICK:
+ case GD_OP_RESET_BRICK:
ret = glusterd_rb_use_rsp_dict (aggr, rsp);
if (ret)
goto out;
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;
+}
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h
index ca07efd54ba..419ab48323a 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.h
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.h
@@ -242,7 +242,7 @@ glusterd_volinfo_bricks_delete (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);
int32_t
glusterd_volume_brickinfos_delete (glusterd_volinfo_t *volinfo);
@@ -741,4 +741,36 @@ assign_brick_groups (glusterd_volinfo_t *volinfo);
glusterd_brickinfo_t*
get_last_brick_of_brick_group (glusterd_volinfo_t *volinfo,
glusterd_brickinfo_t *brickinfo);
+int
+glusterd_get_rb_dst_brickinfo (glusterd_volinfo_t *volinfo,
+ glusterd_brickinfo_t **brickinfo);
+int
+rb_update_dstbrick_port (glusterd_brickinfo_t *dst_brickinfo, dict_t *rsp_dict,
+ dict_t *req_dict);
+int
+glusterd_op_perform_replace_brick (glusterd_volinfo_t *volinfo,
+ char *old_brick, char *new_brick,
+ dict_t *dict);
+int32_t
+glusterd_brick_unlink_socket_file (glusterd_volinfo_t *volinfo,
+ glusterd_brickinfo_t *brickinfo);
+char *
+gd_rb_op_to_str (char *op);
+
+glusterd_op_t
+gd_cli_to_gd_op (char *cli_op);
+
+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);
+
+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);
#endif
diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
index fe5d4c8e348..b38b0e6960e 100644
--- a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
+++ b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
@@ -1253,7 +1253,7 @@ glusterd_op_stage_create_volume (dict_t *dict, char **op_errstr,
goto out;
ret = glusterd_new_brick_validate (brick, brick_info, msg,
- sizeof (msg));
+ sizeof (msg), NULL);
if (ret)
goto out;
diff --git a/xlators/mgmt/glusterd/src/glusterd.c b/xlators/mgmt/glusterd/src/glusterd.c
index 7d108276cb4..705ce721ea8 100644
--- a/xlators/mgmt/glusterd/src/glusterd.c
+++ b/xlators/mgmt/glusterd/src/glusterd.c
@@ -123,6 +123,7 @@ const char *gd_op_list[GD_OP_MAX + 1] = {
[GD_OP_SYS_EXEC] = "Execute system commands",
[GD_OP_GSYNC_CREATE] = "Geo-replication Create",
[GD_OP_SNAP] = "Snapshot",
+ [GD_OP_RESET_BRICK] = "Reset Brick",
[GD_OP_MAX] = "Invalid op"
};
diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h
index 430798f5fbd..eb03d05b6d9 100644
--- a/xlators/mgmt/glusterd/src/glusterd.h
+++ b/xlators/mgmt/glusterd/src/glusterd.h
@@ -119,6 +119,7 @@ typedef enum glusterd_op_ {
GD_OP_TIER_MIGRATE,
GD_OP_SCRUB_STATUS,
GD_OP_SCRUB_ONDEMAND,
+ GD_OP_RESET_BRICK,
GD_OP_MAX,
} glusterd_op_t;
@@ -950,6 +951,9 @@ int
glusterd_handle_fsm_log (rpcsvc_request_t *req);
int
+glusterd_handle_reset_brick (rpcsvc_request_t *req);
+
+int
glusterd_xfer_cli_deprobe_resp (rpcsvc_request_t *req, int32_t op_ret,
int32_t op_errno, char *op_errstr,
char *hostname, dict_t *dict);
@@ -1192,4 +1196,6 @@ int
glusterd_remove_brick_migrate_cbk (glusterd_volinfo_t *volinfo,
gf_defrag_status_t status);
+int
+__glusterd_handle_reset_brick (rpcsvc_request_t *req);
#endif