diff options
Diffstat (limited to 'xlators/mgmt/glusterd/src')
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-geo-rep.c | 2687 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-handler.c | 2 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-hooks.c | 14 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-op-sm.c | 47 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-op-sm.h | 6 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-rpc-ops.c | 16 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-syncop.c | 165 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.c | 233 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.h | 20 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-volgen.h | 1 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd.c | 42 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd.h | 18 | 
12 files changed, 2677 insertions, 574 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-geo-rep.c b/xlators/mgmt/glusterd/src/glusterd-geo-rep.c index 6440efa153e..29a20f50760 100644 --- a/xlators/mgmt/glusterd/src/glusterd-geo-rep.c +++ b/xlators/mgmt/glusterd/src/glusterd-geo-rep.c @@ -25,6 +25,24 @@  #include <signal.h> +static int +dict_get_param (dict_t *dict, char *key, char **param); + +static int +glusterd_get_statefile_name (glusterd_volinfo_t *volinfo, char *slave, +                             char *conf_path, char **statefile); + +static int +glusterd_get_slave_details_confpath (glusterd_volinfo_t *volinfo, dict_t *dict, +                                     char **slave_ip, char **slave_vol, +                                     char **conf_path); + +static int +glusterd_get_slave_info (dict_t *dict, char **slave_ip, char **slave_vol); + +static int +glusterd_gsync_read_frm_status (char *path, char *buf, size_t blen); +  static char *gsync_reserved_opts[] = {          "gluster-command-dir",          "pid-file", @@ -41,6 +59,148 @@ static char *gsync_reserved_opts[] = {  };  int +__glusterd_handle_sys_exec (rpcsvc_request_t *req) +{ +        int32_t                 ret     = 0; +        dict_t                  *dict   = NULL; +        gf_cli_req              cli_req = {{0},}; +        glusterd_op_t           cli_op = GD_OP_SYS_EXEC; +        glusterd_conf_t         *priv   = NULL; +        char                    *host_uuid = NULL; +        char                    err_str[2048] = {0,}; +        xlator_t                *this = NULL; + +        GF_ASSERT (req); + +        this = THIS; +        GF_ASSERT (this); +        priv = this->private; +        GF_ASSERT (priv); + +        ret = xdr_to_generic (req->msg[0], &cli_req, +                              (xdrproc_t)xdr_gf_cli_req); +        if (ret < 0) { +                req->rpc_err = GARBAGE_ARGS; +                goto out; +        } + +        if (cli_req.dict.dict_len) { +                dict = dict_new (); +                if (!dict) +                        goto out; + + +                ret = dict_unserialize (cli_req.dict.dict_val, +                                        cli_req.dict.dict_len, +                                        &dict); +                if (ret < 0) { +                        gf_log (this->name, GF_LOG_ERROR, "failed to " +                                "unserialize req-buffer to dictionary"); +                        snprintf (err_str, sizeof (err_str), "Unable to decode " +                                  "the command"); +                        goto out; +               } else { +                        dict->extra_stdfree = cli_req.dict.dict_val; +                } + +                host_uuid = gf_strdup (uuid_utoa(MY_UUID)); +                if (host_uuid == NULL) { +                        snprintf (err_str, sizeof (err_str), "Failed to get " +                                  "the uuid of local glusterd"); +                        ret = -1; +                        goto out; +                } + +                ret = dict_set_dynstr (dict, "host-uuid", host_uuid); +                if (ret) +                        goto out; +        } + +        ret = glusterd_op_begin_synctask (req, cli_op, dict); + +out: +        if (ret) { +                if (err_str[0] == '\0') +                        snprintf (err_str, sizeof (err_str), +                                  "Operation failed"); +                ret = glusterd_op_send_cli_response (cli_op, ret, 0, req, +                                                     dict, err_str); +        } +        return ret; +} + +int +__glusterd_handle_copy_file (rpcsvc_request_t *req) +{ +        int32_t                 ret     = 0; +        dict_t                  *dict   = NULL; +        gf_cli_req              cli_req = {{0},}; +        glusterd_op_t           cli_op = GD_OP_COPY_FILE; +        glusterd_conf_t         *priv   = NULL; +        char                    *host_uuid = NULL; +        char                    err_str[2048] = {0,}; +        xlator_t                *this = NULL; + +        GF_ASSERT (req); + +        this = THIS; +        GF_ASSERT (this); +        priv = this->private; +        GF_ASSERT (priv); + +        ret = xdr_to_generic (req->msg[0], &cli_req, +                              (xdrproc_t)xdr_gf_cli_req); +        if (ret < 0) { +                req->rpc_err = GARBAGE_ARGS; +                goto out; +        } + +        if (cli_req.dict.dict_len) { +                dict = dict_new (); +                if (!dict) +                        goto out; + + +                ret = dict_unserialize (cli_req.dict.dict_val, +                                        cli_req.dict.dict_len, +                                        &dict); +                if (ret < 0) { +                        gf_log (this->name, GF_LOG_ERROR, "failed to " +                                "unserialize req-buffer to dictionary"); +                        snprintf (err_str, sizeof (err_str), "Unable to decode " +                                  "the command"); +                        goto out; +               } else { +                        dict->extra_stdfree = cli_req.dict.dict_val; +                } + +                host_uuid = gf_strdup (uuid_utoa(MY_UUID)); +                if (host_uuid == NULL) { +                        snprintf (err_str, sizeof (err_str), "Failed to get " +                                  "the uuid of local glusterd"); +                        ret = -1; +                        goto out; +                } + +                ret = dict_set_dynstr (dict, "host-uuid", host_uuid); +                if (ret) +                        goto out; +        } + +        ret = glusterd_op_begin_synctask (req, cli_op, dict); + +out: +        if (ret) { +                if (err_str[0] == '\0') +                        snprintf (err_str, sizeof (err_str), +                                  "Operation failed"); +                ret = glusterd_op_send_cli_response (cli_op, ret, 0, req, +                                                     dict, err_str); +        } +        return ret; +} + +int  __glusterd_handle_gsync_set (rpcsvc_request_t *req)  {          int32_t                 ret     = 0; @@ -104,13 +264,13 @@ __glusterd_handle_gsync_set (rpcsvc_request_t *req)          ret = dict_get_str (dict, "master", &master);          if (ret < 0) {                  gf_log (this->name, GF_LOG_INFO, "master not found, while " -                        "handling"GEOREP" options"); +                        "handling "GEOREP" options");                  master = "(No Master)";          }          ret = dict_get_str (dict, "slave", &slave);          if (ret < 0) { -                gf_log (this->name, GF_LOG_INFO, "slave not not found, while" +                gf_log (this->name, GF_LOG_INFO, "slave not found, while"                          "handling "GEOREP" options");                  slave = "(No Slave)";          } @@ -124,6 +284,10 @@ __glusterd_handle_gsync_set (rpcsvc_request_t *req)          }          switch (type) { +        case GF_GSYNC_OPTION_TYPE_CREATE: +                strncpy (operation, "create", sizeof (operation)); +                cli_op = GD_OP_GSYNC_CREATE; +                break;          case GF_GSYNC_OPTION_TYPE_START:                  strncpy (operation, "start", sizeof (operation)); @@ -140,12 +304,9 @@ __glusterd_handle_gsync_set (rpcsvc_request_t *req)          case GF_GSYNC_OPTION_TYPE_STATUS:                  strncpy (operation, "status", sizeof (operation));                  break; -        case GF_GSYNC_OPTION_TYPE_ROTATE: -                strncpy (operation, "rotate", sizeof(operation)); -                break;          } -        ret = glusterd_op_begin_synctask (req, GD_OP_GSYNC_SET, dict); +        ret = glusterd_op_begin_synctask (req, cli_op, dict);  out:          if (ret) { @@ -158,6 +319,17 @@ out:          return ret;  } +int +glusterd_handle_sys_exec (rpcsvc_request_t *req) +{ +        return glusterd_big_locked_handler (req, __glusterd_handle_sys_exec); +} + +int +glusterd_handle_copy_file (rpcsvc_request_t *req) +{ +        return glusterd_big_locked_handler (req, __glusterd_handle_copy_file); +}  int  glusterd_handle_gsync_set (rpcsvc_request_t *req) @@ -448,7 +620,7 @@ _fcbk_conftodict (char *resbuf, size_t blen, FILE *fp, void *data)  }  static int -glusterd_gsync_get_config (char *master, char *slave, char *gl_workdir, dict_t *dict) +glusterd_gsync_get_config (char *master, char *slave, char *conf_path, dict_t *dict)  {          /* key + value, where value must be able to accommodate a path */          char resbuf[256 + PATH_MAX] = {0,}; @@ -456,7 +628,7 @@ glusterd_gsync_get_config (char *master, char *slave, char *gl_workdir, dict_t *          runinit (&runner);          runner_add_args  (&runner, GSYNCD_PREFIX"/gsyncd", "-c", NULL); -        runner_argprintf (&runner, "%s/"GSYNC_CONF, gl_workdir); +        runner_argprintf (&runner, "%s", conf_path);          runner_argprintf (&runner, ":%s", master);          runner_add_args  (&runner, slave, "--config-get-all", NULL); @@ -466,13 +638,13 @@ glusterd_gsync_get_config (char *master, char *slave, char *gl_workdir, dict_t *  static int  glusterd_gsync_get_param_file (char *prmfile, const char *param, char *master, -                               char *slave, char *gl_workdir) +                               char *slave, char *conf_path)  {          runner_t            runner = {0,};          runinit (&runner);          runner_add_args  (&runner, GSYNCD_PREFIX"/gsyncd", "-c", NULL); -        runner_argprintf (&runner, "%s/"GSYNC_CONF, gl_workdir); +        runner_argprintf (&runner, "%s", conf_path);          runner_argprintf (&runner, ":%s", master);          runner_add_args  (&runner, slave, "--config-get", NULL);          runner_argprintf (&runner, "%s-file", param); @@ -481,83 +653,14 @@ glusterd_gsync_get_param_file (char *prmfile, const char *param, char *master,  }  static int -glusterd_gsync_get_session_owner (char *master, char *slave, char *session_owner, -                                  char *gl_workdir) -{ -        runner_t runner = {0,}; - -        runinit(&runner); -        runner_add_args  (&runner, GSYNCD_PREFIX"/gsyncd", "-c", NULL); -        runner_argprintf (&runner, "%s/"GSYNC_CONF, gl_workdir); -        runner_argprintf (&runner, ":%s", master); -        runner_add_args  (&runner, slave, "--config-get", "session-owner", -                          NULL); - -        return glusterd_query_extutil (session_owner, &runner); -} - -/* check whether @slave is local or remote. normalized - * urls starting with ssh are considered to be remote - * @returns - *    1 if slave is remote - *    0 is slave is local - */ -static int -glusterd_gsync_slave_is_remote (char *slave) -{ -        int   ret     = 0; -        char *ssh_pos = NULL; - -        ssh_pos = strstr(slave, "ssh://"); -        if ( ssh_pos && ((ssh_pos - slave) == 0) ) -                ret = 1; - -        return ret; -} - -static int -glusterd_gsync_get_slave_log_file (char *master, char *slave, char *log_file) -{ -        int              ret        = -1; -        runner_t         runner     = {0,}; -        char uuid_str[64]           = {0,}; -        glusterd_conf_t *priv       = NULL; -        char            *gl_workdir = NULL; - -        GF_ASSERT(THIS); -        GF_ASSERT(THIS->private); - -        priv = THIS->private; - -        GF_VALIDATE_OR_GOTO("gsyncd", master, out); -        GF_VALIDATE_OR_GOTO("gsyncd", slave, out); - -        gl_workdir = priv->workdir; - -        /* get the session owner for the master-slave session */ -        ret = glusterd_gsync_get_session_owner (master, slave, uuid_str, -                                                gl_workdir); -        if (ret) -                goto out; - -        /* get the log file for the slave */ -        runinit(&runner); -        runner_add_args  (&runner, GSYNCD_PREFIX"/gsyncd", "-c", NULL); -        runner_argprintf (&runner, "%s/"GSYNC_CONF, gl_workdir); -        runner_argprintf (&runner, "--session-owner=%s", uuid_str); -        runner_add_args  (&runner, slave, "--config-get", "log-file", NULL); - -        ret = glusterd_query_extutil (log_file, &runner); - - out: -        return ret; -} - -static int -gsyncd_getpidfile (char *master, char *slave, char *pidfile) +gsyncd_getpidfile (char *master, char *slave, char *pidfile, char *conf_path)  {          int                ret             = -1;          glusterd_conf_t    *priv  = NULL; +        char               *confpath = NULL; +        char                conf_buf[PATH_MAX] = ""; +        struct stat         stbuf = {0,}; +          GF_ASSERT (THIS);          GF_ASSERT (THIS->private); @@ -567,8 +670,22 @@ gsyncd_getpidfile (char *master, char *slave, char *pidfile)          GF_VALIDATE_OR_GOTO ("gsync", master, out);          GF_VALIDATE_OR_GOTO ("gsync", slave, out); +        ret = lstat (conf_path, &stbuf); +        if (!ret) { +                gf_log ("", GF_LOG_DEBUG, "Using passed config template(%s).", +                        conf_path); +                confpath = conf_path; +        } else { +                ret = snprintf (conf_buf, sizeof(conf_buf) - 1, +                                "%s/"GSYNC_CONF_TEMPLATE, priv->workdir); +                conf_buf[ret] = '\0'; +                confpath = conf_buf; +                gf_log ("", GF_LOG_DEBUG, "Using default config template(%s).", +                        confpath); +        } +          ret = glusterd_gsync_get_param_file (pidfile, "pid", master, -                                              slave, priv->workdir); +                                              slave, confpath);          if (ret == -1) {                  ret = -2;                  gf_log ("", GF_LOG_WARNING, "failed to create the pidfile string"); @@ -582,32 +699,6 @@ gsyncd_getpidfile (char *master, char *slave, char *pidfile)  }  static int -glusterd_gsyncd_getlogfile (char *master, char *slave, char *log_file) -{ -        int                ret             = -1; -        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); - -        ret = glusterd_gsync_get_param_file (log_file, "log", master, -                                              slave, priv->workdir); -        if (ret == -1) { -                ret = -2; -                gf_log ("", GF_LOG_WARNING, "failed to gsyncd logfile"); -                goto out; -        } - - out: -        return ret; -} - -static int  gsync_status_byfd (int fd)  {          GF_ASSERT (fd >= -1); @@ -624,12 +715,12 @@ gsync_status_byfd (int fd)   * return -1 when not running   */  int -gsync_status (char *master, char *slave, int *status) +gsync_status (char *master, char *slave, char *conf_path, int *status)  {          char pidfile[PATH_MAX] = {0,};          int  fd                = -1; -        fd = gsyncd_getpidfile (master, slave, pidfile); +        fd = gsyncd_getpidfile (master, slave, pidfile, conf_path);          if (fd == -2)                  return -1; @@ -666,10 +757,38 @@ out:  }  static int -gsync_verify_config_options (dict_t *dict, char **op_errstr) +glusterd_verify_gsyncd_spawn (char *master, char *slave) +{ +        int                 ret = 0; +        runner_t            runner = {0,}; + +        runinit (&runner); +        runner_add_args (&runner, GSYNCD_PREFIX"/gsyncd", +                         "--verify", "spawning", NULL); +        runner_argprintf (&runner, ":%s", master); +        runner_add_args  (&runner, slave, NULL); +        runner_redir (&runner, STDOUT_FILENO, RUN_PIPE); +        ret = runner_start (&runner); +        if (ret) { +                gf_log ("", GF_LOG_ERROR, "spawning child failed"); +                ret = -1; +                goto out; +        } + +        if (runner_end (&runner) != 0) +                ret = -1; + +out: +        gf_log ("", GF_LOG_DEBUG, "returning %d", ret); +        return ret; +} + +static int +gsync_verify_config_options (dict_t *dict, char **op_errstr, char *volname)  {          char  **resopt    = NULL;          int     i         = 0; +        int     ret       = -1;          char   *subop     = NULL;          char   *slave     = NULL;          char   *op_name   = NULL; @@ -699,6 +818,12 @@ gsync_verify_config_options (dict_t *dict, char **op_errstr)          }          if (runcmd (GSYNCD_PREFIX"/gsyncd", "--config-check", op_name, NULL)) { +                ret = glusterd_verify_gsyncd_spawn (volname, slave); +                if (ret) { +                        gf_log ("", GF_LOG_ERROR, "Unable to spawn gsyncd"); +                        return 0; +                } +                  gf_log ("", GF_LOG_WARNING, "Invalid option %s", op_name);                  *op_errstr = gf_strdup ("Invalid option"); @@ -748,30 +873,76 @@ gsync_verify_config_options (dict_t *dict, char **op_errstr)  static int  glusterd_get_gsync_status_mst_slv (glusterd_volinfo_t *volinfo, -                                   char *slave, dict_t *rsp_dict, char *node); +                                   char *slave, char *conf_path, +                                   dict_t *rsp_dict, char *node);  static int  _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                          *slave_buf = NULL; +        char                          *slave_vol = NULL; +        char                          *tmp       = NULL; +        char                          *save_ptr  = NULL; +        char                           conf_path[PATH_MAX] = ""; +        int                           ret = -1; +        glusterd_conf_t              *priv = NULL;          param = (glusterd_gsync_status_temp_t *)data;          GF_ASSERT (param);          GF_ASSERT (param->volinfo); +        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) +        if (slave) {                  slave ++; -        else +                slave_buf = gf_strdup (slave); +                if (!slave_buf) { +                        gf_log ("", GF_LOG_ERROR, +                                "Failed to gf_strdup"); +                        ret = -1; +                        goto out; +                } +        } else                  return 0; +        tmp  = strtok_r (slave_buf, ":", &save_ptr); +        while (tmp) { +                slave_vol = tmp; +                tmp  = strtok_r (NULL, ":", &save_ptr); +        } + +        if (!slave_vol) { +                gf_log ("", GF_LOG_ERROR, "Invalid slave name"); +                ret = -1; +                goto out; +        } + +        ret = snprintf (conf_path, sizeof(conf_path) - 1, +                        "%s/"GEOREP"/%s-%s/gsyncd.conf", +                        priv->workdir, param->volinfo->volname, +                        slave_vol); +        conf_path[ret] = '\0'; +          ret = glusterd_get_gsync_status_mst_slv(param->volinfo, -                                                slave, param->rsp_dict, +                                                slave, conf_path, +                                                param->rsp_dict,                                                  param->node); -        return 0; +out: + +        if (slave_buf) +                GF_FREE(slave_buf); + +        gf_log ("", GF_LOG_DEBUG, "Returning %d.", ret); +        return ret;  } @@ -792,19 +963,22 @@ static int  glusterd_remove_slave_in_info (glusterd_volinfo_t *volinfo, char *slave,                                 char **op_errstr)  { +        int   zero_slave_entries = _gf_true;          int   ret = 0;          char *slavekey = NULL;          GF_ASSERT (volinfo);          GF_ASSERT (slave); -        ret = glusterd_get_slave (volinfo, slave, &slavekey); -        if (ret < 0) { -                ret++; -                goto out; -        } - -        dict_del (volinfo->gsync_slaves, slavekey); +        do { +                ret = glusterd_get_slave (volinfo, slave, &slavekey); +                if (ret < 0 && zero_slave_entries) { +                        ret++; +                        goto out; +                } +                zero_slave_entries = _gf_false; +                dict_del (volinfo->gsync_slaves, slavekey); +        } while (ret >= 0);          ret = glusterd_store_volinfo (volinfo,                                        GLUSTERD_VOLINFO_VER_AC_INCREMENT); @@ -859,6 +1033,7 @@ glusterd_gsync_get_uuid (char *slave, glusterd_volinfo_t *vol,  static int  glusterd_check_gsync_running_local (char *master, char *slave, +                                    char *conf_path,                                      gf_boolean_t *is_run)  {          int                 ret    = -1; @@ -869,7 +1044,7 @@ glusterd_check_gsync_running_local (char *master, char *slave,          GF_ASSERT (is_run);          *is_run = _gf_false; -        ret = gsync_status (master, slave, &ret_status); +        ret = gsync_status (master, slave, conf_path, &ret_status);          if (ret == 0 && ret_status == 0) {                  *is_run = _gf_true;          } else if (ret == -1) { @@ -886,7 +1061,8 @@ glusterd_check_gsync_running_local (char *master, char *slave,  static int  glusterd_store_slave_in_info (glusterd_volinfo_t *volinfo, char *slave, -                              char *host_uuid, char **op_errstr) +                              char *host_uuid, char **op_errstr, +                              gf_boolean_t is_force)  {          int    ret = 0;          int    maxslv = 0; @@ -909,7 +1085,8 @@ glusterd_store_slave_in_info (glusterd_volinfo_t *volinfo, char *slave,          case -1:                                  break;          default: -                GF_ASSERT (ret > 0); +                if (!is_force) +                        GF_ASSERT (ret > 0);                  ret = dict_get_str (volinfo->gsync_slaves, slavekey, &slaveentry);                  GF_ASSERT (ret == 0); @@ -918,13 +1095,23 @@ glusterd_store_slave_in_info (glusterd_volinfo_t *volinfo, char *slave,                   * assert an uuid mismatch                   */                  t = strtail (slaveentry, host_uuid); -                GF_ASSERT (!t || *t != ':'); +                if (!is_force) +                        GF_ASSERT (!t || *t != ':'); + +                if (is_force) { +                        gf_log ("", GF_LOG_DEBUG, GEOREP" has already been " +                                "invoked for the %s (master) and %s (slave)." +                                " Allowing without saving info again due to" +                                " force command.", volinfo->volname, slave); +                        ret = 0; +                        goto out; +                }                  gf_log ("", GF_LOG_ERROR, GEOREP" has already been invoked for "                                            "the %s (master) and %s (slave) "                                            "from a different machine",                                             volinfo->volname, slave); -                *op_errstr = gf_strdup (GEOREP" already running in an an" +                *op_errstr = gf_strdup (GEOREP" already running in "                                          "another machine");                  ret = -1;                  goto out; @@ -957,23 +1144,26 @@ glusterd_store_slave_in_info (glusterd_volinfo_t *volinfo, char *slave,          return ret;  } -  static int  glusterd_op_verify_gsync_start_options (glusterd_volinfo_t *volinfo, -                                        char *slave, char **op_errstr) +                                        char *slave, char *conf_path, +                                        char *statefile, char **op_errstr, +                                        gf_boolean_t is_force)  {          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; +        glusterd_conf_t        *priv = NULL; +        xlator_t               *this = NULL; +        struct stat             stbuf = {0,};          this = THIS;          GF_ASSERT (volinfo);          GF_ASSERT (slave);          GF_ASSERT (op_errstr); +        GF_ASSERT (conf_path);          GF_ASSERT (this && this->private);          priv  = this->private; @@ -983,26 +1173,56 @@ glusterd_op_verify_gsync_start_options (glusterd_volinfo_t *volinfo,                            "before "GEOREP" start", volinfo->volname);                  goto out;          } + +        ret = lstat (statefile, &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_log ("", GF_LOG_ERROR, "%s", msg); +                *op_errstr = gf_strdup (msg); +                goto out; +        } + +        /* Check if the gsync slave info is stored. If not +         * session has not been created */ +        ret = glusterd_gsync_get_uuid (slave, volinfo, uuid); +        if (ret) { +                snprintf (msg, sizeof (msg), "Session between %s and %s has" +                          " not been created. Please create session and retry.", +                          volinfo->volname, slave); +                gf_log ("", GF_LOG_ERROR, "%s", msg); +                goto out; +        } + +        if (is_force) { +                ret = 0; +                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 (slave, volinfo, uuid); -        if ((ret == 0) && (uuid_compare (MY_UUID, uuid) == 0)) { -                ret = glusterd_check_gsync_running_local (volinfo->volname, -                                                          slave, &is_running); -                if (ret) { -                        snprintf (msg, sizeof (msg), GEOREP" start option " -                                  "validation failed "); -                        goto out; -                } -                if (_gf_true == is_running) { -                        snprintf (msg, sizeof (msg), GEOREP " session between" -                                  " %s & %s already started", volinfo->volname, -                                  slave); -                        ret = -1; -                        goto out; -                } +        ret = glusterd_check_gsync_running_local (volinfo->volname, +                                                  slave, conf_path, +                                                  &is_running); +        if (ret) { +                snprintf (msg, sizeof (msg), GEOREP" start option " +                          "validation failed "); +                goto out; +        } +        if (_gf_true == is_running) { +                snprintf (msg, sizeof (msg), GEOREP " session between" +                          " %s & %s already started", volinfo->volname, +                          slave); +                ret = -1; +                goto out; +        } + +        ret = glusterd_verify_gsyncd_spawn (volinfo->volname, slave); +        if (ret) { +                snprintf (msg, sizeof (msg), "Unable to spawn gsyncd"); +                gf_log ("", GF_LOG_ERROR, "%s", msg);          } -        ret = 0;  out:          if (ret && (msg[0] != '\0')) {                  *op_errstr = gf_strdup (msg); @@ -1028,11 +1248,13 @@ glusterd_check_gsync_running (glusterd_volinfo_t *volinfo, gf_boolean_t *flag)  static int  glusterd_op_verify_gsync_running (glusterd_volinfo_t *volinfo, -                                  char *slave, char **op_errstr) +                                  char *slave, char *conf_path, +                                  char **op_errstr)  { -        int                     ret = -1; -        char                    msg[2048] = {0}; -        uuid_t                  uuid = {0}; +        int        pfd               = -1; +        int        ret               = -1; +        char       msg[2048]         = {0}; +        char       pidfile[PATH_MAX] = {0,};          GF_ASSERT (THIS && THIS->private);          GF_ASSERT (volinfo); @@ -1045,12 +1267,25 @@ glusterd_op_verify_gsync_running (glusterd_volinfo_t *volinfo,                  goto out;          } -        ret = glusterd_gsync_get_uuid (slave, volinfo, uuid); -        if (ret == -1) { -                snprintf (msg, sizeof (msg), GEOREP" session between %s & %s" -                          " not active", volinfo->volname, slave); + +        pfd = gsyncd_getpidfile (volinfo->volname, slave, pidfile, conf_path); +        if (pfd == -2) { +                gf_log ("", GF_LOG_ERROR, GEOREP" stop validation " +                        "failed for %s & %s", volinfo->volname, slave); +                ret = -1;                  goto out;          } +        if (gsync_status_byfd (pfd) == -1) { +                snprintf (msg, sizeof (msg), GEOREP" session b/w %s & %s is not" +                          " running on this node.", volinfo->volname, slave); +                gf_log ("", GF_LOG_ERROR, "%s", msg); +                ret = -1; +                /* monitor gsyncd already dead */ +                goto out; +        } + +        if (pfd < 0) +                goto out;          ret = 0;  out: @@ -1070,6 +1305,18 @@ glusterd_verify_gsync_status_opts (dict_t *dict, char **op_errstr)          gf_boolean_t       exists = _gf_false;          glusterd_volinfo_t *volinfo = NULL;          int                ret = 0; +        char               *conf_path = NULL; +        char               *slave_ip = NULL; +        char               *slave_vol = NULL; +        glusterd_conf_t    *priv = NULL; + +        if (THIS) +                priv = THIS->private; +        if (priv == NULL) { +                gf_log ("", GF_LOG_ERROR, "priv of glusterd not present"); +                *op_errstr = gf_strdup ("glusterd defunct"); +                goto out; +        }          ret = dict_get_str (dict, "master", &volname);          if (ret < 0) { @@ -1094,7 +1341,17 @@ glusterd_verify_gsync_status_opts (dict_t *dict, char **op_errstr)                  goto out;          } - out: +        ret = glusterd_get_slave_details_confpath (volinfo, dict, &slave_ip, +                                                   &slave_vol, &conf_path); +        if (ret) { +                snprintf (errmsg, sizeof (errmsg), +                          "Unable to fetch slave  or confpath details."); +                gf_log ("", GF_LOG_ERROR, "%s", errmsg); +                ret = -1; +                goto out; +        } + +out:          gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);          return ret; @@ -1103,7 +1360,7 @@ glusterd_verify_gsync_status_opts (dict_t *dict, char **op_errstr)  int  glusterd_op_gsync_args_get (dict_t *dict, char **op_errstr, -                            char **master, char **slave) +                            char **master, char **slave, char **host_uuid)  {          int             ret = -1; @@ -1128,9 +1385,460 @@ glusterd_op_gsync_args_get (dict_t *dict, char **op_errstr,                  }          } +        if (host_uuid) { +                ret = dict_get_str (dict, "host-uuid", host_uuid); +                if (ret < 0) { +                        gf_log ("", GF_LOG_WARNING, "host_uuid not found"); +                        *op_errstr = gf_strdup ("host_uuid not found"); +                        goto out; +                } +        } + +        ret = 0; +out: +        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); +        return ret; +} + +int +glusterd_op_stage_sys_exec (dict_t *dict, char **op_errstr) +{ +        char             errmsg[PATH_MAX]          = ""; +        char            *command                   = NULL; +        char             command_path[PATH_MAX]    = ""; +        struct stat      st                        = {0,}; +        int              ret                       = -1; + +        ret = dict_get_str (dict, "command", &command); +        if (ret) { +                strcpy (errmsg, "internal error"); +                gf_log ("", GF_LOG_ERROR, +                        "Unable to get command from dict"); +                goto out; +        } + +        /* enforce local occurrence of the command */ +        if (strchr (command, '/')) { +                strcpy (errmsg, "invalid command name"); +                ret = -1; +                goto out; +        } + +        sprintf (command_path, GSYNCD_PREFIX"/peer_%s", command); +        /* check if it's executable */ +        ret = access (command_path, X_OK); +        if (!ret) +                /* check if it's a regular file */ +                ret = stat (command_path, &st); +        if (!ret && !S_ISREG (st.st_mode)) +                ret = -1; + +out: +        if (ret) { +                if (errmsg[0] == '\0') +                        snprintf (errmsg, sizeof (errmsg), "%s not found.", +                                  command); +                *op_errstr = gf_strdup (errmsg); +                gf_log ("", GF_LOG_ERROR, "%s", errmsg); +        } + +        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); +        return ret; +} + +int +glusterd_op_stage_copy_file (dict_t *dict, char **op_errstr) +{ +        char             abs_filename[PATH_MAX] = ""; +        char             errmsg[PATH_MAX]       = ""; +        char            *filename               = NULL; +        char            *host_uuid              = NULL; +        char             uuid_str [64]          = {0}; +        int              ret                    = -1; +        glusterd_conf_t *priv                   = NULL; +        struct stat      stbuf                  = {0,}; + +        if (THIS) +                priv = THIS->private; +        if (priv == NULL) { +                gf_log ("", GF_LOG_ERROR, "priv of glusterd not present"); +                *op_errstr = gf_strdup ("glusterd defunct"); +                goto out; +        } + +        ret = dict_get_str (dict, "host-uuid", &host_uuid); +        if (ret < 0) { +                gf_log ("", GF_LOG_ERROR, "Unable to fetch" +                        " host-uuid from dict."); +                goto out; +        } + +        uuid_utoa_r (MY_UUID, uuid_str); +        if (!strcmp (uuid_str, host_uuid)) { +                ret = dict_get_str (dict, "source", &filename); +                if (ret < 0) { +                        gf_log ("", GF_LOG_ERROR, "Unable to fetch" +                                " filename from dict."); +                        *op_errstr = gf_strdup ("command unsuccessful"); +                        goto out; +                } +                snprintf (abs_filename, sizeof(abs_filename), +                          "%s/%s", priv->workdir, filename); + +                ret = lstat (abs_filename, &stbuf); +                if (ret) { +                        snprintf (errmsg, sizeof (errmsg), "Source file" +                                  " does not exist in %s", priv->workdir); +                        *op_errstr = gf_strdup (errmsg); +                        goto out; +                } + +                if (!S_ISREG(stbuf.st_mode)) { +                        snprintf (errmsg, sizeof (errmsg), "Source file" +                                 " is not a regular file."); +                        *op_errstr = gf_strdup (errmsg); +                        gf_log ("", GF_LOG_ERROR, "%s", errmsg); +                        ret = -1; +                        goto out; +                } +        } + +        ret = 0; +out: +        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); +        return ret; +} + +static int +glusterd_get_statefile_name (glusterd_volinfo_t *volinfo, char *slave, +                             char *conf_path, char **statefile) +{ +        glusterd_conf_t *priv = NULL; +        int              ret = -1; +        char            *master    = NULL; +        char            *buf       = NULL; +        dict_t          *confd = NULL; +        char            *confpath = NULL; +        char             conf_buf[PATH_MAX] = ""; +        struct stat      stbuf = {0,}; + +        GF_ASSERT (THIS); +        GF_ASSERT (THIS->private); +        GF_ASSERT (volinfo); + +        master = volinfo->volname; + +        confd = dict_new (); +        if (!confd) { +                gf_log ("", GF_LOG_ERROR, "Unable to create new dict"); +                goto out; +        } + +        priv = THIS->private; + +        ret = lstat (conf_path, &stbuf); +        if (!ret) { +                gf_log ("", GF_LOG_DEBUG, "Using passed config template(%s).", +                        conf_path); +                confpath = conf_path; +        } else { +                ret = snprintf (conf_buf, sizeof(conf_buf) - 1, +                                "%s/"GSYNC_CONF_TEMPLATE, priv->workdir); +                conf_buf[ret] = '\0'; +                confpath = conf_buf; +                gf_log ("", GF_LOG_DEBUG, "Using default config template(%s).", +                        confpath); +        } + +        ret = glusterd_gsync_get_config (master, slave, confpath, +                                         confd); +        if (ret) { +                gf_log ("", GF_LOG_ERROR, "Unable to get configuration data" +                        "for %s(master), %s(slave)", master, slave); +                goto out; + +        } + +        ret = dict_get_param (confd, "state_file", &buf); +        if (ret) { +                gf_log ("", GF_LOG_ERROR, "Unable to get state_file's name."); +                goto out; +        } + +        *statefile = gf_strdup(buf); +        if (!*statefile) { +                gf_log ("", GF_LOG_ERROR, "Unable to gf_strdup."); +                ret = -1; +                goto out; +        } + +        ret = 0; + out: +        if (confd) +                dict_destroy (confd); + +        gf_log ("", GF_LOG_DEBUG, "Returning %d ", ret); +        return ret; +} + +static int +glusterd_create_status_file (char *master, char *slave, +                             char *slave_vol, char *status) +{ +        int                ret    = -1; +        runner_t           runner = {0,}; +        glusterd_conf_t   *priv   = NULL; + +        if (THIS) +                priv = THIS->private; +        if (priv == NULL) { +                gf_log ("", GF_LOG_ERROR, "priv of glusterd not present"); +                goto out; +        } + +        if (!status) { +                gf_log ("", GF_LOG_ERROR, "Status Empty"); +                goto out; +        } +        gf_log ("", GF_LOG_DEBUG, "slave = %s", slave); + +        runinit (&runner); +        runner_add_args (&runner, GSYNCD_PREFIX"/gsyncd", "--create", +                         status, "-c", NULL); +        runner_argprintf (&runner, "%s/"GEOREP"/%s-%s/gsyncd.conf", +                          priv->workdir, master, slave_vol); +        runner_argprintf (&runner, ":%s", master); +        runner_add_args  (&runner, slave, NULL); +        synclock_unlock (&priv->big_lock); +        ret = runner_run (&runner); +        synclock_lock (&priv->big_lock); +        if (ret) { +                gf_log ("", GF_LOG_ERROR, "Creating status file failed."); +                ret = -1; +                goto out; +        } + +        ret = 0; +out: +        gf_log ("", GF_LOG_DEBUG, "returning %d", ret); +        return ret; +} + +static int +glusterd_verify_slave (char *volname, char *slave_ip, char *slave, +                       char **op_errstr) +{ +        int32_t         ret     = -1; +        runner_t        runner    = {0,}; +        glusterd_conf_t *priv   = NULL; +        char            log_file_path[PATH_MAX] = ""; +        char            buf[PATH_MAX]           = ""; + +        GF_ASSERT (volname); +        GF_ASSERT (slave_ip); +        GF_ASSERT (slave); + +        if (THIS) +                priv = THIS->private; +        if (priv == NULL) { +                gf_log ("", GF_LOG_ERROR, "priv of glusterd not present"); +                goto out; +        } + +        snprintf (log_file_path, sizeof(log_file_path), +                  DEFAULT_LOG_FILE_DIRECTORY"/create_verify_log"); + +        runinit (&runner); +        runner_add_args  (&runner, GSYNCD_PREFIX"/gverify.sh", NULL); +        runner_argprintf (&runner, "%s", volname); +        runner_argprintf (&runner, "%s", slave_ip); +        runner_argprintf (&runner, "%s", slave); +        runner_argprintf (&runner, "%s", log_file_path); +        runner_redir (&runner, STDOUT_FILENO, RUN_PIPE); +        synclock_unlock (&priv->big_lock); +        ret = runner_run (&runner); +        synclock_lock (&priv->big_lock); +        if (ret) { +                gf_log ("", GF_LOG_ERROR, "Not a valid slave"); +                ret = glusterd_gsync_read_frm_status (log_file_path, +                                                      buf, sizeof(buf)); +                if (ret) { +                        gf_log ("", GF_LOG_ERROR, "Unable to read from %s", +                                log_file_path); +                        goto out; +                } +                *op_errstr = gf_strdup (buf); +                ret = -1; +                goto out; +        } +        ret = 0; +out: +        unlink (log_file_path); +        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); +        return ret; +} + +int +glusterd_op_stage_gsync_create (dict_t *dict, char **op_errstr) +{ +        char               *down_peerstr              = NULL; +        char               *slave                     = NULL; +        char               *volname                   = NULL; +        char               *host_uuid                 = NULL; +        char               *statefile                 = NULL; +        char               *slave_ip                  = NULL; +        char               *slave_vol                 = NULL; +        char               *conf_path                 = NULL; +        char                errmsg[PATH_MAX]          = ""; +        char                common_pem_file[PATH_MAX] = ""; +        char                uuid_str [64]             = ""; +        int                 ret                       = -1; +        int                 is_pem_push               = -1; +        gf_boolean_t        is_force                  = -1; +        gf_boolean_t        exists                    = _gf_false; +        glusterd_conf_t    *conf                      = NULL; +        glusterd_volinfo_t *volinfo                   = NULL; +        struct stat         stbuf                     = {0,}; +        xlator_t           *this                      = NULL; + +        this = THIS; +        GF_ASSERT (this); +        conf = this->private; +        GF_ASSERT (conf); + +        ret = glusterd_op_gsync_args_get (dict, op_errstr, &volname, +                                          &slave, &host_uuid); +        if (ret) { +                gf_log ("", GF_LOG_ERROR, "Unable to fetch arguments"); +                gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); +                return -1; +        } + +        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); +                gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); +                return -1; +        } + +        is_force = dict_get_str_boolean (dict, "force", _gf_false); + +        ret = glusterd_get_slave_details_confpath (volinfo, dict, &slave_ip, +                                                   &slave_vol, &conf_path); +        if (ret) { +                snprintf (errmsg, sizeof (errmsg), +                          "Unable to fetch slave  or confpath details."); +                gf_log ("", GF_LOG_ERROR, "%s", errmsg); +                ret = -1; +                goto out; +        } + +        uuid_utoa_r (MY_UUID, uuid_str); +        if (!strcmp (uuid_str, host_uuid)) { +                ret = glusterd_are_vol_all_peers_up (volinfo, +                                                     &conf->peers, +                                                     &down_peerstr); +                if (ret == _gf_false) { +                        snprintf (errmsg, sizeof (errmsg), "Peer %s," +                                  " which is a part of %s volume, is" +                                  " down. Please bring up the peer and" +                                  " retry.", down_peerstr, +                                  volinfo->volname); +                        gf_log ("", GF_LOG_ERROR, "%s", errmsg); +                        *op_errstr = gf_strdup (errmsg); +                        GF_FREE (down_peerstr); +                        down_peerstr = NULL; +                        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); +                        return -1; +                } + +                ret = glusterd_verify_slave (volname, slave_ip, slave_vol, +                                             op_errstr); +                if (ret) { +                        gf_log ("", GF_LOG_ERROR, +                                "%s is not a valid slave volume.", +                                slave); +                        ret = -1; +                        goto out; +                } + +                ret = dict_get_int32 (dict, "push_pem", &is_pem_push); +                if (!ret && is_pem_push) { +                        snprintf (common_pem_file, sizeof(common_pem_file), +                                  "%s"GLUSTERD_COMMON_PEM_PUB_FILE, +                                  conf->workdir); + +                        ret = lstat (common_pem_file, &stbuf); +                        if (ret) { +                                snprintf (errmsg, sizeof (errmsg), "%s" +                                          " required for push-pem is" +                                          " not present.", common_pem_file); +                                gf_log ("", GF_LOG_ERROR, "%s", errmsg); +                                ret = -1; +                                goto out; +                        } + +                        if (!S_ISREG(stbuf.st_mode)) { +                                snprintf (errmsg, sizeof (errmsg), "%s" +                                          " required for push-pem is" +                                          " not a regular file.", +                                          common_pem_file); +                                gf_log ("", GF_LOG_ERROR, "%s", errmsg); +                                ret = -1; +                                goto out; +                        } +                } +        } + +        ret = glusterd_get_statefile_name (volinfo, slave, conf_path, &statefile); +        if (ret) { +                if (!strstr(slave, "::")) +                        snprintf (errmsg, sizeof (errmsg), +                                  "%s is not a valid slave url.", slave); +                else +                        snprintf (errmsg, sizeof (errmsg), "Unable to get " +                                  "statefile's name"); +                gf_log ("", GF_LOG_ERROR, "%s", errmsg); +                goto out; +        } + +        ret = lstat (statefile, &stbuf); +        if (!ret) { +                snprintf (errmsg, sizeof (errmsg), "Session between %s" +                          " and %s is already created.", +                          volinfo->volname, slave); +                gf_log ("", GF_LOG_ERROR, "%s", errmsg); +                ret = -1; +                goto out; +        } + +        ret = dict_set_str (dict, "statefile", statefile); +        if (ret) { +                gf_log ("", GF_LOG_ERROR, +                        "Unable to store statefile path"); +                goto out; +        } + +        ret = glusterd_verify_gsyncd_spawn (volinfo->volname, slave); +        if (ret) { +                snprintf (errmsg, sizeof (errmsg), "Unable to spawn gsyncd"); +                gf_log ("", GF_LOG_ERROR, "%s", errmsg); +                goto out; +        }          ret = 0;  out: + +        if (is_force) +                ret = 0; + +        if (ret && errmsg[0] != '\0') +                *op_errstr = gf_strdup (errmsg); +          gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);          return ret;  } @@ -1142,11 +1850,29 @@ glusterd_op_stage_gsync_set (dict_t *dict, char **op_errstr)          int                     type    = 0;          char                    *volname = NULL;          char                    *slave   = NULL; +        char                    *slave_ip = NULL; +        char                    *slave_vol = NULL; +        char                    *down_peerstr = NULL; +        char                    *statefile    = NULL; +        char                    *path_list    = NULL; +        char                    *conf_path    = NULL;          gf_boolean_t            exists   = _gf_false;          glusterd_volinfo_t      *volinfo = NULL;          char                    errmsg[PATH_MAX] = {0,};          dict_t                  *ctx = NULL; +        gf_boolean_t            is_force = 0; +        gf_boolean_t            is_running = _gf_false; +        uuid_t                  uuid = {0}; +        char                    uuid_str [64] = {0}; +        char                    *host_uuid = NULL; +        xlator_t                *this = NULL; +        glusterd_conf_t         *conf = NULL; +        struct stat             stbuf = {0,}; +        this = THIS; +        GF_ASSERT (this); +        conf = this->private; +        GF_ASSERT (conf);          ret = dict_get_int32 (dict, "type", &type);          if (ret < 0) { @@ -1155,23 +1881,13 @@ glusterd_op_stage_gsync_set (dict_t *dict, char **op_errstr)                  goto out;          } -        switch (type) { -        case GF_GSYNC_OPTION_TYPE_STATUS: +        if (type == GF_GSYNC_OPTION_TYPE_STATUS) {                  ret = glusterd_verify_gsync_status_opts (dict, op_errstr); - -                goto out; -        case GF_GSYNC_OPTION_TYPE_CONFIG: -                ret = gsync_verify_config_options (dict, op_errstr); - -                goto out; - -        case GF_GSYNC_OPTION_TYPE_ROTATE: -                /* checks same as status mode */ -                ret = glusterd_verify_gsync_status_opts(dict, op_errstr);                  goto out;          } -        ret = glusterd_op_gsync_args_get (dict, op_errstr, &volname, &slave); +        ret = glusterd_op_gsync_args_get (dict, op_errstr, +                                          &volname, &slave, NULL);          if (ret)                  goto out; @@ -1186,12 +1902,86 @@ glusterd_op_stage_gsync_set (dict_t *dict, char **op_errstr)                  goto out;          } +        ret = glusterd_get_slave_details_confpath (volinfo, dict, &slave_ip, +                                                   &slave_vol, &conf_path); +        if (ret) { +                snprintf (errmsg, sizeof (errmsg), +                          "Unable to fetch slave or confpath details."); +                gf_log ("", GF_LOG_ERROR, "%s", errmsg); +                ret = -1; +                goto out; +        } + +        ret = glusterd_get_statefile_name (volinfo, slave, conf_path, &statefile); +        if (ret) { +                if (!strstr(slave, "::")) +                        snprintf (errmsg, sizeof (errmsg), +                                  "%s is not a valid slave url.", slave); +                else +                        snprintf (errmsg, sizeof (errmsg), +                                  "Unable to get statefile's name"); +                gf_log ("", GF_LOG_ERROR, "%s", errmsg); +                ret = -1; +                goto out; +        } + +        ret = dict_set_str (dict, "statefile", statefile); +        if (ret) { +                gf_log ("", GF_LOG_ERROR, +                        "Unable to store statefile path"); +                goto out; +        } + +        if ((type == GF_GSYNC_OPTION_TYPE_CONFIG) || +            (type == GF_GSYNC_OPTION_TYPE_DELETE)) { +                ret = lstat (statefile, &stbuf); +                if (ret) { +                        snprintf (errmsg, sizeof(errmsg), "Geo-replication" +                                  " session between %s and %s does not exist.", +                                  volinfo->volname, slave); +                        gf_log ("", GF_LOG_ERROR, "%s. statefile = %s", +                                errmsg, statefile); +                        *op_errstr = gf_strdup (errmsg); +                        ret = -1; +                        goto out; +                } +        } + +        is_force = dict_get_str_boolean (dict, "force", _gf_false); + +        /* Check if all peers that are a part of the volume are up or not */ +        if ((type == GF_GSYNC_OPTION_TYPE_DELETE) || +            ((type == GF_GSYNC_OPTION_TYPE_STOP) && !is_force)) { +                ret = dict_get_str (dict, "host-uuid", &host_uuid); +                if (ret < 0) +                        goto out; + +                uuid_utoa_r (MY_UUID, uuid_str); +                if (!strcmp (uuid_str, host_uuid)) { +                        ret = glusterd_are_vol_all_peers_up (volinfo, +                                                             &conf->peers, +                                                             &down_peerstr); +                        if (ret == _gf_false) { +                                snprintf (errmsg, sizeof (errmsg), "Peer %s," +                                          " which is a part of %s volume, is" +                                          " down. Please bring up the peer and" +                                          " retry.", down_peerstr, +                                          volinfo->volname); +                                *op_errstr = gf_strdup (errmsg); +                                ret = -1; +                                GF_FREE (down_peerstr); +                                down_peerstr = NULL; +                                goto out; +                        } +                } +        } +          switch (type) {          case GF_GSYNC_OPTION_TYPE_START:                  /* don't attempt to start gsync if replace-brick is                   * in progress */                  if (glusterd_is_rb_ongoing (volinfo)) { -                        snprintf (errmsg, sizeof(errmsg),"replace-brick is in" +                        snprintf (errmsg, sizeof(errmsg), "replace-brick is in"                                     " progress, not starting geo-replication");                          *op_errstr = gf_strdup (errmsg);                          ret = -1; @@ -1199,16 +1989,18 @@ glusterd_op_stage_gsync_set (dict_t *dict, char **op_errstr)                  }                  ret = glusterd_op_verify_gsync_start_options (volinfo, slave, -                                                              op_errstr); +                                                              conf_path, statefile, +                                                              op_errstr, is_force);                  if (ret)                          goto out;                  ctx = glusterd_op_get_ctx();                  if (ctx) { -                        /*gsyncd does a fuse mount to start the geo-rep session*/ +                        /* gsyncd does a fuse mount to start +                         * the geo-rep session */                          if (!glusterd_is_fuse_available ()) { -                                gf_log ("glusterd", GF_LOG_ERROR, "Unable to open" -                                        " /dev/fuse (%s), geo-replication start" -                                        " failed", strerror (errno)); +                                gf_log ("glusterd", GF_LOG_ERROR, "Unable to " +                                        "open /dev/fuse (%s), geo-replication " +                                        "start failed", strerror (errno));                                  snprintf (errmsg, sizeof(errmsg),                                            "fuse unvailable");                                  *op_errstr = gf_strdup (errmsg); @@ -1219,17 +2011,72 @@ glusterd_op_stage_gsync_set (dict_t *dict, char **op_errstr)                  break;          case GF_GSYNC_OPTION_TYPE_STOP: -                ret = glusterd_op_verify_gsync_running (volinfo, slave, -                                                        op_errstr); +                if (!is_force) { +                        ret = glusterd_op_verify_gsync_running (volinfo, slave, +                                                                conf_path, +                                                                op_errstr); +                        if (ret) { +                                ret = glusterd_get_local_brickpaths (volinfo, +                                                                     &path_list); +                                if (path_list) +                                        ret = -1; +                        } +                } +                break; + +        case GF_GSYNC_OPTION_TYPE_CONFIG: +                ret = gsync_verify_config_options (dict, op_errstr, volname); +                goto out; +                break; + +        case GF_GSYNC_OPTION_TYPE_DELETE: +                /* Check if the gsync session is still running +                 * If so ask the user to stop geo-replication first.*/ +                ret = glusterd_gsync_get_uuid (slave, volinfo, uuid); +                if (ret) { +                        snprintf (errmsg, sizeof(errmsg), "Geo-replication" +                                  " session between %s and %s does not exist.", +                                  volinfo->volname, slave); +                        gf_log ("", GF_LOG_ERROR, "%s", errmsg); +                        *op_errstr = gf_strdup (errmsg); +                        ret = -1; +                        goto out; +                } else { +                        ret = glusterd_check_gsync_running_local (volinfo->volname, +                                                                  slave, conf_path, +                                                                  &is_running); +                        if (_gf_true == is_running) { +                                snprintf (errmsg, sizeof (errmsg), GEOREP +                                          " session between %s & %s is " +                                          "still active. Please stop the " +                                          "session and retry.", +                                          volinfo->volname, slave); +                                gf_log ("", GF_LOG_ERROR, "%s", errmsg); +                                *op_errstr = gf_strdup (errmsg); +                                ret = -1; +                                goto out; +                        } +                } + +                ret = glusterd_verify_gsyncd_spawn (volinfo->volname, slave); +                if (ret) { +                        snprintf (errmsg, sizeof (errmsg), +                                  "Unable to spawn gsyncd"); +                        *op_errstr = gf_strdup (errmsg); +                        gf_log ("", GF_LOG_ERROR, "%s", errmsg); +                } +                  break;          }  out: +        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);          return ret;  }  static int -stop_gsync (char *master, char *slave, char **msg) +stop_gsync (char *master, char *slave, char **msg, +            char *conf_path, gf_boolean_t is_force)  {          int32_t         ret     = 0;          int             pfd     = -1; @@ -1241,19 +2088,16 @@ stop_gsync (char *master, char *slave, char **msg)          GF_ASSERT (THIS);          GF_ASSERT (THIS->private); -        pfd = gsyncd_getpidfile (master, slave, pidfile); -        if (pfd == -2) { +        pfd = gsyncd_getpidfile (master, slave, pidfile, conf_path); +        if (pfd == -2 && !is_force) {                  gf_log ("", GF_LOG_ERROR, GEOREP" stop validation "                          " failed for %s & %s", master, slave);                  ret = -1;                  goto out;          } -        if (gsync_status_byfd (pfd) == -1) { +        if (gsync_status_byfd (pfd) == -1 && !is_force) {                  gf_log ("", GF_LOG_ERROR, "gsyncd b/w %s & %s is not"                          " running", master, slave); -                if (msg) -                        *msg = gf_strdup ("Warning: "GEOREP" session was " -                                          "defunct at stop time");                  /* monitor gsyncd already dead */                  goto out;          } @@ -1288,16 +2132,21 @@ stop_gsync (char *master, char *slave, char **msg)  out:          sys_close (pfd); + +        if (is_force) +                ret = 0;          return ret;  }  static int  glusterd_check_restart_gsync_session (glusterd_volinfo_t *volinfo, char *slave, -                                      dict_t *resp_dict); +                                      dict_t *resp_dict, char *path_list, +                                      char *conf_path, gf_boolean_t is_force);  static int  glusterd_gsync_configure (glusterd_volinfo_t *volinfo, char *slave, -                          dict_t *dict, dict_t *resp_dict, char **op_errstr) +                          char *path_list, dict_t *dict, +                          dict_t *resp_dict, char **op_errstr)  {          int32_t         ret     = -1;          char            *op_name = NULL; @@ -1306,6 +2155,9 @@ glusterd_gsync_configure (glusterd_volinfo_t *volinfo, char *slave,          glusterd_conf_t *priv   = NULL;          char            *subop  = NULL;          char            *master = NULL; +        char            *conf_path = NULL; +        char            *slave_vol = NULL; +        struct stat      stbuf     = {0, };          GF_ASSERT (slave);          GF_ASSERT (op_errstr); @@ -1340,10 +2192,17 @@ glusterd_gsync_configure (glusterd_volinfo_t *volinfo, char *slave,                  goto out;          } +        ret = dict_get_str (dict, "conf_path", &conf_path); +        if (ret) { +                gf_log ("", GF_LOG_ERROR, +                        "Unable to fetch conf file path."); +                goto out; +        } +          master = "";          runinit (&runner);          runner_add_args (&runner, GSYNCD_PREFIX"/gsyncd", "-c", NULL); -        runner_argprintf (&runner, "%s/"GSYNC_CONF, priv->workdir); +        runner_argprintf (&runner, "%s", conf_path);          if (volinfo) {                  master = volinfo->volname;                  runner_argprintf (&runner, ":%s", master); @@ -1366,13 +2225,39 @@ glusterd_gsync_configure (glusterd_volinfo_t *volinfo, char *slave,                  goto out;          } + +        if (!strcmp (op_name, "state_file")) { + +                ret = lstat (op_value, &stbuf); +                if (ret) { +                        ret = dict_get_str (dict, "slave_vol", &slave_vol); +                        if (ret) { +                                gf_log ("", GF_LOG_ERROR, +                                        "Unable to fetch slave volume name."); +                                goto out; +                        } + +                        ret = glusterd_create_status_file (volinfo->volname, slave, +                                                           slave_vol, +                                                           "Switching Status File"); +                        if (ret || lstat (op_value, &stbuf)) { +                                gf_log ("", GF_LOG_ERROR, "Unable to create %s" +                                        ". Error : %s", op_value, +                                        strerror (errno)); +                                ret = -1; +                                goto out; +                        } +                } +        } +          ret = 0;          gf_asprintf (op_errstr, "config-%s successful", subop);  out:          if (!ret && volinfo) {                  ret = glusterd_check_restart_gsync_session (volinfo, slave, -                                                            resp_dict); +                                                            resp_dict, path_list, +                                                            conf_path, 0);                  if (ret)                          *op_errstr = gf_strdup ("internal error");          } @@ -1498,12 +2383,13 @@ dict_get_param (dict_t *dict, char *key, char **param)  }  static int -glusterd_read_status_file (char *master, char *slave, -                           dict_t *dict, char *node) +glusterd_read_status_file (glusterd_volinfo_t *volinfo, char *slave, +                           char *conf_path, dict_t *dict, char *node)  {          glusterd_conf_t *priv = NULL;          int              ret = 0;          char            *statefile = NULL; +        char            *master    = NULL;          char             buf[1024] = {0, };          char             nds[1024] = {0, };          char             mst[1024] = {0, }; @@ -1514,16 +2400,21 @@ glusterd_read_status_file (char *master, char *slave,          int              gsync_count = 0;          int              status = 0;          char *dyn_node = NULL; +        char *path_list = NULL;          GF_ASSERT (THIS);          GF_ASSERT (THIS->private); +        GF_ASSERT (volinfo); + +        master = volinfo->volname;          confd = dict_new ();          if (!dict)                  return -1;          priv = THIS->private; -        ret = glusterd_gsync_get_config (master, slave, priv->workdir, + +        ret = glusterd_gsync_get_config (master, slave, conf_path,                                           confd);          if (ret) {                  gf_log ("", GF_LOG_ERROR, "Unable to get configuration data" @@ -1532,13 +2423,6 @@ glusterd_read_status_file (char *master, char *slave,          } -        ret = gsync_status (master, slave, &status); -        if (ret == 0 && status == -1) { -                strncpy (buf, "defunct", sizeof (buf)); -                goto done; -        } else if (ret == -1) -                goto out; -          ret = dict_get_param (confd, "state_file", &statefile);          if (ret)                  goto out; @@ -1549,7 +2433,17 @@ glusterd_read_status_file (char *master, char *slave,                  strncpy (buf, "defunct", sizeof (buf));                  goto done;          } -        if (strcmp (buf, "OK") != 0) + +        ret = gsync_status (master, slave, conf_path, &status); +        if (ret == 0 && status == -1) { +                if ((strcmp (buf, "Not Started")) && +                    (strcmp (buf, "Stopped"))) +                    strncpy (buf, "defunct", sizeof (buf)); +                goto done; +        } else if (ret == -1) +                goto out; + +        if (strcmp (buf, "Stable") != 0)                  goto done;          ret = dict_get_param (confd, "state_socket_unencoded", &statefile); @@ -1575,6 +2469,19 @@ glusterd_read_status_file (char *master, char *slave,          }   done: +        if ((!strcmp (buf, "defunct")) || +            (!strcmp (buf, "Not Started")) || +            (!strcmp (buf, "Stopped"))) { +                ret = glusterd_get_local_brickpaths (volinfo, &path_list); +                if (!path_list) { +                        gf_log ("", GF_LOG_DEBUG, "This node not being part of" +                                " volume should not be running gsyncd. Hence" +                                " shouldn't display status for this node."); +                        ret = 0; +                        goto out; +                } +        } +          ret = dict_get_int32 (dict, "gsync-count", &gsync_count);          if (ret) @@ -1635,13 +2542,14 @@ glusterd_read_status_file (char *master, char *slave,  static int  glusterd_check_restart_gsync_session (glusterd_volinfo_t *volinfo, char *slave, -                                      dict_t *resp_dict) +                                      dict_t *resp_dict, char *path_list, +                                      char *conf_path, gf_boolean_t is_force)  {          int                    ret = 0; -        uuid_t                 uuid = {0, };          glusterd_conf_t        *priv = NULL;          char                   *status_msg = NULL; +        gf_boolean_t           is_running = _gf_false;          GF_ASSERT (volinfo);          GF_ASSERT (slave); @@ -1650,18 +2558,22 @@ glusterd_check_restart_gsync_session (glusterd_volinfo_t *volinfo, char *slave,          priv = THIS->private; -        if (glusterd_gsync_get_uuid (slave, volinfo, uuid)) -                /* session does not exist, nothing to do */ +        ret = glusterd_check_gsync_running_local (volinfo->volname, +                                                  slave, conf_path, +                                                  &is_running); +        if (!ret && (_gf_true != is_running)) +                /* gsynd not running, nothing to do */                  goto out; -        if (uuid_compare (MY_UUID, uuid) == 0) { -                ret = stop_gsync (volinfo->volname, slave, &status_msg); -                if (ret == 0 && status_msg) -                        ret = dict_set_str (resp_dict, "gsync-status", -                                            status_msg); -                if (ret == 0) -                        ret = glusterd_start_gsync (volinfo, slave, -                                                    uuid_utoa(MY_UUID), NULL); -        } + +        ret = stop_gsync (volinfo->volname, slave, &status_msg, +                          conf_path, is_force); +        if (ret == 0 && status_msg) +                ret = dict_set_str (resp_dict, "gsync-status", +                                    status_msg); +        if (ret == 0) +                ret = glusterd_start_gsync (volinfo, slave, path_list, +                                            conf_path, uuid_utoa(MY_UUID), +                                            NULL);   out:          gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); @@ -1669,7 +2581,7 @@ glusterd_check_restart_gsync_session (glusterd_volinfo_t *volinfo, char *slave,  }  static int32_t -glusterd_marker_create_volfile (glusterd_volinfo_t *volinfo) +glusterd_marker_changelog_create_volfile (glusterd_volinfo_t *volinfo)  {          int32_t          ret     = 0; @@ -1693,58 +2605,73 @@ out:  }  static int -glusterd_set_marker_gsync (glusterd_volinfo_t *volinfo) +glusterd_set_gsync_knob (glusterd_volinfo_t *volinfo, char *key, int *vc)  { -        int                      ret     = -1; -        int                      marker_set = _gf_false; -        char                    *gsync_status = NULL; +        int   ret          = -1; +        int   conf_enabled = _gf_false; +        char *knob_on      = NULL;          GF_ASSERT (THIS);          GF_ASSERT (THIS->private); -        marker_set = glusterd_volinfo_get_boolean (volinfo, VKEY_MARKER_XTIME); -        if (marker_set == -1) { -                gf_log ("", GF_LOG_ERROR, "failed to get the marker status"); -                ret = -1; +        conf_enabled = glusterd_volinfo_get_boolean (volinfo, key); +        if (conf_enabled == -1) { +                gf_log ("", GF_LOG_ERROR, +                        "failed to get key %s from volinfo", key);                  goto out;          } -        if (marker_set == _gf_false) { -                gsync_status = gf_strdup ("on"); -                if (gsync_status == NULL) { +        ret = 0; +        if (conf_enabled == _gf_false) { +                *vc = 1; +                knob_on = gf_strdup ("on"); +                if (knob_on == NULL) {                          ret = -1;                          goto out;                  }                  ret = glusterd_gsync_volinfo_dict_set (volinfo, -                                                       VKEY_MARKER_XTIME, gsync_status); -                if (ret < 0) -                        goto out; - -                ret = glusterd_marker_create_volfile (volinfo); -                if (ret) { -                        gf_log ("", GF_LOG_ERROR, "Setting dict failed"); -                        goto out; -                } +                                                       key, knob_on);          } -        ret = 0; -out: + out:          gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);          return ret;  } +static int +glusterd_set_gsync_confs (glusterd_volinfo_t *volinfo) +{ +        int ret             = -1; +        int volfile_changed = 0; + +        ret = glusterd_set_gsync_knob (volinfo, +                                       VKEY_MARKER_XTIME, &volfile_changed); +        if (ret) +                goto out; + +        ret = glusterd_set_gsync_knob (volinfo, +                                       VKEY_CHANGELOG, &volfile_changed); +        if (ret) +                goto out; +        if (volfile_changed) +                ret = glusterd_marker_changelog_create_volfile (volinfo); + out: +        return ret; +}  static int  glusterd_get_gsync_status_mst_slv (glusterd_volinfo_t *volinfo, -                                   char *slave, dict_t *rsp_dict, -                                   char *node) +                                   char *slave, char *conf_path, +                                   dict_t *rsp_dict, char *node)  { +        char              *statefile = NULL;          uuid_t             uuid = {0, };          glusterd_conf_t    *priv = NULL;          int                ret = 0; +        struct stat        stbuf = {0, };          GF_ASSERT (volinfo);          GF_ASSERT (slave); @@ -1754,19 +2681,38 @@ glusterd_get_gsync_status_mst_slv (glusterd_volinfo_t *volinfo,          priv = THIS->private;          ret = glusterd_gsync_get_uuid (slave, volinfo, uuid); -        if ((ret == 0) && (uuid_compare (MY_UUID, uuid) != 0)) -                goto out; -          if (ret) { -                ret = 0;                  gf_log ("", GF_LOG_INFO, "geo-replication status %s %s :"                          "session is not active", volinfo->volname, slave); -                goto out; + +                ret = glusterd_get_statefile_name (volinfo, slave, +                                                   conf_path, &statefile); +                if (ret) { +                        if (!strstr(slave, "::")) +                                gf_log ("", GF_LOG_INFO, +                                        "%s is not a valid slave url.", slave); +                        else +                                gf_log ("", GF_LOG_INFO, "Unable to get" +                                        " statefile's name"); +                        ret = 0; +                        goto out; +                } + +                ret = lstat (statefile, &stbuf); +                if (ret) { +                        gf_log ("", GF_LOG_INFO, "%s statefile not present.", +                                statefile); +                        ret = 0; +                        goto out; +                }          } -        ret = glusterd_read_status_file (volinfo->volname, -                                         slave, rsp_dict, node); - out: +        ret = glusterd_read_status_file (volinfo, slave, conf_path, +                                         rsp_dict, node); +out: +        if (statefile) +                GF_FREE (statefile); +          gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);          return ret;  } @@ -1817,6 +2763,7 @@ glusterd_get_gsync_status (dict_t *dict, char **op_errstr, dict_t *rsp_dict)  {          char               *slave  = NULL;          char               *volname = NULL; +        char               *conf_path = NULL;          char               errmsg[PATH_MAX] = {0, };          gf_boolean_t       exists = _gf_false;          glusterd_volinfo_t *volinfo = NULL; @@ -1854,7 +2801,14 @@ glusterd_get_gsync_status (dict_t *dict, char **op_errstr, dict_t *rsp_dict)                  goto out;          } -        ret = glusterd_get_gsync_status_mst_slv (volinfo, slave, +        ret = dict_get_str (dict, "conf_path", &conf_path); +        if (ret) { +                gf_log ("", GF_LOG_ERROR, +                        "Unable to fetch conf file path."); +                goto out; +        } + +        ret = glusterd_get_gsync_status_mst_slv (volinfo, slave, conf_path,                                                   rsp_dict, my_hostname);   out: @@ -1863,300 +2817,405 @@ glusterd_get_gsync_status (dict_t *dict, char **op_errstr, dict_t *rsp_dict)  }  static int -glusterd_send_sigstop (pid_t pid) -{ -        int ret = 0; -        ret = kill (pid, SIGSTOP); -        if (ret) -                gf_log ("", GF_LOG_ERROR, GEOREP"failed to send SIGSTOP signal"); -        return ret; -} - -static int -glusterd_send_sigcont (pid_t pid) -{ -        int ret = 0; -        ret = kill (pid, SIGCONT); -        if (ret) -                gf_log ("", GF_LOG_ERROR, GEOREP"failed to send SIGCONT signal"); -        return ret; -} - -/* - * Log rotations flow is something like this: - * - Send SIGSTOP to process group (this will stop monitor/worker process - *   and also the slave if it's local) - * - Rotate log file for monitor/worker - * - Rotate log file for slave if it's local - * - Send SIGCONT to the process group. Monitor wakes up, kills the worker - *   (this is done in the SIGCONT handler), which results in the termination - *   of the slave (local/remote). After returning from signal handler, - *   monitor detects absence of worker and starts it again, which in-turn - *   starts the slave. - */ -static int -glusterd_send_log_rotate_signal (pid_t pid, char *logfile1, char *logfile2) +glusterd_gsync_delete (glusterd_volinfo_t *volinfo, char *slave, +                       char *slave_vol, char *path_list, dict_t *dict, +                       dict_t *resp_dict, char **op_errstr)  { -        int         ret         = 0; -        char rlogfile[PATH_MAX] = {0,}; -        time_t      rottime     = 0; - -        ret = glusterd_send_sigstop (-pid); -        rottime = time (NULL); +        int32_t         ret     = -1; +        runner_t        runner    = {0,}; +        glusterd_conf_t *priv   = NULL; +        char            *master = NULL; +        char            *gl_workdir = NULL; +        char             geo_rep_dir[PATH_MAX] = ""; +        char            *conf_path = NULL; -        snprintf (rlogfile, sizeof (rlogfile), "%s.%"PRIu64, logfile1, -                  (uint64_t) rottime); -        ret = rename (logfile1, rlogfile); -        if (ret) -                gf_log ("", GF_LOG_ERROR, "rename failed for geo-rep log file"); +        GF_ASSERT (slave); +        GF_ASSERT (slave_vol); +        GF_ASSERT (op_errstr); +        GF_ASSERT (dict); +        GF_ASSERT (resp_dict); -        if (!*logfile2) { -                gf_log ("", GF_LOG_DEBUG, "Slave is not local," -                        " skipping rotation"); -                ret = 0; +        if (THIS) +                priv = THIS->private; +        if (priv == NULL) { +                gf_log ("", GF_LOG_ERROR, "priv of glusterd not present"); +                *op_errstr = gf_strdup ("glusterd defunct");                  goto out;          } -        (void) snprintf (rlogfile, sizeof (rlogfile), "%s.%"PRIu64, logfile2, -                         (uint64_t) rottime); -        ret = rename (logfile2, rlogfile); -        if (ret) -                gf_log ("", GF_LOG_ERROR, "rename failed for geo-rep slave" -                        " log file"); +        ret = dict_get_str (dict, "conf_path", &conf_path); +        if (ret) { +                gf_log ("", GF_LOG_ERROR, +                        "Unable to fetch conf file path."); +                goto out; +        } - out: -        ret = glusterd_send_sigcont (-pid); +        gl_workdir = priv->workdir; +        master = ""; +        runinit (&runner); +        runner_add_args  (&runner, GSYNCD_PREFIX"/gsyncd", +                          "--delete", "-c", NULL); +        runner_argprintf (&runner, "%s", conf_path); -        return ret; -} +        if (volinfo) { +                master = volinfo->volname; +                runner_argprintf (&runner, ":%s", master); +        } +        runner_add_arg (&runner, slave); +        runner_redir (&runner, STDOUT_FILENO, RUN_PIPE); +        synclock_unlock (&priv->big_lock); +        ret = runner_run (&runner); +        synclock_lock (&priv->big_lock); +        if (ret) { +                gf_log ("", GF_LOG_ERROR, "gsyncd failed to " +                        "delete session info for %s and %s peers", +                        master, slave); -static int -glusterd_get_pid_from_file (char *master, char *slave, pid_t *pid) -{ -        int ret                = -1; -        int pfd                = 0; -        char pidfile[PATH_MAX] = {0,}; -        char buff[1024]        = {0,}; +                gf_asprintf (op_errstr, "gsyncd failed to " +                             "delete session info for %s and %s peers", +                             master, slave); -        pfd = gsyncd_getpidfile (master, slave, pidfile); -        if (pfd == -2) { -                gf_log ("", GF_LOG_ERROR, GEOREP" log-rotate validation " -                        " failed for %s & %s", master, slave); -                goto out; -        } -        if (gsync_status_byfd (pfd) == -1) { -                gf_log ("", GF_LOG_ERROR, "gsyncd b/w %s & %s is not" -                        " running", master, slave);                  goto out;          } -        if (pfd < 0) -                goto out; +        ret = snprintf (geo_rep_dir, sizeof(geo_rep_dir) - 1, +                        "%s/"GEOREP"/%s-%s", gl_workdir, +                        volinfo->volname, slave_vol); +        geo_rep_dir[ret] = '\0'; -        ret = read (pfd, buff, 1024); -        if (ret < 0) { -                gf_log ("", GF_LOG_ERROR, GEOREP" cannot read pid from pid-file"); -                goto out; +        ret = rmdir (geo_rep_dir); +        if (ret) { +                if (errno == ENOENT) +                        gf_log ("", GF_LOG_DEBUG, "Geo Rep Dir(%s) Not Present.", +                                geo_rep_dir); +                else { +                        gf_log ("", GF_LOG_ERROR, "Unable to delete " +                                "Geo Rep Dir(%s). Error: %s", geo_rep_dir, +                                strerror (errno)); +                        goto out; +                }          } - -        *pid = strtol (buff, NULL, 10);          ret = 0; +        gf_asprintf (op_errstr, "delete successful"); +  out: -        sys_close(pfd); +        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);          return ret;  } -static int -glusterd_do_gsync_log_rotate (char *master, char *slave, uuid_t *uuid, char **op_errstr) +int +glusterd_op_sys_exec (dict_t *dict, char **op_errstr, dict_t *rsp_dict)  { -        int              ret     = 0; -        glusterd_conf_t *priv    = NULL; -        pid_t            pid     = 0; -        char log_file1[PATH_MAX] = {0,}; -        char log_file2[PATH_MAX] = {0,}; +        char                   buf[PATH_MAX]          = ""; +        char                   cmd_arg_name[PATH_MAX] = ""; +        char                   output_name[PATH_MAX]  = ""; +        char                   errmsg[PATH_MAX]       = ""; +        char                  *ptr                    = NULL; +        char                  *bufp                   = NULL; +        char                  *command                = NULL; +        char                 **cmd_args               = NULL; +        int                    ret                    = -1; +        int                    i                      = -1; +        int                    cmd_args_count         = 0; +        int                    output_count           = 0; +        glusterd_conf_t       *priv                   = NULL; +        runner_t               runner                 = {0,}; -        GF_ASSERT (THIS); -        GF_ASSERT (THIS->private); - -        priv = THIS->private; +        GF_ASSERT (dict); +        GF_ASSERT (op_errstr); +        GF_ASSERT (rsp_dict); -        ret = glusterd_get_pid_from_file (master, slave, &pid); -        if (ret) +        if (THIS) +                priv = THIS->private; +        if (priv == NULL) { +                gf_log ("", GF_LOG_ERROR, "priv of glusterd not present"); +                *op_errstr = gf_strdup ("glusterd defunct");                  goto out; +        } -        /* log file */ -        ret = glusterd_gsyncd_getlogfile (master, slave, log_file1); -        if (ret) +        ret = dict_get_str (dict, "command", &command); +        if (ret) { +                gf_log ("", GF_LOG_ERROR, +                        "Unable to get command from dict");                  goto out; +        } -        /* check if slave is local or remote */ -        ret = glusterd_gsync_slave_is_remote (slave); -        if (ret) -                goto do_rotate; - -        /* slave log file - slave is local and it's log can be rotated */ -        ret = glusterd_gsync_get_slave_log_file (master, slave, log_file2); +        ret = dict_get_int32 (dict, "cmd_args_count", &cmd_args_count);          if (ret) -                goto out; - - do_rotate: -        ret = glusterd_send_log_rotate_signal (pid, log_file1, log_file2); - - out: -        if (ret && op_errstr) -                *op_errstr = gf_strdup("Error rotating log file"); -        return ret; -} - -static int -glusterd_do_gsync_log_rotation_mst_slv (glusterd_volinfo_t *volinfo, char *slave, -                                        char **op_errstr) -{ -        uuid_t           uuid = {0, }; -        glusterd_conf_t *priv = NULL; -        int              ret  = 0; -        char             errmsg[1024] = {0,}; -        xlator_t        *this    = NULL; +                gf_log ("", GF_LOG_INFO, "No cmd_args_count"); + +        if (cmd_args_count) { +                cmd_args = GF_CALLOC (cmd_args_count, sizeof (char*), +                                      gf_common_mt_char); +                if (!cmd_args) { +                        gf_log ("", GF_LOG_ERROR, "Unable to calloc. " +                                "Errno = %s", strerror(errno)); +                        goto out; +                } -        GF_ASSERT (volinfo); -        GF_ASSERT (slave); -        GF_ASSERT (THIS); -        this = THIS; -        GF_ASSERT (this->private); -        priv = this->private; +                for (i=1; i <= cmd_args_count; i++) { +                        memset (cmd_arg_name, '\0', sizeof(cmd_arg_name)); +                        snprintf (cmd_arg_name, sizeof(cmd_arg_name), +                                  "cmd_arg_%d", i); +                        ret = dict_get_str (dict, cmd_arg_name, &cmd_args[i-1]); +                        if (ret) { +                                gf_log ("", GF_LOG_ERROR, +                                        "Unable to get %s in dict", +                                        cmd_arg_name); +                                goto out; +                        } +                } +        } -        ret = glusterd_gsync_get_uuid (slave, volinfo, uuid); -        if ((ret == 0) && (uuid_compare (MY_UUID, uuid) != 0)) +        runinit (&runner); +        runner_argprintf (&runner, GSYNCD_PREFIX"/peer_%s", command); +        for (i=0; i < cmd_args_count; i++) +                runner_add_arg (&runner, cmd_args[i]); +        runner_redir (&runner, STDOUT_FILENO, RUN_PIPE); +        synclock_unlock (&priv->big_lock); +        ret = runner_start (&runner); +        if (ret == -1) { +                snprintf (errmsg, sizeof (errmsg), "Unable to " +                          "execute command. Error : %s", +                          strerror (errno)); +                *op_errstr = gf_strdup (errmsg); +                gf_log ("", GF_LOG_ERROR, "%s", errmsg); +                ret = -1; +                synclock_lock (&priv->big_lock);                  goto out; +        } + +        ptr = fgets(buf, sizeof(buf), runner_chio (&runner, STDOUT_FILENO)); +        if (ptr) { +                ret = dict_get_int32 (rsp_dict, "output_count", &output_count); +                if (ret) +                        output_count = 1; +                else +                        output_count++; +                memset (output_name, '\0', sizeof (output_name)); +                snprintf (output_name, sizeof (output_name), +                          "output_%d", output_count); +                if (buf[strlen(buf) - 1] == '\n') +                        buf[strlen(buf) - 1] = '\0'; +                bufp = gf_strdup (buf); +                if (!bufp) +                        gf_log ("", GF_LOG_ERROR, "gf_strdup failed."); +                ret = dict_set_dynstr (rsp_dict, output_name, bufp); +                if (ret) { +                        GF_FREE (bufp); +                        gf_log ("", GF_LOG_ERROR, "output set failed."); +                } +                ret = dict_set_int32 (rsp_dict, "output_count", output_count); +                if (ret) +                        gf_log ("", GF_LOG_ERROR, "output_count set failed."); +        } +        ret = runner_end (&runner);          if (ret) { -                snprintf(errmsg, sizeof(errmsg), "geo-replication session b/w %s %s not active", -                         volinfo->volname, slave); -                gf_log (this->name, GF_LOG_WARNING, "%s", errmsg); -                if (op_errstr) -                        *op_errstr = gf_strdup(errmsg); +                snprintf (errmsg, sizeof (errmsg), "Unable to " +                          "end. Error : %s", +                          strerror (errno)); +                *op_errstr = gf_strdup (errmsg); +                gf_log ("", GF_LOG_ERROR, "%s", errmsg); +                ret = -1; +                synclock_lock (&priv->big_lock);                  goto out;          } +        synclock_lock (&priv->big_lock); -        ret = glusterd_do_gsync_log_rotate (volinfo->volname, slave, &uuid, op_errstr); +        ret = 0; +out: +        if (cmd_args) { +                GF_FREE (cmd_args); +                cmd_args = NULL; +        } - out: -        gf_log (this->name, GF_LOG_DEBUG, "Returning with %d", ret); +        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);          return ret;  } -static int -_iterate_log_rotate_mst_slv (dict_t *this, char *key, data_t *value, void *data) +int +glusterd_op_copy_file (dict_t *dict, char **op_errstr)  { -        glusterd_gsync_status_temp_t  *param = NULL; -        char                          *slave = NULL; +        char             abs_filename[PATH_MAX] = ""; +        char             errmsg[PATH_MAX]       = ""; +        char            *filename               = NULL; +        char            *host_uuid              = NULL; +        char             uuid_str [64]          = {0}; +        char            *contents               = NULL; +        char             buf[1024]              = ""; +        int              ret                    = -1; +        int              fd                     = -1; +        int              bytes_writen           = 0; +        int              bytes_read             = 0; +        int              contents_size          = -1; +        int              file_mode              = -1; +        glusterd_conf_t *priv                   = NULL; +        struct stat      stbuf                  = {0,}; -        param = (glusterd_gsync_status_temp_t *) data; -        GF_ASSERT (param); -        GF_ASSERT (param->volinfo); - -        slave = strchr (value->data, ':'); -        if (slave) -                slave++; -        else { -                gf_log ("", GF_LOG_ERROR, "geo-replication log-rotate: slave (%s) " -                        "not conforming to format", slave); -                return -1; +        if (THIS) +                priv = THIS->private; +        if (priv == NULL) { +                gf_log ("", GF_LOG_ERROR, "priv of glusterd not present"); +                *op_errstr = gf_strdup ("glusterd defunct"); +                goto out;          } -        (void) glusterd_do_gsync_log_rotation_mst_slv (param->volinfo, slave, NULL); -        return 0; -} +        ret = dict_get_str (dict, "host-uuid", &host_uuid); +        if (ret < 0) +                goto out; -static int -glusterd_do_gsync_log_rotation_mst (glusterd_volinfo_t *volinfo) -{ -        glusterd_gsync_status_temp_t  param = {0, }; +        ret = dict_get_str (dict, "source", &filename); +        if (ret < 0) { +               gf_log ("", GF_LOG_ERROR, "Unable to fetch" +                       " filename from dict."); +               *op_errstr = gf_strdup ("command unsuccessful"); +               goto out; +        } +        snprintf (abs_filename, sizeof(abs_filename), +                  "%s/%s", priv->workdir, filename); -        GF_ASSERT (volinfo); +        uuid_utoa_r (MY_UUID, uuid_str); +        if (!strcmp (uuid_str, host_uuid)) { +                ret = lstat (abs_filename, &stbuf); +                if (ret) { +                        snprintf (errmsg, sizeof (errmsg), "Source file" +                                 " does not exist in %s", priv->workdir); +                        *op_errstr = gf_strdup (errmsg); +                        gf_log ("", GF_LOG_ERROR, "%s", errmsg); +                        goto out; +                } -        param.volinfo = volinfo; -        dict_foreach (volinfo->gsync_slaves, _iterate_log_rotate_mst_slv, ¶m); -        return 0; -} +                contents = GF_CALLOC(1, stbuf.st_size+1, gf_common_mt_char); +                if (!contents) { +                        snprintf (errmsg, sizeof (errmsg), +                                  "Unable to allocate memory"); +                        *op_errstr = gf_strdup (errmsg); +                        gf_log ("", GF_LOG_ERROR, "%s", errmsg); +                        ret = -1; +                        goto out; +                } -static int -glusterd_rotate_gsync_all () -{ -        int32_t             ret     = 0; -        glusterd_conf_t    *priv    = NULL; -        glusterd_volinfo_t *volinfo = NULL; +                fd = open (abs_filename, O_RDONLY); +                if (fd < 0) { +                        snprintf (errmsg, sizeof (errmsg), "Unable to open %s", +                                  abs_filename); +                        *op_errstr = gf_strdup (errmsg); +                        gf_log ("", GF_LOG_ERROR, "%s", errmsg); +                        ret = -1; +                        goto out; +                } -        GF_ASSERT (THIS); -        priv = THIS->private; +                do { +                        ret = read (fd, buf, sizeof(buf)); +                        if (ret > 0) { +                                memcpy (contents+bytes_read, buf, ret); +                                bytes_read += ret; +                                memset (buf, '\0', sizeof(buf)); +                        } +                } while (ret > 0); -        GF_ASSERT (priv); +                if (bytes_read != stbuf.st_size) { +                        snprintf (errmsg, sizeof (errmsg), "Unable to read all " +                                  "the data from %s", abs_filename); +                        *op_errstr = gf_strdup (errmsg); +                        gf_log ("", GF_LOG_ERROR, "%s", errmsg); +                        ret = -1; +                        goto out; +                } -        list_for_each_entry (volinfo, &priv->volumes, vol_list) { -                ret = glusterd_do_gsync_log_rotation_mst (volinfo); -                if (ret) +                ret = dict_set_int32 (dict, "contents_size", stbuf.st_size); +                if (ret) { +                        snprintf (errmsg, sizeof (errmsg), "Unable to set" +                                  " contents size in dict."); +                        *op_errstr = gf_strdup (errmsg); +                        gf_log ("", GF_LOG_ERROR, "%s", errmsg);                          goto out; -        } +                } - out: -        gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret); -        return ret; -} +                ret = dict_set_int32 (dict, "file_mode", +                                      (int32_t)stbuf.st_mode); +                if (ret) { +                        snprintf (errmsg, sizeof (errmsg), "Unable to set" +                                  " file mode in dict."); +                        *op_errstr = gf_strdup (errmsg); +                        gf_log ("", GF_LOG_ERROR, "%s", errmsg); +                        goto out; +                } -static int -glusterd_rotate_gsync_logs (dict_t *dict, char **op_errstr, dict_t *rsp_dict) -{ -        char                *slave   = NULL; -        char                *volname = NULL; -        char errmsg[1024]            = {0,}; -        gf_boolean_t         exists  = _gf_false; -        glusterd_volinfo_t  *volinfo = NULL; -        char               **linearr = NULL; -        int                  ret     = 0; +                ret = dict_set_bin (dict, "common_pem_contents", +                                    contents, stbuf.st_size); +                if (ret) { +                        snprintf (errmsg, sizeof (errmsg), "Unable to set" +                                  " pem contents in dict."); +                        *op_errstr = gf_strdup (errmsg); +                        gf_log ("", GF_LOG_ERROR, "%s", errmsg); +                        goto out; +                } +                close (fd); +        } else { +                ret = dict_get_bin (dict, "common_pem_contents", +                                    (void **) &contents); +                if (ret) { +                        snprintf (errmsg, sizeof (errmsg), "Unable to get" +                                  " pem contents in dict."); +                        *op_errstr = gf_strdup (errmsg); +                        gf_log ("", GF_LOG_ERROR, "%s", errmsg); +                        goto out; +                } -        ret = dict_get_str (dict, "master", &volname); -        if (ret < 0) { -                ret = glusterd_rotate_gsync_all (); -                goto out; -        } +                ret = dict_get_int32 (dict, "contents_size", &contents_size); +                if (ret) { +                        snprintf (errmsg, sizeof (errmsg), "Unable to set" +                                  " contents size in dict."); +                        *op_errstr = gf_strdup (errmsg); +                        gf_log ("", GF_LOG_ERROR, "%s", errmsg); +                        goto out; +                } -        exists = glusterd_check_volume_exists (volname); -        ret = glusterd_volinfo_find (volname, &volinfo); -        if ((ret) || (!exists)) { -                snprintf (errmsg, sizeof(errmsg), "Volume %s does not" -                          " exist", volname); -                gf_log ("", GF_LOG_WARNING, "%s", errmsg); -                *op_errstr = gf_strdup (errmsg); -                ret = -1; -                goto out; -        } +                ret = dict_get_int32 (dict, "file_mode", &file_mode); +                if (ret) { +                        snprintf (errmsg, sizeof (errmsg), "Unable to get" +                                  " file mode in dict."); +                        *op_errstr = gf_strdup (errmsg); +                        gf_log ("", GF_LOG_ERROR, "%s", errmsg); +                        goto out; +                } -        ret = dict_get_str (dict, "slave", &slave); -        if (ret < 0) { -                ret = glusterd_do_gsync_log_rotation_mst (volinfo); -                goto out; -        } +                fd = open (abs_filename, O_WRONLY | O_TRUNC | O_CREAT, 0600); +                if (fd < 0) { +                        snprintf (errmsg, sizeof (errmsg), "Unable to open %s", +                                  abs_filename); +                        *op_errstr = gf_strdup (errmsg); +                        gf_log ("", GF_LOG_ERROR, "%s", errmsg); +                        ret = -1; +                        goto out; +                } -        /* for the given slave use the normalized url */ -        ret = glusterd_urltransform_single (slave, "normalize", &linearr); -        if (ret == -1) -                goto out; +                bytes_writen = write (fd, contents, contents_size); -        ret = glusterd_do_gsync_log_rotation_mst_slv (volinfo, linearr[0], -                                                      op_errstr); -        if (ret) -                gf_log ("gsyncd", GF_LOG_ERROR, "gsyncd log-rotate failed for" -                        " %s & %s", volname, slave); +                if (bytes_writen != contents_size) { +                        snprintf (errmsg, sizeof (errmsg), "Failed to write" +                                  " to %s", abs_filename); +                        *op_errstr = gf_strdup (errmsg); +                        gf_log ("", GF_LOG_ERROR, "%s", errmsg); +                        ret = -1; +                        goto out; +                } -        glusterd_urltransform_free (linearr, 1); - out: +                fchmod (fd, file_mode); +                close (fd); +        } + +        ret = 0; +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)  { @@ -2166,11 +3225,15 @@ glusterd_op_gsync_set (dict_t *dict, char **op_errstr, dict_t *rsp_dict)          dict_t             *resp_dict = NULL;          char               *host_uuid = NULL;          char               *slave  = NULL; +        char               *slave_vol = NULL;          char               *volname = NULL; +        char               *path_list = NULL;          glusterd_volinfo_t *volinfo = NULL;          glusterd_conf_t    *priv = NULL; +        gf_boolean_t        is_force = _gf_false;          char               *status_msg = NULL; -        uuid_t              uuid = {0, }; +        gf_boolean_t        is_running = _gf_false; +        char               *conf_path = NULL;          GF_ASSERT (THIS);          GF_ASSERT (THIS->private); @@ -2196,15 +3259,22 @@ glusterd_op_gsync_set (dict_t *dict, char **op_errstr, dict_t *rsp_dict)                  goto out;          } -        if (type == GF_GSYNC_OPTION_TYPE_ROTATE) { -                ret = glusterd_rotate_gsync_logs (dict, op_errstr, resp_dict); +        ret = dict_get_str (dict, "slave", &slave); +        if (ret < 0)                  goto out; +        ret = dict_get_str (dict, "slave_vol", &slave_vol); +        if (ret) { +                gf_log ("", GF_LOG_ERROR, "Unable to fetch slave volume name."); +                goto out;          } -        ret = dict_get_str (dict, "slave", &slave); -        if (ret < 0) +        ret = dict_get_str (dict, "conf_path", &conf_path); +        if (ret) { +                gf_log ("", GF_LOG_ERROR, +                        "Unable to fetch conf file path.");                  goto out; +        }          if (dict_get_str (dict, "master", &volname) == 0) {                  ret = glusterd_volinfo_find (volname, &volinfo); @@ -2213,11 +3283,24 @@ glusterd_op_gsync_set (dict_t *dict, char **op_errstr, dict_t *rsp_dict)                                  volname);                          goto out;                  } + +                ret = glusterd_get_local_brickpaths (volinfo, &path_list);          }          if (type == GF_GSYNC_OPTION_TYPE_CONFIG) { -                ret = glusterd_gsync_configure (volinfo, slave, dict, resp_dict, -                                                op_errstr); +                ret = glusterd_gsync_configure (volinfo, slave, path_list, +                                                dict, resp_dict, op_errstr); +                goto out; +        } + +        if (type == GF_GSYNC_OPTION_TYPE_DELETE) { +                ret = glusterd_remove_slave_in_info(volinfo, slave, op_errstr); +                if (ret && !is_force && path_list) +                        goto out; + +                ret = glusterd_gsync_delete (volinfo, slave, slave_vol, +                                             path_list, dict, resp_dict, +                                             op_errstr);                  goto out;          } @@ -2226,48 +3309,636 @@ glusterd_op_gsync_set (dict_t *dict, char **op_errstr, dict_t *rsp_dict)                  goto out;          } +        is_force = dict_get_str_boolean (dict, "force", _gf_false); +          if (type == GF_GSYNC_OPTION_TYPE_START) { -                ret = glusterd_set_marker_gsync (volinfo); +                ret = glusterd_set_gsync_confs (volinfo);                  if (ret != 0) { -                        gf_log ("", GF_LOG_WARNING, "marker start failed"); +                        gf_log ("", GF_LOG_WARNING, "marker/changelog start failed");                          *op_errstr = gf_strdup ("failed to initialize indexing");                          ret = -1;                          goto out;                  } -                ret = glusterd_store_slave_in_info(volinfo, slave, -                                                   host_uuid, op_errstr); -                if (ret) -                        goto out; -                ret = glusterd_start_gsync (volinfo, slave, host_uuid, -                                            op_errstr); +                ret = glusterd_start_gsync (volinfo, slave, path_list, +                                            conf_path, host_uuid, op_errstr);          }          if (type == GF_GSYNC_OPTION_TYPE_STOP) { - -                ret = glusterd_gsync_get_uuid (slave, volinfo, uuid); -                if (ret) { +                ret = glusterd_check_gsync_running_local (volinfo->volname, +                                                          slave, conf_path, +                                                          &is_running); +                if (!ret && !is_force && path_list && +                    (_gf_true != is_running)) {                          gf_log ("", GF_LOG_WARNING, GEOREP" is not set up for"                                  "%s(master) and %s(slave)", volname, slave);                          *op_errstr = strdup (GEOREP" is not set up");                          goto out;                  } -                ret = glusterd_remove_slave_in_info(volinfo, slave, op_errstr); -                if (ret) +                ret = stop_gsync (volname, slave, &status_msg, conf_path, is_force); +                if (ret == 0 && status_msg) +                        ret = dict_set_str (resp_dict, "gsync-status", +                                            status_msg); +                if (ret != 0 && !is_force && path_list) +                        *op_errstr = gf_strdup ("internal error"); + +                if (!ret) { +                        ret = glusterd_create_status_file (volinfo->volname, +                                                           slave, slave_vol, "Stopped"); +                        if (ret) { +                                gf_log ("", GF_LOG_ERROR, "Unable to update" +                                        "state_file. Error : %s", +                                        strerror (errno)); +                        } +                } +        } + +out: +        if (path_list) { +                GF_FREE (path_list); +                path_list = NULL; +        } + +        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); +        return ret; +} + +static int +glusterd_get_slave_details_confpath (glusterd_volinfo_t *volinfo, dict_t *dict, +                                     char **slave_ip, char **slave_vol, +                                     char **conf_path) +{ +        int                ret                = -1; +        char               confpath[PATH_MAX] = ""; +        glusterd_conf_t   *priv               = NULL; + +        GF_ASSERT (THIS); +        priv = THIS->private; +        GF_ASSERT (priv); + +        ret = glusterd_get_slave_info (dict, slave_ip, slave_vol); +        if (ret) { +                gf_log ("", GF_LOG_ERROR, +                        "Unable to fetch slave details."); +                ret = -1; +                goto out; +        } + +        ret = snprintf (confpath, sizeof(confpath) - 1, +                        "%s/"GEOREP"/%s-%s/gsyncd.conf", +                        priv->workdir, volinfo->volname, *slave_vol); +        confpath[ret] = '\0'; +        *conf_path = gf_strdup (confpath); +        if (!(*conf_path)) { +                gf_log ("", GF_LOG_ERROR, +                        "Unable to gf_strdup. Error: %s", strerror (errno)); +                ret = -1; +                goto out; +        } + +        ret = dict_set_str (dict, "conf_path", *conf_path); +        if (ret) { +                gf_log ("", GF_LOG_ERROR, +                        "Unable to store conf_path"); +                goto out; +        } + +out: +        gf_log ("", GF_LOG_DEBUG,"Returning %d", ret); +        return ret; + +} + +static int +glusterd_get_slave_info (dict_t *dict, char **slave_ip, char **slave_vol) +{ +        char     *tmp       = NULL; +        char     *save_ptr  = NULL; +        char     *slave     = NULL; +        char    **linearr   = NULL; +        int32_t   ret       = -1; + +        GF_ASSERT (dict); + +        ret = dict_get_str (dict, "slave", &slave); +        if (slave) { +                ret = glusterd_urltransform_single (slave, "normalize", +                                                    &linearr); +                if (ret == -1) { +                        gf_log ("", GF_LOG_ERROR, "Failed to normalize url"); +                        goto out; +                } + +                tmp = strtok_r (linearr[0], "/", &save_ptr); +                tmp = strtok_r (NULL, "/", &save_ptr); +                slave = strtok_r (tmp, ":", &save_ptr); +                if (slave) { +                        *slave_ip = gf_strdup (slave); +                        if (!*slave_ip) { +                                gf_log ("", GF_LOG_ERROR, +                                        "Failed to gf_strdup"); +                                ret = -1; +                                goto out; +                        } +                        gf_log ("", GF_LOG_DEBUG, "Slave IP : %s", *slave_ip); +                        ret = 0; +                } else { +                        gf_log ("", GF_LOG_ERROR, "Invalid slave name");                          goto out; +                } -                if (uuid_compare (MY_UUID, uuid) != 0) { +                slave = strtok_r (NULL, ":", &save_ptr); +                if (slave) { +                        *slave_vol = gf_strdup (slave); +                        if (!*slave_vol) { +                                gf_log ("", GF_LOG_ERROR, +                                        "Failed to gf_strdup"); +                                ret = -1; +                                goto out; +                        } +                        gf_log ("", GF_LOG_DEBUG, "Slave Vol : %s", *slave_vol); +                        ret = 0; +                } else { +                        gf_log ("", GF_LOG_ERROR, "Invalid slave name");                          goto out;                  } -                ret = stop_gsync (volname, slave, &status_msg); -                if (ret == 0 && status_msg) -                        ret = dict_set_str (resp_dict, "gsync-status", -                                            status_msg); -                if (ret != 0) -                        *op_errstr = gf_strdup ("internal error"); +                ret = dict_set_str (dict, "slave_ip", *slave_ip); +                if (ret) { +                        gf_log ("", GF_LOG_ERROR, +                                "Unable to store slave IP."); +                        goto out; +                } + +                ret = dict_set_str (dict, "slave_vol", *slave_vol); +                if (ret) { +                        gf_log ("", GF_LOG_ERROR, +                                "Unable to store slave volume name."); +                        goto out; +                } +        } else +                gf_log ("", GF_LOG_ERROR, "Unable to fetch slave from dict"); + +out: +        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); +        return ret; +} + +static void +runinit_gsyncd_setrx (runner_t *runner, char *conf_path) +{ +        runinit (runner); +        runner_add_args (runner, GSYNCD_PREFIX"/gsyncd", "-c", NULL); +        runner_argprintf (runner, "%s", conf_path); +        runner_add_arg (runner, "--config-set-rx"); +} + +static int +glusterd_check_gsync_present (int *valid_state) +{ +        char                buff[PATH_MAX] = {0, }; +        runner_t            runner = {0,}; +        char               *ptr = NULL; +        int                 ret = 0; + +        runinit (&runner); +        runner_add_args (&runner, GSYNCD_PREFIX"/gsyncd", "--version", NULL); +        runner_redir (&runner, STDOUT_FILENO, RUN_PIPE); +        ret = runner_start (&runner); +        if (ret == -1) { +                if (errno == ENOENT) { +                        gf_log ("glusterd", GF_LOG_INFO, GEOREP +                                 " module not installed in the system"); +                        *valid_state = 0; +                } +                else { +                        gf_log ("glusterd", GF_LOG_ERROR, GEOREP +                                  " module not working as desired"); +                        *valid_state = -1; +                } +                goto out; +        } + +        ptr = fgets(buff, sizeof(buff), runner_chio (&runner, STDOUT_FILENO)); +        if (ptr) { +                if (!strstr (buff, "gsyncd")) { +                        ret = -1; +                        gf_log ("glusterd", GF_LOG_ERROR, GEOREP" module not " +                                 "working as desired"); +                        *valid_state = -1; +                        goto out; +                } +        } else { +                ret = -1; +                gf_log ("glusterd", GF_LOG_ERROR, GEOREP" module not " +                         "working as desired"); +                *valid_state = -1; +                goto out; +        } + +        ret = 0; + out: + +        runner_end (&runner); + +        gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret); +        return ret; + +} + +static int +create_conf_file (glusterd_conf_t *conf, char *conf_path) +#define RUN_GSYNCD_CMD do {                                                          \ +        ret = runner_run_reuse (&runner);                                            \ +        if (ret == -1) {                                                             \ +                runner_log (&runner, "glusterd", GF_LOG_ERROR, "command failed");    \ +                runner_end (&runner);                                                \ +                goto out;                                                            \ +        }                                                                            \ +        runner_end (&runner);                                                        \ +} while (0) +{ +        int ret = 0; +        runner_t runner = {0,}; +        char georepdir[PATH_MAX] = {0,}; +        int valid_state = 0; + +        valid_state = -1; +        ret = glusterd_check_gsync_present (&valid_state); +        if (-1 == ret) { +                ret = valid_state; +                goto out; +        } + +        ret = snprintf (georepdir, sizeof(georepdir) - 1, "%s/"GEOREP, +                        conf->workdir); +        georepdir[ret] = '\0'; + +        /************ +         * master pre-configuration +         ************/ + +        /* remote-gsyncd */ +        runinit_gsyncd_setrx (&runner, conf_path); +        runner_add_args (&runner, "remote-gsyncd", GSYNCD_PREFIX"/gsyncd", ".", ".", NULL); +        RUN_GSYNCD_CMD; + +        runinit_gsyncd_setrx (&runner, conf_path); +        runner_add_args (&runner, "remote-gsyncd", "/nonexistent/gsyncd", +                         ".", "^ssh:", NULL); +        RUN_GSYNCD_CMD; + +        /* gluster-command-dir */ +        runinit_gsyncd_setrx (&runner, conf_path); +        runner_add_args (&runner, "gluster-command-dir", SBIN_DIR"/", +                         ".", ".", NULL); +        RUN_GSYNCD_CMD; + +        /* gluster-params */ +        runinit_gsyncd_setrx (&runner, conf_path); +        runner_add_args (&runner, "gluster-params", +                         "aux-gfid-mount xlator-option=*-dht.assert-no-child-down=true", +                         ".", ".", NULL); +        RUN_GSYNCD_CMD; + +        /* ssh-command */ +        runinit_gsyncd_setrx (&runner, conf_path); +        runner_add_arg (&runner, "ssh-command"); +        runner_argprintf (&runner, +                          "ssh -oPasswordAuthentication=no " +                           "-oStrictHostKeyChecking=no " +                           "-i %s/secret.pem", georepdir); +        runner_add_args (&runner, ".", ".", NULL); +        RUN_GSYNCD_CMD; + +        /* pid-file */ +        runinit_gsyncd_setrx (&runner, conf_path); +        runner_add_arg (&runner, "pid-file"); +        runner_argprintf (&runner, "%s/${mastervol}-${slavevol}/${eSlave}.pid", georepdir); +        runner_add_args (&runner, ".", ".", NULL); +        RUN_GSYNCD_CMD; + +        /* state-file */ +        runinit_gsyncd_setrx (&runner, conf_path); +        runner_add_arg (&runner, "state-file"); +        runner_argprintf (&runner, "%s/${mastervol}-${slavevol}/${eSlave}.status", georepdir); +        runner_add_args (&runner, ".", ".", NULL); +        RUN_GSYNCD_CMD; + +        /* state-detail-file */ +        runinit_gsyncd_setrx (&runner, conf_path); +        runner_add_arg (&runner, "state-detail-file"); +        runner_argprintf (&runner, "%s/${mastervol}-${slavevol}/${eSlave}-detail.status", georepdir); +        runner_add_args (&runner, ".", ".", NULL); +        RUN_GSYNCD_CMD; + +        /* state-socket */ +        runinit_gsyncd_setrx (&runner, conf_path); +        runner_add_arg (&runner, "state-socket-unencoded"); +        runner_argprintf (&runner, "%s/${mastervol}-${slavevol}/${eSlave}.socket", georepdir); +        runner_add_args (&runner, ".", ".", NULL); +        RUN_GSYNCD_CMD; + +        /* socketdir */ +        runinit_gsyncd_setrx (&runner, conf_path); +        runner_add_args (&runner, "socketdir", GLUSTERD_SOCK_DIR, ".", ".", NULL); +        RUN_GSYNCD_CMD; + +        /* log-file */ +        runinit_gsyncd_setrx (&runner, conf_path); +        runner_add_args (&runner, +                         "log-file", +                         DEFAULT_LOG_FILE_DIRECTORY"/"GEOREP"/${mastervol}/${eSlave}.log", +                         ".", ".", NULL); +        RUN_GSYNCD_CMD; + +        /* gluster-log-file */ +        runinit_gsyncd_setrx (&runner, conf_path); +        runner_add_args (&runner, +                         "gluster-log-file", +                         DEFAULT_LOG_FILE_DIRECTORY"/"GEOREP"/${mastervol}/${eSlave}${local_id}.gluster.log", +                         ".", ".", NULL); +        RUN_GSYNCD_CMD; + +        /* ignore-deletes */ +        runinit_gsyncd_setrx (&runner, conf_path); +        runner_add_args (&runner, "ignore-deletes", "true", ".", ".", NULL); +        RUN_GSYNCD_CMD; + +        /* special-sync-mode */ +        runinit_gsyncd_setrx (&runner, conf_path); +        runner_add_args (&runner, "special-sync-mode", "partial", ".", ".", NULL); +        RUN_GSYNCD_CMD; + +        /* change-detector == changelog */ +        runinit_gsyncd_setrx (&runner, conf_path); +        runner_add_args(&runner, "change-detector", "changelog", ".", ".", NULL); +        RUN_GSYNCD_CMD; + +        runinit_gsyncd_setrx (&runner, conf_path); +        runner_add_arg(&runner, "working-dir"); +        runner_argprintf(&runner, "%s/${mastervol}/${eSlave}", +                         DEFAULT_VAR_RUN_DIRECTORY); +        runner_add_args (&runner, ".", ".", NULL); +        RUN_GSYNCD_CMD; + +        /************ +         * slave pre-configuration +         ************/ + +        /* gluster-command-dir */ +        runinit_gsyncd_setrx (&runner, conf_path); +        runner_add_args (&runner, "gluster-command-dir", SBIN_DIR"/", +                         ".", NULL); +        RUN_GSYNCD_CMD; + +        /* gluster-params */ +        runinit_gsyncd_setrx (&runner, conf_path); +        runner_add_args (&runner, "gluster-params", +                         "aux-gfid-mount xlator-option=*-dht.assert-no-child-down=true", +                         ".", NULL); +        RUN_GSYNCD_CMD; + +        /* log-file */ +        runinit_gsyncd_setrx (&runner, conf_path); +        runner_add_args (&runner, +                         "log-file", +                         DEFAULT_LOG_FILE_DIRECTORY"/"GEOREP"-slaves/${session_owner}:${eSlave}.log", +                         ".", NULL); +        RUN_GSYNCD_CMD; + +        /* MountBroker log-file */ +        runinit_gsyncd_setrx (&runner, conf_path); +        runner_add_args (&runner, +                         "log-file-mbr", +                         DEFAULT_LOG_FILE_DIRECTORY"/"GEOREP"-slaves/mbr/${session_owner}:${eSlave}.log", +                         ".", NULL); +        RUN_GSYNCD_CMD; + +        /* gluster-log-file */ +        runinit_gsyncd_setrx (&runner, conf_path); +        runner_add_args (&runner, +                         "gluster-log-file", +                         DEFAULT_LOG_FILE_DIRECTORY"/"GEOREP"-slaves/${session_owner}:${eSlave}.gluster.log", +                         ".", NULL); +        RUN_GSYNCD_CMD; + + out: +        return ret ? -1 : 0; +} + +static int +glusterd_create_essential_dir_files (glusterd_volinfo_t *volinfo, dict_t *dict, char *slave, char *slave_vol, char **op_errstr) +{ +        int                ret              = -1; +        char              *conf_path        = NULL; +        char              *statefile        = NULL; +        char               buf[PATH_MAX]    = ""; +        char               errmsg[PATH_MAX] = ""; +        glusterd_conf_t   *conf             = NULL; +        struct stat        stbuf            = {0,}; + +        GF_ASSERT (THIS); +        conf = THIS->private; + +        ret = dict_get_str (dict, "conf_path", &conf_path); +        if (ret) { +                snprintf (errmsg, sizeof (errmsg), +                          "Unable to fetch conf file path."); +                gf_log ("", GF_LOG_ERROR, "%s", errmsg); +                goto out; +        } + +        ret = dict_get_str (dict, "statefile", &statefile); +        if (ret) { +                snprintf (errmsg, sizeof (errmsg), +                          "Unable to fetch statefile path."); +                gf_log ("", GF_LOG_ERROR, "%s", errmsg); +                goto out; +        } + +        ret = snprintf (buf, sizeof(buf) - 1, "%s/"GEOREP"/%s-%s", +                        conf->workdir, volinfo->volname, slave_vol); +        buf[ret] = '\0'; +        ret = mkdir_p (buf, 0777, _gf_true); +        if (ret) { +                snprintf (errmsg, sizeof (errmsg), "Unable to create %s" +                          ". Error : %s", buf, strerror (errno)); +                *op_errstr = gf_strdup (errmsg); +                gf_log ("", GF_LOG_ERROR, "%s", errmsg); +                goto out; +        } + +        ret = snprintf (buf, PATH_MAX, DEFAULT_LOG_FILE_DIRECTORY"/"GEOREP"/%s", +                        volinfo->volname); +        buf[ret] = '\0'; +        ret = mkdir_p (buf, 0777, _gf_true); +        if (ret) { +                snprintf (errmsg, sizeof (errmsg), "Unable to create %s" +                          ". Error : %s", buf, strerror (errno)); +                *op_errstr = gf_strdup (errmsg); +                gf_log ("", GF_LOG_ERROR, "%s", errmsg); +                goto out; +        } + +        ret = lstat (conf_path, &stbuf); +        if (!ret) { +                gf_log ("", GF_LOG_DEBUG, "Session already running." +                        " Not creating config file again."); +        } else { +                ret = create_conf_file (conf, conf_path); +                if (ret || lstat (conf_path, &stbuf)) { +                        snprintf (errmsg, sizeof (errmsg), "Failed to create" +                                  " config file(%s).", conf_path); +                        gf_log ("", GF_LOG_ERROR, "%s", errmsg); +                        goto out; +                } +        } + +        ret = lstat (statefile, &stbuf); +        if (!ret) { +                gf_log ("", GF_LOG_DEBUG, "Session already running." +                        " Not creating status file again."); +                goto out; +        } else { +                ret = glusterd_create_status_file (volinfo->volname, slave, slave_vol, +                                                   "Not Started"); +                if (ret || lstat (statefile, &stbuf)) { +                        snprintf (errmsg, sizeof (errmsg), "Unable to create %s" +                                  ". Error : %s", statefile, strerror (errno)); +                        *op_errstr = gf_strdup (errmsg); +                        gf_log ("", GF_LOG_ERROR, "%s", errmsg); +                        ret = -1; +                        goto out; +                } +        } + +out: +        gf_log ("", GF_LOG_DEBUG,"Returning %d", ret); +        return ret; +} + +int +glusterd_op_gsync_create (dict_t *dict, char **op_errstr, dict_t *rsp_dict) +{ +        char                common_pem_file[PATH_MAX] = ""; +        char                errmsg[PATH_MAX]          = ""; +        char                hooks_args[PATH_MAX]      = ""; +        char                uuid_str [64]             = ""; +        char               *host_uuid                 = NULL; +        char               *slave_ip                  = NULL; +        char               *slave_vol                 = NULL; +        char               *arg_buf                   = NULL; +        char               *volname                   = NULL; +        char               *slave                     = NULL; +        int32_t             ret                       = -1; +        int32_t             is_pem_push               = -1; +        gf_boolean_t        is_force                  = -1; +        glusterd_conf_t    *conf                      = NULL; +        glusterd_volinfo_t *volinfo                   = NULL; + +        GF_ASSERT (THIS); +        conf = THIS->private; +        GF_ASSERT (conf); +        GF_ASSERT (dict); +        GF_ASSERT (op_errstr); + +        ret = glusterd_op_gsync_args_get (dict, op_errstr, +                                          &volname, &slave, &host_uuid); +        if (ret) +                goto out; + +        snprintf (common_pem_file, sizeof(common_pem_file), +                  "%s"GLUSTERD_COMMON_PEM_PUB_FILE, conf->workdir); + +        ret = glusterd_volinfo_find (volname, &volinfo); +        if (ret) { +                gf_log ("", GF_LOG_ERROR, "Volinfo for %s" +                        " (master) not found", volname); +                goto out; +        } + +        ret = dict_get_str (dict, "slave_vol", &slave_vol); +        if (ret) { +                snprintf (errmsg, sizeof (errmsg), +                          "Unable to fetch slave volume name."); +                gf_log ("", GF_LOG_ERROR, "%s", errmsg); +                goto out; +        } + +        is_force = dict_get_str_boolean (dict, "force", _gf_false); + +        uuid_utoa_r (MY_UUID, uuid_str); +        if (!strcmp (uuid_str, host_uuid)) { +                ret = dict_get_str (dict, "slave_ip", &slave_ip); +                if (ret) { +                        snprintf (errmsg, sizeof (errmsg), +                                  "Unable to fetch slave IP." +                                  " No Hooks Arguments."); +                        gf_log ("", GF_LOG_ERROR, "%s", errmsg); +                        if (is_force) { +                                ret = 0; +                                goto create_essentials; +                        } +                        ret = -1; +                        goto out; +                } + +                ret = dict_get_int32 (dict, "push_pem", &is_pem_push); +                if (!ret && is_pem_push) { +                        gf_log ("", GF_LOG_DEBUG, "Trying to setup" +                                " pem files in slave"); +                        is_pem_push = 1; +                } else +                        is_pem_push = 0; + +                snprintf(hooks_args, sizeof(hooks_args), +                         "is_push_pem=%d pub_file=%s slave_ip=%s", +                         is_pem_push, common_pem_file, slave_ip); + +        } else +                snprintf(hooks_args, sizeof(hooks_args), +                         "This argument will stop the hooks script"); + +        arg_buf = gf_strdup (hooks_args); +        if (!arg_buf) { +                gf_log ("", GF_LOG_ERROR, "Failed to" +                        " gf_strdup"); +                if (is_force) { +                        ret = 0; +                        goto create_essentials; +                } +                ret = -1; +                goto out; +        } + +        ret = dict_set_str (dict, "hooks_args", arg_buf); +        if (ret) { +                gf_log ("", GF_LOG_ERROR, "Failed to set" +                        " hooks_args in dict."); +                if (is_force) { +                        ret = 0; +                        goto create_essentials; +                } +                goto out; +        } + +create_essentials: + +        ret = glusterd_create_essential_dir_files (volinfo, dict, slave, slave_vol, op_errstr); +        if (ret) +                goto out; + +        ret = glusterd_store_slave_in_info (volinfo, slave, +                                            host_uuid, op_errstr, +                                            is_force); +        if (ret) { +                snprintf (errmsg, sizeof (errmsg), "Unable to store" +                          " slave info."); +                gf_log ("", GF_LOG_ERROR, "%s", errmsg); +                goto out;          }  out: diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c index 480ee01b0ce..38427d82292 100644 --- a/xlators/mgmt/glusterd/src/glusterd-handler.c +++ b/xlators/mgmt/glusterd/src/glusterd-handler.c @@ -3922,6 +3922,8 @@ rpcsvc_actor_t gd_svc_cli_actors[] = {  #ifdef HAVE_BD_XLATOR          [GLUSTER_CLI_BD_OP]              = {"BD_OP",              GLUSTER_CLI_BD_OP,            glusterd_handle_cli_bd_op,             NULL, 0, DRC_NA},  #endif +        [GLUSTER_CLI_COPY_FILE]     = {"COPY_FILE", GLUSTER_CLI_COPY_FILE, glusterd_handle_copy_file, NULL, 0, DRC_NA}, +        [GLUSTER_CLI_SYS_EXEC]      = {"SYS_EXEC", GLUSTER_CLI_SYS_EXEC, glusterd_handle_sys_exec, NULL, 0, DRC_NA},  };  struct rpcsvc_program gd_svc_cli_prog = { diff --git a/xlators/mgmt/glusterd/src/glusterd-hooks.c b/xlators/mgmt/glusterd/src/glusterd-hooks.c index a61e1e85f2d..2b43a452e0c 100644 --- a/xlators/mgmt/glusterd/src/glusterd-hooks.c +++ b/xlators/mgmt/glusterd/src/glusterd-hooks.c @@ -49,6 +49,7 @@ char glusterd_hook_dirnames[GD_OP_MAX][256] =          [GD_OP_RESET_VOLUME]            = EMPTY,          [GD_OP_SYNC_VOLUME]             = EMPTY,          [GD_OP_LOG_ROTATE]              = EMPTY, +        [GD_OP_GSYNC_CREATE]            = "gsync-create",          [GD_OP_GSYNC_SET]               = EMPTY,          [GD_OP_PROFILE_VOLUME]          = EMPTY,          [GD_OP_QUOTA]                   = EMPTY, @@ -185,6 +186,7 @@ static int  glusterd_hooks_add_op_args (runner_t *runner, glusterd_op_t op,                              dict_t *op_ctx, glusterd_commit_hook_type_t type)  { +        char                   *hooks_args       = NULL;          int                     vol_count        = 0;          gf_boolean_t            truth            = _gf_false;          glusterd_volinfo_t      *voliter         = NULL; @@ -236,6 +238,18 @@ glusterd_hooks_add_op_args (runner_t *runner, glusterd_op_t op,                          ret = glusterd_hooks_set_volume_args (op_ctx, runner);                          break; +                case GD_OP_GSYNC_CREATE: +                        ret = dict_get_str (op_ctx, "hooks_args", &hooks_args); +                        if (ret) +                                gf_log ("", GF_LOG_DEBUG, +                                        "No Hooks Arguments."); +                        else +                                gf_log ("", GF_LOG_DEBUG, +                                        "Hooks Args = %s", hooks_args); +                        if (hooks_args) +                                runner_argprintf (runner, "%s", hooks_args); +                        break; +                  default:                          break; diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c index fb8d1f17efb..1774b133b93 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c @@ -2504,12 +2504,13 @@ glusterd_op_build_payload (dict_t **req, char **op_errstr, dict_t *op_ctx)                          }                          break; +                case GD_OP_GSYNC_CREATE:                  case GD_OP_GSYNC_SET:                          {                                  ret = glusterd_op_gsync_args_get (dict,                                                                    &errstr,                                                                    &volname, -                                                                  NULL); +                                                                  NULL, NULL);                                  if (ret == 0) {                                          ret = glusterd_dict_set_volid                                                  (dict, volname, op_errstr); @@ -2622,6 +2623,18 @@ glusterd_op_build_payload (dict_t **req, char **op_errstr, dict_t *op_ctx)                          }                          break; +                case GD_OP_COPY_FILE: +                        { +                                dict_copy (dict, req_dict); +                                break; +                        } + +                case GD_OP_SYS_EXEC: +                        { +                                dict_copy (dict, req_dict); +                                break; +                        } +                  default:                          break;          } @@ -3755,6 +3768,10 @@ glusterd_op_stage_validate (glusterd_op_t op, dict_t *dict, char **op_errstr,                          ret = glusterd_op_stage_sync_volume (dict, op_errstr);                          break; +                case GD_OP_GSYNC_CREATE: +                        ret = glusterd_op_stage_gsync_create (dict, op_errstr); +                        break; +                  case GD_OP_GSYNC_SET:                          ret = glusterd_op_stage_gsync_set (dict, op_errstr);                          break; @@ -3793,13 +3810,21 @@ glusterd_op_stage_validate (glusterd_op_t op, dict_t *dict, char **op_errstr,                          ret = glusterd_op_stage_bd (dict, op_errstr);                          break;  #endif + +                case GD_OP_COPY_FILE: +                        ret = glusterd_op_stage_copy_file (dict, op_errstr); +                        break; + +                case GD_OP_SYS_EXEC: +                        ret = glusterd_op_stage_sys_exec (dict, op_errstr); +                        break; +                  default:                          gf_log (this->name, GF_LOG_ERROR, "Unknown op %s",                                  gd_op_list[op]);          } -        gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret); - +        gf_log (this->name, GF_LOG_DEBUG, "OP = %d. Returning %d", op, ret);          return ret;  } @@ -3857,6 +3882,11 @@ glusterd_op_commit_perform (glusterd_op_t op, dict_t *dict, char **op_errstr,                          ret = glusterd_op_sync_volume (dict, op_errstr, rsp_dict);                          break; +                case GD_OP_GSYNC_CREATE: +                        ret = glusterd_op_gsync_create (dict, op_errstr, +                                                        rsp_dict); +                        break; +                  case GD_OP_GSYNC_SET:                          ret = glusterd_op_gsync_set (dict, op_errstr, rsp_dict);                          break; @@ -3896,6 +3926,15 @@ glusterd_op_commit_perform (glusterd_op_t op, dict_t *dict, char **op_errstr,                          ret = 0;                          break;  #endif + +                case GD_OP_COPY_FILE: +                        ret = glusterd_op_copy_file (dict, op_errstr); +                        break; + +                case GD_OP_SYS_EXEC: +                        ret = glusterd_op_sys_exec (dict, op_errstr, rsp_dict); +                        break; +                  default:                          gf_log (this->name, GF_LOG_ERROR, "Unknown op %s",                                  gd_op_list[op]); @@ -3904,8 +3943,8 @@ glusterd_op_commit_perform (glusterd_op_t op, dict_t *dict, char **op_errstr,          if (ret == 0)              glusterd_op_commit_hook (op, dict, GD_COMMIT_HOOK_POST); -        gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret); +        gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);          return ret;  } diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.h b/xlators/mgmt/glusterd/src/glusterd-op-sm.h index df8b8c1410e..321c5c484f5 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.h +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.h @@ -15,8 +15,8 @@  #include "config.h"  #endif -#ifndef GSYNC_CONF -#define GSYNC_CONF GEOREP"/gsyncd.conf" +#ifndef GSYNC_CONF_TEMPLATE +#define GSYNC_CONF_TEMPLATE GEOREP"/gsyncd_template.conf"  #endif  #include <pthread.h> @@ -270,7 +270,7 @@ glusterd_are_all_volumes_stopped ();  int  glusterd_stop_bricks (glusterd_volinfo_t *volinfo);  int -gsync_status (char *master, char *slave, int *status); +gsync_status (char *master, char *slave, char *conf_path, int *status);  int  glusterd_check_gsync_running (glusterd_volinfo_t *volinfo, gf_boolean_t *flag); diff --git a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c index 18a74349487..2d8d381bf26 100644 --- a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c @@ -84,6 +84,7 @@ glusterd_op_send_cli_response (glusterd_op_t op, int32_t op_ret,                  }                  break;          } +        case GD_OP_GSYNC_CREATE:          case GD_OP_GSYNC_SET:          {                 if (ctx) { @@ -146,6 +147,21 @@ glusterd_op_send_cli_response (glusterd_op_t op, int32_t op_ret,                  /*nothing specific to be done*/                  break;          } +        case GD_OP_COPY_FILE: +        { +               if (ctx) +                        ret = dict_get_str (ctx, "errstr", &errstr); +               break; +        } +        case GD_OP_SYS_EXEC: +        { +               if (ctx) { +                        ret = dict_get_str (ctx, "errstr", &errstr); +                        ret = dict_set_str (ctx, "glusterd_workdir", +                                            conf->workdir); +               } +               break; +        }          }          rsp.op_ret = op_ret; diff --git a/xlators/mgmt/glusterd/src/glusterd-syncop.c b/xlators/mgmt/glusterd/src/glusterd-syncop.c index 7b0c28baf1a..a694cae84d1 100644 --- a/xlators/mgmt/glusterd/src/glusterd-syncop.c +++ b/xlators/mgmt/glusterd/src/glusterd-syncop.c @@ -32,14 +32,77 @@ gd_synctask_barrier_wait (struct syncargs *args, int count)  static void  gd_collate_errors (struct syncargs *args, int op_ret, int op_errno, -                   char *op_errstr) +                   char *op_errstr, int op_code, +                   glusterd_peerinfo_t *peerinfo, u_char *uuid)  { -        if (args->op_ret) -                return; -        args->op_ret = op_ret; -        args->op_errno = op_errno; -        if (op_ret && op_errstr && strcmp (op_errstr, "")) -                args->errstr = gf_strdup (op_errstr); +        char     err_str[PATH_MAX] = "Please check log file for details."; +        char     op_err[PATH_MAX] = ""; +        int      len               = -1; +        char    *peer_str      = NULL; + +        if (op_ret) { +                args->op_ret = op_ret; +                args->op_errno = op_errno; + +                if (peerinfo) +                        peer_str = peerinfo->hostname; +                else +                        peer_str = uuid_utoa (uuid); + +                if (op_errstr && strcmp (op_errstr, "")) { +                        len = snprintf (err_str, sizeof(err_str) - 1, +                                        "Error: %s", op_errstr); +                        err_str[len] = '\0'; +                } + +                switch (op_code){ +                        case GLUSTERD_MGMT_CLUSTER_LOCK : +                        { +                                len = snprintf (op_err, sizeof(op_err) - 1, +                                                "Locking failed on %s. %s", +                                                peer_str, err_str); +                                break; +                        } +                        case GLUSTERD_MGMT_CLUSTER_UNLOCK : +                        { +                                len = snprintf (op_err, sizeof(op_err) - 1, +                                                "Unlocking failed on %s. %s", +                                                peer_str, err_str); +                                break; +                        } +                        case GLUSTERD_MGMT_STAGE_OP : +                        { +                                len = snprintf (op_err, sizeof(op_err) - 1, +                                                "Staging failed on %s. %s", +                                                peer_str, err_str); +                                break; +                        } +                        case GLUSTERD_MGMT_COMMIT_OP : +                        { +                                len = snprintf (op_err, sizeof(op_err) - 1, +                                                "Commit failed on %s. %s", +                                                peer_str, err_str); +                                break; +                        } +                } +                op_err[len] = '\0'; + +                if (args->errstr) { +                        len = snprintf (err_str, sizeof(err_str) - 1, +                                        "%s\n%s", args->errstr, +                                        op_err); +                        GF_FREE (args->errstr); +                        args->errstr = NULL; +                } else +                        len = snprintf (err_str, sizeof(err_str) - 1, +                                        "%s", op_err); +                err_str[len] = '\0'; + +                gf_log ("", GF_LOG_ERROR, "%s", op_err); +                args->errstr = gf_strdup (err_str); +        } + +        return;  }  static void @@ -169,6 +232,9 @@ glusterd_syncop_aggr_rsp_dict (glusterd_op_t op, dict_t *aggr, dict_t *rsp)                          goto out;          break; +        case GD_OP_GSYNC_CREATE: +        break; +          case GD_OP_GSYNC_SET:                  ret = glusterd_gsync_use_rsp_dict (aggr, rsp, NULL);                  if (ret) @@ -203,6 +269,12 @@ glusterd_syncop_aggr_rsp_dict (glusterd_op_t op, dict_t *aggr, dict_t *rsp)          break; +        case GD_OP_SYS_EXEC: +                ret = glusterd_sys_exec_output_rsp_dict (aggr, rsp); +                if (ret) +                        goto out; +        break; +          default:          break;          } @@ -246,7 +318,8 @@ _gd_syncop_mgmt_lock_cbk (struct rpc_req *req, struct iovec *iov,          op_ret = rsp.op_ret;          op_errno = rsp.op_errno;  out: -        gd_collate_errors (args, op_ret, op_errno, NULL); +        gd_collate_errors (args, op_ret, op_errno, NULL, +                           GLUSTERD_MGMT_CLUSTER_LOCK, peerinfo, rsp.uuid);          STACK_DESTROY (frame->root);          synctask_barrier_wake(args);          return 0; @@ -312,7 +385,8 @@ _gd_syncop_mgmt_unlock_cbk (struct rpc_req *req, struct iovec *iov,          op_ret = rsp.op_ret;          op_errno = rsp.op_errno;  out: -        gd_collate_errors (args, op_ret, op_errno, NULL); +        gd_collate_errors (args, op_ret, op_errno, NULL, +                           GLUSTERD_MGMT_CLUSTER_UNLOCK, peerinfo, rsp.uuid);          STACK_DESTROY (frame->root);          synctask_barrier_wake(args);          return 0; @@ -356,6 +430,7 @@ _gd_syncop_stage_op_cbk (struct rpc_req *req, struct iovec *iov,          xlator_t                    *this       = NULL;          dict_t                      *rsp_dict   = NULL;          call_frame_t                *frame      = NULL; +        glusterd_peerinfo_t         *peerinfo   = NULL;          int                         op_ret      = -1;          int                         op_errno    = -1; @@ -389,6 +464,15 @@ _gd_syncop_stage_op_cbk (struct rpc_req *req, struct iovec *iov,                  }          } +        ret = glusterd_friend_find (rsp.uuid, NULL, &peerinfo); +        if (ret) { +                gf_log (this->name, GF_LOG_CRITICAL, "Staging response " +                        "for 'Volume %s' received from unknown " +                        "peer: %s", gd_op_list[rsp.op], +                        uuid_utoa (rsp.uuid)); +                goto out; +        } +          uuid_copy (args->uuid, rsp.uuid);          if (rsp.op == GD_OP_REPLACE_BRICK) {                  pthread_mutex_lock (&args->lock_dict); @@ -407,7 +491,9 @@ _gd_syncop_stage_op_cbk (struct rpc_req *req, struct iovec *iov,          op_errno = rsp.op_errno;  out: -        gd_collate_errors (args, op_ret, op_errno, rsp.op_errstr); +        gd_collate_errors (args, op_ret, op_errno, rsp.op_errstr, +                           GLUSTERD_MGMT_STAGE_OP, peerinfo, rsp.uuid); +          if (rsp_dict)                  dict_unref (rsp_dict); @@ -588,14 +674,15 @@ int32_t  _gd_syncop_commit_op_cbk (struct rpc_req *req, struct iovec *iov,                            int count, void *myframe)  { -        int                         ret         = -1; -        gd1_mgmt_commit_op_rsp      rsp         = {{0},}; -        struct syncargs             *args       = NULL; -        xlator_t                    *this       = NULL; -        dict_t                      *rsp_dict   = NULL; -        call_frame_t                *frame      = NULL; -        int                         op_ret      = -1; -        int                         op_errno    = -1; +        int                          ret           = -1; +        gd1_mgmt_commit_op_rsp       rsp           = {{0},}; +        struct syncargs             *args          = NULL; +        xlator_t                    *this          = NULL; +        dict_t                      *rsp_dict      = NULL; +        call_frame_t                *frame         = NULL; +        glusterd_peerinfo_t         *peerinfo      = NULL; +        int                          op_ret        = -1; +        int                          op_errno      = -1;          this  = THIS;          frame = myframe; @@ -628,6 +715,15 @@ _gd_syncop_commit_op_cbk (struct rpc_req *req, struct iovec *iov,                  }          } +        ret = glusterd_friend_find (rsp.uuid, NULL, &peerinfo); +        if (ret) { +                gf_log (this->name, GF_LOG_CRITICAL, "Commit response " +                        "for 'Volume %s' received from unknown " +                        "peer: %s", gd_op_list[rsp.op], +                        uuid_utoa (rsp.uuid)); +                goto out; +        } +          uuid_copy (args->uuid, rsp.uuid);          pthread_mutex_lock (&args->lock_dict);          { @@ -642,8 +738,10 @@ _gd_syncop_commit_op_cbk (struct rpc_req *req, struct iovec *iov,          op_ret = rsp.op_ret;          op_errno = rsp.op_errno; +  out: -        gd_collate_errors (args, op_ret, op_errno, rsp.op_errstr); +        gd_collate_errors (args, op_ret, op_errno, rsp.op_errstr, +                           GLUSTERD_MGMT_COMMIT_OP, peerinfo, rsp.uuid);          if (rsp_dict)                  dict_unref (rsp_dict); @@ -816,12 +914,16 @@ stage_done:                  peer_cnt++;          }          gd_synctask_barrier_wait((&args), peer_cnt); -        ret = args.op_ret; -        if (dict_get_str (op_ctx, "errstr", &errstr) == 0) + +        if (args.errstr) +                 *op_errstr = gf_strdup (args.errstr); +        else if (dict_get_str (op_ctx, "errstr", &errstr) == 0)                  *op_errstr = gf_strdup (errstr); -        else if (args.errstr) -                *op_errstr = gf_strdup (args.errstr); +        ret = args.op_ret; + +        gf_log (this->name, GF_LOG_DEBUG, "Sent stage op req for 'Volume %s' " +                "to %d peers", gd_op_list[op], peer_cnt);  out:          if (rsp_dict)                  dict_unref (rsp_dict); @@ -881,6 +983,7 @@ commit_done:                  ret = 0;                  goto out;          } +          gd_syncargs_init (&args, op_ctx);          synctask_barrier_init((&args));          peer_cnt = 0; @@ -892,17 +995,23 @@ commit_done:          }          gd_synctask_barrier_wait((&args), peer_cnt);          ret = args.op_ret; -        if (dict_get_str (op_ctx, "errstr", &errstr) == 0) +        if (args.errstr) +                 *op_errstr = gf_strdup (args.errstr); +        else if (dict_get_str (op_ctx, "errstr", &errstr) == 0)                  *op_errstr = gf_strdup (errstr); -        else if (args.errstr) -                *op_errstr = gf_strdup (args.errstr); +        gf_log (this->name, GF_LOG_DEBUG, "Sent commit op req for 'Volume %s' " +                "to %d peers", gd_op_list[op], peer_cnt);  out:          if (!ret)                  glusterd_op_modify_op_ctx (op, op_ctx);          if (rsp_dict)                  dict_unref (rsp_dict); + +        GF_FREE (args.errstr); +        args.errstr = NULL; +          return ret;  } @@ -1108,8 +1217,10 @@ out:          if (req_dict)                  dict_unref (req_dict); -        if (op_errstr) +        if (op_errstr) {                  GF_FREE (op_errstr); +                op_errstr = NULL; +        }          return;  } diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c index be5941830f8..6a760087c12 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -3969,10 +3969,13 @@ glusterd_restart_bricks (glusterd_conf_t *conf)  int  _local_gsyncd_start (dict_t *this, char *key, data_t *value, void *data)  { +        char                        *path_list = NULL;          char                        *slave = NULL;          int                          uuid_len = 0; +        int                          ret = 0;          char                         uuid_str[64] = {0};          glusterd_volinfo_t           *volinfo = NULL; +        char                         *conf_path = NULL;          volinfo = data;          GF_ASSERT (volinfo); @@ -3984,9 +3987,24 @@ _local_gsyncd_start (dict_t *this, char *key, data_t *value, void *data)          uuid_len = (slave - value->data - 1);          strncpy (uuid_str, (char*)value->data, uuid_len); -        glusterd_start_gsync (volinfo, slave, uuid_str, NULL); -        return 0; +        ret = glusterd_get_local_brickpaths (volinfo, &path_list); + +        ret = dict_get_str (this, "conf_path", &conf_path); +        if (ret) { +                gf_log ("", GF_LOG_ERROR, +                        "Unable to fetch conf file path."); +                goto out; +        } + +        glusterd_start_gsync (volinfo, slave, path_list, conf_path, +                              uuid_str, NULL); + +        GF_FREE (path_list); +        path_list = NULL; + +out: +        return ret;  }  int @@ -5425,12 +5443,92 @@ glusterd_delete_all_bricks (glusterd_volinfo_t* volinfo)  }  int +glusterd_get_local_brickpaths (glusterd_volinfo_t *volinfo, char **pathlist) +{ +        char                 **path_tokens  = NULL; +        char                  *tmp_path_list = NULL; +        char                   path[PATH_MAX] = ""; +        int32_t                count          = 0; +        int32_t                pathlen        = 0; +        int32_t                total_len      = 0; +        int32_t                ret            = 0; +        int                    i              = 0; +        glusterd_brickinfo_t  *brickinfo      = NULL; + +        if ((!volinfo) || (!pathlist)) +            goto out; + +        path_tokens = GF_CALLOC (sizeof(char*), volinfo->brick_count, +                                 gf_gld_mt_charptr); +        if (!path_tokens) { +                gf_log ("", GF_LOG_DEBUG, "Could not allocate memory."); +                ret = -1; +                goto out; +        } + +        list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { +                if (uuid_compare (brickinfo->uuid, MY_UUID)) +                        continue; + +                 pathlen = snprintf (path, sizeof(path), +                                     "--path=%s ", brickinfo->path); +                 if (pathlen < sizeof(path)) +                        path[pathlen] = '\0'; +                 else +                        path[sizeof(path)-1] = '\0'; +                 path_tokens[count] = gf_strdup (path); +                 if (!path_tokens[count]) { +                        gf_log ("", GF_LOG_DEBUG, +                                "Could not allocate memory."); +                        ret = -1; +                        goto out; +                 } +                 count++; +                 total_len += pathlen; +        } + +        tmp_path_list = GF_CALLOC (sizeof(char), total_len + 1, +                                   gf_gld_mt_char); +        if (!tmp_path_list) { +                gf_log ("", GF_LOG_DEBUG, "Could not allocate memory."); +                ret = -1; +                goto out; +        } + +        for (i = 0; i < count; i++) +                strcat (tmp_path_list, path_tokens[i]); + +        if (count) +                *pathlist = tmp_path_list; + +        ret = count; +out: +        for (i = 0; i < count; i++) { +                GF_FREE (path_tokens[i]); +                path_tokens[i] = NULL; +        } + +        GF_FREE (path_tokens); +        path_tokens = NULL; + +        if (ret == 0) { +                gf_log ("", GF_LOG_DEBUG, "No Local Bricks Present."); +                GF_FREE (tmp_path_list); +                tmp_path_list = NULL; +        } + +        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); +        return ret; +} + +int  glusterd_start_gsync (glusterd_volinfo_t *master_vol, char *slave, -                      char *glusterd_uuid_str, char **op_errstr) +                      char *path_list, char *conf_path, +                      char *glusterd_uuid_str, +                      char **op_errstr)  {          int32_t         ret     = 0;          int32_t         status  = 0; -        char            buf[PATH_MAX]   = {0,};          char            uuid_str [64] = {0};          runner_t        runner = {0,};          xlator_t        *this = NULL; @@ -5443,32 +5541,23 @@ glusterd_start_gsync (glusterd_volinfo_t *master_vol, char *slave,          GF_ASSERT (priv);          uuid_utoa_r (MY_UUID, uuid_str); -        if (strcmp (uuid_str, glusterd_uuid_str)) -                goto out; - -        ret = gsync_status (master_vol->volname, slave, &status); -        if (status == 0) -                goto out; -        snprintf (buf, PATH_MAX, "%s/"GEOREP"/%s", priv->workdir, master_vol->volname); -        ret = mkdir_p (buf, 0777, _gf_true); -        if (ret) { -                errcode = -1; +        if (!path_list) { +                ret = 0; +                gf_log ("", GF_LOG_DEBUG, "No Bricks in this node." +                        " Not starting gsyncd.");                  goto out;          } -        snprintf (buf, PATH_MAX, DEFAULT_LOG_FILE_DIRECTORY"/"GEOREP"/%s", -                  master_vol->volname); -        ret = mkdir_p (buf, 0777, _gf_true); -        if (ret) { -                errcode = -1; +        ret = gsync_status (master_vol->volname, slave, conf_path, &status); +        if (status == 0)                  goto out; -        }          uuid_utoa_r (master_vol->volume_id, uuid_str);          runinit (&runner); -        runner_add_args  (&runner, GSYNCD_PREFIX"/gsyncd", "-c", NULL); -        runner_argprintf (&runner, "%s/"GSYNC_CONF, priv->workdir); +        runner_add_args  (&runner, GSYNCD_PREFIX"/gsyncd", +                          path_list, "-c", NULL); +        runner_argprintf (&runner, "%s", conf_path);          runner_argprintf (&runner, ":%s", master_vol->volname);          runner_add_args  (&runner, slave, "--config-set", "session-owner",                            uuid_str, NULL); @@ -5481,9 +5570,12 @@ glusterd_start_gsync (glusterd_volinfo_t *master_vol, char *slave,          }          runinit (&runner); -        runner_add_args  (&runner, GSYNCD_PREFIX"/gsyncd", "--monitor", "-c", NULL); -        runner_argprintf (&runner, "%s/"GSYNC_CONF, priv->workdir); +        runner_add_args  (&runner, GSYNCD_PREFIX"/gsyncd", +                          path_list, "--monitor", "-c", NULL); +        runner_argprintf (&runner, "%s", conf_path);          runner_argprintf (&runner, ":%s", master_vol->volname); +        runner_argprintf (&runner, "--glusterd-uuid=%s", +                          uuid_utoa (priv->uuid));          runner_add_arg   (&runner, slave);          synclock_unlock (&priv->big_lock);          ret = runner_run (&runner); @@ -5499,7 +5591,7 @@ glusterd_start_gsync (glusterd_volinfo_t *master_vol, char *slave,  out:          if ((ret != 0) && errcode == -1) {                  if (op_errstr) -                        *op_errstr = gf_strdup ("internal error, cannot start" +                        *op_errstr = gf_strdup ("internal error, cannot start "                                                  "the " GEOREP " session");          } @@ -6853,6 +6945,61 @@ out:  }  int +glusterd_sys_exec_output_rsp_dict (dict_t *dst, dict_t *src) +{ +        char           output_name[PATH_MAX] = ""; +        char          *output = NULL; +        int            ret      = 0; +        int            i      = 0; +        int            len    = 0; +        int            src_output_count      = 0; +        int            dst_output_count      = 0; + +        if (!dst || !src) { +                gf_log ("", GF_LOG_ERROR, "Source or Destination " +                        "dict is empty."); +                goto out; +        } + +        ret = dict_get_int32 (dst, "output_count", &dst_output_count); + +        ret = dict_get_int32 (src, "output_count", &src_output_count); +        if (ret) { +                gf_log ("", GF_LOG_DEBUG, "No output from source"); +                ret = 0; +                goto out; +        } + +        for (i = 1; i <= src_output_count; i++) { +                len = snprintf (output_name, sizeof(output_name) - 1, +                                "output_%d", i); +                output_name[len] = '\0'; +                ret = dict_get_str (src, output_name, &output); +                if (ret) { +                        gf_log ("", GF_LOG_ERROR, "Unable to fetch %s", +                                output_name); +                        goto out; +                } + +                len = snprintf (output_name, sizeof(output_name) - 1, +                                "output_%d", i+dst_output_count); +                output_name[len] = '\0'; +                ret = dict_set_dynstr (dst, output_name, gf_strdup (output)); +                if (ret) { +                        gf_log ("", GF_LOG_ERROR, "Unable to set %s", +                                output_name); +                        goto out; +                } +        } + +        ret = dict_set_int32 (dst, "output_count", +                              dst_output_count+src_output_count); +out: +        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); +        return ret; +} + +int  glusterd_use_rsp_dict (dict_t *aggr, dict_t *rsp_dict)  {          int            ret      = 0; @@ -7404,3 +7551,39 @@ gd_is_remove_brick_committed (glusterd_volinfo_t *volinfo)          return _gf_true;  } + +gf_boolean_t +glusterd_are_vol_all_peers_up (glusterd_volinfo_t *volinfo, +                               struct list_head *peers, +                               char **down_peerstr) +{ +        glusterd_peerinfo_t   *peerinfo  = NULL; +        glusterd_brickinfo_t  *brickinfo = NULL; +        gf_boolean_t           ret       = _gf_false; + +        list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { +                if (!uuid_compare (brickinfo->uuid, MY_UUID)) +                        continue; + +                list_for_each_entry (peerinfo, peers, uuid_list) { +                        if (uuid_compare (peerinfo->uuid, brickinfo->uuid)) +                                continue; + +                        /*Found peer who owns the brick, return false +                         * if peer is not connected or not friend */ +                        if (!(peerinfo->connected) || +                           (peerinfo->state.state != +                             GD_FRIEND_STATE_BEFRIENDED)) { +                                *down_peerstr = gf_strdup (peerinfo->hostname); +                                gf_log ("", GF_LOG_DEBUG, "Peer %s is down. ", +                                        peerinfo->hostname); +                                goto out; +                        } +                } +       } + +        ret = _gf_true; +out: +        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); +        return ret; +} diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h index 912b394b497..818b3f4faed 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.h +++ b/xlators/mgmt/glusterd/src/glusterd-utils.h @@ -367,7 +367,13 @@ int  glusterd_restart_gsyncds (glusterd_conf_t *conf);  int  glusterd_start_gsync (glusterd_volinfo_t *master_vol, char *slave, -                      char *glusterd_uuid_str, char **op_errstr); +                      char *path_list, char *conf_path, +                      char *glusterd_uuid_str, +                      char **op_errstr); +int +glusterd_get_local_brickpaths (glusterd_volinfo_t *volinfo, +                               char **pathlist); +  int32_t  glusterd_recreate_bricks (glusterd_conf_t *conf);  int32_t @@ -471,6 +477,8 @@ int  glusterd_volume_heal_use_rsp_dict (dict_t *aggr, dict_t *rsp_dict);  int  glusterd_use_rsp_dict (dict_t *aggr, dict_t *rsp_dict); +int +glusterd_sys_exec_output_rsp_dict (dict_t *aggr, dict_t *rsp_dict);  int32_t  glusterd_handle_node_rsp (dict_t *req_ctx, void *pending_entry,                            glusterd_op_t op, dict_t *rsp_dict, dict_t *op_ctx, @@ -487,6 +495,11 @@ glusterd_profile_volume_brick_rsp (void *pending_entry,                                     dict_t *rsp_dict, dict_t *op_ctx,                                     char **op_errstr, gd_node_type type); +gf_boolean_t +glusterd_are_vol_all_peers_up (glusterd_volinfo_t *volinfo, +                               struct list_head *peers, +                               char **down_peerstr); +  /* Should be used only when an operation is in progress, as that is the only   * time a lock_owner is set   */ @@ -531,4 +544,9 @@ gd_peer_uuid_str (glusterd_peerinfo_t *peerinfo);  gf_boolean_t  gd_is_remove_brick_committed (glusterd_volinfo_t *volinfo); + +gf_boolean_t +glusterd_are_vol_all_peers_up (glusterd_volinfo_t *volinfo, +                               struct list_head *peers, +                               char **down_peerstr);  #endif diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.h b/xlators/mgmt/glusterd/src/glusterd-volgen.h index 6a41f47c16c..4ff899f4aad 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volgen.h +++ b/xlators/mgmt/glusterd/src/glusterd-volgen.h @@ -23,6 +23,7 @@  #define VKEY_DIAG_LAT_MEASUREMENT "diagnostics.latency-measurement"  #define VKEY_FEATURES_LIMIT_USAGE "features.limit-usage"  #define VKEY_MARKER_XTIME         GEOREP".indexing" +#define VKEY_CHANGELOG            "changelog.changelog"  #define VKEY_FEATURES_QUOTA       "features.quota"  #define AUTH_ALLOW_MAP_KEY "auth.allow" diff --git a/xlators/mgmt/glusterd/src/glusterd.c b/xlators/mgmt/glusterd/src/glusterd.c index 53ca33ef92a..a43c8d54207 100644 --- a/xlators/mgmt/glusterd/src/glusterd.c +++ b/xlators/mgmt/glusterd/src/glusterd.c @@ -94,6 +94,9 @@ const char *gd_op_list[GD_OP_MAX + 1] = {          [GD_OP_LIST_VOLUME]             = "Lists",          [GD_OP_CLEARLOCKS_VOLUME]       = "Clear locks",          [GD_OP_DEFRAG_BRICK_VOLUME]     = "Rebalance", +        [GD_OP_COPY_FILE]               = "Copy File", +        [GD_OP_SYS_EXEC]                = "Execute system commands", +        [GD_OP_GSYNC_CREATE]            = "Geo-replication Create",          [GD_OP_MAX]                     = "Invalid op"  }; @@ -519,7 +522,7 @@ runinit_gsyncd_setrx (runner_t *runner, glusterd_conf_t *conf)  {          runinit (runner);          runner_add_args (runner, GSYNCD_PREFIX"/gsyncd", "-c", NULL); -        runner_argprintf (runner, "%s/"GSYNC_CONF,conf->workdir); +        runner_argprintf (runner, "%s/"GSYNC_CONF_TEMPLATE, conf->workdir);          runner_add_arg (runner, "--config-set-rx");  } @@ -581,7 +584,7 @@ configure_syncdaemon (glusterd_conf_t *conf)          /* gluster-params */          runinit_gsyncd_setrx (&runner, conf);          runner_add_args (&runner, "gluster-params", -                         "xlator-option=*-dht.assert-no-child-down=true", +                         "aux-gfid-mount xlator-option=*-dht.assert-no-child-down=true",                           ".", ".", NULL);          RUN_GSYNCD_CMD; @@ -598,14 +601,30 @@ configure_syncdaemon (glusterd_conf_t *conf)          /* pid-file */          runinit_gsyncd_setrx (&runner, conf);          runner_add_arg (&runner, "pid-file"); -        runner_argprintf (&runner, "%s/${mastervol}/${eSlave}.pid", georepdir); +        runner_argprintf (&runner, "%s/${mastervol}-${slavevol}/${eSlave}.pid", georepdir);          runner_add_args (&runner, ".", ".", NULL);          RUN_GSYNCD_CMD;          /* state-file */          runinit_gsyncd_setrx (&runner, conf);          runner_add_arg (&runner, "state-file"); -        runner_argprintf (&runner, "%s/${mastervol}/${eSlave}.status", georepdir); +        runner_argprintf (&runner, "%s/${mastervol}-${slavevol}/${eSlave}.status", georepdir); +        runner_add_args (&runner, ".", ".", NULL); +        RUN_GSYNCD_CMD; + +        /* state-detail-file */ +        runinit_gsyncd_setrx (&runner, conf); +        runner_add_arg (&runner, "state-detail-file"); +        runner_argprintf (&runner, "%s/${mastervol}-${slavevol}/${eSlave}-detail.status", +                          georepdir); +        runner_add_args (&runner, ".", ".", NULL); +        RUN_GSYNCD_CMD; + +        /* state-detail-file */ +        runinit_gsyncd_setrx (&runner, conf); +        runner_add_arg (&runner, "state-detail-file"); +        runner_argprintf (&runner, "%s/${mastervol}-${slavevol}/${eSlave}-detail.status", +                          georepdir);          runner_add_args (&runner, ".", ".", NULL);          RUN_GSYNCD_CMD; @@ -647,6 +666,18 @@ configure_syncdaemon (glusterd_conf_t *conf)          runner_add_args (&runner, "special-sync-mode", "partial", ".", ".", NULL);          RUN_GSYNCD_CMD; +        /* change-detector == changelog */ +        runinit_gsyncd_setrx (&runner, conf); +        runner_add_args(&runner, "change-detector", "changelog", ".", ".", NULL); +        RUN_GSYNCD_CMD; + +        runinit_gsyncd_setrx (&runner, conf); +        runner_add_arg(&runner, "working-dir"); +        runner_argprintf(&runner, "%s/${mastervol}/${eSlave}", +                         DEFAULT_VAR_RUN_DIRECTORY); +        runner_add_args (&runner, ".", ".", NULL); +        RUN_GSYNCD_CMD; +          /************           * slave pre-configuration           ************/ @@ -660,7 +691,7 @@ configure_syncdaemon (glusterd_conf_t *conf)          /* gluster-params */          runinit_gsyncd_setrx (&runner, conf);          runner_add_args (&runner, "gluster-params", -                         "xlator-option=*-dht.assert-no-child-down=true", +                         "aux-gfid-mount xlator-option=*-dht.assert-no-child-down=true",                           ".", NULL);          RUN_GSYNCD_CMD; @@ -967,6 +998,7 @@ init (xlator_t *this)                  first_time = 1;          } +        setenv ("GLUSTERD_WORKING_DIR", workdir, 1);          gf_log (this->name, GF_LOG_INFO, "Using %s as working directory",                  workdir); diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h index 6bd9431e83e..ccdf1c435e9 100644 --- a/xlators/mgmt/glusterd/src/glusterd.h +++ b/xlators/mgmt/glusterd/src/glusterd.h @@ -47,6 +47,7 @@  #define GLUSTERD_QUORUM_TYPE_KEY        "cluster.server-quorum-type"  #define GLUSTERD_QUORUM_RATIO_KEY       "cluster.server-quorum-ratio"  #define GLUSTERD_GLOBAL_OPT_VERSION     "global-option-version" +#define GLUSTERD_COMMON_PEM_PUB_FILE    "/geo-replication/common_secret.pem.pub"  #define GLUSTERD_SERVER_QUORUM "server" @@ -95,6 +96,9 @@ typedef enum glusterd_op_ {          GD_OP_CLEARLOCKS_VOLUME,          GD_OP_DEFRAG_BRICK_VOLUME,          GD_OP_BD_OP, +        GD_OP_COPY_FILE, +        GD_OP_SYS_EXEC, +        GD_OP_GSYNC_CREATE,          GD_OP_MAX,  } glusterd_op_t; @@ -602,6 +606,12 @@ int  glusterd_handle_reset_volume (rpcsvc_request_t *req);  int +glusterd_handle_copy_file (rpcsvc_request_t *req); + +int +glusterd_handle_sys_exec (rpcsvc_request_t *req); + +int  glusterd_handle_gsync_set (rpcsvc_request_t *req);  int @@ -685,6 +695,12 @@ int glusterd_op_stage_heal_volume (dict_t *dict, char **op_errstr);  int glusterd_op_heal_volume (dict_t *dict, char **op_errstr);  int glusterd_op_stage_gsync_set (dict_t *dict, char **op_errstr);  int glusterd_op_gsync_set (dict_t *dict, char **op_errstr, dict_t *rsp_dict); +int glusterd_op_stage_copy_file (dict_t *dict, char **op_errstr); +int glusterd_op_copy_file (dict_t *dict, char **op_errstr); +int glusterd_op_stage_sys_exec (dict_t *dict, char **op_errstr); +int glusterd_op_sys_exec (dict_t *dict, char **op_errstr, dict_t *rsp_dict); +int glusterd_op_stage_gsync_create (dict_t *dict, char **op_errstr); +int glusterd_op_gsync_create (dict_t *dict, char **op_errstr, dict_t *rsp_dict);  int glusterd_op_quota (dict_t *dict, char **op_errstr, dict_t *rsp_dict);  int glusterd_op_stage_quota (dict_t *dict, char **op_errstr);  int glusterd_op_stage_replace_brick (dict_t *dict, char **op_errstr, @@ -726,7 +742,7 @@ int glusterd_op_statedump_volume_args_get (dict_t *dict, char **volname,                                             char **options, int *option_cnt);  int glusterd_op_gsync_args_get (dict_t *dict, char **op_errstr, -                                char **master, char **slave); +                                char **master, char **slave, char **host_uuid);  /* Synctask part */  int32_t glusterd_op_begin_synctask (rpcsvc_request_t *req, glusterd_op_t op,                                      void *dict);  | 
