diff options
| author | Kaushik BV <kaushikbv@gluster.com> | 2011-04-13 22:14:37 +0000 | 
|---|---|---|
| committer | Anand Avati <avati@gluster.com> | 2011-04-14 01:00:55 -0700 | 
| commit | 93cb168fb362c7aea3c10371574a5c5566bb0222 (patch) | |
| tree | 44f7fd323980d3c073498c81be34ddc6f739b0ef | |
| parent | 77cd50a12887b13db4c49be6a979a5ecb8239570 (diff) | |
mgmt/glusterd: Implementation of volume gsync status [master [slave]]
Changes made in the path of gsync start/stop as well, where we
maintain a list of  active gsync sessions, hence gsync stop could be
executed at all nodes.
A new dict in glusterd_volinfo_t added to maintain an active list
of gsync slaves running on each master.
Signed-off-by: Kaushik BV <kaushikbv@gluster.com>
Signed-off-by: Anand Avati <avati@gluster.com>
BUG: 2536 (gsync service introspection)
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=2536
| -rw-r--r-- | cli/src/cli-cmd-parser.c | 49 | ||||
| -rw-r--r-- | cli/src/cli-rpc-ops.c | 77 | ||||
| -rw-r--r-- | rpc/xdr/src/cli1-xdr.c | 3 | ||||
| -rw-r--r-- | rpc/xdr/src/cli1-xdr.h | 9 | ||||
| -rw-r--r-- | rpc/xdr/src/cli1-xdr.x | 1 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-handler.c | 30 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-op-sm.c | 1074 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-op-sm.h | 15 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-rpc-ops.c | 115 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-store.c | 49 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.c | 8 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd.h | 2 | 
12 files changed, 1267 insertions, 165 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index 1cfba3561fc..e8b0e778ae6 100644 --- a/cli/src/cli-cmd-parser.c +++ b/cli/src/cli-cmd-parser.c @@ -1120,13 +1120,14 @@ out:  int32_t  cli_cmd_gsync_set_parse (const char **words, int wordcount, dict_t **options)  { -        int32_t            ret     = 0; +        int32_t            ret     = -1;          int32_t            config_type = 0;          dict_t             *dict   = NULL;          gf1_cli_gsync_set  type    = GF_GSYNC_OPTION_TYPE_NONE;          char               *append_str = NULL;          size_t             append_len = 0;          int                i = 0; +        int32_t            status_type = 0;          GF_ASSERT (words);          GF_ASSERT (options); @@ -1138,6 +1139,43 @@ cli_cmd_gsync_set_parse (const char **words, int wordcount, dict_t **options)          if (!dict)                  goto out; +        if (wordcount < 3) +                goto out; + +        if ((strcmp (words[2], "status")) == 0) { +                type = GF_GSYNC_OPTION_TYPE_STATUS; + +                if (wordcount == 3) +                        status_type = GF_GSYNC_OPTION_TYPE_STATUS_ALL; +                else if (wordcount == 4) +                        status_type = GF_GSYNC_OPTION_TYPE_STATUS_MASTER; +                else if (wordcount == 5) +                        status_type = GF_GSYNC_OPTION_TYPE_STATUS_MST_SLV; +                else +                        goto out; + + +                ret = dict_set_int32 (dict, "status-type", status_type); +                if (ret < 0) +                        goto out; + +                if (wordcount < 4) +                        goto set_type; +                ret = dict_set_str (dict, "master", (char *)words[3]); +                if (ret < 0) +                        goto out; + +                if (wordcount < 5) +                        goto set_type; +                ret = dict_set_str (dict, "slave", (char *)words[4]); +                if (ret < 0) +                        goto out; + + + +                goto set_type; +        } +          if (wordcount < 5)                  goto out; @@ -1150,12 +1188,18 @@ cli_cmd_gsync_set_parse (const char **words, int wordcount, dict_t **options)                  goto out;          if ((strcmp (words[2], "start")) == 0) { +                if (wordcount != 5) +                        goto out; +                  type = GF_GSYNC_OPTION_TYPE_START;                  goto set_type;          }          if ((strcmp (words[2], "stop")) == 0) { +                if (wordcount != 5) +                        goto out; +                  type = GF_GSYNC_OPTION_TYPE_STOP;                  goto set_type; @@ -1219,6 +1263,9 @@ cli_cmd_gsync_set_parse (const char **words, int wordcount, dict_t **options)                  ret = dict_set_int32 (dict, "config_type", config_type);                  if (ret < 0)                          goto out; +        } else { +                ret = -1; +                goto out;          }  set_type: diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c index 9da2d9378f8..a6665d1ed5d 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -2580,6 +2580,7 @@ out:          return ret;  } +  int  gf_cli3_1_gsync_get_command (gf1_cli_gsync_set_rsp rsp)  { @@ -2616,6 +2617,7 @@ gf_cli3_1_gsync_get_command (gf1_cli_gsync_set_rsp rsp)          return 0;  } +  int  gf_cli3_1_gsync_get_param_file (char *prmfile, const char *ext, char *master, char *slave, char *gl_workdir)  { @@ -2673,6 +2675,55 @@ gf_cli3_1_gsync_get_param_file (char *prmfile, const char *ext, char *master, ch          return ret ? -1 : 0;  } +int +gf_cli3_1_gsync_out_status (dict_t *dict) +{ +        int              gsync_count = 0; +        int              i = 0; +        int              ret = 0; +        char             mst[PATH_MAX] = {0, }; +        char             slv[PATH_MAX]= {0, }; +        char             sts[PATH_MAX] = {0, }; +        char             *mst_val = NULL; +        char             *slv_val = NULL; +        char             *sts_val = NULL; + + +        ret = dict_get_int32 (dict, "gsync-count", &gsync_count); +        if (ret) { +                cli_out ("No Gsync sessions for the selected"); +                ret = 0; +                goto out; +        } + +        cli_out ("Gsync Status:"); + +        for (i = 1; i <= gsync_count; i++) { +                snprintf (mst, sizeof(mst), "master%d", i); +                snprintf (slv, sizeof(slv), "slave%d", i); +                snprintf (sts, sizeof(sts), "status%d", i); + +                ret = dict_get_str (dict, mst, &mst_val); +                if (ret) +                        goto out; + +                ret = dict_get_str (dict, slv, &slv_val); +                if (ret) +                        goto out; + +                ret = dict_get_str (dict, sts, &sts_val); +                if (ret) +                        goto out; + +                cli_out ("Master:%-20s   Slave:%-50s  Status:%-10s", mst_val, +                         slv_val, sts_val); + +        } + + out: +        return ret; + +}  /* status: 0 when gsync is running   * -1 when not running @@ -2860,6 +2911,7 @@ gf_cli3_1_gsync_set_cbk (struct rpc_req *req, struct iovec *iov,  {          int                     ret     = 0;          gf1_cli_gsync_set_rsp   rsp     = {0, }; +        dict_t                  *dict   = NULL;          if (req->rpc_status == -1) {                  ret = -1; @@ -2873,6 +2925,20 @@ gf_cli3_1_gsync_set_cbk (struct rpc_req *req, struct iovec *iov,                  goto out;          } +        dict = dict_new (); + +        if (!dict) { +                ret = -1; +                goto out; +        } + +        ret = dict_unserialize (rsp.status_dict.status_dict_val, +                                rsp.status_dict.status_dict_len, +                                &dict); + +        if (ret) +                goto out; +          if (rsp.op_ret) {                  cli_out ("%s", rsp.op_errstr ? rsp.op_errstr :                           "command unsuccessful"); @@ -2882,10 +2948,17 @@ gf_cli3_1_gsync_set_cbk (struct rpc_req *req, struct iovec *iov,                  if (rsp.type == GF_GSYNC_OPTION_TYPE_START)                          ret = gf_cli3_1_start_gsync (rsp.master, rsp.slave,                                                        rsp.glusterd_workdir); -                else if (rsp.config_type == GF_GSYNC_OPTION_TYPE_CONFIG_GET_ALL) +                else if (rsp.config_type == GF_GSYNC_OPTION_TYPE_CONFIG_GET_ALL +                         || rsp.config_type == GF_GSYNC_OPTION_TYPE_CONFIG_GET)                          ret = gf_cli3_1_gsync_get_command (rsp); -                else +                else if (rsp.type == GF_GSYNC_OPTION_TYPE_STATUS) +                        ret = gf_cli3_1_gsync_out_status (dict); +                else if (rsp.type == GF_GSYNC_OPTION_TYPE_STOP) +                        cli_out ("Gsync session stopped successfully"); +                else if (!rsp.op_errstr)                          cli_out ("command executed successfully"); +                else +                        cli_out (rsp.op_errstr);          }  out:          ret = rsp.op_ret; diff --git a/rpc/xdr/src/cli1-xdr.c b/rpc/xdr/src/cli1-xdr.c index fa24ad90bbb..f1594eb9662 100644 --- a/rpc/xdr/src/cli1-xdr.c +++ b/rpc/xdr/src/cli1-xdr.c @@ -761,6 +761,9 @@ xdr_gf1_cli_gsync_set_rsp (XDR *xdrs, gf1_cli_gsync_set_rsp *objp)  		 return FALSE;          if (!xdr_string (xdrs, &objp->glusterd_workdir, ~0))                  return FALSE; +        if (!xdr_bytes (xdrs, (char **)&objp->status_dict.status_dict_val, +                        (u_int *) &objp->status_dict.status_dict_len, ~0)) +                return FALSE;  	return TRUE;  } diff --git a/rpc/xdr/src/cli1-xdr.h b/rpc/xdr/src/cli1-xdr.h index dba58349296..2002a3ae473 100644 --- a/rpc/xdr/src/cli1-xdr.h +++ b/rpc/xdr/src/cli1-xdr.h @@ -92,6 +92,11 @@ enum gf1_cli_gsync_set {  	GF_GSYNC_OPTION_TYPE_CONFIG_DEL = 5,  	GF_GSYNC_OPTION_TYPE_CONFIG_GET = 6,  	GF_GSYNC_OPTION_TYPE_CONFIG_GET_ALL = 7, +        GF_GSYNC_OPTION_TYPE_STATUS = 8, +        GF_GSYNC_OPTION_TYPE_STATUS_ALL = 9, +        GF_GSYNC_OPTION_TYPE_STATUS_MASTER = 10, +        GF_GSYNC_OPTION_TYPE_STATUS_MST_SLV = 11 +  };  typedef enum gf1_cli_gsync_set gf1_cli_gsync_set; @@ -482,6 +487,10 @@ struct gf1_cli_gsync_set_rsp {  	char *slave;  	char *gsync_prefix;          char *glusterd_workdir; +	struct { +		u_int status_dict_len; +		char *status_dict_val; +	} status_dict;  };  typedef struct gf1_cli_gsync_set_rsp gf1_cli_gsync_set_rsp; diff --git a/rpc/xdr/src/cli1-xdr.x b/rpc/xdr/src/cli1-xdr.x index 035927f89e4..fc38cf7b252 100644 --- a/rpc/xdr/src/cli1-xdr.x +++ b/rpc/xdr/src/cli1-xdr.x @@ -347,6 +347,7 @@ struct gf1_cli_gsync_set_rsp {          string  slave<>;          string  gsync_prefix<>;          string  glusterd_workdir<>; +        opaque  status_dict<>;  };  struct gf1_cli_stats_volume_req { diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c index 3ebe5f51f42..247c655b031 100644 --- a/xlators/mgmt/glusterd/src/glusterd-handler.c +++ b/xlators/mgmt/glusterd/src/glusterd-handler.c @@ -1669,8 +1669,14 @@ glusterd_handle_gsync_set (rpcsvc_request_t *req)          char                    *slave = NULL;          char                    operation[256] = {0,};          int                     type = 0; +        glusterd_conf_t         *priv   = NULL; +        char                    *host_uuid = NULL;          GF_ASSERT (req); +        GF_ASSERT (THIS); +        GF_ASSERT (THIS->private); + +        priv = THIS->private;          ret = glusterd_op_set_cli_op (cli_op);          if (ret) { @@ -1701,20 +1707,32 @@ glusterd_handle_gsync_set (rpcsvc_request_t *req)                  } else {                          dict->extra_stdfree = cli_req.dict.dict_val;                  } + +                host_uuid = gf_strdup (uuid_utoa(priv->uuid)); +                if (host_uuid == NULL) { +                        gf_log ("glusterd", GF_LOG_ERROR, "failed to get" +                                "the uuid of the host machine"); +                        ret = -1; +                        goto out; +                } +                ret = dict_set_dynstr (dict, "host-uuid", host_uuid); +                if (ret) +                        goto out; +          }          ret = dict_get_str (dict, "master", &master);          if (ret < 0) { -                gf_log ("", GF_LOG_WARNING, "master not found, while handling" +                gf_log ("", GF_LOG_INFO, "master not found, while handling"                           "gsync options"); -                goto out; +                master = "(No Master)";          }          ret = dict_get_str (dict, "slave", &slave);          if (ret < 0) { -                gf_log ("", GF_LOG_WARNING, "slave not not found, while" +                gf_log ("", GF_LOG_INFO, "slave not not found, while"                          "handling gsync options"); -                goto out; +                slave = "(No Slave)";          }          ret = dict_get_int32 (dict, "type", &type); @@ -1737,6 +1755,10 @@ glusterd_handle_gsync_set (rpcsvc_request_t *req)          case GF_GSYNC_OPTION_TYPE_CONFIGURE:                  strncpy (operation, "configure", sizeof (operation));                  break; + +        case GF_GSYNC_OPTION_TYPE_STATUS: +                strncpy (operation, "status", sizeof (operation)); +                break;          }          gf_cmd_log ("volume gsync", " %s command on %s,%s", operation, master, diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c index 56ea9a19d71..ad95e340c70 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c @@ -1695,6 +1695,115 @@ volname_from_master (char *master)  }  int +glusterd_gsync_get_cannonical_slave_name (char *cann, char *master, char *slave) +{ +        FILE               *in = NULL; +        char                buff[PATH_MAX] = {0, }; +        char                cmd[PATH_MAX] = {0, }; +        char               *ptr = NULL; +        char                buffer[PATH_MAX] = {0, }; +        glusterd_conf_t    *priv  = NULL; +        int                 ret = 0; + +        GF_ASSERT (THIS); +        GF_ASSERT (THIS->private); + +        priv = THIS->private; + +        snprintf (cmd, PATH_MAX, GSYNCD_PREFIX"/gsyncd" +                  " --canonicalize-url" +                  " %s %s", master, slave); +        if (!(in = popen(cmd, "r"))) { +                gf_log ("", GF_LOG_ERROR, "popen failed"); +                return -1; +        } + +        ptr = fgets(buff, sizeof(buff), in); +        if (ptr == NULL) { +                ret = -1; +                goto out; +        } + +        memset (buff, 0, PATH_MAX); +        memset (buffer, 0, PATH_MAX); + +        ptr = fgets(buff, sizeof(buff), in); +        if (ptr) { +                buff[strlen(buff)-1]='\0'; //strip off \n +                strncpy (cann, buff, PATH_MAX); +        } + + out: +        ret |= pclose (in); + +        if (ret) +                gf_log ("", GF_LOG_ERROR, "popen failed"); + +        return ret ? -1 : 0; + +} + +int +glusterd_gsync_get_param_file (char *prmfile, const char *ext, char *master, +                                char *slave, char *gl_workdir) +{ +        FILE               *in = NULL; +        char                buff[PATH_MAX] = {0, }; +        char                cmd[PATH_MAX] = {0, }; +        char               *ptr = NULL; +        char                prmfolder[PATH_MAX] = {0, }; +        char               *dotp = NULL; +        int                 ret = 0; + +        if (!(master && slave && gl_workdir)) { +                GF_ASSERT (!master && !slave && !gl_workdir); +                /* extension adjustment mode */ + +                dotp = strrchr (prmfile, '.'); +                if (!dotp++ || +                    /* overflow */ +                    dotp - prmfile + strlen (ext) + 1 > PATH_MAX) +                        return -1; + +                strcpy (dotp, ext); +                return 0; +        } + +        snprintf (cmd, PATH_MAX, GSYNCD_PREFIX"/gsyncd" +                                     " --canonicalize-escape-url" +                                     " %s %s", master, slave); +        if (!(in = popen(cmd, "r"))) { +                gf_log ("", GF_LOG_ERROR, "popen failed"); +                return -1; +        } + +        ptr = fgets(buff, sizeof(buff), in); +        if (ptr) { +                buff[strlen(buff)-1]='\0'; //strip off \n +                snprintf (prmfolder, PATH_MAX, "%s/gsync/%s", gl_workdir, buff); +        } else { +                ret = -1; +                goto out; +        } + +        memset (buff, 0, PATH_MAX); + +        ptr = fgets(buff, sizeof(buff), in); +        if (ptr) { +                buff[strlen(buff)-1]='\0'; //strip off \n +                snprintf (prmfile, PATH_MAX, "%s/%s.%s", prmfolder, buff, ext); +        } + + out: +        ret |= pclose (in); + +        if (ret) +                gf_log ("", GF_LOG_ERROR, "popen failed"); + +        return ret ? -1 : 0; +} + +int  glusterd_gsync_get_pid_file (char *pidfile, char *master, char *slave)  {          FILE               *in = NULL; @@ -1752,30 +1861,34 @@ glusterd_gsync_get_pid_file (char *pidfile, char *master, char *slave)  int  gsync_status (char *master, char *slave, int *status)  { -        int     ret             = -1; -        char    pidfile[PATH_MAX]   = {0,}; -        FILE    *file           = NULL; +        int                ret             = -1; +        char               pidfile[PATH_MAX]   = {0,}; +        FILE               *file           = NULL; +        glusterd_conf_t    *priv  = NULL; + +        GF_ASSERT (THIS); +        GF_ASSERT (THIS->private); + +        priv = THIS->private;          GF_VALIDATE_OR_GOTO ("gsync", master, out);          GF_VALIDATE_OR_GOTO ("gsync", slave, out);          GF_VALIDATE_OR_GOTO ("gsync", status, out); -        ret = glusterd_gsync_get_pid_file (pidfile, master, slave); +        ret = glusterd_gsync_get_param_file (pidfile, "pid", master, +                                              slave, priv->workdir);          if (ret == -1) { -                ret = -1;                  gf_log ("", GF_LOG_WARNING, "failed to create the pidfile string");                  goto out;          } +        *status = -1;          file = fopen (pidfile, "r+");          if (file) {                  ret = lockf (fileno (file), F_TEST, 0); -                if (ret == 0) -                        *status = -1; -                else +                if (ret != 0)                          *status = 0; -        } else -                *status = -1; +        }          ret = 0;  out:          return ret; @@ -1875,6 +1988,93 @@ gsync_validate_config_option (dict_t *dict, int32_t config_type,          return ret;  } +static void +_get_status_mst_slv (dict_t *this, char *key, data_t *value, void *data) +{ +        glusterd_gsync_status_temp_t  *param = NULL; +        char                          *slave = NULL; +        int                           ret = 0; +        char                          master[PATH_MAX] = {0, }; + +        param = (glusterd_gsync_status_temp_t *)data; + +        slave = strchr(value->data, ':'); +        if (slave) +                slave ++; +        else +                return; + +        master[0] = ':'; +        strcat (master, param->volinfo->volname); + +        ret = glusterd_get_gsync_status_mst_slv(param->volinfo, master, +                                                slave, param->rsp_dict); + +} + +/* The return   status indicates success (ret_status = 0) if the host uuid + *  matches,    status indicates failure (ret_status = -1) if the host uuid + *  mismatches, status indicates not found if the slave is not found to be + *  spawned for the given master */ +static void +_compare_host_uuid (dict_t *this, char *key, data_t *value, void *data) +{ +        glusterd_gsync_slaves_t     *status = NULL; +        char                        *slave = NULL; +        int                          uuid_len = 0; + +        status = (glusterd_gsync_slaves_t *)data; + +        if ((status->ret_status == -1) || (status->ret_status == 0)) +                return; +        slave = strchr(value->data, ':'); +        if (slave) +                slave ++; + +        uuid_len = (slave - value->data - 1); + +        if (strncmp (slave, status->slave, PATH_MAX) == 0) { +                if (strncmp (value->data, status->host_uuid, uuid_len) == 0) { +                        status->ret_status = 0; +                } else { +                        status->ret_status = -1; +                        strncpy (status->rmt_hostname, value->data, uuid_len); +                        status->rmt_hostname[uuid_len] = '\0'; +                } +        } + +} + +static void +_get_max_gsync_slave_num (dict_t *this, char *key, data_t *value, void *data) +{ +        int                          tmp_slvnum = 0; +        glusterd_gsync_slaves_t     *status = NULL; + +        status = (glusterd_gsync_slaves_t *)data; + +        sscanf (key, "slave%d", &tmp_slvnum); +        if (tmp_slvnum > status->ret_status) +                status->ret_status = tmp_slvnum; +} + +static void +_remove_gsync_slave (dict_t *this, char *key, data_t *value, void *data) +{ +        glusterd_gsync_slaves_t     *status = NULL; +        char                        *slave = NULL; + + +        status = (glusterd_gsync_slaves_t *)data; + +        slave = strchr(value->data, ':'); +        if (slave) +                slave ++; + +        if (strncmp (slave, status->slave, PATH_MAX) == 0) +                dict_del (this, key); + +}  int  gsync_verify_config_options (dict_t *dict, char **op_errstr) @@ -1909,41 +2109,286 @@ out:  }  static int -glusterd_op_stage_gsync_set (dict_t *dict, char **op_errstr) +glusterd_remove_slave_in_info (glusterd_volinfo_t *volinfo, char *master, +                              char *slave,char *host_uuid, char **op_errstr)  { -        int             ret     = 0; -        int             type    = 0; -        int             status  = 0; -        dict_t          *ctx    = NULL; -        char            *volname = NULL; -        char            *master  = NULL; -        char            *slave   = NULL; -        gf_boolean_t    exists   = _gf_false; -        glusterd_volinfo_t *volinfo = NULL; +        int                         ret = 0; +        glusterd_gsync_slaves_t     status = {0, }; +        char                        cann_slave[PATH_MAX] = {0,  }; -        ctx = glusterd_op_get_ctx (GD_OP_GSYNC_SET); -        if (!ctx) { -                gf_log ("gsync", GF_LOG_DEBUG, "gsync command doesn't " -                        "correspond to this glusterd"); +        GF_ASSERT (volinfo); +        GF_ASSERT (master); +        GF_ASSERT (slave); +        GF_ASSERT (host_uuid); + +        ret = glusterd_gsync_get_cannonical_slave_name (cann_slave, master, +                                                        slave); +        if (ret) +                goto out; + +        status.slave = cann_slave; +        status.host_uuid = host_uuid; +        status.ret_status = 1; + +        dict_foreach (volinfo->gsync_slaves, _remove_gsync_slave, &status); + +        ret = glusterd_store_volinfo (volinfo, +                                      GLUSTERD_VOLINFO_VER_AC_INCREMENT); +        if (ret) { +                 *op_errstr = gf_strdup ("Failed to store the Volume" +                                         "information");                  goto out;          } + out: +        gf_log ("", GF_LOG_DEBUG, "returning %d", ret); +        return ret; -        ret = dict_get_str (dict, "master", &master); -        if (ret < 0) { -                gf_log ("", GF_LOG_WARNING, "master not found"); -                *op_errstr = gf_strdup ("master not found"); +} + +static int +glusterd_gsync_get_uuid (char *master, char *slave, glusterd_volinfo_t *vol, +                         uuid_t uuid) +{ + +        int                         ret = 0; +        glusterd_gsync_slaves_t     status = {0, }; +        char                        cann_slave[PATH_MAX] = {0,  }; +        char                        host_uuid_str[32] = {0}; +        xlator_t                    *this = NULL; +        glusterd_conf_t             *priv = NULL; + + +        this = THIS; +        GF_ASSERT (this); +        priv = this->private; +        GF_ASSERT (priv); +        GF_ASSERT (vol); +        GF_ASSERT (master); +        GF_ASSERT (slave); + +        uuid_utoa_r (priv->uuid, host_uuid_str); +        ret = glusterd_gsync_get_cannonical_slave_name (cann_slave, master, +                                                        slave); +        if (ret) +                goto out; + +        status.slave = cann_slave; +        status.host_uuid = host_uuid_str; +        status.ret_status = 1; +        dict_foreach (vol->gsync_slaves, _compare_host_uuid, &status); +        if (status.ret_status == 0) { +                uuid_copy (uuid, priv->uuid); +        } else if (status.ret_status == -1) { +                uuid_parse (status.rmt_hostname, uuid); +        } else {                  ret = -1;                  goto out;          } +        ret = 0; + out: +        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); +        return ret; -        ret = dict_get_str (dict, "slave", &slave); -        if (ret < 0) { -                gf_log ("", GF_LOG_WARNING, "slave not found"); -                *op_errstr = gf_strdup ("slave not found"); +} + +static int +glusterd_check_gsync_running_local (char *master, char *slave, +                                      gf_boolean_t *is_run) +{ +        int                 ret    = -1; +        int                 ret_status = 0; + +        GF_ASSERT (master); +        GF_ASSERT (slave); +        GF_ASSERT (is_run); + +        *is_run = _gf_false; +        ret = gsync_status (master, slave, &ret_status); +        if (ret == 0 && ret_status == 0) { +                *is_run = _gf_true; +        } else if (ret == -1) { +                gf_log ("", GF_LOG_WARNING, "gsync start validation " +                        " failed"); +                goto out; +        } +        ret = 0; + out: +        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); +        return ret; + +} + +static int +glusterd_store_slave_in_info (glusterd_volinfo_t *volinfo, char *master, +                              char *slave, char *host_uuid, char **op_errstr) +{ +        int                         ret = 0; +        glusterd_gsync_slaves_t     status = {0, }; +        char                        cann_slave[PATH_MAX] = {0,  }; +        char                       *value = NULL; +        char                        key[512] = {0, }; + + +        ret = glusterd_gsync_get_cannonical_slave_name (cann_slave, master, +                                                        slave); +        if (ret) +                goto out; + +        status.slave = cann_slave; +        status.host_uuid = host_uuid; +        status.ret_status = 1; +        dict_foreach (volinfo->gsync_slaves, _compare_host_uuid, &status); + +        if (status.ret_status == -1) { +                gf_log ("", GF_LOG_ERROR, "Gsync has already been invoked for " +                                          "the %s (master) and %s (slave)" +                                          "from a different machine", +                                           master, slave); +                 *op_errstr = gf_strdup ("Gsync already running in an an" +                                        "orhter machine");                  ret = -1;                  goto out;          } +        memset (&status, 0, sizeof (status)); + +        dict_foreach (volinfo->gsync_slaves, _get_max_gsync_slave_num, &status); + +        gf_asprintf (&value,  "%s:%s", host_uuid, cann_slave); +        snprintf (key, 512, "slave%d", status.ret_status +1); +        ret = dict_set_dynstr (volinfo->gsync_slaves, key, value); + +        if (ret) +                goto out; +        ret = glusterd_store_volinfo (volinfo, +                                      GLUSTERD_VOLINFO_VER_AC_INCREMENT); +        if (ret) { +                 *op_errstr = gf_strdup ("Failed to store the Volume" +                                         "information"); +                goto out; +        } +        ret = 0; + out: +        return ret; +} + + +static int +glusterd_op_verify_gsync_start_options (glusterd_volinfo_t *volinfo, +                                        char *master, char *slave, +                                        char **op_errstr) +{ +        int                     ret = -1; +        gf_boolean_t            is_running = _gf_false; +        char                    msg[2048] = {0}; +        uuid_t                  uuid = {0}; +        glusterd_conf_t         *priv = NULL; +        xlator_t                *this = NULL; + +        this = THIS; + +        GF_ASSERT (volinfo); +        GF_ASSERT (master); +        GF_ASSERT (slave); +        GF_ASSERT (op_errstr); +        GF_ASSERT (this && this->private); + +        priv  = this->private; + +        if (GLUSTERD_STATUS_STARTED != volinfo->status) { +                snprintf (msg, sizeof (msg), "Volume %s needs to be started " +                          "before gsync start", volinfo->volname); +                goto out; +        } +        /*Check if the gsync is already started in cmd. inited host +         * If so initiate add it into the glusterd's priv*/ +        ret = glusterd_gsync_get_uuid (master, slave, volinfo, uuid); +        if ((ret == 0) && (uuid_compare (priv->uuid, uuid) == 0)) { +                ret = glusterd_check_gsync_running_local (master, slave, +                                                          &is_running); +                if (ret) { +                        snprintf (msg, sizeof (msg), "gsync start option " +                                  "validation failed "); +                        goto out; +                } +                if (_gf_true == is_running) { +                        snprintf (msg, sizeof (msg), "gsync %s %s already " +                                  "started", master, slave); +                        ret = -1; +                        goto out; +                } +        } +        ret = 0; +out: +        if (ret && (msg[0] != '\0')) { +                *op_errstr = gf_strdup (msg); +        } +        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); +        return ret; +} + +static int +glusterd_op_verify_gsync_running (glusterd_volinfo_t *volinfo, +                                  char *master, char *slave, +                                  char **op_errstr) +{ +        int                     ret = -1; +        char                    msg[2048] = {0}; +        uuid_t                  uuid = {0}; +        glusterd_conf_t         *priv = NULL; + +        GF_ASSERT (THIS && THIS->private); +        GF_ASSERT (volinfo); +        GF_ASSERT (master); +        GF_ASSERT (slave); +        GF_ASSERT (op_errstr); + +        priv = THIS->private; + +        if (GLUSTERD_STATUS_STARTED != volinfo->status) { +                snprintf (msg, sizeof (msg), "Volume %s needs to be started " +                          "before gsync start", volinfo->volname); +                goto out; +        } +        ret = glusterd_gsync_get_uuid (master, slave, volinfo, uuid); +        if (ret == -1) { +                snprintf (msg, sizeof (msg), "Gsync session is not active"); +                goto out; +        } + +        ret = 0; +out: +        if (ret && (msg[0] != '\0')) { +                *op_errstr = gf_strdup (msg); +        } +        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); +        return ret; +} + +static int +glusterd_verify_gsync_status_opts (dict_t *dict, char **op_errstr) +{ +        int                status_type = 0; +        char               *master = NULL; +        char               *slave  = NULL; +        char               *volname = NULL; +        char               errmsg[PATH_MAX] = {0, }; +        gf_boolean_t       exists = _gf_false; +        glusterd_volinfo_t *volinfo = NULL; +        int                ret = 0; + + +        ret = dict_get_int32 (dict, "status-type", &status_type); +        if (ret) +                goto out; + +        if (status_type == GF_GSYNC_OPTION_TYPE_STATUS_ALL) +                goto out; + +        ret = dict_get_str (dict, "master", &master); +        if (ret < 0) +                goto out; +          volname = volname_from_master (master);          if (volname == NULL) {                  gf_log ("", GF_LOG_WARNING, "volname couldn't be found"); @@ -1953,82 +2398,136 @@ glusterd_op_stage_gsync_set (dict_t *dict, char **op_errstr)          }          exists = glusterd_check_volume_exists (volname); -        if (!exists) { -                gf_log ("", GF_LOG_WARNING, "volname doesnot exist"); -                *op_errstr = gf_strdup ("volname doesnot exist"); +        ret = glusterd_volinfo_find (volname, &volinfo); +        if ((ret) || (!exists)) { +                gf_log ("", GF_LOG_WARNING, "volume name does not exist"); +                snprintf (errmsg, sizeof(errmsg), "Volume name %s does not" +                          "exist", volname); +                *op_errstr = gf_strdup (errmsg);                  ret = -1;                  goto out;          } + +        if (status_type == GF_GSYNC_OPTION_TYPE_STATUS_MASTER) +                goto out; + +        if (status_type != GF_GSYNC_OPTION_TYPE_STATUS_MST_SLV) +                goto out; + +        ret = dict_get_str (dict, "slave", &slave); +        if (ret < 0) +                goto out; + +        ret = glusterd_op_verify_gsync_running (volinfo, master, +                                                slave, op_errstr); + + out: +        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); +        return ret; + +} + + +static int +glusterd_op_gsync_args_get (dict_t *dict, char **op_errstr, +                            char **master, char **slave) +{ + +        int             ret = -1; +        GF_ASSERT (dict); +        GF_ASSERT (op_errstr); +        GF_ASSERT (master); +        GF_ASSERT (slave); + +        ret = dict_get_str (dict, "master", master); +        if (ret < 0) { +                gf_log ("", GF_LOG_WARNING, "master not found"); +                *op_errstr = gf_strdup ("master not found"); +                goto out; +        } + +        ret = dict_get_str (dict, "slave", slave); +        if (ret < 0) { +                gf_log ("", GF_LOG_WARNING, "slave not found"); +                *op_errstr = gf_strdup ("slave not found"); +                goto out; +        } + + +        ret = 0; +out: +        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); +        return ret; +} + +static int +glusterd_op_stage_gsync_set (dict_t *dict, char **op_errstr) +{ +        int                     ret     = 0; +        int                     type    = 0; +        char                    *volname = NULL; +        char                    *master  = NULL; +        char                    *slave   = NULL; +        gf_boolean_t            exists   = _gf_false; +        glusterd_volinfo_t      *volinfo = NULL; +        char                    errmsg[PATH_MAX] = {0,}; + +          ret = dict_get_int32 (dict, "type", &type);          if (ret < 0) {                  gf_log ("", GF_LOG_WARNING, "command type not found");                  *op_errstr = gf_strdup ("command unsuccessful"); -                ret = -1;                  goto out;          } -        ret = glusterd_volinfo_find (volname, &volinfo); -        if (ret) { -                 gf_log ("", GF_LOG_WARNING, "volinfo not found " -                         "for %s", volname); -                 *op_errstr = gf_strdup ("command unsuccessful"); -                 ret = -1; -                 goto out; +        if (type == GF_GSYNC_OPTION_TYPE_STATUS) { +                ret = glusterd_verify_gsync_status_opts (dict, op_errstr); + +                goto out;          } -        if (type == GF_GSYNC_OPTION_TYPE_START) { -                if (GLUSTERD_STATUS_STARTED != volinfo->status) { -                        gf_log ("", GF_LOG_WARNING, "%s volume not started", -                                volname); -                        *op_errstr = gf_strdup ("please start the volume"); -                        ret = -1; -                        goto out; -                } -                //check if the gsync is already started -                ret = gsync_status (master, slave, &status); -                if (ret == 0 && status == 0) { -                        gf_log ("", GF_LOG_WARNING, "gsync already started"); -                        *op_errstr = gf_strdup ("gsync already started"); -                        ret = -1; -                        goto out; -                } else if (ret == -1) { -                        gf_log ("", GF_LOG_WARNING, "gsync start validation " -                                " failed"); -                        *op_errstr = gf_strdup ("command to failed, please " -                                                "check the log file"); -                        goto out; -                } -                ret = 0; +        ret = glusterd_op_gsync_args_get (dict, op_errstr, &master, &slave); +        if (ret) +                goto out; +        volname = volname_from_master (master); +        if (volname == NULL) { +                gf_log ("", GF_LOG_WARNING, "volname couldn't be found"); +                *op_errstr = gf_strdup ("volname not found"); +                ret = -1;                  goto out;          } -        if (type == GF_GSYNC_OPTION_TYPE_STOP) { -                ret = gsync_status (master, slave, &status); -                if (ret == 0 && status == -1) { -                        gf_log ("", GF_LOG_WARNING, "gsync not running"); -                        *op_errstr = gf_strdup ("gsync not running"); -                        glusterd_gsync_volinfo_dict_set (volinfo, -                                        "features.marker-gsync", "off"); -                        ret = -1; -                        goto out; -                }  else if (ret == -1) { -                        gf_log ("", GF_LOG_WARNING, "gsync stop validation " -                                " failed"); -                        *op_errstr = gf_strdup ("command failed, please " -                                                "check the log file"); -                        goto out; -                } -                ret = 0; +        exists = glusterd_check_volume_exists (volname); +        ret = glusterd_volinfo_find (volname, &volinfo); +        if ((ret) || (!exists)) { +                gf_log ("", GF_LOG_WARNING, "volume name does not exist"); +                snprintf (errmsg, sizeof(errmsg), "Volume name %s does not" +                          "exist", volname); +                *op_errstr = gf_strdup (errmsg); +                ret = -1;                  goto out;          } -        if (type == GF_GSYNC_OPTION_TYPE_CONFIGURE) { +        switch (type) { +        case GF_GSYNC_OPTION_TYPE_START: +                ret = glusterd_op_verify_gsync_start_options (volinfo, master, +                                                              slave, op_errstr); +                if (ret) +                        goto out; +                break; +        case GF_GSYNC_OPTION_TYPE_STOP: +                ret = glusterd_op_verify_gsync_running (volinfo, master, +                                                        slave, op_errstr); +                if (ret) +                        goto out; +                break; +        case GF_GSYNC_OPTION_TYPE_CONFIGURE:                  ret = gsync_verify_config_options (dict, op_errstr);                  if (ret < 0)                          goto out; +                break;          } -          ret = 0;  out:          if (volname) @@ -3635,12 +4134,17 @@ stop_gsync (char *master, char *slave, char **op_errstr)          char            pidfile[PATH_MAX] = {0,};          char            buf [1024] = {0,};          int             i       = 0; +        glusterd_conf_t *priv = NULL; + +        GF_ASSERT (THIS); +        GF_ASSERT (THIS->private); + +        priv = THIS->private;          ret = gsync_status (master, slave, &status);          if (ret == 0 && status == -1) { -                gf_log ("", GF_LOG_WARNING, "gsync is not running"); -                *op_errstr = gf_strdup ("gsync is not running"); -                ret = -1; +                gf_log ("", GF_LOG_WARNING, "Gsync is not running"); +                *op_errstr = gf_strdup ("Gsync is not running");                  goto out;          } else if (ret == -1) {                  gf_log ("", GF_LOG_WARNING, "gsync stop validation " @@ -3650,10 +4154,12 @@ stop_gsync (char *master, char *slave, char **op_errstr)                  goto out;          } -        ret = glusterd_gsync_get_pid_file (pidfile, master, slave); +        ret = glusterd_gsync_get_param_file (pidfile, "pid", master, +                                              slave, priv->workdir);          if (ret == -1) { -                ret = -1; -                gf_log ("", GF_LOG_WARNING, "failed to create the pidfile string"); +                gf_log ("", GF_LOG_WARNING, "failed to create the pidfile" +                        " string"); +                *op_errstr = gf_strdup ("Operation Failed! due to corrupt pid");                  goto out;          } @@ -3835,87 +4341,141 @@ out:          return ret;  } -  int -gsync_configure (char *master, char *slave, -                 dict_t *dict, char **op_errstr) +glusterd_gsync_read_frm_status (char *path, char *data)  { -        int32_t         ret     = -1; -        int32_t         config_type = 0; +        int                 ret = 0; +        FILE               *status_file = NULL; -        ret = dict_get_int32 (dict, "config_type", &config_type); +        GF_ASSERT (path); +        GF_ASSERT (data); +        status_file = fopen (path, "r"); +        if (status_file  == NULL) { +                gf_log ("", GF_LOG_WARNING, "Unable to read the Gsync status" +                        " file"); +                return -1; +        } +        ret = fread (data, PATH_MAX, 1, status_file);          if (ret < 0) { -                gf_log ("", GF_LOG_WARNING, "couldn't get the " -                        "config-type for %s %s", master, slave); -                *op_errstr = gf_strdup ("configure command failed, " -                                        "please check the log-file\n"); -                goto out; +                gf_log ("", GF_LOG_WARNING, "Status file of Gsync is corrupt"); +                return -1;          } -        if (config_type == GF_GSYNC_OPTION_TYPE_CONFIG_SET) { -                ret = gsync_config_set (master, slave, dict, op_errstr); +        return 0; +} + +int +glusterd_read_status_file (char *master, char *slave, +                           dict_t *dict) +{ +        glusterd_conf_t  *priv = NULL; +        int              ret = 0; +        char             statusfile[PATH_MAX] = {0, }; +        char             buff[PATH_MAX] = {0, }; +        char             mst[PATH_MAX] = {0, }; +        char             slv[PATH_MAX] = {0, }; +        char             sts[PATH_MAX] = {0, }; +        int              gsync_count = 0; +        int              status = 0; + +        GF_ASSERT (THIS); +        GF_ASSERT (THIS->private); + +        priv = THIS->private; +        ret = glusterd_gsync_get_param_file (statusfile, "status", master, +                                              slave, priv->workdir); +        if (ret) { +                gf_log ("", GF_LOG_WARNING, "Unable to get the name of status" +                        "file for %s(master), %s(slave)", master, slave);                  goto out; +          } -        if (config_type == GF_GSYNC_OPTION_TYPE_CONFIG_DEL) { -                ret = gsync_config_del (master, slave, dict, op_errstr); +        ret = gsync_status (master, slave, &status); +        if (ret == 0 && status == -1) { +                strncpy (buff, "Corrupt\n", sizeof (buff)); +                goto done; +        } else if (ret == -1) { +                gf_log ("", GF_LOG_WARNING, "Unable to determine " +                        " Gsync's status");                  goto out;          } -        if ((config_type == GF_GSYNC_OPTION_TYPE_CONFIG_GET_ALL) || -           (config_type == GF_GSYNC_OPTION_TYPE_CONFIG_GET)) +        ret = glusterd_gsync_read_frm_status (statusfile, buff); +        if (ret) { +                gf_log ("", GF_LOG_WARNING, "Unable to read the status" +                        "file for %s(master), %s(slave)", master, slave);                  goto out; -         else { -                gf_log ("", GF_LOG_WARNING, "Invalid config type"); -                *op_errstr = gf_strdup ("Invalid config type"); -                ret = -1; +          } -out: -        return ret; -} + done: +        ret = dict_get_int32 (dict, "gsync-count", &gsync_count); -int -gsync_command_exec (dict_t *dict, char **op_errstr) -{ -        char            *master = NULL; -        char            *slave  = NULL; -        int32_t         ret     = -1; -        int32_t         type    = -1; +        if (ret) +                gsync_count = 1; +        else +                gsync_count++; -        GF_VALIDATE_OR_GOTO ("gsync", dict, out); -        GF_VALIDATE_OR_GOTO ("gsync", op_errstr, out); +        snprintf (mst, sizeof (mst), "master%d", gsync_count); +        ret = dict_set_dynstr (dict, mst, gf_strdup (master)); +        if (ret) +                goto out; -        ret = dict_get_int32 (dict, "type", &type); -        if (ret < 0) +        snprintf (slv, sizeof (slv), "slave%d", gsync_count); +        ret = dict_set_dynstr (dict, slv, gf_strdup (slave)); +        if (ret)                  goto out; -        ret = dict_get_str (dict, "master", &master); -        if (ret < 0) +        snprintf (sts, sizeof (slv), "status%d", gsync_count); +        ret = dict_set_dynstr (dict, sts, gf_strdup (buff)); +        if (ret) +                goto out; +        ret = dict_set_int32 (dict, "gsync-count", gsync_count); +        if (ret)                  goto out; -        ret = dict_get_str (dict, "slave", &slave); -        if (ret < 0) +        ret = 0; + out: +        gf_log ("", GF_LOG_DEBUG, "Returning %d ", ret); +        return ret; +} + +int +glusterd_gsync_configure (char *master, char *slave, +                 dict_t *dict, char **op_errstr) +{ +        int32_t         ret     = -1; +        int32_t         config_type = 0; + +        ret = dict_get_int32 (dict, "config_type", &config_type); +        if (ret < 0) { +                gf_log ("", GF_LOG_WARNING, "couldn't get the " +                        "config-type for %s %s", master, slave); +                *op_errstr = gf_strdup ("configure command failed, " +                                        "please check the log-file\n");                  goto out; +        } -        if (type == GF_GSYNC_OPTION_TYPE_START) { -                ret = 0; +        if (config_type == GF_GSYNC_OPTION_TYPE_CONFIG_SET) { +                ret = gsync_config_set (master, slave, dict, op_errstr);                  goto out;          } -        if (type == GF_GSYNC_OPTION_TYPE_STOP) { -                ret = stop_gsync (master, slave, op_errstr); +        if (config_type == GF_GSYNC_OPTION_TYPE_CONFIG_DEL) { +                ret = gsync_config_del (master, slave, dict, op_errstr);                  goto out;          } -        if (type == GF_GSYNC_OPTION_TYPE_CONFIGURE) { -                ret = gsync_configure (master, slave, dict, op_errstr); +        if ((config_type == GF_GSYNC_OPTION_TYPE_CONFIG_GET_ALL) || +           (config_type == GF_GSYNC_OPTION_TYPE_CONFIG_GET))                  goto out; -        } else { +         else {                  gf_log ("", GF_LOG_WARNING, "Invalid config type");                  *op_errstr = gf_strdup ("Invalid config type");                  ret = -1;          } +  out:          return ret;  } @@ -3953,6 +4513,12 @@ glusterd_set_marker_gsync (char *master)          char                    *marker_value   = NULL;          gf_boolean_t             marker_set = _gf_false;          char                    *gsync_status = NULL; +        glusterd_conf_t         *priv = NULL; + +        GF_ASSERT (THIS); +        GF_ASSERT (THIS->private); + +        priv = THIS->private;          volname = volname_from_master (master); @@ -3997,48 +4563,244 @@ out:  } + + +  int -glusterd_op_gsync_set (dict_t *dict) +glusterd_get_gsync_status_mst_slv( glusterd_volinfo_t *volinfo, char *master, +                                   char *slave, dict_t *rsp_dict)  { -        char            *master = NULL; -        int32_t         ret     = -1; -        int32_t         type    = -1; -        dict_t          *ctx    = NULL; -        char            *op_errstr = NULL; +        uuid_t             uuid = {0, }; +        glusterd_conf_t    *priv = NULL; +        int                ret = 0; + +        GF_ASSERT (volinfo); +        GF_ASSERT (master); +        GF_ASSERT (slave); +        GF_ASSERT (THIS); +        GF_ASSERT (THIS->private); + +        priv = THIS->private; + +        ret = glusterd_gsync_get_uuid (master, slave, volinfo, uuid); +        if ((ret == 0) && (uuid_compare (priv->uuid, uuid) != 0)) +                goto out; + +        ret = glusterd_read_status_file (master, slave, rsp_dict); + out: +        gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret); +        return ret; +} + +static int +glusterd_get_gsync_status_mst (glusterd_volinfo_t *volinfo, dict_t *rsp_dict) +{ +        glusterd_gsync_status_temp_t  param = {0, }; + +        GF_ASSERT (volinfo); + +        param.rsp_dict = rsp_dict; +        param.volinfo = volinfo; +        dict_foreach (volinfo->gsync_slaves, _get_status_mst_slv, ¶m); + +        return 0; +} + +static int +glusterd_get_gsync_status_all ( dict_t *rsp_dict) +{ + +        int32_t                 ret = 0; +        glusterd_conf_t         *priv = NULL; +        glusterd_volinfo_t      *volinfo = NULL; + +        GF_ASSERT (THIS); +        priv = THIS->private; + +        GF_ASSERT (priv); + +        list_for_each_entry (volinfo, &priv->volumes, vol_list) { +                ret = glusterd_get_gsync_status_mst (volinfo, rsp_dict); +                if (ret) +                        goto out; +        } + +out: +        gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret); +        return ret; + +} + +static int +glusterd_get_gsync_status (dict_t *dict, char **op_errstr, dict_t *rsp_dict) +{ +        int                status_type = 0; +        char               *master = NULL; +        char               *slave  = NULL; +        char               *volname = NULL; +        char               errmsg[PATH_MAX] = {0, }; +        gf_boolean_t       exists = _gf_false; +        glusterd_volinfo_t *volinfo = NULL; +        int                ret = 0; + + +        ret = dict_get_int32 (dict, "status-type", &status_type); +        if (ret) +                goto out; + +        if (status_type == GF_GSYNC_OPTION_TYPE_STATUS_ALL) { +                ret = glusterd_get_gsync_status_all (rsp_dict); +                goto out; +        } + +        ret = dict_get_str (dict, "master", &master); +        if (ret < 0) +                goto out; + +        volname = volname_from_master (master); +        if (volname == NULL) { +                gf_log ("", GF_LOG_WARNING, "volname couldn't be found"); +                *op_errstr = gf_strdup ("volname not found"); +                ret = -1; +                goto out; +        } + +        exists = glusterd_check_volume_exists (volname); +        ret = glusterd_volinfo_find (volname, &volinfo); +        if ((ret) || (!exists)) { +                gf_log ("", GF_LOG_WARNING, "volume name does not exist"); +                snprintf (errmsg, sizeof(errmsg), "Volume name %s does not" +                          "exist", volname); +                *op_errstr = gf_strdup (errmsg); +                ret = -1; +                goto out; +        } + + +        if (status_type == GF_GSYNC_OPTION_TYPE_STATUS_MASTER) { +                ret = glusterd_get_gsync_status_mst (volinfo, rsp_dict); +                goto out; +        } + +        ret = dict_get_str (dict, "slave", &slave); +        if (ret < 0) +                goto out; + +        ret = glusterd_get_gsync_status_mst_slv (volinfo, master, +                                                 slave, rsp_dict); + + out: +        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); +        return ret; + + +} + + +int +glusterd_op_gsync_set (dict_t *dict, char **op_errstr, dict_t *rsp_dict) +{ +        char               *master = NULL; +        int32_t             ret     = -1; +        int32_t             type    = -1; +        dict_t             *ctx    = NULL; +        dict_t             *resp_dict = NULL; +        char               *host_uuid = NULL; +        char               *slave  = NULL; +        char               *volname = NULL; +        glusterd_volinfo_t *volinfo = NULL; +        glusterd_conf_t    *priv = NULL; +        uuid_t              uuid = {0, }; + +        GF_ASSERT (THIS); +        GF_ASSERT (THIS->private); +        GF_ASSERT (dict); +        GF_ASSERT (op_errstr); + +        priv = THIS->private;          ret = dict_get_int32 (dict, "type", &type);          if (ret < 0)                  goto out; +        ret = dict_get_str (dict, "host-uuid", &host_uuid); +        if (ret < 0) +                goto out; + +        if (type == GF_GSYNC_OPTION_TYPE_STATUS) { +                ctx = glusterd_op_get_ctx (GD_OP_GSYNC_SET); +                resp_dict = ctx ? ctx : rsp_dict; + +                ret = glusterd_get_gsync_status (dict, op_errstr, resp_dict); +                goto out; + +        } +          ret = dict_get_str (dict, "master", &master);          if (ret < 0)                  goto out; +        ret = dict_get_str (dict, "slave", &slave); +        if (ret < 0) +                goto out; + +        volname = volname_from_master (master); + +        ret = glusterd_volinfo_find (volname, &volinfo); +        if (ret) { +                gf_log ("", GF_LOG_ERROR, "Volinfo for %s (master) not found", +                        volname); +                goto out; +        } +          if (type == GF_GSYNC_OPTION_TYPE_START) {                  ret = glusterd_set_marker_gsync (master);                  if (ret != 0) {                          gf_log ("", GF_LOG_WARNING, "marker start failed"); -                        op_errstr = gf_strdup ("gsync start failed"); +                        *op_errstr = gf_strdup ("gsync start failed");                          ret = -1;                          goto out;                  } +                ret = glusterd_store_slave_in_info(volinfo, master, slave, +                                                   host_uuid, op_errstr); +                if (ret) +                        goto out; +          } -out: -        ctx = glusterd_op_get_ctx (GD_OP_GSYNC_SET); -        if (ctx) { -                ret = gsync_command_exec (dict, &op_errstr); -                if (op_errstr) { -                        ret = dict_set_str (ctx, "errstr", op_errstr); -                        if (ret) { -                                GF_FREE (op_errstr); -                                gf_log ("", GF_LOG_WARNING, "failed to set " -                                        "error message in ctx"); -                        } +        if (type == GF_GSYNC_OPTION_TYPE_STOP) { + +                ret = glusterd_gsync_get_uuid (master, slave, volinfo, uuid); +                if (ret) { +                        gf_log ("", GF_LOG_WARNING, "Gsync is not runing for" +                                "%s(master) and %s(slave)", master, slave); +                        *op_errstr = strdup ("Gsync is not running"); +                        goto out; +                } + +                ret = glusterd_remove_slave_in_info(volinfo, master, slave, +                                                    host_uuid, op_errstr); +                if (ret) +                        goto out; + +                if (uuid_compare (priv->uuid, uuid) != 0) { +                        goto out;                  } + +                ret = stop_gsync (master, slave, op_errstr); +                if (ret) +                        goto out; +          } +        if (type == GF_GSYNC_OPTION_TYPE_CONFIGURE) { +                ret = glusterd_gsync_configure (master, slave, dict, op_errstr); +                goto out; +        } + +out: +        gf_log ("", GF_LOG_DEBUG,"Returning %d", ret);          return ret;  } @@ -6811,7 +7573,7 @@ glusterd_op_commit_perform (glusterd_op_t op, dict_t *dict, char **op_errstr,                          break;                  case GD_OP_GSYNC_SET: -                        ret = glusterd_op_gsync_set (dict); +                        ret = glusterd_op_gsync_set (dict, op_errstr, rsp_dict);                          break;                  case GD_OP_PROFILE_VOLUME: diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.h b/xlators/mgmt/glusterd/src/glusterd-op-sm.h index 9c322b0bffd..d10d5c1a4f9 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.h +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.h @@ -163,6 +163,17 @@ typedef struct glusterd_pr_brick_rsp_conv_t {          dict_t *dict;  } glusterd_pr_brick_rsp_conv_t; +typedef struct glusterd_gsync_slaves { +        char *slave; +        char *host_uuid; +        int   ret_status; +        char rmt_hostname[256]; +} glusterd_gsync_slaves_t; + +typedef struct glusterd_gsync_status_temp { +        dict_t *rsp_dict; +        glusterd_volinfo_t *volinfo; +}glusterd_gsync_status_temp_t;  int  glusterd_op_sm_new_event (glusterd_op_sm_event_type_t event_type,                            glusterd_op_sm_event_t **new_event); @@ -286,4 +297,8 @@ gf_boolean_t  glusterd_are_all_volumes_stopped ();  int  glusterd_stop_bricks (glusterd_volinfo_t *volinfo); +int +glusterd_get_gsync_status_mst_slv( glusterd_volinfo_t *volinfo, char *master, +                                   char *slave, dict_t *rsp_dict); +  #endif diff --git a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c index 8600c7b93c1..27fe5b5f8eb 100644 --- a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c @@ -304,7 +304,13 @@ glusterd_op_send_cli_response (glusterd_op_t op, int32_t op_ret,                                          rsp.op_name =                                                  gf_strdup (op_name);                          } -                } else if (op_errstr) + +                        ret = dict_allocate_and_serialize (ctx, +                                        &rsp.status_dict.status_dict_val, +                                    (size_t*)&rsp.status_dict.status_dict_len); + +                } +                if (op_errstr)                          rsp.op_errstr = op_errstr;                  cli_rsp = &rsp;                  sfunc = gf_xdr_serialize_cli_gsync_set_rsp; @@ -827,7 +833,108 @@ out:          GLUSTERD_STACK_DESTROY (((call_frame_t *)myframe));          return ret;  } +static int32_t +glusterd_append_status_dicts (dict_t *dst, dict_t *src) +{ +        int              dst_count = 0; +        int              src_count = 0; +        int              i = 0; +        int              ret = 0; +        char             mst[PATH_MAX] = {0,}; +        char             slv[PATH_MAX] = {0, }; +        char             sts[PATH_MAX] = {0, }; +        char             *mst_val = NULL; +        char             *slv_val = NULL; +        char             *sts_val = NULL; + +        GF_ASSERT (dst); + +        if (src == NULL) +                goto out; + +        ret = dict_get_int32 (dst, "gsync-count", &dst_count); +        if (ret) +                dst_count = 0; + +        ret = dict_get_int32 (src, "gsync-count", &src_count); +        if (ret || !src_count) { +                gf_log ("", GF_LOG_DEBUG, "Source brick empty"); +                ret = 0; +                goto out; +        } + +        for (i = 1; i <= src_count; i++) { +                snprintf (mst, sizeof(mst), "master%d", i); +                snprintf (slv, sizeof(slv), "slave%d", i); +                snprintf (sts, sizeof(sts), "status%d", i); + +                ret = dict_get_str (src, mst, &mst_val); +                if (ret) +                        goto out; + +                ret = dict_get_str (src, slv, &slv_val); +                if (ret) +                        goto out; + +                ret = dict_get_str (src, sts, &sts_val); +                if (ret) +                        goto out; + +                snprintf (mst, sizeof(mst), "master%d", i+dst_count); +                snprintf (slv, sizeof(slv), "slave%d", i+dst_count); +                snprintf (sts, sizeof(sts), "status%d", i+dst_count); + +                ret = dict_set_dynstr (dst, mst, gf_strdup (mst_val)); +                if (ret) +                        goto out; + +                ret = dict_set_dynstr (dst, slv, gf_strdup (slv_val)); +                if (ret) +                        goto out; + +                ret = dict_set_dynstr (dst, sts, gf_strdup (sts_val)); +                if (ret) +                        goto out; + +        } + +        ret = dict_set_int32 (dst, "gsync-count", dst_count+src_count); + + out: +        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); +        return ret; + +} + +static int32_t +glusterd_gsync_use_rsp_dict (dict_t *rsp_dict, char *op_errstr) +{ +        dict_t             *ctx = NULL; +        int                ret = 0; + +        ctx = glusterd_op_get_ctx (GD_OP_GSYNC_SET); +        if (!ctx) { +                gf_log ("", GF_LOG_ERROR, +                        "Operation Context is not present"); +                GF_ASSERT (0); +        } + +        if (rsp_dict) { +                ret = glusterd_append_status_dicts (ctx, rsp_dict); +                if (ret) +                        goto out; +        } +        if (strcmp ("", op_errstr)) { +                ret = dict_set_dynstr (ctx, "errstr", gf_strdup(op_errstr)); +                if (ret) +                        goto out; +        } +        ret = 0; + out: +        gf_log ("", GF_LOG_DEBUG, "Returning %d ", ret); +        return ret; +}  static int32_t  glusterd_rb_use_rsp_dict (dict_t *rsp_dict)  { @@ -1173,6 +1280,12 @@ glusterd3_1_commit_op_cbk (struct rpc_req *req, struct iovec *iov,                                  goto out;                  break; +                case GD_OP_GSYNC_SET: +                        ret = glusterd_gsync_use_rsp_dict (dict, rsp.op_errstr); +                        if (ret) +                                goto out; +                break; +                  default:                  break;                  } diff --git a/xlators/mgmt/glusterd/src/glusterd-store.c b/xlators/mgmt/glusterd/src/glusterd-store.c index 8058adcd0f9..836c9d12cf5 100644 --- a/xlators/mgmt/glusterd/src/glusterd-store.c +++ b/xlators/mgmt/glusterd/src/glusterd-store.c @@ -448,6 +448,40 @@ out:          return ret;  } +static void +_storeslaves (dict_t *this, char *key, data_t *value, void *data) +{ +        int32_t                      ret = 0; +        glusterd_store_handle_t  *shandle = NULL; + +        shandle = (glusterd_store_handle_t*)data; + +        GF_ASSERT (shandle); +        GF_ASSERT (shandle->fd > 0); +        GF_ASSERT (shandle->path); +        GF_ASSERT (key); +        GF_ASSERT (value && value->data); + +        if ((!shandle) || (shandle->fd <= 0) || (!shandle->path)) +                return; + +        if (!key) +                return; +        if (!value || !value->data) +                return; + +        gf_log ("", GF_LOG_DEBUG, "Storing in volinfo:key= %s, val=%s", +                key, value->data); + +        ret = glusterd_store_save_value (shandle->fd, key, (char*)value->data); +        if (ret) { +                gf_log ("", GF_LOG_ERROR, "Unable to write into store" +                                " handle for path: %s", shandle->path); +                return; +        } +} + +  void _storeopts (dict_t *this, char *key, data_t *value, void *data)  {          int32_t                      ret = 0; @@ -587,6 +621,8 @@ glusterd_store_volinfo_write (int fd, glusterd_volinfo_t *volinfo)          shandle->fd = fd;          dict_foreach (volinfo->dict, _storeopts, shandle); + +        dict_foreach (volinfo->gsync_slaves, _storeslaves, shandle);          shandle->fd = 0;  out:          gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); @@ -1479,7 +1515,18 @@ glusterd_store_retrieve_volume (char    *volname)                          if (ret)                                  gf_log ("", GF_LOG_WARNING,                                          "failed to parse uuid"); -                } else { +                } else if (strstr (key, "slave")) { +                        ret = dict_set_str(volinfo->gsync_slaves, key, +                                                gf_strdup (value)); +                        if (ret) { +                                gf_log ("",GF_LOG_ERROR, "Error in " +                                                "dict_set_str"); +                                goto out; +                        } +                        gf_log ("", GF_LOG_DEBUG, "Parsed as Gsync-" +                                "skave:key=%s,value:%s", key, value); +                } +                else {                          exists = glusterd_check_option_exists (key, NULL);                          if (exists == -1) {                                  ret = -1; diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c index 1c1873a6e9f..bd6a4ed0432 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -522,6 +522,14 @@ glusterd_volinfo_new (glusterd_volinfo_t **volinfo)                  goto out;          } +        new_volinfo->gsync_slaves = dict_new (); +        if (!new_volinfo->gsync_slaves) { +                if (new_volinfo) +                        GF_FREE (new_volinfo); + +                goto out; +        } +          *volinfo = new_volinfo;          ret = 0; diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h index 821a2ca46f2..9175983c7c9 100644 --- a/xlators/mgmt/glusterd/src/glusterd.h +++ b/xlators/mgmt/glusterd/src/glusterd.h @@ -206,6 +206,8 @@ struct glusterd_volinfo_ {          uuid_t                  volume_id;          char                    *logdir; + +        dict_t                  *gsync_slaves;  };  typedef struct glusterd_volinfo_ glusterd_volinfo_t;  | 
