summaryrefslogtreecommitdiffstats
path: root/xlators/mgmt/glusterd/src/glusterd-replace-brick.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/mgmt/glusterd/src/glusterd-replace-brick.c')
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-replace-brick.c349
1 files changed, 88 insertions, 261 deletions
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,