From 7382534ac11deda2317d31f5545409824e785380 Mon Sep 17 00:00:00 2001 From: Krishnan Parthasarathi Date: Tue, 26 Jul 2011 19:24:10 +0530 Subject: glusterd: handle replace-brick in paused state. This change ensures that glusterd retains 'state' information of an ongoing replace brick operation even if it went down midway. Change-Id: I01d5f86c22c91a3e8801614ea172956719061a05 BUG: 3252 Reviewed-on: http://review.gluster.com/110 Tested-by: Gluster Build System Reviewed-by: Vijay Bellur --- xlators/mgmt/glusterd/src/glusterd-op-sm.c | 35 +++++++--- xlators/mgmt/glusterd/src/glusterd-store.c | 102 ++++++++++++++++++++++------- xlators/mgmt/glusterd/src/glusterd-store.h | 3 + 3 files changed, 109 insertions(+), 31 deletions(-) diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c index 6ef1723bd72..7de8f6af6f8 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c @@ -3207,7 +3207,6 @@ glusterd_op_replace_brick (dict_t *dict, dict_t *rsp_dict) goto out; } - volinfo->version++; volinfo->defrag_status = 0; ret = glusterd_check_generate_start_nfs (volinfo); @@ -3216,14 +3215,6 @@ glusterd_op_replace_brick (dict_t *dict, dict_t *rsp_dict) "Failed to generate nfs volume file"); } - ret = glusterd_store_update_volume (volinfo); - - if (ret) - goto out; - - ret = glusterd_volume_compute_cksum (volinfo); - if (ret) - goto out; ret = glusterd_fetchspec_notify (THIS); glusterd_set_rb_status (volinfo, GF_RB_STATUS_NONE); @@ -3291,6 +3282,16 @@ glusterd_op_replace_brick (dict_t *dict, dict_t *rsp_dict) "received status - doing nothing"); ctx = glusterd_op_get_ctx (GD_OP_REPLACE_BRICK); if (ctx) { + if (glusterd_is_rb_paused (volinfo)) { + ret = dict_set_str (ctx, "status-reply", + "replace brick has been paused"); + if (ret) + gf_log (THIS->name, GF_LOG_ERROR, + "failed to set pump status" + "in ctx"); + goto out; + } + ret = rb_do_operation_status (volinfo, src_brickinfo, dst_brickinfo); if (ret) @@ -3308,6 +3309,22 @@ glusterd_op_replace_brick (dict_t *dict, dict_t *rsp_dict) if (ret) goto out; + if (!ret && replace_op != GF_REPLACE_OP_STATUS) { + volinfo->version++; + ret = glusterd_store_update_volume (volinfo); + if (ret) { + gf_log (THIS->name, GF_LOG_DEBUG, "Couldn't store" + " replace-brick operation's state."); + goto out; + } + + ret = glusterd_volume_compute_cksum (volinfo); + if (ret) { + gf_log (THIS->name, GF_LOG_DEBUG, "Computing " + " for volume store failed."); + goto out; + } + } out: return ret; } diff --git a/xlators/mgmt/glusterd/src/glusterd-store.c b/xlators/mgmt/glusterd/src/glusterd-store.c index 153329f9e1e..8b37c878eb0 100644 --- a/xlators/mgmt/glusterd/src/glusterd-store.c +++ b/xlators/mgmt/glusterd/src/glusterd-store.c @@ -1133,16 +1133,18 @@ out: int32_t glusterd_store_retrieve_volume (char *volname) { - int32_t ret = -1; - glusterd_volinfo_t *volinfo = NULL; - glusterd_store_iter_t *iter = NULL; - char *key = NULL; - char *value = NULL; - char volpath[PATH_MAX] = {0,}; - glusterd_conf_t *priv = NULL; - char path[PATH_MAX] = {0,}; - int exists = 0; - glusterd_store_op_errno_t op_errno = GD_STORE_SUCCESS; + int32_t ret = -1; + glusterd_volinfo_t *volinfo = NULL; + glusterd_store_iter_t *iter = NULL; + char *key = NULL; + char *value = NULL; + char volpath[PATH_MAX] = {0,}; + glusterd_conf_t *priv = NULL; + char path[PATH_MAX] = {0,}; + char dst_brick[PATH_MAX] = {0, }; + int exists = 0; + int dst_port = -1; + glusterd_store_op_errno_t op_errno = GD_STORE_SUCCESS; ret = glusterd_volinfo_new (&volinfo); @@ -1176,33 +1178,66 @@ glusterd_store_retrieve_volume (char *volname) strlen (GLUSTERD_STORE_KEY_VOL_TYPE))) { volinfo->type = atoi (value); } else if (!strncmp (key, GLUSTERD_STORE_KEY_VOL_COUNT, - strlen (GLUSTERD_STORE_KEY_VOL_COUNT))) { + strlen (GLUSTERD_STORE_KEY_VOL_COUNT))) { volinfo->brick_count = atoi (value); } else if (!strncmp (key, GLUSTERD_STORE_KEY_VOL_STATUS, - strlen (GLUSTERD_STORE_KEY_VOL_STATUS))) { + strlen (GLUSTERD_STORE_KEY_VOL_STATUS))) { volinfo->status = atoi (value); } else if (!strncmp (key, GLUSTERD_STORE_KEY_VOL_VERSION, - strlen (GLUSTERD_STORE_KEY_VOL_VERSION))) { + strlen (GLUSTERD_STORE_KEY_VOL_VERSION))) { volinfo->version = atoi (value); } else if (!strncmp (key, GLUSTERD_STORE_KEY_VOL_PORT, - strlen (GLUSTERD_STORE_KEY_VOL_PORT))) { + strlen (GLUSTERD_STORE_KEY_VOL_PORT))) { volinfo->port = atoi (value); } else if (!strncmp (key, GLUSTERD_STORE_KEY_VOL_SUB_COUNT, - strlen (GLUSTERD_STORE_KEY_VOL_SUB_COUNT))) { + strlen (GLUSTERD_STORE_KEY_VOL_SUB_COUNT))) { volinfo->sub_count = atoi (value); } else if (!strncmp (key, GLUSTERD_STORE_KEY_VOL_TRANSPORT, - strlen (GLUSTERD_STORE_KEY_VOL_TRANSPORT))) { + strlen (GLUSTERD_STORE_KEY_VOL_TRANSPORT))) { volinfo->transport_type = atoi (value); volinfo->nfs_transport_type = volinfo->transport_type; if (volinfo->transport_type == GF_TRANSPORT_BOTH_TCP_RDMA) { volinfo->nfs_transport_type = GF_DEFAULT_NFS_TRANSPORT; } } else if (!strncmp (key, GLUSTERD_STORE_KEY_VOL_ID, - strlen (GLUSTERD_STORE_KEY_VOL_ID))) { + strlen (GLUSTERD_STORE_KEY_VOL_ID))) { ret = uuid_parse (value, volinfo->volume_id); if (ret) gf_log ("", GF_LOG_WARNING, "failed to parse uuid"); + } else if (!strncmp (key, GLUSTERD_STORE_KEY_RB_STATUS, + strlen (GLUSTERD_STORE_KEY_RB_STATUS))) { + glusterd_set_rb_status (volinfo, atoi (value)); + + } else if (volinfo->rb_status > GF_RB_STATUS_NONE && + !strncmp (key, GLUSTERD_STORE_KEY_RB_SRC_BRICK, + strlen (GLUSTERD_STORE_KEY_RB_SRC_BRICK))) { + ret = glusterd_brickinfo_from_brick (value, + &volinfo->src_brick); + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to create" + " src brickinfo"); + goto out; + } + + } else if (volinfo->rb_status > GF_RB_STATUS_NONE && + !strncmp (key, GLUSTERD_STORE_KEY_RB_DST_BRICK, + strlen (GLUSTERD_STORE_KEY_RB_DST_BRICK))) { + sscanf (value, "%d:%s", &dst_port, dst_brick); + if (dst_port == -1 || dst_brick[0] == 0) { + gf_log ("", GF_LOG_ERROR, "replace brick: " + "dst brick info is invalid"); + goto out; + } + ret = glusterd_brickinfo_from_brick (dst_brick, + &volinfo->dst_brick); + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to create" + " dst brickinfo"); + goto out; + } + volinfo->dst_brick->port = dst_port; + } else { exists = glusterd_check_option_exists (key, NULL); if (exists == -1) { @@ -1307,11 +1342,11 @@ out: int32_t glusterd_store_update_volume (glusterd_volinfo_t *volinfo) { - int32_t ret = -1; - char buf[1024] = {0,}; - glusterd_brickinfo_t *brickinfo = NULL; - glusterd_brickinfo_t *tmp = NULL; - int32_t brick_count = 0; + int32_t ret = -1; + char buf[PATH_MAX+20] = {0,}; + glusterd_brickinfo_t *brickinfo = NULL; + glusterd_brickinfo_t *tmp = NULL; + int32_t brick_count = 0; list_for_each_entry (tmp, &volinfo->bricks, brick_list) { @@ -1364,6 +1399,29 @@ glusterd_store_update_volume (glusterd_volinfo_t *volinfo) if (ret) goto out; + snprintf (buf, sizeof (buf), "%d", volinfo->rb_status); + ret = glusterd_store_save_value (volinfo->shandle, GLUSTERD_STORE_KEY_RB_STATUS, + buf); + if (ret) + goto out; + + if (volinfo->rb_status > GF_RB_STATUS_NONE) { + snprintf (buf, sizeof (buf), "%s:%s", volinfo->src_brick->hostname, + volinfo->src_brick->path); + ret = glusterd_store_save_value (volinfo->shandle, GLUSTERD_STORE_KEY_RB_SRC_BRICK, + buf); + if (ret) + goto out; + + snprintf (buf, sizeof (buf), "%d:%s:%s", volinfo->dst_brick->port, + volinfo->dst_brick->hostname, volinfo->dst_brick->path); + ret = glusterd_store_save_value (volinfo->shandle, GLUSTERD_STORE_KEY_RB_DST_BRICK, + buf); + if (ret) + goto out; + } + + list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { ret = glusterd_store_create_brick (volinfo, brickinfo, brick_count); diff --git a/xlators/mgmt/glusterd/src/glusterd-store.h b/xlators/mgmt/glusterd/src/glusterd-store.h index b2e7bcc5ea0..3f64e6a6319 100644 --- a/xlators/mgmt/glusterd/src/glusterd-store.h +++ b/xlators/mgmt/glusterd/src/glusterd-store.h @@ -49,6 +49,9 @@ #define GLUSTERD_STORE_KEY_VOL_VERSION "version" #define GLUSTERD_STORE_KEY_VOL_TRANSPORT "transport-type" #define GLUSTERD_STORE_KEY_VOL_ID "volume-id" +#define GLUSTERD_STORE_KEY_RB_STATUS "rb_status" +#define GLUSTERD_STORE_KEY_RB_SRC_BRICK "rb_src" +#define GLUSTERD_STORE_KEY_RB_DST_BRICK "rb_dst" #define GLUSTERD_STORE_KEY_BRICK_HOSTNAME "hostname" #define GLUSTERD_STORE_KEY_BRICK_PATH "path" -- cgit