diff options
| author | Ajeet Jha <ajha@redhat.com> | 2013-12-02 12:55:18 +0530 | 
|---|---|---|
| committer | Vijay Bellur <vbellur@redhat.com> | 2014-01-27 09:44:33 -0800 | 
| commit | f33d09f23b089bd07437eb714f8dffa43460d6b5 (patch) | |
| tree | d574dcc8b030a59425d9b0717879eb4033866c3e | |
| parent | 30592e7f92515c5df620f300d6a3df6373ac6200 (diff) | |
glusterd/geo-rep: more glusterd and cli fixes for geo-rep.
    -> handle option validation cases in reset case.
    -> Creating valid conf path when glusterd restarts.
    -> Reading the gsyncd worker thread status and displaying it.
    -> Displaying status-detail per worker.
    -> Fetch checkpoint info in geo-rep status.
    -> use-tarssh value validation added.
misc: misc geo-rep fixes based on cluster, logrotate etc..
    -> cluster/dht: fix 'stime' getxattr getting overwritten.
    -> cluster/afr: return max of 'stime' values in subvol.
    -> geo-rep-logrotate: Sending SIGHUP to geo-rep auxiliary.
    -> cluster/dht: fix convoluted logic while aggregating.
    -> cluster/*: fix 'stime' min/max fetch logic.
Change-Id: I811acea0bbd6194797a3e55d89295d1ea021ac85
BUG: 1036552
Signed-off-by: Ajeet Jha <ajha@redhat.com>
Reviewed-on: http://review.gluster.org/6405
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Amar Tumballi <amarts@gmail.com>
Reviewed-by: Anand Avati <avati@redhat.com>
Reviewed-on: http://review.gluster.org/6810
Reviewed-by: Vijay Bellur <vbellur@redhat.com>
| -rw-r--r-- | cli/src/cli-cmd-parser.c | 12 | ||||
| -rw-r--r-- | cli/src/cli-rpc-ops.c | 258 | ||||
| -rw-r--r-- | cli/src/cli.h | 14 | ||||
| -rw-r--r-- | extras/glusterfs-georep-logrotate | 18 | ||||
| -rw-r--r-- | libglusterfs/src/mem-types.h | 3 | ||||
| -rw-r--r-- | rpc/rpc-lib/src/protocol-common.h | 17 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-inode-read.c | 2 | ||||
| -rw-r--r-- | xlators/cluster/dht/src/dht-common.c | 8 | ||||
| -rw-r--r-- | xlators/lib/src/libxlator.c | 55 | ||||
| -rw-r--r-- | xlators/lib/src/libxlator.h | 3 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-geo-rep.c | 563 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-mountbroker.c | 1 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.c | 136 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.h | 11 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd.c | 21 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd.h | 2 | 
16 files changed, 646 insertions, 478 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index 88fbf96ff..b086418ff 100644 --- a/cli/src/cli-cmd-parser.c +++ b/cli/src/cli-cmd-parser.c @@ -1706,13 +1706,13 @@ config_parse (const char **words, int wordcount, dict_t *dict,                  }                  append_str[append_len - 2] = '\0';                  /* "checkpoint now" is special: we resolve that "now" */ -                if (strcmp (words[cmdi + 1], "checkpoint") == 0 && -                    strcmp (append_str, "now") == 0) { +                if ((strcmp (words[cmdi + 1], "checkpoint") == 0) && +                    (strcmp (append_str, "now") == 0)) {                          struct timeval tv = {0,};                          ret = gettimeofday (&tv, NULL);                          if (ret == -1) -                                goto out; /* FIXME: free append_str? */ +                                goto out;                          GF_FREE (append_str);                          append_str = GF_CALLOC (1, 300, cli_mt_append_str); @@ -1720,10 +1720,8 @@ config_parse (const char **words, int wordcount, dict_t *dict,                                  ret = -1;                                  goto out;                          } -                        strcpy (append_str, "as of "); -                        gf_time_fmt (append_str + strlen ("as of "), -                                     300 - strlen ("as of "), -                                     tv.tv_sec, gf_timefmt_FT); +                        snprintf (append_str, 300, "now:%ld.%06ld", +                                  tv.tv_sec, tv.tv_usec);                  }                  ret = dict_set_dynstr (dict, "op_value", append_str); diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c index 3d2f90c04..013dd09b6 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -3874,85 +3874,22 @@ gf_cli_gsync_config_command (dict_t *dict)          return runner_run (&runner);  } -int -gf_cli_fetch_gsyncd_status_values (char *status, -                                   gf_cli_gsync_status_t *sts_val) -{ -        int32_t   ret      = -1; -        char     *tmp      = NULL; -        char     *save_ptr = NULL; -        char     *key      = NULL; -        char     *value    = NULL; - -        if (!status || !sts_val) { -                gf_log ("", GF_LOG_ERROR, "status or sts_val is null"); -                goto out; -        } - -        tmp = strtok_r (status, "\n", &save_ptr); - -        if (tmp) -                sts_val->health = gf_strdup (tmp); - -        while (tmp) { -                key = strtok_r (tmp, "=", &value); - -                if ((key) && (!strcmp(key, "Uptime"))) -                        sts_val->uptime = gf_strdup (value); - -                if ((key) && (!strcmp(key, "FilesSyncd"))) -                        sts_val->files_syncd = gf_strdup (value); - -                if ((key) && (!strcmp(key, "FilesPending"))) -                        sts_val->files_pending = gf_strdup (value); - -                if ((key) && (!strcmp(key, "BytesPending"))) { -                        value = gf_uint64_2human_readable(atol(value)); -                        sts_val->bytes_pending = gf_strdup (value); -                } - -                if ((key) && (!strcmp(key, "DeletesPending"))) -                        sts_val->deletes_pending = gf_strdup (value); - -                tmp = strtok_r (NULL, ";", &save_ptr); -        } - -        if (sts_val->health) -                ret = 0; - -        if (!sts_val->uptime) -                sts_val->uptime = gf_strdup ("N/A"); - -        if (!sts_val->files_syncd) -                sts_val->files_syncd = gf_strdup ("N/A"); - -        if (!sts_val->files_pending) -                sts_val->files_pending = gf_strdup ("N/A"); - -        if (!sts_val->bytes_pending) -                sts_val->bytes_pending = gf_strdup ("N/A"); - -        if (!sts_val->deletes_pending) -                sts_val->deletes_pending = gf_strdup ("N/A"); - -out: -        gf_log ("", GF_LOG_DEBUG, "Returning %d.", ret); -        return ret; -} -  char* -get_struct_variable (int mem_num, gf_cli_gsync_status_t *sts_val) +get_struct_variable (int mem_num, gf_gsync_status_t *sts_val)  {          switch (mem_num) { -        case 0: return (sts_val->node); -        case 1: return (sts_val->master); -        case 2: return (sts_val->slave); -        case 3: return (sts_val->health); -        case 4: return (sts_val->uptime); -        case 5: return (sts_val->files_syncd); -        case 6: return (sts_val->files_pending); -        case 7: return (sts_val->bytes_pending); -        case 8: return (sts_val->deletes_pending); +        case 0:  return (sts_val->node); +        case 1:  return (sts_val->master); +        case 2:  return (sts_val->brick); +        case 3:  return (sts_val->slave_node); +        case 4:  return (sts_val->worker_status); +        case 5:  return (sts_val->checkpoint_status); +        case 6:  return (sts_val->crawl_status); +        case 7:  return (sts_val->files_syncd); +        case 8:  return (sts_val->files_remaining); +        case 9:  return (sts_val->bytes_remaining); +        case 10: return (sts_val->purges_remaining); +        case 11: return (sts_val->total_files_skipped);          default:                   goto out;          } @@ -3963,28 +3900,23 @@ out:  int  gf_cli_print_status (char **title_values, -                     gf_cli_gsync_status_t **sts_vals, +                     gf_gsync_status_t **sts_vals,                       int *spacing, int gsync_count,                       int number_of_fields, int is_detail)  { -        int     indents                  = 0;          int     i                        = 0;          int     j                        = 0;          int     ret                      = 0; +        int     status_fields            = 6; /* Indexed at 0 */          int     total_spacing            = 0;          char  **output_values            = NULL;          char   *tmp                      = NULL;          char   *hyphens                  = NULL; -        char    heading[PATH_MAX]        = {0, }; -        char    indent_spaces[PATH_MAX]  = {0, };          /* calculating spacing for hyphens */          for (i = 0; i < number_of_fields; i++) { -                /* Suppressing master and slave output for status detail */ -                if ((is_detail) && ((i == 1) || (i == 2))) { -                        total_spacing++; -                        continue; -                } else if ((!is_detail) && (i > 4)) { +                /* Suppressing detail output for status */ +                if ((!is_detail) && (i > status_fields)) {                         /* Suppressing detailed output for                          * status */                          continue; @@ -4018,64 +3950,29 @@ gf_cli_print_status (char **title_values,                  goto out;          } -        ret = snprintf(heading, sizeof(heading), "MASTER: %s  SLAVE: %s", -                       sts_vals[0]->master, sts_vals[0]->slave); -        if (ret) { -                if (ret < sizeof(heading)) -                        heading[ret] = '\0'; -                else -                        heading[sizeof(heading) - 1] = '\0'; -                ret = 0; -        } else { -                ret = -1; -                goto out; -        } - -        if (is_detail) { -                cli_out (" "); -                if (strlen(heading) > total_spacing) -                        cli_out ("%s", heading); -                else { -                        /* Printing the heading with centre justification */ -                        indents = (total_spacing - strlen(heading)) / 2; -                        memset (indent_spaces, ' ', indents); -                        indent_spaces[indents] = '\0'; -                        ret = snprintf (hyphens, total_spacing, "%s%s", -                                        indent_spaces, heading); -                        if (ret) { -                                hyphens[ret] = '\0'; -                                cli_out ("%s", hyphens); -                                ret = 0; -                        } else { -                                ret = -1; -                                goto out; -                        } -                } -                cli_out (" "); -        } +        cli_out (" ");          /* setting the title "NODE", "MASTER", etc. from title_values[]             and printing the same */          for (j = 0; j < number_of_fields; j++) { -                /* Suppressing master and slave output for status detail */ -                if ((is_detail) && ((j == 1) || (j == 2))) { -                        output_values[j][0] = '\0'; -                        continue; -                } else if ((!is_detail) && (j > 4)) { +                if ((!is_detail) && (j > status_fields)) {                         /* Suppressing detailed output for                          * status */                         output_values[j][0] = '\0'; -                        continue; +                       continue;                  }                  memset (output_values[j], ' ', spacing[j]);                  memcpy (output_values[j], title_values[j],                          strlen(title_values[j]));                  output_values[j][spacing[j]] = '\0';          } -        cli_out ("%s %s %s %s %s %s %s %s %s", output_values[0], -                 output_values[1], output_values[2], output_values[3], -                 output_values[4], output_values[5], output_values[6], -                 output_values[7], output_values[8]); +        cli_out ("%s %s %s %s %s %s %s %s %s %s %s %s", +                 output_values[0], output_values[1], +                 output_values[2], output_values[3], +                 output_values[4], output_values[5], +                 output_values[6], output_values[7], +                 output_values[8], output_values[9], +                 output_values[10], output_values[11]);          /* setting and printing the hyphens */          memset (hyphens, '-', total_spacing); @@ -4084,12 +3981,7 @@ gf_cli_print_status (char **title_values,          for (i = 0; i < gsync_count; i++) {                  for (j = 0; j < number_of_fields; j++) { -                        /* Suppressing master and slave output for -                         * status detail */ -                        if ((is_detail) && ((j == 1) || (j == 2))) { -                                output_values[j][0] = '\0'; -                                continue; -                        }  else if ((!is_detail) && (j > 4)) { +                        if ((!is_detail) && (j > status_fields)) {                                  /* Suppressing detailed output for                                   * status */                                  output_values[j][0] = '\0'; @@ -4107,10 +3999,13 @@ gf_cli_print_status (char **title_values,                          output_values[j][spacing[j]] = '\0';                  } -                cli_out ("%s %s %s %s %s %s %s %s %s", output_values[0], -                         output_values[1], output_values[2], output_values[3], -                         output_values[4], output_values[5], output_values[6], -                         output_values[7], output_values[8]); +                cli_out ("%s %s %s %s %s %s %s %s %s %s %s %s", +                         output_values[0], output_values[1], +                         output_values[2], output_values[3], +                         output_values[4], output_values[5], +                         output_values[6], output_values[7], +                         output_values[8], output_values[9], +                         output_values[10], output_values[11]);          }  out: @@ -4130,47 +4025,23 @@ out:  int  gf_cli_read_status_data (dict_t *dict, -                         gf_cli_gsync_status_t **sts_vals, +                         gf_gsync_status_t **sts_vals,                           int *spacing, int gsync_count,                           int number_of_fields)  { -        int     ret            = 0; -        int     i              = 0; -        int     j              = 0; -        char    mst[PATH_MAX]  = {0, }; -        char    slv[PATH_MAX]  = {0, }; -        char    sts[PATH_MAX]  = {0, }; -        char    nds[PATH_MAX]  = {0, }; -        char   *status         = NULL; -        char   *tmp            = NULL; +        char   *tmp                    = NULL; +        char    sts_val_name[PATH_MAX] = ""; +        int     ret                    = 0; +        int     i                      = 0; +        int     j                      = 0;          /* Storing per node status info in each object */          for (i = 0; i < gsync_count; i++) { -                snprintf (nds, sizeof(nds), "node%d", i + 1); -                snprintf (mst, sizeof(mst), "master%d", i + 1); -                snprintf (slv, sizeof(slv), "slave%d", i + 1); -                snprintf (sts, sizeof(sts), "status%d", i + 1); +                snprintf (sts_val_name, sizeof(sts_val_name), "status_value%d", i);                  /* Fetching the values from dict, and calculating                     the max length for each field */ -                ret = dict_get_str (dict, nds, &(sts_vals[i]->node)); -                if (ret) -                        goto out; - -                ret = dict_get_str (dict, mst, &(sts_vals[i]->master)); -                if (ret) -                        goto out; - -                ret = dict_get_str (dict, slv, &(sts_vals[i]->slave)); -                if (ret) -                        goto out; - -                ret = dict_get_str (dict, sts, &status); -                if (ret) -                        goto out; - -                /* Fetching health and uptime from sts_val */ -                ret = gf_cli_fetch_gsyncd_status_values (status, sts_vals[i]); +                ret = dict_get_bin (dict, sts_val_name, (void **)&(sts_vals[i]));                  if (ret)                          goto out; @@ -4192,25 +4063,23 @@ out:  }  int -gf_cli_gsync_status_output (dict_t *dict, int status_detail) +gf_cli_gsync_status_output (dict_t *dict, gf_boolean_t is_detail)  {          int                     gsync_count    = 0;          int                     i              = 0; -        int                     j              = 0;          int                     ret            = 0; -        int                     spacing[10]    = {0}; -        int                     num_of_fields  = 9; +        int                     spacing[13]    = {0}; +        int                     num_of_fields  = 12;          char                    errmsg[1024]   = "";          char                   *master         = NULL;          char                   *slave          = NULL; -        char                   *tmp            = NULL; -        char                   *title_values[] = {"NODE", "MASTER", "SLAVE", -                                                  "HEALTH", "UPTIME", -                                                  "FILES SYNCD", -                                                  "FILES PENDING", -                                                  "BYTES PENDING", -                                                  "DELETES PENDING"}; -        gf_cli_gsync_status_t **sts_vals = NULL; +        char                   *title_values[] = {"MASTER NODE", "MASTER VOL", +                                                  "MASTER BRICK", "SLAVE", +                                                  "STATUS", "CHECKPOINT STATUS", +                                                  "CRAWL STATUS", "FILES SYNCD", +                                                  "FILES PENDING", "BYTES PENDING", +                                                  "DELETES PENDING", "FILES SKIPPED"}; +        gf_gsync_status_t     **sts_vals       = NULL;          /* Checks if any session is active or not */          ret = dict_get_int32 (dict, "gsync-count", &gsync_count); @@ -4244,14 +4113,14 @@ gf_cli_gsync_status_output (dict_t *dict, int status_detail)          /* gsync_count = number of nodes reporting output.             each sts_val object will store output of each             node */ -        sts_vals = GF_CALLOC (gsync_count, sizeof (gf_cli_gsync_status_t *), +        sts_vals = GF_CALLOC (gsync_count, sizeof (gf_gsync_status_t *),                                gf_common_mt_char);          if (!sts_vals) {                  ret = -1;                  goto out;          }          for (i = 0; i < gsync_count; i++) { -                sts_vals[i] = GF_CALLOC (1, sizeof (gf_cli_gsync_status_t), +                sts_vals[i] = GF_CALLOC (1, sizeof (gf_gsync_status_t),                                           gf_common_mt_char);                  if (!sts_vals[i]) {                          ret = -1; @@ -4267,23 +4136,15 @@ gf_cli_gsync_status_output (dict_t *dict, int status_detail)          }          ret = gf_cli_print_status (title_values, sts_vals, spacing, gsync_count, -                                   num_of_fields, status_detail); +                                   num_of_fields, is_detail);          if (ret) {                  gf_log ("", GF_LOG_ERROR, "Unable to print status output");                  goto out;          }  out: -        if (sts_vals) { -                for (i = 0; i < gsync_count; i++) { -                        for (j = 3; j < num_of_fields; j++) { -                                tmp = get_struct_variable(j, sts_vals[i]); -                                if (tmp) -                                        GF_FREE (tmp); -                        } -                } +        if (sts_vals)                  GF_FREE (sts_vals); -        }          return ret;  } @@ -4602,7 +4463,10 @@ gf_cli_gsync_set_cbk (struct rpc_req *req, struct iovec *iov,                          status_detail = dict_get_str_boolean (dict,                                                                "status-detail",                                                                _gf_false); -                        ret = gf_cli_gsync_status_output (dict, status_detail); +                        if (status_detail) +                                ret = gf_cli_gsync_status_output (dict, status_detail); +                        else +                                ret = gf_cli_gsync_status_output (dict, status_detail);                  break;                  case GF_GSYNC_OPTION_TYPE_DELETE: diff --git a/cli/src/cli.h b/cli/src/cli.h index 1fe8ffff7..73d23d684 100644 --- a/cli/src/cli.h +++ b/cli/src/cli.h @@ -147,18 +147,6 @@ struct cli_local {  #endif  }; -struct gf_cli_gsync_detailed_status_ { -        char *node; -        char *master; -        char *slave; -        char *health; -        char *uptime; -        char *files_syncd; -        char *files_pending; -        char *bytes_pending; -        char *deletes_pending; -}; -  struct cli_volume_status {          int            port;          int            online; @@ -177,8 +165,6 @@ struct cli_volume_status {  #endif  }; -typedef struct gf_cli_gsync_detailed_status_ gf_cli_gsync_status_t; -  typedef struct cli_volume_status cli_volume_status_t;  typedef struct cli_local cli_local_t; diff --git a/extras/glusterfs-georep-logrotate b/extras/glusterfs-georep-logrotate index 6a69ab1e3..85e69d2c0 100644 --- a/extras/glusterfs-georep-logrotate +++ b/extras/glusterfs-georep-logrotate @@ -7,12 +7,30 @@ delaycompress  notifempty  /var/log/glusterfs/geo-replication/*/*.log { +  sharedscripts +  postrotate +  for pid in `ps -aef | grep glusterfs | egrep "\-\-aux-gfid-mount" | awk '{print $2}'`; do +    /usr/bin/kill -HUP $pid > /dev/null 2>&1 || true +  done +  endscript  }  /var/log/glusterfs/geo-replication-slaves/*.log { +  sharedscripts +  postrotate +  for pid in `ps -aef | grep glusterfs | egrep "\-\-aux-gfid-mount" | awk '{print $2}'`; do +    /usr/bin/kill -HUP $pid > /dev/null 2>&1 || true +  done +  endscript  }  /var/log/glusterfs/geo-replication-slaves/*/*.log { +  sharedscripts +  postrotate +  for pid in `ps -aef | grep glusterfs | egrep "\-\-aux-gfid-mount" | awk '{print $2}'`; do +    /usr/bin/kill -HUP $pid > /dev/null 2>&1 || true +  done +  endscript  } diff --git a/libglusterfs/src/mem-types.h b/libglusterfs/src/mem-types.h index fc0aa9018..726d38eb6 100644 --- a/libglusterfs/src/mem-types.h +++ b/libglusterfs/src/mem-types.h @@ -118,6 +118,7 @@ enum gf_common_mem_types_ {          gf_common_mt_auxgids              = 102,          gf_common_mt_syncopctx            = 103,          gf_common_mt_iobrefs              = 104, -        gf_common_mt_end                  = 105 +        gf_common_mt_gsync_status_t       = 105, +        gf_common_mt_end                  = 106  };  #endif diff --git a/rpc/rpc-lib/src/protocol-common.h b/rpc/rpc-lib/src/protocol-common.h index d64f280cf..5876a500b 100644 --- a/rpc/rpc-lib/src/protocol-common.h +++ b/rpc/rpc-lib/src/protocol-common.h @@ -221,6 +221,23 @@ typedef enum {          GF_AFR_OP_STATISTICS_HEAL_COUNT_PER_REPLICA,  } gf_xl_afr_op_t ; +struct gf_gsync_detailed_status_ { +        char node[NAME_MAX]; +        char master[NAME_MAX]; +        char brick[NAME_MAX]; +        char slave_node[NAME_MAX]; +        char worker_status[NAME_MAX]; +        char checkpoint_status[NAME_MAX]; +        char crawl_status[NAME_MAX]; +        char files_syncd[NAME_MAX]; +        char files_remaining[NAME_MAX]; +        char bytes_remaining[NAME_MAX]; +        char purges_remaining[NAME_MAX]; +        char total_files_skipped[NAME_MAX]; +}; + +typedef struct gf_gsync_detailed_status_ gf_gsync_status_t; +  #define GLUSTER_HNDSK_PROGRAM    14398633 /* Completely random */  #define GLUSTER_HNDSK_VERSION    2   /* 0.0.2 */ diff --git a/xlators/cluster/afr/src/afr-inode-read.c b/xlators/cluster/afr/src/afr-inode-read.c index 8a2853319..3e80129f9 100644 --- a/xlators/cluster/afr/src/afr-inode-read.c +++ b/xlators/cluster/afr/src/afr-inode-read.c @@ -1348,7 +1348,7 @@ afr_aggregate_stime_xattr (dict_t *this, char *key, data_t *value, void *data)          int ret = 0;          if (fnmatch (GF_XATTR_STIME_PATTERN, key, FNM_NOESCAPE) == 0) -                ret = gf_get_min_stime (THIS, data, key, value); +                ret = gf_get_max_stime (THIS, data, key, value);          return ret;  } diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c index 898f41f0e..ed4babd32 100644 --- a/xlators/cluster/dht/src/dht-common.c +++ b/xlators/cluster/dht/src/dht-common.c @@ -2015,13 +2015,7 @@ dht_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          if (!local->xattr) {                  local->xattr = dict_copy_with_ref (xattr, NULL);          } else { -                /* first aggregate everything into xattr and then copy into -                 * local->xattr. This is required as we want to have -                 * 'local->xattr' as the proper final dictionary passed above -                 * distribute xlator. -                 */ -                dht_aggregate_xattr (xattr, local->xattr); -                local->xattr = dict_copy (xattr, local->xattr); +                dht_aggregate_xattr (local->xattr, xattr);          }  out:          if (is_last_call (this_call_cnt)) { diff --git a/xlators/lib/src/libxlator.c b/xlators/lib/src/libxlator.c index 9e5357255..63e9bcf9f 100644 --- a/xlators/lib/src/libxlator.c +++ b/xlators/lib/src/libxlator.c @@ -452,6 +452,61 @@ gf_get_min_stime (xlator_t *this, dict_t *dst, char *key, data_t *value)          /* can't use 'min()' macro here as we need to compare two fields             in the array, selectively */ +        if ((host_value_timebuf[0] < host_timebuf[0]) || +            ((host_value_timebuf[0] == host_timebuf[0]) && +             (host_value_timebuf[1] < host_timebuf[1]))) { +                update_timebuf (value_timebuf, net_timebuf); +        } + +        ret = 0; +out: +        return ret; +error: +        /* To be used only when net_timebuf is not set in the dict */ +        if (net_timebuf) +                GF_FREE (net_timebuf); + +        return ret; +} + +int +gf_get_max_stime (xlator_t *this, dict_t *dst, char *key, data_t *value) +{ +        int ret = -1; +        uint32_t *net_timebuf = NULL; +        uint32_t *value_timebuf = NULL; +        uint32_t host_timebuf[2] = {0,}; +        uint32_t host_value_timebuf[2] = {0,}; + +        /* stime should be maximum of all the other nodes */ +        ret = dict_get_bin (dst, key, (void **)&net_timebuf); +        if (ret < 0) { +                net_timebuf = GF_CALLOC (1, sizeof (int64_t), +                                           gf_common_mt_char); +                if (!net_timebuf) +                        goto out; + +                ret = dict_set_bin (dst, key, net_timebuf, sizeof (int64_t)); +                if (ret < 0) { +                        gf_log (this->name, GF_LOG_WARNING, +                                "key=%s: dict set failed", key); +                        goto error; +                } +        } + +        value_timebuf = data_to_bin (value); +        if (!value_timebuf) { +                gf_log (this->name, GF_LOG_WARNING, +                        "key=%s: getting value of stime failed", key); +                ret = -1; +                goto out; +        } + +        get_hosttime (value_timebuf, host_value_timebuf); +        get_hosttime (net_timebuf, host_timebuf); + +        /* can't use 'max()' macro here as we need to compare two fields +           in the array, selectively */          if ((host_value_timebuf[0] > host_timebuf[0]) ||              ((host_value_timebuf[0] == host_timebuf[0]) &&               (host_value_timebuf[1] > host_timebuf[1]))) { diff --git a/xlators/lib/src/libxlator.h b/xlators/lib/src/libxlator.h index 08bd77b91..175d3141d 100644 --- a/xlators/lib/src/libxlator.h +++ b/xlators/lib/src/libxlator.h @@ -151,4 +151,7 @@ match_uuid_local (const char *name, char *uuid);  int  gf_get_min_stime (xlator_t *this, dict_t *dst, char *key, data_t *value); +int +gf_get_max_stime (xlator_t *this, dict_t *dst, char *key, data_t *value); +  #endif /* !_LIBXLATOR_H */ diff --git a/xlators/mgmt/glusterd/src/glusterd-geo-rep.c b/xlators/mgmt/glusterd/src/glusterd-geo-rep.c index 5786694bd..5d724cc2a 100644 --- a/xlators/mgmt/glusterd/src/glusterd-geo-rep.c +++ b/xlators/mgmt/glusterd/src/glusterd-geo-rep.c @@ -28,17 +28,6 @@  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_info (char *slave, char **slave_ip, -                         char **slave_vol, char **op_errstr); - -static int -glusterd_gsync_read_frm_status (char *path, char *buf, size_t blen); -  struct gsync_config_opt_vals_ gsync_confopt_vals[] = {          {.op_name        = "change_detector",           .no_of_pos_vals = 2, @@ -55,6 +44,11 @@ struct gsync_config_opt_vals_ gsync_confopt_vals[] = {           .case_sensitive = _gf_false,           .values         = {"critical", "error", "warning", "info", "debug"}          }, +        {.op_name        = "use-tarssh", +         .no_of_pos_vals = 6, +         .case_sensitive = _gf_false, +         .values         = {"true", "false", "0", "1", "yes", "no"} +        },          {.op_name = NULL,          },  }; @@ -74,6 +68,11 @@ static char *gsync_reserved_opts[] = {          NULL  }; +static char *gsync_no_restart_opts[] = { +        "checkpoint", +        NULL +}; +  int  __glusterd_handle_sys_exec (rpcsvc_request_t *req)  { @@ -899,6 +898,8 @@ gsync_verify_config_options (dict_t *dict, char **op_errstr, char *volname)                  }                  if (op_match) { +                        if (!op_value) +                                goto out;                          val_match = _gf_false;                          for (i = 0; i < conf_vals->no_of_pos_vals; i++) {                                  if(conf_vals->case_sensitive){ @@ -912,7 +913,7 @@ gsync_verify_config_options (dict_t *dict, char **op_errstr, char *volname)                          if (!val_match) {                                  ret = snprintf (errmsg, sizeof(errmsg) - 1, -                                                "Invalid values (%s) for" +                                                "Invalid value(%s) for"                                                  " option %s", op_value,                                                  op_name);                                  errmsg[ret] = '\0'; @@ -923,7 +924,7 @@ gsync_verify_config_options (dict_t *dict, char **op_errstr, char *volname)                          }                  }          } - +out:          return 0;  } @@ -1581,7 +1582,7 @@ out:          return ret;  } -static int +int  glusterd_get_statefile_name (glusterd_volinfo_t *volinfo, char *slave,                               char *conf_path, char **statefile)  { @@ -1736,7 +1737,7 @@ glusterd_verify_slave (char *volname, char *slave_ip, char *slave,                  gf_log ("", GF_LOG_ERROR, "Not a valid slave");                  ret = glusterd_gsync_read_frm_status (log_file_path,                                                        buf, sizeof(buf)); -                if (ret) { +                if (ret <= 0) {                          gf_log ("", GF_LOG_ERROR, "Unable to read from %s",                                  log_file_path);                          goto out; @@ -2391,6 +2392,8 @@ glusterd_gsync_configure (glusterd_volinfo_t *volinfo, char *slave,          char            *slave_ip  = NULL;          char            *slave_vol = NULL;          struct stat      stbuf     = {0, }; +        gf_boolean_t     restart_required = _gf_true; +        char           **resopt    = NULL;          GF_ASSERT (slave);          GF_ASSERT (op_errstr); @@ -2495,18 +2498,28 @@ glusterd_gsync_configure (glusterd_volinfo_t *volinfo, char *slave,  out:          if (!ret && volinfo) { +            for (resopt = gsync_no_restart_opts; *resopt; resopt++) { +                restart_required = _gf_true; +                if (!strcmp ((*resopt), op_name)){ +                    restart_required = _gf_false; +                    break; +                } +            } + +            if (restart_required) {                  ret = glusterd_check_restart_gsync_session (volinfo, slave,                                                              resp_dict, path_list,                                                              conf_path, 0);                  if (ret) -                        *op_errstr = gf_strdup ("internal error"); +                    *op_errstr = gf_strdup ("internal error"); +            }          }          gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);          return ret;  } -static int +int  glusterd_gsync_read_frm_status (char *path, char *buf, size_t blen)  {          int                 ret = 0; @@ -2530,7 +2543,6 @@ glusterd_gsync_read_frm_status (char *path, char *buf, size_t blen)                          char *p = buf + len - 1;                          while (isspace (*p))                                  *p-- = '\0'; -                        ret = 0;                  }          } else if (ret < 0)                  gf_log ("", GF_LOG_ERROR, "Status file of gsyncd is corrupt"); @@ -2540,20 +2552,146 @@ glusterd_gsync_read_frm_status (char *path, char *buf, size_t blen)  }  static int -glusterd_gsync_fetch_status_extra (char *path, char *buf, size_t blen) +dict_get_param (dict_t *dict, char *key, char **param) +{ +        char  *dk = NULL; +        char   *s = NULL; +        char    x = '\0'; +        int   ret = 0; + +        if (dict_get_str (dict, key, param) == 0) +                return 0; + +        dk = gf_strdup (key); +        if (!key) +                return -1; + +        s = strpbrk (dk, "-_"); +        if (!s) +                return -1; +        x = (*s == '-') ? '_' : '-'; +        *s++ = x; +        while ((s = strpbrk (s, "-_"))) +                *s++ = x; + +        ret = dict_get_str (dict, dk, param); + +        GF_FREE (dk); +        return ret; +} + +static int +glusterd_parse_gsync_status (char *buf, gf_gsync_status_t *sts_val) +{ +        int              ret      = -1; +        int              i      = -1; +        int              num_of_fields = 8; +        char            *token    = NULL; +        char           **tokens   = NULL; +        char           **ptr   = NULL; +        char            *save_ptr = NULL; +        char             na_buf[] = "N/A"; + +        if (!buf) { +                gf_log ("", GF_LOG_ERROR, "Empty buf"); +                goto out; +        } + +        tokens = calloc (num_of_fields, sizeof (char *)); +        if (!tokens) { +                gf_log ("", GF_LOG_ERROR, "Out of memory"); +                goto out; +        } + +        ptr = tokens; + +        for (token = strtok_r (buf, ",", &save_ptr); token; +             token = strtok_r (NULL, ",", &save_ptr)) { +                *ptr = gf_strdup(token); +                if (!*ptr) { +                        gf_log ("", GF_LOG_ERROR, "Out of memory"); +                        goto out; +                } +                ptr++; +        } + +        for (i = 0; i < num_of_fields; i++) { +                token = strtok_r (tokens[i], ":", &save_ptr); +                token = strtok_r (NULL, "\0", &save_ptr); +                token++; + +                /* token NULL check */ +                if (!token && (i != 0) && +                    (i != 5) && (i != 7)) +                    token = na_buf; + +                if (i == 0) { +                        if (!token) +                            token = na_buf; +                        else { +                            token++; +                            if (!token) +                                token = na_buf; +                            else +                                token[strlen(token) - 1] = '\0'; +                        } +                        memcpy (sts_val->slave_node, token, strlen(token)); +                } +                if (i == 1) +                        memcpy (sts_val->files_syncd, token, strlen(token)); +                if (i == 2) +                        memcpy (sts_val->purges_remaining, token, strlen(token)); +                if (i == 3) +                        memcpy (sts_val->total_files_skipped, token, strlen(token)); +                if (i == 4) +                        memcpy (sts_val->files_remaining, token, strlen(token)); +                if (i == 5) { +                        if (!token) +                            token = na_buf; +                        else { +                            token++; +                            if (!token) +                                token = na_buf; +                            else +                                token[strlen(token) - 1] = '\0'; +                        } +                        memcpy (sts_val->worker_status, token, strlen(token)); +                } +                if (i == 6) +                        memcpy (sts_val->bytes_remaining, token, strlen(token)); +                if (i == 7) { +                        if (!token) +                            token = na_buf; +                        else { +                            token++; +                            if (!token) +                                token = na_buf; +                            else +                                token[strlen(token) - 2] = '\0'; +                        } +                        memcpy (sts_val->crawl_status, token, strlen(token)); +                } +        } + +        ret = 0; +out: +        for (i = 0; i< num_of_fields; i++) +               if (tokens[i]) +                       GF_FREE(tokens[i]); + +        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); +        return ret; +} + +static int +glusterd_gsync_fetch_status_extra (char *path, gf_gsync_status_t *sts_val)  {          char sockpath[PATH_MAX] = {0,};          struct sockaddr_un   sa = {0,}; -        size_t                l = 0;          int                   s = -1;          struct pollfd       pfd = {0,};          int                 ret = 0; -        l = strlen (buf); -        /* seek to end of data in buf */ -        buf += l; -        blen -= l; -          glusterd_set_socket_filepath (path, sockpath, sizeof (sockpath));          strncpy(sa.sun_path, sockpath, sizeof(sa.sun_path)); @@ -2581,66 +2719,40 @@ glusterd_gsync_fetch_status_extra (char *path, char *buf, size_t blen)                  ret = -1;                  goto out;          } -        ret = read(s, buf, blen); +        ret = read(s, sts_val->checkpoint_status, +                   sizeof(sts_val->checkpoint_status));          /* we expect a terminating 0 byte */ -        if (ret == 0 || (ret > 0 && buf[ret - 1])) +        if (ret == 0 || (ret > 0 && sts_val->checkpoint_status[ret - 1]))                  ret = -1; -        if (ret > 0) +        if (ret > 0) {                  ret = 0; +        } - out: +out:          close (s);          return ret;  } -static int -dict_get_param (dict_t *dict, char *key, char **param) -{ -        char  *dk = NULL; -        char   *s = NULL; -        char    x = '\0'; -        int   ret = 0; - -        if (dict_get_str (dict, key, param) == 0) -                return 0; - -        dk = gf_strdup (key); -        if (!key) -                return -1; - -        s = strpbrk (dk, "-_"); -        if (!s) -                return -1; -        x = (*s == '-') ? '_' : '-'; -        *s++ = x; -        while ((s = strpbrk (s, "-_"))) -                *s++ = x; - -        ret = dict_get_str (dict, dk, param); - -        GF_FREE (dk); -        return ret; -} - -static int +int  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] = "defunct"; -        char             nds[1024] = {0, }; -        char             mst[1024] = {0, }; -        char             slv[1024] = {0, }; -        char             sts[1024] = {0, }; -        char            *bufp = NULL; -        dict_t          *confd = NULL; -        int              gsync_count = 0; -        int              status = 0; -        char *dyn_node = NULL; -        char *path_list = NULL; +        char                    brick_state_file[PATH_MAX] = ""; +        char                    brick_path[PATH_MAX]       = ""; +        char                   *georep_session_wrkng_dir   = NULL; +        char                   *master                     = NULL; +        char                    tmp[1024]                  = ""; +        char                    sts_val_name[1024]         = ""; +        char                    monitor_status[PATH_MAX]   = ""; +        char                   *statefile                  = NULL; +        char                   *socketfile                 = NULL; +        dict_t                 *confd                      = NULL; +        int                     gsync_count                = 0; +        int                     i                          = 0; +        int                     ret                        = 0; +        glusterd_brickinfo_t   *brickinfo                  = NULL; +        gf_gsync_status_t      *sts_val                    = NULL; +        glusterd_conf_t        *priv                       = NULL;          GF_ASSERT (THIS);          GF_ASSERT (THIS->private); @@ -2661,7 +2773,7 @@ glusterd_read_status_file (glusterd_volinfo_t *volinfo, char *slave,          if (ret) {                  gf_log ("", GF_LOG_ERROR, "Unable to get configuration data"                          "for %s(master), %s(slave)", master, slave); -                goto done; +                goto out;          } @@ -2670,120 +2782,168 @@ glusterd_read_status_file (glusterd_volinfo_t *volinfo, char *slave,                  gf_log ("", GF_LOG_ERROR, "Unable to get state_file's name "                          "for %s(master), %s(slave). Please check gsync "                          "config file.", master, slave); -                goto done; +                goto out;          } -        ret = glusterd_gsync_read_frm_status (statefile, buf, sizeof (buf)); -        if (ret) { + +        ret = glusterd_gsync_read_frm_status (statefile, monitor_status, +                                              sizeof (monitor_status)); +        if (ret <= 0) {                  gf_log ("", GF_LOG_ERROR, "Unable to read the status"                          "file for %s(master), %s(slave)", master, slave); -                strncpy (buf, "defunct", sizeof (buf)); -                goto done; -        } - -        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) { -                gf_log ("", GF_LOG_ERROR, "Unable to get gsync status"); -                goto done; +                strncpy (monitor_status, "defunct", sizeof (monitor_status));          } -        if (strcmp (buf, "Stable") != 0) -                goto done; - -        ret = dict_get_param (confd, "state_socket_unencoded", &statefile); +        ret = dict_get_param (confd, "georep_session_working_dir", +                              &georep_session_wrkng_dir);          if (ret) { -                gf_log ("", GF_LOG_ERROR, "Unable to get state_socket_unencoded" -                        " filepath. Please check gsync config file."); -                goto done; +                gf_log ("", GF_LOG_ERROR, "Unable to get geo-rep session's " +                        "working directory name for %s(master), %s(slave). " +                        "Please check gsync config file.", master, slave); +                goto out;          } -        ret = glusterd_gsync_fetch_status_extra (statefile, buf, sizeof (buf)); + +        ret = dict_get_param (confd, "state_socket_unencoded", &socketfile);          if (ret) { -                gf_log ("", GF_LOG_ERROR, "Unable to fetch extra status" -                        "for %s(master), %s(slave)", master, slave); -                /* there is a slight chance that this occurs due to race -                 * -- in that case, the following options all seem bad: -                 * -                 * - suppress irregurlar behavior by just leaving status -                 *   on "OK" -                 * - freak out users with a misleading "defunct" -                 * - overload the meaning of the regular error signal -                 *   mechanism of gsyncd, that is, when status is "faulty" -                 * -                 * -- so we just come up with something new... -                 */ -                strncpy (buf, "N/A", sizeof (buf)); -                goto done; +                gf_log ("", GF_LOG_ERROR, "Unable to get socket file's name " +                        "for %s(master), %s(slave). Please check gsync " +                        "config file.", master, slave); +                goto out;          } - 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; +        ret = dict_get_int32 (dict, "gsync-count", &gsync_count); +        if (ret) +                gsync_count = 0; + +        list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { +                if (uuid_compare (brickinfo->uuid, MY_UUID)) +                        continue; + +                sts_val = GF_CALLOC (1, sizeof(gf_gsync_status_t), +                                     gf_common_mt_gsync_status_t); +                if (!sts_val) { +                        gf_log ("", GF_LOG_ERROR, "Out Of Memory");                          goto out;                  } -        } -        ret = dict_get_int32 (dict, "gsync-count", &gsync_count); +                /* Creating the brick state file's path */ +                memset(brick_state_file, '\0', PATH_MAX); +                memcpy (brick_path, brickinfo->path, PATH_MAX - 1); +                for (i = 0; i < strlen(brick_path) - 1; i++) +                        if (brick_path[i] == '/') +                                brick_path[i] = '_'; +                ret = snprintf(brick_state_file, PATH_MAX - 1, "%s%s.status", +                               georep_session_wrkng_dir, brick_path); +                brick_state_file[ret] = '\0'; + +                gf_log ("", GF_LOG_DEBUG, "brick_state_file = %s", brick_state_file); + +                memset (tmp, '\0', sizeof(tmp)); + +                ret = glusterd_gsync_read_frm_status (brick_state_file, +                                                      tmp, sizeof (tmp)); +                if (ret <= 0) { +                        gf_log ("", GF_LOG_ERROR, "Unable to read the status" +                                "file for %s brick for  %s(master), %s(slave) " +                                "session", brickinfo->path, master, slave); +                        memcpy (sts_val->slave_node, slave, strlen(slave)); +                        sts_val->slave_node[strlen(slave)] = '\0'; +                        ret = snprintf (sts_val->worker_status, sizeof(sts_val->worker_status), "N/A"); +                        sts_val->worker_status[ret] = '\0'; +                        ret = snprintf (sts_val->checkpoint_status, sizeof(sts_val->checkpoint_status), "N/A"); +                        sts_val->checkpoint_status[ret] = '\0'; +                        ret = snprintf (sts_val->crawl_status, sizeof(sts_val->crawl_status), "N/A"); +                        sts_val->crawl_status[ret] = '\0'; +                        ret = snprintf (sts_val->files_syncd, sizeof(sts_val->files_syncd), "N/A"); +                        sts_val->files_syncd[ret] = '\0'; +                        ret = snprintf (sts_val->purges_remaining, sizeof(sts_val->purges_remaining), "N/A"); +                        sts_val->purges_remaining[ret] = '\0'; +                        ret = snprintf (sts_val->total_files_skipped, sizeof(sts_val->total_files_skipped), "N/A"); +                        sts_val->total_files_skipped[ret] = '\0'; +                        ret = snprintf (sts_val->files_remaining, sizeof(sts_val->files_remaining), "N/A"); +                        sts_val->files_remaining[ret] = '\0'; +                        ret = snprintf (sts_val->bytes_remaining, sizeof(sts_val->bytes_remaining), "N/A"); +                        sts_val->bytes_remaining[ret] = '\0'; +                        goto store_status; +                } -        if (ret) -                gsync_count = 1; -        else -                gsync_count++; +                ret = glusterd_gsync_fetch_status_extra (socketfile, sts_val); +                if (ret || strlen(sts_val->checkpoint_status) == 0) { +                        gf_log ("", GF_LOG_DEBUG, "No checkpoint status" +                                "for %s(master), %s(slave)", master, slave); +                        ret = snprintf (sts_val->checkpoint_status, sizeof(sts_val->checkpoint_status), "N/A"); +                        sts_val->checkpoint_status[ret] = '\0'; +                } -        (void) snprintf (nds, sizeof (nds), "node%d", gsync_count); -        dyn_node = gf_strdup (node); -        if (!dyn_node) -                goto out; -        ret = dict_set_dynstr (dict, nds, dyn_node); -        if (ret) { -                GF_FREE (dyn_node); -                goto out; -        } +                ret = glusterd_parse_gsync_status (tmp, sts_val); +                if (ret) { +                        gf_log ("", GF_LOG_ERROR, +                                "Unable to parse the gsync status for %s", +                                brickinfo->path); +                        memcpy (sts_val->slave_node, slave, strlen(slave)); +                        sts_val->slave_node[strlen(slave)] = '\0'; +                        ret = snprintf (sts_val->worker_status, sizeof(sts_val->worker_status), "N/A"); +                        sts_val->worker_status[ret] = '\0'; +                        ret = snprintf (sts_val->checkpoint_status, sizeof(sts_val->checkpoint_status), "N/A"); +                        sts_val->checkpoint_status[ret] = '\0'; +                        ret = snprintf (sts_val->crawl_status, sizeof(sts_val->crawl_status), "N/A"); +                        sts_val->crawl_status[ret] = '\0'; +                        ret = snprintf (sts_val->files_syncd, sizeof(sts_val->files_syncd), "N/A"); +                        sts_val->files_syncd[ret] = '\0'; +                        ret = snprintf (sts_val->purges_remaining, sizeof(sts_val->purges_remaining), "N/A"); +                        sts_val->purges_remaining[ret] = '\0'; +                        ret = snprintf (sts_val->total_files_skipped, sizeof(sts_val->total_files_skipped), "N/A"); +                        sts_val->total_files_skipped[ret] = '\0'; +                        ret = snprintf (sts_val->files_remaining, sizeof(sts_val->files_remaining), "N/A"); +                        sts_val->files_remaining[ret] = '\0'; +                        ret = snprintf (sts_val->bytes_remaining, sizeof(sts_val->bytes_remaining), "N/A"); +                        sts_val->bytes_remaining[ret] = '\0'; +                } -        snprintf (mst, sizeof (mst), "master%d", gsync_count); -        master = gf_strdup (master); -        if (!master) -                goto out; -        ret = dict_set_dynstr (dict, mst, master); -        if (ret) { -                GF_FREE (master); -                goto out; -        } +store_status: +                if ((strcmp (monitor_status, "Stable"))) { +                        memcpy (sts_val->worker_status, monitor_status, strlen(monitor_status)); +                        sts_val->worker_status[strlen(monitor_status)] = '\0'; +                        ret = snprintf (sts_val->crawl_status, sizeof(sts_val->crawl_status), "N/A"); +                        sts_val->crawl_status[ret] = '\0'; +                        ret = snprintf (sts_val->checkpoint_status, sizeof(sts_val->checkpoint_status), "N/A"); +                        sts_val->checkpoint_status[ret] = '\0'; +                } -        snprintf (slv, sizeof (slv), "slave%d", gsync_count); -        slave = gf_strdup (slave); -        if (!slave) -                goto out; -        ret = dict_set_dynstr (dict, slv, slave); -        if (ret) { -                GF_FREE (slave); -                goto out; -        } +                if (strcmp (sts_val->worker_status, "Active")) { +                        ret = snprintf (sts_val->checkpoint_status, sizeof(sts_val->checkpoint_status), "N/A"); +                        sts_val->checkpoint_status[ret] = '\0'; +                        ret = snprintf (sts_val->crawl_status, sizeof(sts_val->crawl_status), "N/A"); +                        sts_val->crawl_status[ret] = '\0'; +                } -        snprintf (sts, sizeof (slv), "status%d", gsync_count); -        bufp = gf_strdup (buf); -        if (!bufp) -                goto out; -        ret = dict_set_dynstr (dict, sts, bufp); -        if (ret) { -                GF_FREE (bufp); -                goto out; +                if (!strcmp (sts_val->slave_node, "N/A")) { +                        memcpy (sts_val->slave_node, slave, strlen(slave)); +                        sts_val->slave_node[strlen(slave)] = '\0'; +                } + +                memcpy (sts_val->node, node, strlen(node)); +                sts_val->node[strlen(node)] = '\0'; +                memcpy (sts_val->brick, brickinfo->path, strlen(brickinfo->path)); +                sts_val->brick[strlen(brickinfo->path)] = '\0'; +                memcpy (sts_val->master, master, strlen(master)); +                sts_val->master[strlen(master)] = '\0'; + +                snprintf (sts_val_name, sizeof (sts_val_name), "status_value%d", gsync_count); +                ret = dict_set_bin (dict, sts_val_name, sts_val, sizeof(gf_gsync_status_t)); +                if (ret) { +                        GF_FREE (sts_val); +                        goto out; +                } + +                gsync_count++; +                sts_val = NULL;          } +          ret = dict_set_int32 (dict, "gsync-count", gsync_count);          if (ret)                  goto out; - out: +out:          dict_destroy (confd);          return 0; @@ -3246,30 +3406,32 @@ glusterd_op_sys_exec (dict_t *dict, char **op_errstr, dict_t *rsp_dict)                  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."); +        do { +                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 = dict_set_int32 (rsp_dict, "output_count", output_count); -                if (ret) -                        gf_log ("", GF_LOG_ERROR, "output_count set failed."); -        } +        } while (ptr);          ret = runner_end (&runner);          if (ret) { @@ -3708,7 +3870,7 @@ out:  } -static int +int  glusterd_get_slave_info (char *slave, char **slave_ip,                           char **slave_vol, char **op_errstr)  { @@ -3888,7 +4050,7 @@ create_conf_file (glusterd_conf_t *conf, char *conf_path)          /* 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", +                         "aux-gfid-mount",                           ".", ".", NULL);          RUN_GSYNCD_CMD; @@ -3902,6 +4064,16 @@ create_conf_file (glusterd_conf_t *conf, char *conf_path)          runner_add_args (&runner, ".", ".", NULL);          RUN_GSYNCD_CMD; +        /* ssh-command tar */ +        runinit_gsyncd_setrx (&runner, conf_path); +        runner_add_arg (&runner, "ssh-command-tar"); +        runner_argprintf (&runner, +                          "ssh -oPasswordAuthentication=no " +                           "-oStrictHostKeyChecking=no " +                           "-i %s/tar_ssh.pem", georepdir); +        runner_add_args (&runner, ".", ".", NULL); +        RUN_GSYNCD_CMD; +          /* pid-file */          runinit_gsyncd_setrx (&runner, conf_path);          runner_add_arg (&runner, "pid-file"); @@ -3909,6 +4081,13 @@ create_conf_file (glusterd_conf_t *conf, char *conf_path)          runner_add_args (&runner, ".", ".", NULL);          RUN_GSYNCD_CMD; +        /* geo-rep-working-dir */ +        runinit_gsyncd_setrx (&runner, conf_path); +        runner_add_arg (&runner, "georep-session-working-dir"); +        runner_argprintf (&runner, "%s/${mastervol}_${remotehost}_${slavevol}/", georepdir); +        runner_add_args (&runner, ".", ".", NULL); +        RUN_GSYNCD_CMD; +          /* state-file */          runinit_gsyncd_setrx (&runner, conf_path);          runner_add_arg (&runner, "state-file"); @@ -3986,7 +4165,7 @@ create_conf_file (glusterd_conf_t *conf, char *conf_path)          /* 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", +                         "aux-gfid-mount",                           ".", NULL);          RUN_GSYNCD_CMD; diff --git a/xlators/mgmt/glusterd/src/glusterd-mountbroker.c b/xlators/mgmt/glusterd/src/glusterd-mountbroker.c index 0d67d1303..4ce441da8 100644 --- a/xlators/mgmt/glusterd/src/glusterd-mountbroker.c +++ b/xlators/mgmt/glusterd/src/glusterd-mountbroker.c @@ -231,7 +231,6 @@ parse_mount_pattern_desc (gf_mount_spec_t *mspec, char *pdesc)  const char *georep_mnt_desc_template =          "SUP(" -                "xlator-option=\\*-dht.assert-no-child-down=true "                  "volfile-server=localhost "                  "client-pid=%d "                  "user-map-root=%s " diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c index fe20e95f2..e2e363bc3 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -4726,14 +4726,24 @@ _local_gsyncd_start (dict_t *this, char *key, data_t *value, void *data)  {          char                        *path_list = NULL;          char                        *slave = NULL; +        char                        *slave_ip = NULL; +        char                        *slave_vol = NULL; +        char                        *statefile = NULL; +        char                         buf[1024] = "faulty";          int                          uuid_len = 0;          int                          ret = 0;          char                         uuid_str[64] = {0}; -        glusterd_volinfo_t           *volinfo = NULL; -        char                         *conf_path = NULL; +        glusterd_volinfo_t          *volinfo = NULL; +        char                         confpath[PATH_MAX] = ""; +        char                        *op_errstr = NULL; +        glusterd_conf_t             *priv = NULL; + +        GF_ASSERT (THIS); +        priv = THIS->private; +        GF_ASSERT (priv); +        GF_ASSERT (data);          volinfo = data; -        GF_ASSERT (volinfo);          slave = strchr(value->data, ':');          if (slave)                  slave ++; @@ -4743,22 +4753,63 @@ _local_gsyncd_start (dict_t *this, char *key, data_t *value, void *data)          strncpy (uuid_str, (char*)value->data, uuid_len); +        /* Getting Local Brickpaths */          ret = glusterd_get_local_brickpaths (volinfo, &path_list); -        ret = dict_get_str (this, "conf_path", &conf_path); +        /*Generating the conf file path needed by gsyncd */ +        ret = glusterd_get_slave_info (slave, &slave_ip, +                                       &slave_vol, &op_errstr);          if (ret) {                  gf_log ("", GF_LOG_ERROR, -                        "Unable to fetch conf file path."); +                        "Unable to fetch slave details."); +                ret = -1;                  goto out;          } -        glusterd_start_gsync (volinfo, slave, path_list, conf_path, -                              uuid_str, NULL); +        ret = snprintf (confpath, sizeof(confpath) - 1, +                        "%s/"GEOREP"/%s_%s_%s/gsyncd.conf", +                        priv->workdir, volinfo->volname, +                        slave_ip, slave_vol); +        confpath[ret] = '\0'; + +        /* Fetching the last status of the node */ +        ret = glusterd_get_statefile_name (volinfo, slave, +                                           confpath, &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"); +                goto out; +        } + +        ret = glusterd_gsync_read_frm_status (statefile, buf, sizeof (buf)); +        if (ret < 0) { +                gf_log ("", GF_LOG_ERROR, "Unable to read the status"); +                goto out; +        } -        GF_FREE (path_list); -        path_list = NULL; +        /* Looks for the last status, to find if the sessiom was running +         * when the node went down. If the session was not started or +         * not started, do not restart the geo-rep session */ +        if ((!strcmp (buf, "Not Started")) || +            (!strcmp (buf, "Stopped"))) { +                gf_log ("", GF_LOG_INFO, +                        "Geo-Rep Session was not started between " +                        "%s and %s::%s. Not Restarting", volinfo->volname, +                        slave_ip, slave_vol); +                goto out; +        } + +        glusterd_start_gsync (volinfo, slave, path_list, confpath, +                              uuid_str, NULL);  out: +        if (path_list) +                GF_FREE (path_list); +          return ret;  } @@ -7340,21 +7391,16 @@ glusterd_append_gsync_status (dict_t *dst, dict_t *src)  } -static int32_t +int32_t  glusterd_append_status_dicts (dict_t *dst, dict_t *src)  { -        int              dst_count = 0; -        int              src_count = 0; -        int              i = 0; -        int              ret = 0; -        char             mst[PATH_MAX] = {0,}; -        char             slv[PATH_MAX] = {0, }; -        char             sts[PATH_MAX] = {0, }; -        char             nds[PATH_MAX] = {0, }; -        char             *mst_val = NULL; -        char             *slv_val = NULL; -        char             *sts_val = NULL; -        char             *nds_val = NULL; +        char                sts_val_name[PATH_MAX] = {0, }; +        int                 dst_count              = 0; +        int                 src_count              = 0; +        int                 i                      = 0; +        int                 ret                    = 0; +        gf_gsync_status_t  *sts_val                = NULL; +        gf_gsync_status_t  *dst_sts_val            = NULL;          GF_ASSERT (dst); @@ -7372,49 +7418,29 @@ glusterd_append_status_dicts (dict_t *dst, dict_t *src)                  goto out;          } -        for (i = 1; i <= src_count; i++) { -                snprintf (nds, sizeof(nds), "node%d", i); -                snprintf (mst, sizeof(mst), "master%d", i); -                snprintf (slv, sizeof(slv), "slave%d", i); -                snprintf (sts, sizeof(sts), "status%d", i); - -                ret = dict_get_str (src, nds, &nds_val); -                if (ret) -                        goto out; - -                ret = dict_get_str (src, mst, &mst_val); -                if (ret) -                        goto out; - -                ret = dict_get_str (src, slv, &slv_val); -                if (ret) -                        goto out; +        for (i = 0; i < src_count; i++) { +                memset (sts_val_name, '\0', sizeof(sts_val_name)); +                snprintf (sts_val_name, sizeof(sts_val_name), "status_value%d", i); -                ret = dict_get_str (src, sts, &sts_val); +                ret = dict_get_bin (src, sts_val_name, (void **) &sts_val);                  if (ret)                          goto out; -                snprintf (nds, sizeof(nds), "node%d", i+dst_count); -                snprintf (mst, sizeof(mst), "master%d", i+dst_count); -                snprintf (slv, sizeof(slv), "slave%d", i+dst_count); -                snprintf (sts, sizeof(sts), "status%d", i+dst_count); - -                ret = dict_set_dynstr (dst, nds, gf_strdup (nds_val)); -                if (ret) +                dst_sts_val = GF_CALLOC (1, sizeof(gf_gsync_status_t), +                                         gf_common_mt_gsync_status_t); +                if (!dst_sts_val) { +                        gf_log ("", GF_LOG_ERROR, "Out Of Memory");                          goto out; +                } -                ret = dict_set_dynstr (dst, mst, gf_strdup (mst_val)); -                if (ret) -                        goto out; +                memcpy (dst_sts_val, sts_val, sizeof(gf_gsync_status_t)); -                ret = dict_set_dynstr (dst, slv, gf_strdup (slv_val)); -                if (ret) -                        goto out; +                memset (sts_val_name, '\0', sizeof(sts_val_name)); +                snprintf (sts_val_name, sizeof(sts_val_name), "status_value%d", i + dst_count); -                ret = dict_set_dynstr (dst, sts, gf_strdup (sts_val)); +                ret = dict_set_bin (dst, sts_val_name, dst_sts_val, sizeof(gf_gsync_status_t));                  if (ret)                          goto out; -          }          ret = dict_set_int32 (dst, "gsync-count", dst_count+src_count); diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h index ec5155918..05d5c7172 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.h +++ b/xlators/mgmt/glusterd/src/glusterd-utils.h @@ -589,6 +589,17 @@ glusterd_get_slave_details_confpath (glusterd_volinfo_t *volinfo, dict_t *dict,                                       char **conf_path, char **op_errstr);  int +glusterd_get_slave_info (char *slave, char **slave_ip, +                         char **slave_vol, char **op_errstr); + +int +glusterd_get_statefile_name (glusterd_volinfo_t *volinfo, char *slave, +                             char *conf_path, char **statefile); + +int +glusterd_gsync_read_frm_status (char *path, char *buf, size_t blen); + +int  glusterd_check_restart_gsync_session (glusterd_volinfo_t *volinfo, char *slave,                                        dict_t *resp_dict, char *path_list,                                        char *conf_path, gf_boolean_t is_force); diff --git a/xlators/mgmt/glusterd/src/glusterd.c b/xlators/mgmt/glusterd/src/glusterd.c index c2be2c9da..58833869a 100644 --- a/xlators/mgmt/glusterd/src/glusterd.c +++ b/xlators/mgmt/glusterd/src/glusterd.c @@ -594,7 +594,7 @@ configure_syncdaemon (glusterd_conf_t *conf)          /* gluster-params */          runinit_gsyncd_setrx (&runner, conf);          runner_add_args (&runner, "gluster-params", -                         "aux-gfid-mount xlator-option=*-dht.assert-no-child-down=true", +                         "aux-gfid-mount",                           ".", ".", NULL);          RUN_GSYNCD_CMD; @@ -608,6 +608,16 @@ configure_syncdaemon (glusterd_conf_t *conf)          runner_add_args (&runner, ".", ".", NULL);          RUN_GSYNCD_CMD; +        /* ssh-command tar */ +        runinit_gsyncd_setrx (&runner, conf); +        runner_add_arg (&runner, "ssh-command-tar"); +        runner_argprintf (&runner, +                          "ssh -oPasswordAuthentication=no " +                           "-oStrictHostKeyChecking=no " +                           "-i %s/tar_ssh.pem", georepdir); +        runner_add_args (&runner, ".", ".", NULL); +        RUN_GSYNCD_CMD; +          /* pid-file */          runinit_gsyncd_setrx (&runner, conf);          runner_add_arg (&runner, "pid-file"); @@ -615,6 +625,13 @@ configure_syncdaemon (glusterd_conf_t *conf)          runner_add_args (&runner, ".", ".", NULL);          RUN_GSYNCD_CMD; +        /* geo-rep working dir */ +        runinit_gsyncd_setrx (&runner, conf); +        runner_add_arg (&runner, "georep-session-working-dir"); +        runner_argprintf (&runner, "%s/${mastervol}_${remotehost}_${slavevol}/", georepdir); +        runner_add_args (&runner, ".", ".", NULL); +        RUN_GSYNCD_CMD; +          /* state-file */          runinit_gsyncd_setrx (&runner, conf);          runner_add_arg (&runner, "state-file"); @@ -701,7 +718,7 @@ configure_syncdaemon (glusterd_conf_t *conf)          /* gluster-params */          runinit_gsyncd_setrx (&runner, conf);          runner_add_args (&runner, "gluster-params", -                         "aux-gfid-mount xlator-option=*-dht.assert-no-child-down=true", +                         "aux-gfid-mount",                           ".", NULL);          RUN_GSYNCD_CMD; diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h index adef55128..ab383ac1c 100644 --- a/xlators/mgmt/glusterd/src/glusterd.h +++ b/xlators/mgmt/glusterd/src/glusterd.h @@ -47,7 +47,7 @@  #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 GEO_CONF_MAX_OPT_VALS           5 +#define GEO_CONF_MAX_OPT_VALS           6  #define GLUSTERD_CREATE_HOOK_SCRIPT     "/hooks/1/gsync-create/post/" \                                          "S56glusterd-geo-rep-create-post.sh"  | 
