diff options
author | Saravanakumar Arumugam <sarumuga@redhat.com> | 2016-05-19 21:13:04 +0530 |
---|---|---|
committer | Aravinda VK <avishwan@redhat.com> | 2016-06-13 03:36:56 -0700 |
commit | 4e553071de6455d36ea49cb1d41ff9e57ca43bc8 (patch) | |
tree | f82c437591d52d206a7b966ab37d8aa23f04ec5d /xlators | |
parent | 1cd0e86cea9a6d3e52340cfa33622bfb4b9ce4d6 (diff) |
glusterd/geo-rep: upgrade path when slave vol uuid involved
slave volume uuid is involved in identifying a geo-replication
session.
This patch addresses upgrade path, where existing geo-rep session
is gracefully upgraded to involve slave volume uuid.
Change-Id: Ib7ff5109b161592f24fc86fc7e93a407655fab86
BUG: 1342452
Reviewed-on: http://review.gluster.org/#/c/14425/
Signed-off-by: Saravanakumar Arumugam <sarumuga@redhat.com>
Reviewed-on: http://review.gluster.org/14640
Smoke: Gluster Build System <jenkins@build.gluster.com>
NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
CentOS-regression: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Aravinda VK <avishwan@redhat.com>
Diffstat (limited to 'xlators')
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-geo-rep.c | 198 |
1 files changed, 188 insertions, 10 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-geo-rep.c b/xlators/mgmt/glusterd/src/glusterd-geo-rep.c index 54ae10aafa6..47ef39cbaf0 100644 --- a/xlators/mgmt/glusterd/src/glusterd-geo-rep.c +++ b/xlators/mgmt/glusterd/src/glusterd-geo-rep.c @@ -420,13 +420,13 @@ parse_slave_url (char *slv_url, char **slave) } tmp += 2; tmp = strchr (tmp, ':'); - if (!tmp) { - goto out; - } else + if (!tmp) + gf_msg_debug (this->name, 0, "old slave: %s!", *slave); + else *tmp = '\0'; ret = 0; - gf_msg_debug (this->name, 0, "parse slave: %s !!", *slave); + gf_msg_debug (this->name, 0, "parsed slave: %s!", *slave); out: return ret; } @@ -583,8 +583,8 @@ struct dictidxmark { struct slave_vol_config { char old_slvhost[_POSIX_HOST_NAME_MAX+1]; - char slave_voluuid[GF_UUID_BUF_SIZE]; unsigned old_slvidx; + char slave_voluuid[GF_UUID_BUF_SIZE]; }; static int @@ -1480,6 +1480,151 @@ glusterd_gsync_get_uuid (char *slave, glusterd_volinfo_t *vol, return ret; } +static int +update_slave_voluuid (dict_t *dict, char *key, data_t *value, void *data) +{ + char *slave = NULL; + char *slave_url = NULL; + char *slave_vol = NULL; + char *slave_host = NULL; + char *errmsg = NULL; + xlator_t *this = NULL; + int ret = -1; + char slv_url[VOLINFO_SLAVE_URL_MAX] = {0}; + char slave_voluuid[GF_UUID_BUF_SIZE] = {0}; + char *slave_info = NULL; + char *new_value = NULL; + char *same_key = NULL; + int cnt = 0; + gf_boolean_t *voluuid_updated = NULL; + + this = THIS; + + voluuid_updated = data; + slave_info = value->data; + gf_msg_debug (this->name, 0, "slave_info: %s!", slave_info); + + /* old slave format: + * master_node_uuid:ssh://slave_host::slave_vol + * New slave format: + * master_node_uuid:ssh://slave_host::slave_vol:slave_voluuid */ + while (slave_info) { + slave_info = strchr (slave_info, ':'); + if (slave_info) + cnt++; + else + break; + + slave_info++; + } + + gf_msg_debug (this->name, 0, "cnt: %d", cnt); + /* check whether old slave format and update vol uuid if old format. + * With volume uuid, number of ':' is 5 and is 4 without. + */ + if (cnt == 4) { + strncpy (slv_url, value->data, sizeof(slv_url)); + + ret = parse_slave_url (slv_url, &slave); + if (ret == -1) { + gf_msg (this->name, GF_LOG_ERROR, 0, + GD_MSG_SLAVE_VOL_PARSE_FAIL, + "Error in parsing slave: %s!", value->data); + goto out; + } + + ret = glusterd_get_slave_info (slave, &slave_url, + &slave_host, &slave_vol, &errmsg); + if (ret) { + if (errmsg) + gf_msg (this->name, GF_LOG_ERROR, 0, + GD_MSG_SLAVEINFO_FETCH_ERROR, + "Unable to fetch slave details. Error: %s", + errmsg); + else + gf_msg (this->name, GF_LOG_ERROR, 0, + GD_MSG_SLAVEINFO_FETCH_ERROR, + "Unable to fetch slave details."); + ret = -1; + goto out; + } + + ret = glusterd_get_slave_voluuid (slave_host, slave_vol, + slave_voluuid); + if ((ret) || (strlen(slave_voluuid) == 0)) { + gf_msg (this->name, GF_LOG_ERROR, 0, + GD_MSG_REMOTE_VOL_UUID_FAIL, + "Unable to get remote volume uuid" + "slavehost:%s slavevol:%s", + slave_host, slave_vol); + /* Avoiding failure due to remote vol uuid fetch */ + ret = 0; + goto out; + } + ret = gf_asprintf (&new_value, "%s:%s", + value->data, slave_voluuid); + ret = gf_asprintf (&same_key, "%s", key); + + /* delete old key and add new value */ + dict_del (dict, key); + + /* set new value for the same key*/ + ret = dict_set_dynstr (dict, same_key, new_value); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, 0, + GD_MSG_REMOTE_VOL_UUID_FAIL, + "Error in setting dict value" + "new_value :%s", new_value); + goto out; + } + *voluuid_updated = _gf_true; + } + + ret = 0; +out: + if (errmsg) + GF_FREE (errmsg); + + gf_msg_debug (this->name, 0, "Returning %d.", ret); + return ret; +} + +static int +glusterd_update_slave_voluuid_slaveinfo (glusterd_volinfo_t *volinfo) +{ + int ret = -1; + xlator_t *this = NULL; + gf_boolean_t voluuid_updated = _gf_false; + + this = THIS; + GF_VALIDATE_OR_GOTO ("glusterd", this, out); + GF_VALIDATE_OR_GOTO (this->name, volinfo, out); + + ret = dict_foreach (volinfo->gsync_slaves, update_slave_voluuid, + &voluuid_updated); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, 0, + GD_MSG_REMOTE_VOL_UUID_FAIL, "Error in updating" + "volinfo"); + goto out; + } + + if (_gf_true == voluuid_updated) { + ret = glusterd_store_volinfo (volinfo, + GLUSTERD_VOLINFO_VER_AC_INCREMENT); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, 0, + GD_MSG_VOLINFO_STORE_FAIL, "Error in storing" + "volinfo"); + goto out; + } + } + +out: + gf_msg_debug (this->name, 0, "Returning %d", ret); + return ret; +} + int glusterd_check_gsync_running_local (char *master, char *slave, char *conf_path, @@ -1650,6 +1795,8 @@ glusterd_op_verify_gsync_start_options (glusterd_volinfo_t *volinfo, glusterd_conf_t *priv = NULL; xlator_t *this = NULL; struct stat stbuf = {0,}; + char statefiledir[PATH_MAX] = {0,}; + char *statedir = NULL; this = THIS; GF_ASSERT (this); @@ -1668,13 +1815,18 @@ glusterd_op_verify_gsync_start_options (glusterd_volinfo_t *volinfo, goto out; } - ret = sys_lstat (statefile, &stbuf); + /* check session directory as statefile may not present + * during upgrade */ + strncpy (statefiledir, statefile, sizeof(statefiledir)); + statedir = dirname (statefiledir); + + ret = sys_lstat (statedir, &stbuf); if (ret) { snprintf (msg, sizeof (msg), "Session between %s and %s has" " not been created. Please create session and retry.", volinfo->volname, slave); gf_msg (this->name, GF_LOG_ERROR, errno, GD_MSG_FILE_OP_FAILED, - "%s", msg); + "%s statefile: %s", msg, statefile); *op_errstr = gf_strdup (msg); goto out; } @@ -2704,6 +2856,8 @@ get_slavehost_from_voluuid (dict_t *dict, char *key, data_t *value, void *data) slave_info = strchr (slave_info, ':'); if (slave_info) slave_info++; + else + break; } if (!(slave_info) || strlen(slave_info) == 0) { @@ -2808,6 +2962,9 @@ glusterd_op_stage_gsync_create (dict_t *dict, char **op_errstr) char old_confpath[PATH_MAX] = {0}; gf_boolean_t is_running = _gf_false; int ret_status = 0; + char *statedir = NULL; + char statefiledir[PATH_MAX] = {0,}; + this = THIS; GF_ASSERT (this); conf = this->private; @@ -3013,7 +3170,10 @@ glusterd_op_stage_gsync_create (dict_t *dict, char **op_errstr) goto out; } - ret = sys_lstat (statefile, &stbuf); + strncpy (statefiledir, statefile, sizeof(statefiledir)); + statedir = dirname (statefiledir); + + ret = sys_lstat (statedir, &stbuf); if (!ret && !is_force) { snprintf (errmsg, sizeof (errmsg), "Session between %s" " and %s is already created.", @@ -3199,6 +3359,8 @@ glusterd_op_stage_gsync_set (dict_t *dict, char **op_errstr) char *slave_vol = NULL; char *down_peerstr = NULL; char *statefile = NULL; + char statefiledir[PATH_MAX] = {0,}; + char *statedir = NULL; char *path_list = NULL; char *conf_path = NULL; gf_boolean_t exists = _gf_false; @@ -3309,7 +3471,13 @@ glusterd_op_stage_gsync_set (dict_t *dict, char **op_errstr) * as this command acts as a fail safe method to stop geo-rep * session. */ if (!((type == GF_GSYNC_OPTION_TYPE_STOP) && is_force)) { - ret = sys_lstat (statefile, &stbuf); + + /* check session directory as statefile may not present + * during upgrade */ + strncpy (statefiledir, statefile, sizeof(statefiledir)); + statedir = dirname (statefiledir); + + ret = sys_lstat (statedir, &stbuf); if (ret) { snprintf (errmsg, sizeof(errmsg), "Geo-replication" " session between %s and %s does not exist.", @@ -4032,7 +4200,7 @@ glusterd_gsync_read_frm_status (char *path, char *buf, size_t blen) status_fd = open (path, O_RDONLY); if (status_fd == -1) { gf_msg (this->name, GF_LOG_ERROR, 0, GD_MSG_FILE_OP_FAILED, - "Unable to read gsyncd status file"); + "Unable to read gsyncd status file %s", path); return -1; } ret = sys_read (status_fd, buf, blen - 1); @@ -5347,6 +5515,16 @@ glusterd_op_gsync_set (dict_t *dict, char **op_errstr, dict_t *rsp_dict) goto out; } + /* If slave volume uuid is not present in gsync_slaves + * update it */ + ret = glusterd_update_slave_voluuid_slaveinfo (volinfo); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, 0, + GD_MSG_REMOTE_VOL_UUID_FAIL, "Error in updating" + " slave volume uuid for old slave info"); + goto out; + } + ret = glusterd_start_gsync (volinfo, slave, path_list, conf_path, host_uuid, op_errstr, _gf_false); |