diff options
| author | Saravanakumar Arumugam <sarumuga@redhat.com> | 2016-05-19 21:13:04 +0530 | 
|---|---|---|
| committer | Aravinda VK <avishwan@redhat.com> | 2016-06-03 19:41:15 -0700 | 
| commit | 124425aef8118116d0bd1daa8269ab2c348b2cb9 (patch) | |
| tree | 219e43b00022e7e0d261d48828448123bec97aa9 | |
| parent | b347cf85300193ab83dcfaca63c39a4907fbf730 (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: 1337473
Signed-off-by: Saravanakumar Arumugam <sarumuga@redhat.com>
Signed-off-by: Kotresh HR <khiremat@redhat.com>
Reviewed-on: http://review.gluster.org/14425
NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
CentOS-regression: Gluster Build System <jenkins@build.gluster.com>
Smoke: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Aravinda VK <avishwan@redhat.com>
| -rw-r--r-- | geo-replication/syncdaemon/gsyncdstatus.py | 3 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-geo-rep.c | 199 | 
2 files changed, 192 insertions, 10 deletions
diff --git a/geo-replication/syncdaemon/gsyncdstatus.py b/geo-replication/syncdaemon/gsyncdstatus.py index 77f3f9e7569..88398e2ce8a 100644 --- a/geo-replication/syncdaemon/gsyncdstatus.py +++ b/geo-replication/syncdaemon/gsyncdstatus.py @@ -272,6 +272,9 @@ class GeorepStatus(object):          if monitor_status in ["Created", "Paused", "Stopped"]:              data["worker_status"] = monitor_status +        if monitor_status == "": +            data["worker_status"] = "Stopped" +          # Checkpoint adjustments          if checkpoint_time == 0:              data["checkpoint_completed"] = DEFAULT_STATUS diff --git a/xlators/mgmt/glusterd/src/glusterd-geo-rep.c b/xlators/mgmt/glusterd/src/glusterd-geo-rep.c index 54ae10aafa6..341e2f91b8d 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,152 @@ 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; +                } +        } + +        ret = 0; +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 +1796,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 +1816,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 +2857,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 +2963,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 +3171,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 +3360,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 +3472,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 +4201,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 +5516,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);  | 
