diff options
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-geo-rep.c | 152 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-op-sm.h | 5 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-volume-ops.c | 20 | 
3 files changed, 176 insertions, 1 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-geo-rep.c b/xlators/mgmt/glusterd/src/glusterd-geo-rep.c index c5c76e11a21..849480a28d2 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, diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.h b/xlators/mgmt/glusterd/src/glusterd-op-sm.h index 62f991933c8..1125368cef9 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.h +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.h @@ -165,6 +165,11 @@ typedef struct glusterd_gsync_status_temp {          char *node;  }glusterd_gsync_status_temp_t; +typedef struct gsync_status_param { +        int is_active; +        glusterd_volinfo_t *volinfo; +}gsync_status_param_t; +  typedef enum cli_cmd_type_ {          PER_REPLICA,          ALL_REPLICA, diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c index df2562ba69f..db9f39c7c05 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c @@ -30,6 +30,8 @@  #define glusterd_op_start_volume_args_get(dict, volname, flags) \          glusterd_op_stop_volume_args_get (dict, volname, flags) +extern int +_get_slave_status (dict_t *this, char *key, data_t *value, void *data);  int  __glusterd_handle_create_volume (rpcsvc_request_t *req) @@ -1059,6 +1061,7 @@ glusterd_op_stage_stop_volume (dict_t *dict, char **op_errstr)          glusterd_volinfo_t                      *volinfo = NULL;          char                                    msg[2048] = {0};          xlator_t                                *this = NULL; +        gsync_status_param_t                    param = {0,};          this = THIS;          GF_ASSERT (this); @@ -1102,7 +1105,22 @@ glusterd_op_stage_stop_volume (dict_t *dict, char **op_errstr)          if (ret && (is_run == _gf_false))                  gf_log (this->name, GF_LOG_WARNING, "Unable to get the status"                          " of active "GEOREP" session"); -        if (is_run) { + +        param.volinfo = volinfo; +        ret = dict_foreach (volinfo->gsync_slaves, _get_slave_status, ¶m); + +        if (ret) { +                gf_log (this->name, GF_LOG_WARNING, "_get_slave_satus failed"); +                snprintf (msg, sizeof(msg), GEOREP" Unable to get the status " +                          "of active "GEOREP" session for the volume '%s'.\n" +                          "Please check the log file for more info. Use " +                          "'force' option to ignore and stop the volume.", +                          volname); +                ret = -1; +                goto out; +        } + +        if (is_run && param.is_active) {                  gf_log (this->name, GF_LOG_WARNING, GEOREP" sessions active"                          "for the volume %s ", volname);                  snprintf (msg, sizeof(msg), GEOREP" sessions are active "  | 
