From 2f499e85a4ae0ac1e84785daa60a5bbfe979cc7f Mon Sep 17 00:00:00 2001 From: Kotresh H R Date: Wed, 8 Jan 2014 10:52:28 +0530 Subject: glusterd/geo-rep : Allow volume to stop if geo-rep is not active. In staging phase of volume stop, code is added to read the state_file for each slave of the master to which the volume belongs. If any of the geo-rep session is active with at least one slave, volume is not allowed to stop else it is allowed. Change-Id: I4a01a357fc86b872e9635b3d19998cdbd9545114 BUG: 1049727 Signed-off-by: Kotresh H R Reviewed-on: http://review.gluster.org/6663 Tested-by: Gluster Build System Reviewed-by: Vijay Bellur --- xlators/mgmt/glusterd/src/glusterd-geo-rep.c | 152 +++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) (limited to 'xlators/mgmt/glusterd/src/glusterd-geo-rep.c') diff --git a/xlators/mgmt/glusterd/src/glusterd-geo-rep.c b/xlators/mgmt/glusterd/src/glusterd-geo-rep.c index c5c76e11a..849480a28 100644 --- a/xlators/mgmt/glusterd/src/glusterd-geo-rep.c +++ b/xlators/mgmt/glusterd/src/glusterd-geo-rep.c @@ -1295,6 +1295,158 @@ glusterd_check_gsync_running (glusterd_volinfo_t *volinfo, gf_boolean_t *flag) return 0; } +/* + * is_geo_rep_active: + * This function reads the state_file and sets is_active to 1 if the + * monitor status is neither "Stopped" or "Not Started" + * + * RETURN VALUE: + * 0: On successful read of state_file. + * -1: error. + */ + +static int +is_geo_rep_active (glusterd_volinfo_t *volinfo, char *slave, + char *conf_path, int *is_active) +{ + dict_t *confd = NULL; + char *statefile = NULL; + char *master = NULL; + char monitor_status[PATH_MAX] = ""; + int ret = -1; + xlator_t *this = NULL; + + this = THIS; + GF_ASSERT (this); + + master = volinfo->volname; + + confd = dict_new (); + if (!confd) { + gf_log ("", GF_LOG_ERROR, "Not able to create dict."); + goto out; + } + + ret = glusterd_gsync_get_config (master, slave, conf_path, + confd); + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to get configuration data " + "for %s(master), %s(slave)", master, slave); + ret = -1; + goto out; + } + + ret = dict_get_param (confd, "state_file", &statefile); + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to get state_file's name " + "for %s(master), %s(slave). Please check gsync " + "config file.", master, slave); + ret = -1; + goto out; + } + + ret = glusterd_gsync_read_frm_status (statefile, monitor_status, + sizeof (monitor_status)); + if (ret <= 0) { + gf_log ("", GF_LOG_ERROR, "Unable to read the status " + "file for %s(master), %s(slave)", master, slave); + strncpy (monitor_status, "defunct", sizeof (monitor_status)); + } + + if ((!strcmp(monitor_status, "Stopped")) || + (!strcmp(monitor_status, "Not Started"))) { + *is_active = 0; + } else { + *is_active = 1; + } + ret = 0; +out: + if (confd) + dict_destroy (confd); + return ret; +} + +/* + * _get_slave_status: + * Called for each slave in the volume from dict_foreach. + * It calls is_geo_rep_active to get the monitor status. + * + * RETURN VALUE: + * 0: On successful read of state_file from is_geo_rep_active. + * When it is found geo-rep is already active from previous calls. + * When there is no slave. + * -1: On error. + */ + +int +_get_slave_status (dict_t *dict, char *key, data_t *value, void *data) +{ + gsync_status_param_t *param = NULL; + char *slave = NULL; + char *slave_ip = NULL; + char *slave_vol = NULL; + char *errmsg = NULL; + char conf_path[PATH_MAX] = ""; + int ret = -1; + glusterd_conf_t *priv = NULL; + xlator_t *this = NULL; + + param = (gsync_status_param_t *)data; + + GF_ASSERT (param); + GF_ASSERT (param->volinfo); + + if (param->is_active) { + ret = 0; + goto out; + } + + this = THIS; + GF_ASSERT (this); + + if (this) + priv = this->private; + if (priv == NULL) { + gf_log ("", GF_LOG_ERROR, "priv of glusterd not present"); + goto out; + } + + slave = strchr(value->data, ':'); + if (!slave) { + ret = 0; + goto out; + } + slave++; + + ret = glusterd_get_slave_info (slave, &slave_ip, &slave_vol, &errmsg); + if (ret) { + if (errmsg) + gf_log ("", GF_LOG_ERROR, "Unable to fetch " + "slave details. Error: %s", errmsg); + else + gf_log ("", GF_LOG_ERROR, + "Unable to fetch slave details."); + ret = -1; + goto out; + } + + ret = snprintf (conf_path, sizeof(conf_path) - 1, + "%s/"GEOREP"/%s_%s_%s/gsyncd.conf", + priv->workdir, param->volinfo->volname, + slave_ip, slave_vol); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "Unable to assign conf_path."); + ret = -1; + goto out; + } + conf_path[ret] = '\0'; + + ret = is_geo_rep_active (param->volinfo,slave, conf_path, + ¶m->is_active); +out: + return ret; +} + static int glusterd_op_verify_gsync_running (glusterd_volinfo_t *volinfo, char *slave, char *conf_path, -- cgit