diff options
| -rw-r--r-- | cli/src/cli-rpc-ops.c | 3 | ||||
| -rw-r--r-- | cli/src/cli-xml-output.c | 255 | ||||
| -rw-r--r-- | cli/src/cli.h | 2 | ||||
| -rw-r--r-- | rpc/rpc-lib/src/protocol-common.h | 3 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-geo-rep.c | 29 | 
5 files changed, 237 insertions, 55 deletions
diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c index b7c6691abd5..b4573f441f7 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -4018,6 +4018,9 @@ get_struct_variable (int mem_num, gf_gsync_status_t *sts_val)          case 9:  return (sts_val->bytes_remaining);          case 10: return (sts_val->purges_remaining);          case 11: return (sts_val->total_files_skipped); +        case 12: return (sts_val->brick_host_uuid); +        case 13: return (sts_val->slavekey); +        case 14: return (sts_val->session_slave);          default:                   goto out;          } diff --git a/cli/src/cli-xml-output.c b/cli/src/cli-xml-output.c index 6ce8041f657..609f7847018 100644 --- a/cli/src/cli-xml-output.c +++ b/cli/src/cli-xml-output.c @@ -3899,76 +3899,219 @@ out:  #if (HAVE_LIB_XML)  int -cli_xml_output_vol_gsync_status (dict_t *dict, xmlTextWriterPtr writer) +gf_gsync_status_t_comparator (const void *p, const void *q)  { -        char                    master_key[PATH_MAX] = ""; -        char                    slave_key[PATH_MAX] = ""; -        char                    status_key[PATH_MAX] = ""; -        char                    node_key[PATH_MAX] = ""; -        char                    *master = NULL; -        char                    *slave = NULL; -        char                    *status = NULL; -        char                    *node = NULL; -        int                     ret = -1; -        int                     gsync_count = 0; -        int                     i = 1; +        char *master1 = NULL; +        char *master2 = NULL; + +        master1 = get_struct_variable (1, (*(gf_gsync_status_t **)p)); +        master2 = get_struct_variable (1, (*(gf_gsync_status_t **)q)); +        if (!master1 || !master2) { +                gf_log ("cli", GF_LOG_ERROR, +                        "struct member empty."); +                return 0; +        } + +        return strcmp (master1,master2); +} +#endif + +#if (HAVE_LIB_XML) +int +cli_xml_output_vol_gsync_status (dict_t *dict, +                                 xmlTextWriterPtr writer) +{ +        int                  ret                         = -1; +        int                  i                           = 1; +        int                  j                           = 0; +        int                  count                       = 0; +        const int            number_of_fields            = 12; +        const int            number_of_basic_fields      = 7; +        int                  closed                      = 1; +        int                  session_closed              = 1; +        gf_gsync_status_t  **status_values               = NULL; +        gf_boolean_t         status_detail               = _gf_false; +        char                 status_value_name[PATH_MAX] = ""; +        char                *tmp                         = NULL; +        char                *volume                      = NULL; +        char                *volume_next                 = NULL; +        char                *slave                       = NULL; +        char                *slave_next                  = NULL; +        char                *title_values[]              = {"master_node", +                                                            "master_node_uuid", +                                                            "master_brick", +                                                            "slave", +                                                            "status", +                                                            "checkpoint_status", +                                                            "crawl_status", +                                                            "files_syncd", +                                                            "files_pending", +                                                            "bytes_pending", +                                                            "deletes_pending", +                                                            "files_skipped"}; -        ret = dict_get_int32 (dict, "gsync-count", &gsync_count); +        GF_ASSERT (dict); + +        ret = dict_get_int32 (dict, "gsync-count", &count);          if (ret)                  goto out; -        for (i=1; i <= gsync_count; i++) { -                snprintf (node_key, sizeof(node_key), "node%d", i); -                snprintf (master_key, sizeof(master_key), "master%d", i); -                snprintf (slave_key, sizeof(slave_key), "slave%d", i); -                snprintf (status_key, sizeof(status_key), "status%d", i); +        status_detail = dict_get_str_boolean (dict, "status-detail", +                                              _gf_false); -                ret = dict_get_str (dict, node_key, &node); -                if (ret) -                        goto out; +        status_values = GF_CALLOC (count, sizeof (gf_gsync_status_t *), +                              gf_common_mt_char); +        if (!status_values) { +                ret = -1; +                goto out; +        } -                ret = dict_get_str (dict, master_key, &master); -                if (ret) +        for (i = 0; i < count; i++) { +                status_values[i] = GF_CALLOC (1, sizeof (gf_gsync_status_t), +                                         gf_common_mt_char); +                if (!status_values[i]) { +                        ret = -1;                          goto out; +                } -                ret = dict_get_str (dict, slave_key, &slave); -                if (ret) -                        goto out; +                snprintf (status_value_name, sizeof (status_value_name), +                          "status_value%d", i); -                ret = dict_get_str (dict, status_key, &status); -                if (ret) +                ret = dict_get_bin (dict, status_value_name, +                                    (void **)&(status_values[i])); +                if (ret) { +                        gf_log ("cli", GF_LOG_ERROR, +                                "struct member empty.");                          goto out; +                } +        } + +        qsort(status_values, count, sizeof (gf_gsync_status_t *), +              gf_gsync_status_t_comparator); + +        for (i = 0; i < count; i++) { +                if (closed) { +                        ret = xmlTextWriterStartElement (writer, +                                                         (xmlChar *)"volume"); +                        XML_RET_CHECK_AND_GOTO (ret, out); + +                        tmp = get_struct_variable (1, status_values[i]); +                        if (!tmp) { +                                gf_log ("cli", GF_LOG_ERROR, +                                        "struct member empty."); +                                ret = -1; +                                goto out; +                        } + +                        ret = xmlTextWriterWriteFormatElement (writer, +                                                        (xmlChar *)"name", +                                                        "%s",tmp); +                        XML_RET_CHECK_AND_GOTO (ret, out); + +                        ret = xmlTextWriterStartElement (writer, +                                                    (xmlChar *)"sessions"); +                        XML_RET_CHECK_AND_GOTO (ret, out); + +                        closed = 0; +                } + +                if (session_closed) { +                        ret = xmlTextWriterStartElement (writer, +                                                         (xmlChar *)"session"); +                        XML_RET_CHECK_AND_GOTO (ret, out); + +                        session_closed = 0; + +                        tmp = get_struct_variable (14, status_values[i]); +                        if (!tmp) { +                                gf_log ("cli", GF_LOG_ERROR, +                                        "struct member empty."); +                                ret = -1; +                                goto out; +                        } + +                        ret = xmlTextWriterWriteFormatElement +                                (writer, (xmlChar *)"session_slave", "%s", tmp); +                        XML_RET_CHECK_AND_GOTO (ret, out); +                } -                /* <pair> */                  ret = xmlTextWriterStartElement (writer, (xmlChar *)"pair");                  XML_RET_CHECK_AND_GOTO (ret, out); -                ret = xmlTextWriterWriteFormatElement (writer, -                                                       (xmlChar *)"node", -                                                       "%s", node); -                XML_RET_CHECK_AND_GOTO (ret, out); +                for (j = 0; j < number_of_fields; j++) { +                  // if detail option is not set and field is not under +                  // basic fields or if field is volume then skip +                        if(!status_detail && j >= number_of_basic_fields) +                                continue; -                ret = xmlTextWriterWriteFormatElement (writer, -                                                       (xmlChar *)"master", -                                                       "%s", master); -                XML_RET_CHECK_AND_GOTO (ret, out); +                        // Displaying the master_node uuid as second field -                ret = xmlTextWriterWriteFormatElement (writer, -                                                       (xmlChar *)"slave", -                                                       "%s", slave); -                XML_RET_CHECK_AND_GOTO (ret, out); +                        if (j == 1) +                                tmp = get_struct_variable (12, +                                                           status_values[i]); +                        else +                                tmp = get_struct_variable (j, status_values[i]); +                        if (!tmp) { +                                gf_log ("cli", GF_LOG_ERROR, +                                        "struct member empty."); +                                ret = -1; +                                goto out; +                        } -                ret = xmlTextWriterWriteFormatElement (writer, -                                                       (xmlChar *)"status", -                                                       "%s", status); -                XML_RET_CHECK_AND_GOTO (ret, out); +                        ret = xmlTextWriterWriteFormatElement (writer, +                                                  (xmlChar *)title_values[j], +                                                  "%s", tmp); +                        XML_RET_CHECK_AND_GOTO (ret, out); +                } -                /* </pair> */                  ret = xmlTextWriterEndElement (writer);                  XML_RET_CHECK_AND_GOTO (ret, out); -        } +                if (i+1 < count) { +                        slave = get_struct_variable (13, status_values[i]); +                        slave_next = get_struct_variable (13, +                                                          status_values[i+1]); +                        volume = get_struct_variable (1, status_values[i]); +                        volume_next = get_struct_variable (1, +                                                           status_values[i+1]); +                        if (!slave || !slave_next || !volume || !volume_next) { +                                gf_log ("cli", GF_LOG_ERROR, +                                        "struct member empty."); +                                ret = -1; +                                goto out; +                        } + +                        if (strcmp (volume, volume_next)!=0) { +                                closed = 1; +                                session_closed = 1; + +                                ret = xmlTextWriterEndElement (writer); +                                XML_RET_CHECK_AND_GOTO (ret, out); + +                                ret = xmlTextWriterEndElement (writer); +                                XML_RET_CHECK_AND_GOTO (ret, out); + +                                ret = xmlTextWriterEndElement (writer); +                                XML_RET_CHECK_AND_GOTO (ret, out); +                        } else if (strcmp (slave, slave_next)!=0) { + +                                session_closed = 1; + +                                ret = xmlTextWriterEndElement (writer); +                                XML_RET_CHECK_AND_GOTO (ret, out); +                        } +                } else { + +                        ret = xmlTextWriterEndElement (writer); +                        XML_RET_CHECK_AND_GOTO (ret, out); + +                        ret = xmlTextWriterEndElement (writer); +                        XML_RET_CHECK_AND_GOTO (ret, out); +                        ret = xmlTextWriterEndElement (writer); +                        XML_RET_CHECK_AND_GOTO (ret, out); +                } +        }  out:          gf_log ("cli",GF_LOG_DEBUG, "Returning %d", ret);          return ret; @@ -4032,19 +4175,21 @@ cli_xml_output_vol_gsync (dict_t *dict, int op_ret, int op_errno,                  break;          case GF_GSYNC_OPTION_TYPE_CONFIG: -                ret = xmlTextWriterStartElement (writer, (xmlChar *)"config"); -                XML_RET_CHECK_AND_GOTO (ret, out); +                if (op_ret == 0) { +                        ret = xmlTextWriterStartElement (writer, (xmlChar *)"config"); +                        XML_RET_CHECK_AND_GOTO (ret, out); -                ret = cli_xml_generate_gsync_config (dict, writer); -                if (ret) -                        goto out; +                        ret = cli_xml_generate_gsync_config (dict, writer); +                        if (ret) +                                goto out; -                ret = xmlTextWriterEndElement (writer); -                XML_RET_CHECK_AND_GOTO (ret, out); +                        ret = xmlTextWriterEndElement (writer); +                        XML_RET_CHECK_AND_GOTO (ret, out); +                }                  break;          case GF_GSYNC_OPTION_TYPE_STATUS: -                ret = cli_xml_output_vol_gsync_status(dict, writer); +                ret = cli_xml_output_vol_gsync_status (dict, writer);                  break;          default:                  ret = 0; diff --git a/cli/src/cli.h b/cli/src/cli.h index 74d35992680..b48911648fa 100644 --- a/cli/src/cli.h +++ b/cli/src/cli.h @@ -181,6 +181,8 @@ extern struct cli_state *global_state; /* use only in readline callback */  typedef const char *(*cli_selector_t) (void *wcon); +char *get_struct_variable (int mem_num, gf_gsync_status_t *sts_val); +  void *cli_getunamb (const char *tok, void **choices, cli_selector_t sel);  int cli_cmd_register (struct cli_cmd_tree *tree, struct cli_cmd *cmd); diff --git a/rpc/rpc-lib/src/protocol-common.h b/rpc/rpc-lib/src/protocol-common.h index 1856387826b..b3e677afd17 100644 --- a/rpc/rpc-lib/src/protocol-common.h +++ b/rpc/rpc-lib/src/protocol-common.h @@ -244,6 +244,9 @@ struct gf_gsync_detailed_status_ {          char bytes_remaining[NAME_MAX];          char purges_remaining[NAME_MAX];          char total_files_skipped[NAME_MAX]; +        char brick_host_uuid[NAME_MAX]; +        char slavekey[NAME_MAX]; +        char session_slave[NAME_MAX];  };  enum glusterd_mgmt_v3_procnum { diff --git a/xlators/mgmt/glusterd/src/glusterd-geo-rep.c b/xlators/mgmt/glusterd/src/glusterd-geo-rep.c index def83fb2055..f4c5f1cb685 100644 --- a/xlators/mgmt/glusterd/src/glusterd-geo-rep.c +++ b/xlators/mgmt/glusterd/src/glusterd-geo-rep.c @@ -3471,6 +3471,10 @@ glusterd_read_status_file (glusterd_volinfo_t *volinfo, char *slave,          char                   *statefile                  = NULL;          char                   *socketfile                 = NULL;          dict_t                 *confd                      = NULL; +        char                   *slavekey                   = NULL; +        char                   *slaveentry                 = NULL; +        char                   *brick_host_uuid            = NULL; +        int                     brick_host_uuid_length     = 0;          int                     gsync_count                = 0;          int                     i                          = 0;          int                     ret                        = 0; @@ -3676,9 +3680,34 @@ store_status:                  sts_val->node[strlen(node)] = '\0';                  memcpy (sts_val->brick, brickinfo->path, strlen(brickinfo->path));                  sts_val->brick[strlen(brickinfo->path)] = '\0'; + +                ret = glusterd_get_slave (volinfo, slave, &slavekey); +                if (ret < 0) { +                        GF_FREE (sts_val); +                        goto out; +                } +                memcpy (sts_val->slavekey, slavekey, strlen(slavekey)); +                sts_val->slavekey[strlen(slavekey)] = '\0'; + +                brick_host_uuid = uuid_utoa(brickinfo->uuid); +                brick_host_uuid_length = strlen (brick_host_uuid); +                memcpy (sts_val->brick_host_uuid, brick_host_uuid, +                        brick_host_uuid_length); +                sts_val->brick_host_uuid[brick_host_uuid_length] = '\0'; +                  memcpy (sts_val->master, master, strlen(master));                  sts_val->master[strlen(master)] = '\0'; +                ret = dict_get_str (volinfo->gsync_slaves, slavekey, +                                    &slaveentry); +                if (ret < 0) { +                        GF_FREE (sts_val); +                        goto out; +                } +                memcpy (sts_val->session_slave, slaveentry, +                        strlen(slaveentry)); +                sts_val->session_slave[strlen(slaveentry)] = '\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) {  | 
