a3470f
From dd892d811ec66841b274f5ed6e22040cbdc003b0 Mon Sep 17 00:00:00 2001
a3470f
From: karthik-us <ksubrahm@redhat.com>
a3470f
Date: Mon, 20 Nov 2017 11:46:59 +0530
a3470f
Subject: [PATCH 080/128] heal: New feature heal info summary to list the
a3470f
 status of brick and count of entries to be healed
a3470f
a3470f
Command output:
a3470f
Brick 192.168.2.8:/brick/1
a3470f
Status: Connected
a3470f
Total Number of entries: 363
a3470f
Number of entries in heal pending: 362
a3470f
Number of entries in split-brain: 0
a3470f
Number of entries possibly healing: 1
a3470f
a3470f
a3470f
<cliOutput>
a3470f
    <healInfo>
a3470f
      <bricks>
a3470f
        <brick hostUuid="9105dd4b-eca8-4fdb-85b2-b81cdf77eda3">
a3470f
          <name>192.168.2.8:/brick/1</name>
a3470f
          <status>Connected</status>
a3470f
          <totalNumberOfEntries>363</numberOfEntries>
a3470f
          <numberOfEntriesInHealPending>362</numberOfEntriesInHealPending>
a3470f
          <numberOfEntriesInSplitBrain>0</numberOfEntriesInSplitBrain>
a3470f
          <numberOfEntriesPossiblyHealing>1</numberOfEntriesPossiblyHealing>
a3470f
        </brick>
a3470f
      </bricks>
a3470f
    </healInfo>
a3470f
    <opRet>0</opRet>
a3470f
    <opErrno>0</opErrno>
a3470f
    <opErrstr/>
a3470f
</cliOutput>
a3470f
a3470f
> Change-Id: I40cb6f77a14131c9e41b292f4901b41a228863d7
a3470f
> BUG: 1261463
a3470f
> Signed-off-by: Mohamed Ashiq Liyazudeen <mliyazud@redhat.com>
a3470f
> Reviewed-on: https://review.gluster.org/12154
a3470f
> Smoke: Gluster Build System <jenkins@build.gluster.org>
a3470f
> Tested-by: Karthik U S <ksubrahm@redhat.com>
a3470f
> CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
a3470f
> Reviewed-by: Ravishankar N <ravishankar@redhat.com>
a3470f
> Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
a3470f
a3470f
Change-Id: I40cb6f77a14131c9e41b292f4901b41a228863d7
a3470f
BUG: 1286820
a3470f
Signed-off-by: karthik-us <ksubrahm@redhat.com>
a3470f
Reviewed-on: https://code.engineering.redhat.com/gerrit/123640
a3470f
Tested-by: RHGS Build Bot <nigelb@redhat.com>
a3470f
Reviewed-by: Ravishankar Narayanankutty <ravishankar@redhat.com>
a3470f
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
a3470f
---
a3470f
 cli/src/cli-cmd-parser.c                        |   5 +
a3470f
 cli/src/cli-cmd-volume.c                        |   9 +-
a3470f
 cli/src/cli-rpc-ops.c                           |   3 +-
a3470f
 heal/src/glfs-heal.c                            | 218 ++++++++++++++++++++----
a3470f
 rpc/rpc-lib/src/protocol-common.h               |   1 +
a3470f
 xlators/mgmt/glusterd/src/glusterd-volume-ops.c |   1 +
a3470f
 6 files changed, 205 insertions(+), 32 deletions(-)
a3470f
a3470f
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c
a3470f
index c95b262..764f420 100644
a3470f
--- a/cli/src/cli-cmd-parser.c
a3470f
+++ b/cli/src/cli-cmd-parser.c
a3470f
@@ -3952,6 +3952,11 @@ cli_cmd_volume_heal_options_parse (const char **words, int wordcount,
a3470f
                                                    GF_SHD_OP_SPLIT_BRAIN_FILES);
a3470f
                                 goto done;
a3470f
                         }
a3470f
+                        if (!strcmp (words[4], "summary")) {
a3470f
+                                ret = dict_set_int32 (dict, "heal-op",
a3470f
+                                                   GF_SHD_OP_HEAL_SUMMARY);
a3470f
+                                goto done;
a3470f
+                        }
a3470f
                 }
a3470f
 
a3470f
                 if (!strcmp (words[3], "statistics")) {
a3470f
diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c
a3470f
index a1e5c51..7110145 100644
a3470f
--- a/cli/src/cli-cmd-volume.c
a3470f
+++ b/cli/src/cli-cmd-volume.c
a3470f
@@ -2803,7 +2803,8 @@ cli_print_brick_status (cli_volume_status_t *status)
a3470f
                              (op == GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK) ||      \
a3470f
                              (op == GF_SHD_OP_INDEX_SUMMARY) ||               \
a3470f
                              (op == GF_SHD_OP_SPLIT_BRAIN_FILES) ||           \
a3470f
-                             (op == GF_SHD_OP_GRANULAR_ENTRY_HEAL_ENABLE))
a3470f
+                             (op == GF_SHD_OP_GRANULAR_ENTRY_HEAL_ENABLE) || \
a3470f
+                             (op == GF_SHD_OP_HEAL_SUMMARY))
a3470f
 
a3470f
 int
a3470f
 cli_launch_glfs_heal (int heal_op, dict_t *options)
a3470f
@@ -2856,6 +2857,12 @@ cli_launch_glfs_heal (int heal_op, dict_t *options)
a3470f
         case GF_SHD_OP_GRANULAR_ENTRY_HEAL_DISABLE:
a3470f
                 runner_add_args (&runner, "granular-entry-heal-op", NULL);
a3470f
                 break;
a3470f
+        case GF_SHD_OP_HEAL_SUMMARY:
a3470f
+                runner_add_args (&runner, "info-summary", NULL);
a3470f
+                if (global_state->mode & GLUSTER_MODE_XML) {
a3470f
+                        runner_add_args (&runner, "xml", NULL);
a3470f
+                }
a3470f
+                break;
a3470f
         default:
a3470f
                 ret = -1;
a3470f
         }
a3470f
diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c
a3470f
index 67e29a0..b91400b 100644
a3470f
--- a/cli/src/cli-rpc-ops.c
a3470f
+++ b/cli/src/cli-rpc-ops.c
a3470f
@@ -9112,11 +9112,12 @@ gf_cli_heal_volume_cbk (struct rpc_req *req, struct iovec *iov,
a3470f
         case    GF_SHD_OP_STATISTICS_HEAL_COUNT_PER_REPLICA:
a3470f
                 heal_op_str = "count of entries to be healed per replica";
a3470f
                 break;
a3470f
-        /* The below 3 cases are never hit; they're coded only to make
a3470f
+        /* The below 4 cases are never hit; they're coded only to make
a3470f
          * compiler warnings go away.*/
a3470f
         case    GF_SHD_OP_SBRAIN_HEAL_FROM_BIGGER_FILE:
a3470f
         case    GF_SHD_OP_SBRAIN_HEAL_FROM_LATEST_MTIME:
a3470f
         case    GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK:
a3470f
+        case    GF_SHD_OP_HEAL_SUMMARY:
a3470f
                 break;
a3470f
 
a3470f
         case    GF_SHD_OP_INVALID:
a3470f
diff --git a/heal/src/glfs-heal.c b/heal/src/glfs-heal.c
a3470f
index 27115f3..27a9624 100644
a3470f
--- a/heal/src/glfs-heal.c
a3470f
+++ b/heal/src/glfs-heal.c
a3470f
@@ -40,18 +40,25 @@ xmlDocPtr        glfsh_doc = NULL;
a3470f
                         ret = 0;                                \
a3470f
         } while (0)                                             \
a3470f
 
a3470f
-typedef int    (*print_status) (dict_t *, char *, uuid_t, uint64_t *,
a3470f
+typedef struct num_entries {
a3470f
+        uint64_t num_entries;
a3470f
+        uint64_t pending_entries;
a3470f
+        uint64_t spb_entries;
a3470f
+        uint64_t possibly_healing_entries;
a3470f
+} num_entries_t;
a3470f
+
a3470f
+typedef int    (*print_status) (dict_t *, char *, uuid_t, num_entries_t *,
a3470f
                  gf_boolean_t flag);
a3470f
 
a3470f
 int glfsh_heal_splitbrain_file (glfs_t *fs, xlator_t *top_subvol,
a3470f
                                 loc_t *rootloc, char *file, dict_t *xattr_req);
a3470f
 
a3470f
-
a3470f
 typedef struct glfs_info {
a3470f
         int (*init)(void);
a3470f
         int (*print_brick_from_xl)(xlator_t *xl, loc_t *rootloc);
a3470f
         int (*print_heal_op_status)(int ret, uint64_t num_entries,
a3470f
                         char *fmt_str);
a3470f
+        int (*print_heal_op_summary)(int ret, num_entries_t *num_entries);
a3470f
         void (*print_heal_status)(char *path, uuid_t gfid, char *status);
a3470f
         void (*print_spb_status)(char *path, uuid_t gfid, char *status);
a3470f
         int (*end) (int op_ret, char *op_errstr);
a3470f
@@ -64,7 +71,7 @@ int32_t is_xml;
a3470f
 #define USAGE_STR "Usage: %s <VOLNAME> [bigger-file <FILE> | "\
a3470f
                   "latest-mtime <FILE> | "\
a3470f
                   "source-brick <HOSTNAME:BRICKNAME> [<FILE>] | "\
a3470f
-                  "split-brain-info]\n"
a3470f
+                  "split-brain-info | info-summary]\n"
a3470f
 
a3470f
 typedef enum {
a3470f
         GLFSH_MODE_CONTINUE_ON_ERROR = 1,
a3470f
@@ -259,6 +266,54 @@ out:
a3470f
         return ret;
a3470f
 }
a3470f
 
a3470f
+int
a3470f
+glfsh_print_xml_heal_op_summary (int ret, num_entries_t *num_entries)
a3470f
+{
a3470f
+        if (ret < 0 && num_entries == 0) {
a3470f
+                xmlTextWriterWriteFormatElement (glfsh_writer,
a3470f
+                                (xmlChar *)"status",
a3470f
+                                "%s", strerror (-ret));
a3470f
+                xmlTextWriterWriteFormatElement (glfsh_writer,
a3470f
+                                (xmlChar *)"totalNumberOfEntries", "-");
a3470f
+                xmlTextWriterWriteFormatElement (glfsh_writer,
a3470f
+                                (xmlChar *)"numberOfEntriesInHealPending", "-");
a3470f
+                xmlTextWriterWriteFormatElement (glfsh_writer,
a3470f
+                                (xmlChar *)"numberOfEntriesInSplitBrain", "-");
a3470f
+                xmlTextWriterWriteFormatElement (glfsh_writer,
a3470f
+                                (xmlChar *)"numberOfEntriesPossiblyHealing",
a3470f
+                                "-");
a3470f
+                goto out;
a3470f
+        } else if (ret == 0) {
a3470f
+                xmlTextWriterWriteFormatElement (glfsh_writer,
a3470f
+                                                 (xmlChar *)"status",
a3470f
+                                                 "%s", "Connected");
a3470f
+        }
a3470f
+
a3470f
+        if (ret < 0) {
a3470f
+                xmlTextWriterWriteFormatElement (glfsh_writer,
a3470f
+                                (xmlChar *)"status", "Failed to process entries"
a3470f
+                                " completely. "
a3470f
+                                "(%s)totalNumberOfEntries%"PRIu64"",
a3470f
+                                strerror (-ret), num_entries->num_entries);
a3470f
+        } else {
a3470f
+                xmlTextWriterWriteFormatElement (glfsh_writer,
a3470f
+                                (xmlChar *)"totalNumberOfEntries",
a3470f
+                                "%"PRIu64"", num_entries->num_entries);
a3470f
+                xmlTextWriterWriteFormatElement (glfsh_writer,
a3470f
+                                (xmlChar *)"numberOfEntriesInHealPending",
a3470f
+                                "%"PRIu64"", num_entries->pending_entries);
a3470f
+                xmlTextWriterWriteFormatElement (glfsh_writer,
a3470f
+                                (xmlChar *)"numberOfEntriesInSplitBrain",
a3470f
+                                "%"PRIu64"", num_entries->spb_entries);
a3470f
+                xmlTextWriterWriteFormatElement (glfsh_writer,
a3470f
+                                (xmlChar *)"numberOfEntriesPossiblyHealing",
a3470f
+                                "%"PRIu64"",
a3470f
+                                num_entries->possibly_healing_entries);
a3470f
+        }
a3470f
+out:
a3470f
+        return xmlTextWriterEndElement (glfsh_writer);
a3470f
+}
a3470f
+
a3470f
 void
a3470f
 glfsh_print_xml_file_status (char *path, uuid_t gfid, char *status)
a3470f
 {
a3470f
@@ -338,6 +393,39 @@ glfsh_no_print_hr_heal_op_status (int ret, uint64_t num_entries, char *fmt_str)
a3470f
 }
a3470f
 
a3470f
 int
a3470f
+glfsh_print_hr_heal_op_summary (int ret, num_entries_t *num_entries)
a3470f
+{
a3470f
+        if (ret < 0 && num_entries->num_entries == 0) {
a3470f
+                printf ("Status: %s\n", strerror (-ret));
a3470f
+                printf ("Total Number of entries: -\n");
a3470f
+                printf ("Number of entries in heal pending: -\n");
a3470f
+                printf ("Number of entries in split-brain: -\n");
a3470f
+                printf ("Number of entries possibly healing: -\n");
a3470f
+                goto out;
a3470f
+        } else if (ret == 0) {
a3470f
+                printf ("Status: Connected\n");
a3470f
+        }
a3470f
+
a3470f
+        if (ret < 0) {
a3470f
+                printf ("Status: Failed to process entries completely. "
a3470f
+                        "(%s)\nTotal Number of entries: %"PRIu64"\n",
a3470f
+                        strerror (-ret), num_entries->num_entries);
a3470f
+        } else {
a3470f
+                printf ("Total Number of entries: %"PRIu64"\n",
a3470f
+                        num_entries->num_entries);
a3470f
+                printf ("Number of entries in heal pending: %"PRIu64"\n",
a3470f
+                        num_entries->pending_entries);
a3470f
+                printf ("Number of entries in split-brain: %"PRIu64"\n",
a3470f
+                        num_entries->spb_entries);
a3470f
+                printf ("Number of entries possibly healing: %"PRIu64"\n",
a3470f
+                        num_entries->possibly_healing_entries);
a3470f
+        }
a3470f
+out:
a3470f
+        printf ("\n");
a3470f
+        return 0;
a3470f
+}
a3470f
+
a3470f
+int
a3470f
 glfsh_print_hr_heal_op_status (int ret, uint64_t num_entries, char *fmt_str)
a3470f
 {
a3470f
         if (ret < 0 && num_entries == 0) {
a3470f
@@ -364,6 +452,13 @@ out:
a3470f
 }
a3470f
 
a3470f
 int
a3470f
+glfsh_print_info_summary (int ret, num_entries_t *num_entries)
a3470f
+{
a3470f
+        return glfsh_output->print_heal_op_summary (ret, num_entries);
a3470f
+
a3470f
+}
a3470f
+
a3470f
+int
a3470f
 glfsh_print_heal_op_status (int ret, uint64_t num_entries,
a3470f
                             gf_xl_afr_op_t heal_op)
a3470f
 {
a3470f
@@ -430,7 +525,8 @@ _get_ancestor (xlator_t *xl, gf_xl_afr_op_t heal_op)
a3470f
                                          NULL};
a3470f
         char **ancestors = NULL;
a3470f
 
a3470f
-        if (heal_op == GF_SHD_OP_INDEX_SUMMARY)
a3470f
+        if (heal_op == GF_SHD_OP_INDEX_SUMMARY ||
a3470f
+            heal_op == GF_SHD_OP_HEAL_SUMMARY)
a3470f
                 ancestors = heal_xls;
a3470f
         else
a3470f
                 ancestors = replica_xl;
a3470f
@@ -465,8 +561,35 @@ glfsh_index_purge (xlator_t *subvol, inode_t *inode, char *name)
a3470f
 }
a3470f
 
a3470f
 int
a3470f
+glfsh_print_summary_status (dict_t *dict, char *path, uuid_t gfid,
a3470f
+                            num_entries_t *num_entries, gf_boolean_t flag)
a3470f
+{
a3470f
+        int     ret     = 0;
a3470f
+        char    *value  = NULL;
a3470f
+
a3470f
+        ret = dict_get_str (dict, "heal-info", &value);
a3470f
+        if (ret)
a3470f
+                goto out;
a3470f
+
a3470f
+        if ((!strcmp (value, "heal")) || (!strcmp (value, "heal-pending"))) {
a3470f
+                (num_entries->pending_entries)++;
a3470f
+        } else if ((!strcmp (value, "split-brain")) ||
a3470f
+                        (!strcmp (value, "split-brain-pending"))) {
a3470f
+                (num_entries->spb_entries)++;
a3470f
+        } else if ((!strcmp (value, "possibly-healing-pending")) ||
a3470f
+                        (!strcmp (value, "possibly-healing"))) {
a3470f
+                (num_entries->possibly_healing_entries)++;
a3470f
+        } else {
a3470f
+                goto out;
a3470f
+        }
a3470f
+        (num_entries->num_entries)++;
a3470f
+out:
a3470f
+        return ret;
a3470f
+}
a3470f
+
a3470f
+int
a3470f
 glfsh_print_spb_status (dict_t *dict, char *path, uuid_t gfid,
a3470f
-                        uint64_t *num_entries, gf_boolean_t flag)
a3470f
+                        num_entries_t *num_entries, gf_boolean_t flag)
a3470f
 {
a3470f
         int   ret    = 0;
a3470f
         gf_boolean_t    pending         = _gf_false;
a3470f
@@ -492,7 +615,7 @@ glfsh_print_spb_status (dict_t *dict, char *path, uuid_t gfid,
a3470f
          */
a3470f
         if (split_b) {
a3470f
                 if (!flag || (flag && !pending)) {
a3470f
-                        (*num_entries)++;
a3470f
+                        (num_entries->num_entries)++;
a3470f
                         glfsh_output->print_spb_status (path ? path :
a3470f
                                                 uuid_utoa_r (gfid, gfid_str),
a3470f
                                                 gfid, NULL);
a3470f
@@ -503,7 +626,8 @@ glfsh_print_spb_status (dict_t *dict, char *path, uuid_t gfid,
a3470f
 
a3470f
 int
a3470f
 glfsh_print_heal_status (dict_t *dict, char *path, uuid_t gfid,
a3470f
-                         uint64_t *num_entries, gf_boolean_t ignore_dirty)
a3470f
+                         num_entries_t *num_entries,
a3470f
+                         gf_boolean_t ignore_dirty)
a3470f
 {
a3470f
         int             ret             = 0;
a3470f
         gf_boolean_t    pending         = _gf_false;
a3470f
@@ -562,7 +686,7 @@ out:
a3470f
         if (ret == -1)
a3470f
                 status = NULL;
a3470f
 
a3470f
-        (*num_entries)++;
a3470f
+        (num_entries->num_entries)++;
a3470f
         glfsh_output->print_heal_status (path ? path :
a3470f
                                          uuid_utoa_r (gfid, gfid_str),
a3470f
                                          gfid,
a3470f
@@ -574,7 +698,7 @@ out:
a3470f
 
a3470f
 int
a3470f
 glfsh_heal_status_boolean (dict_t *dict, char *path, uuid_t gfid,
a3470f
-                           uint64_t *num_entries, gf_boolean_t ignore_dirty)
a3470f
+                           num_entries_t *num_entries, gf_boolean_t ignore_dirty)
a3470f
 {
a3470f
         int             ret             = 0;
a3470f
         char            *value          = NULL;
a3470f
@@ -589,7 +713,7 @@ glfsh_heal_status_boolean (dict_t *dict, char *path, uuid_t gfid,
a3470f
 static int
a3470f
 glfsh_heal_entries (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,
a3470f
                     gf_dirent_t *entries,  uint64_t *offset,
a3470f
-                    uint64_t *num_entries, dict_t *xattr_req) {
a3470f
+                    num_entries_t *num_entries, dict_t *xattr_req) {
a3470f
 
a3470f
         gf_dirent_t      *entry          = NULL;
a3470f
         gf_dirent_t      *tmp            = NULL;
a3470f
@@ -607,7 +731,7 @@ glfsh_heal_entries (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,
a3470f
                                                  xattr_req);
a3470f
                 if (ret)
a3470f
                         continue;
a3470f
-                (*num_entries)++;
a3470f
+                (num_entries->num_entries)++;
a3470f
         }
a3470f
 
a3470f
         return ret;
a3470f
@@ -615,7 +739,7 @@ glfsh_heal_entries (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,
a3470f
 
a3470f
 static int
a3470f
 glfsh_process_entries (xlator_t *xl, fd_t *fd, gf_dirent_t *entries,
a3470f
-                       uint64_t *offset, uint64_t *num_entries,
a3470f
+                       uint64_t *offset, num_entries_t *num_entries,
a3470f
                        print_status glfsh_print_status,
a3470f
                        gf_boolean_t ignore_dirty, glfsh_fail_mode_t mode)
a3470f
 {
a3470f
@@ -687,7 +811,7 @@ out:
a3470f
 static int
a3470f
 glfsh_crawl_directory (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,
a3470f
                        xlator_t *readdir_xl, fd_t *fd, loc_t *loc,
a3470f
-                       dict_t *xattr_req, uint64_t *num_entries,
a3470f
+                       dict_t *xattr_req, num_entries_t *num_entries,
a3470f
                        gf_boolean_t ignore)
a3470f
 {
a3470f
         int             ret          = 0;
a3470f
@@ -732,6 +856,14 @@ glfsh_crawl_directory (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,
a3470f
                                                      ignore, mode);
a3470f
                         if (ret < 0)
a3470f
                                 goto out;
a3470f
+                } else if (heal_op == GF_SHD_OP_HEAL_SUMMARY) {
a3470f
+                        ret = glfsh_process_entries (readdir_xl, fd,
a3470f
+                                                     &entries, &offset,
a3470f
+                                                     num_entries,
a3470f
+                                                     glfsh_print_summary_status,
a3470f
+                                                     ignore, mode);
a3470f
+                        if (ret < 0)
a3470f
+                                goto out;
a3470f
                 } else if (heal_op == GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK) {
a3470f
                         ret = glfsh_heal_entries (fs, top_subvol, rootloc,
a3470f
                                                   &entries, &offset,
a3470f
@@ -786,7 +918,7 @@ int
a3470f
 glfsh_print_pending_heals_type (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,
a3470f
                                 xlator_t *xl, gf_xl_afr_op_t heal_op,
a3470f
                                 dict_t *xattr_req, char *vgfid,
a3470f
-                                uint64_t *num_entries)
a3470f
+                                num_entries_t *num_entries)
a3470f
 {
a3470f
         int ret = 0;
a3470f
         loc_t   dirloc = {0};
a3470f
@@ -827,7 +959,8 @@ glfsh_print_pending_heals (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,
a3470f
                            is_parent_replicate)
a3470f
 {
a3470f
         int ret = 0;
a3470f
-        uint64_t count = 0, total = 0;
a3470f
+        num_entries_t num_entries = {0, };
a3470f
+        num_entries_t total = {0, };
a3470f
 
a3470f
         dict_t *xattr_req = NULL;
a3470f
 
a3470f
@@ -851,13 +984,20 @@ glfsh_print_pending_heals (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,
a3470f
 
a3470f
         ret = glfsh_print_pending_heals_type (fs, top_subvol, rootloc, xl,
a3470f
                                               heal_op, xattr_req,
a3470f
-                                              GF_XATTROP_INDEX_GFID, &count);
a3470f
+                                              GF_XATTROP_INDEX_GFID,
a3470f
+                                              &num_entries);
a3470f
 
a3470f
         if (ret < 0 && heal_op == GF_SHD_OP_GRANULAR_ENTRY_HEAL_ENABLE)
a3470f
                 goto out;
a3470f
 
a3470f
-        total += count;
a3470f
-        count = 0;
a3470f
+        total.num_entries += num_entries.num_entries;
a3470f
+        total.pending_entries += num_entries.pending_entries;
a3470f
+        total.spb_entries += num_entries.spb_entries;
a3470f
+        total.possibly_healing_entries += num_entries.possibly_healing_entries;
a3470f
+        num_entries.num_entries = 0;
a3470f
+        num_entries.pending_entries = 0;
a3470f
+        num_entries.spb_entries = 0;
a3470f
+        num_entries.possibly_healing_entries = 0;
a3470f
         if (ret == -ENOTCONN)
a3470f
                 goto out;
a3470f
 
a3470f
@@ -866,13 +1006,20 @@ glfsh_print_pending_heals (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,
a3470f
                                                       rootloc, xl,
a3470f
                                                       heal_op, xattr_req,
a3470f
                                                       GF_XATTROP_DIRTY_GFID,
a3470f
-                                                      &count);
a3470f
-                total += count;
a3470f
+                                                      &num_entries);
a3470f
+                total.num_entries += num_entries.num_entries;
a3470f
+                total.pending_entries += num_entries.pending_entries;
a3470f
+                total.spb_entries += num_entries.spb_entries;
a3470f
+                total.possibly_healing_entries += num_entries.possibly_healing_entries;
a3470f
         }
a3470f
 out:
a3470f
         if (xattr_req)
a3470f
                 dict_unref (xattr_req);
a3470f
-        glfsh_print_heal_op_status (ret, total, heal_op);
a3470f
+        if (heal_op == GF_SHD_OP_HEAL_SUMMARY) {
a3470f
+                glfsh_print_info_summary (ret, &total);
a3470f
+        } else {
a3470f
+                glfsh_print_heal_op_status (ret, total.num_entries, heal_op);
a3470f
+        }
a3470f
         return ret;
a3470f
 
a3470f
 }
a3470f
@@ -1193,7 +1340,7 @@ int
a3470f
 glfsh_heal_from_brick_type (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,
a3470f
                             char *hostname, char *brickpath, xlator_t *client,
a3470f
                             dict_t *xattr_req, char *vgfid,
a3470f
-                            uint64_t *num_entries)
a3470f
+                            num_entries_t *num_entries)
a3470f
 {
a3470f
         fd_t     *fd        = NULL;
a3470f
         loc_t     dirloc    = {0};
a3470f
@@ -1229,9 +1376,10 @@ glfsh_heal_from_brick (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,
a3470f
                       char *hostname, char *brickpath, char *file)
a3470f
 {
a3470f
         int       ret       = -1;
a3470f
-        uint64_t   count     = 0, total = 0;
a3470f
         dict_t   *xattr_req = NULL;
a3470f
         xlator_t *client    = NULL;
a3470f
+        num_entries_t num_entries = {0, };
a3470f
+        num_entries_t total = {0, };
a3470f
 
a3470f
         xattr_req = dict_new();
a3470f
         if (!xattr_req)
a3470f
@@ -1258,9 +1406,9 @@ glfsh_heal_from_brick (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,
a3470f
                                                   hostname, brickpath,
a3470f
                                                   client, xattr_req,
a3470f
                                                   GF_XATTROP_INDEX_GFID,
a3470f
-                                                  &count);
a3470f
-                total += count;
a3470f
-                count = 0;
a3470f
+                                                  &num_entries);
a3470f
+                total.num_entries += num_entries.num_entries;
a3470f
+                num_entries.num_entries = 0;
a3470f
                 if (ret == -ENOTCONN)
a3470f
                         goto out;
a3470f
 
a3470f
@@ -1268,8 +1416,8 @@ glfsh_heal_from_brick (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,
a3470f
                                                   hostname, brickpath,
a3470f
                                                   client, xattr_req,
a3470f
                                                   GF_XATTROP_DIRTY_GFID,
a3470f
-                                                  &count);
a3470f
-                total += count;
a3470f
+                                                  &num_entries);
a3470f
+                total.num_entries += num_entries.num_entries;
a3470f
                 if (ret < 0)
a3470f
                         goto out;
a3470f
         }
a3470f
@@ -1277,7 +1425,7 @@ out:
a3470f
         if (xattr_req)
a3470f
                 dict_unref (xattr_req);
a3470f
         if (!file)
a3470f
-                glfsh_print_heal_op_status (ret, total,
a3470f
+                glfsh_print_heal_op_status (ret, total.num_entries,
a3470f
                                             GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK);
a3470f
 
a3470f
         return ret;
a3470f
@@ -1326,6 +1474,7 @@ glfsh_info_t glfsh_human_readable = {
a3470f
         .init = glfsh_init,
a3470f
         .print_brick_from_xl = glfsh_print_brick_from_xl,
a3470f
         .print_heal_op_status = glfsh_print_hr_heal_op_status,
a3470f
+        .print_heal_op_summary = glfsh_print_hr_heal_op_summary,
a3470f
         .print_heal_status = glfsh_print_hr_heal_status,
a3470f
         .print_spb_status = glfsh_print_hr_spb_status,
a3470f
         .end = glfsh_end
a3470f
@@ -1345,6 +1494,7 @@ glfsh_info_t glfsh_xml_output = {
a3470f
         .init = glfsh_xml_init,
a3470f
         .print_brick_from_xl = glfsh_print_xml_brick_from_xl,
a3470f
         .print_heal_op_status = glfsh_print_xml_heal_op_status,
a3470f
+        .print_heal_op_summary = glfsh_print_xml_heal_op_summary,
a3470f
         .print_heal_status = glfsh_print_xml_file_status,
a3470f
         .print_spb_status = glfsh_print_xml_file_status,
a3470f
         .end = glfsh_xml_end
a3470f
@@ -1385,6 +1535,8 @@ main (int argc, char **argv)
a3470f
                         is_xml = 1;
a3470f
                 } else if (!strcmp (argv[2], "granular-entry-heal-op")) {
a3470f
                         heal_op = GF_SHD_OP_GRANULAR_ENTRY_HEAL_ENABLE;
a3470f
+		} else if (!strcmp (argv[2], "info-summary")) {
a3470f
+                        heal_op = GF_SHD_OP_HEAL_SUMMARY;
a3470f
                 } else {
a3470f
                         printf (USAGE_STR, argv[0]);
a3470f
                         ret = -1;
a3470f
@@ -1396,6 +1548,10 @@ main (int argc, char **argv)
a3470f
                                 && (!strcmp (argv[3], "xml"))) {
a3470f
                         heal_op = GF_SHD_OP_SPLIT_BRAIN_FILES;
a3470f
                         is_xml = 1;
a3470f
+                } else if ((!strcmp (argv[2], "info-summary"))
a3470f
+                                && (!strcmp (argv[3], "xml"))) {
a3470f
+                        heal_op = GF_SHD_OP_HEAL_SUMMARY;
a3470f
+                        is_xml = 1;
a3470f
                 } else if (!strcmp (argv[2], "bigger-file")) {
a3470f
                         heal_op = GF_SHD_OP_SBRAIN_HEAL_FROM_BIGGER_FILE;
a3470f
                         file = argv[3];
a3470f
@@ -1517,7 +1673,8 @@ main (int argc, char **argv)
a3470f
         if (ret < 0) {
a3470f
                 ret = -EINVAL;
a3470f
                 gf_asprintf (&op_errstr, "Volume %s is not of type %s", volname,
a3470f
-                                     (heal_op == GF_SHD_OP_INDEX_SUMMARY) ?
a3470f
+                                     (heal_op == GF_SHD_OP_INDEX_SUMMARY ||
a3470f
+                                      heal_op == GF_SHD_OP_HEAL_SUMMARY) ?
a3470f
                                      "replicate/disperse":"replicate");
a3470f
                 goto out;
a3470f
         }
a3470f
@@ -1528,6 +1685,7 @@ main (int argc, char **argv)
a3470f
         case GF_SHD_OP_INDEX_SUMMARY:
a3470f
         case GF_SHD_OP_SPLIT_BRAIN_FILES:
a3470f
         case GF_SHD_OP_GRANULAR_ENTRY_HEAL_ENABLE:
a3470f
+        case GF_SHD_OP_HEAL_SUMMARY:
a3470f
                 ret = glfsh_gather_heal_info (fs, top_subvol, &rootloc,
a3470f
                                               heal_op);
a3470f
                 break;
a3470f
diff --git a/rpc/rpc-lib/src/protocol-common.h b/rpc/rpc-lib/src/protocol-common.h
a3470f
index 510817c..80e1f6b 100644
a3470f
--- a/rpc/rpc-lib/src/protocol-common.h
a3470f
+++ b/rpc/rpc-lib/src/protocol-common.h
a3470f
@@ -265,6 +265,7 @@ typedef enum {
a3470f
         GF_SHD_OP_SBRAIN_HEAL_FROM_LATEST_MTIME,
a3470f
         GF_SHD_OP_GRANULAR_ENTRY_HEAL_ENABLE,
a3470f
         GF_SHD_OP_GRANULAR_ENTRY_HEAL_DISABLE,
a3470f
+        GF_SHD_OP_HEAL_SUMMARY,
a3470f
 } gf_xl_afr_op_t ;
a3470f
 
a3470f
 struct gf_gsync_detailed_status_ {
a3470f
diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
a3470f
index 725d194..222d5f4 100644
a3470f
--- a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
a3470f
+++ b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
a3470f
@@ -1867,6 +1867,7 @@ glusterd_handle_heal_cmd (xlator_t *this, glusterd_volinfo_t *volinfo,
a3470f
         case GF_SHD_OP_HEAL_DISABLE:/* This op should be handled in volume-set*/
a3470f
         case GF_SHD_OP_GRANULAR_ENTRY_HEAL_ENABLE: /* This op should be handled in volume-set */
a3470f
         case GF_SHD_OP_GRANULAR_ENTRY_HEAL_DISABLE: /* This op should be handled in volume-set */
a3470f
+        case GF_SHD_OP_HEAL_SUMMARY:/*glfsheal cmd*/
a3470f
         case GF_SHD_OP_SBRAIN_HEAL_FROM_BIGGER_FILE:/*glfsheal cmd*/
a3470f
         case GF_SHD_OP_SBRAIN_HEAL_FROM_LATEST_MTIME:/*glfsheal cmd*/
a3470f
         case GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK:/*glfsheal cmd*/
a3470f
-- 
a3470f
1.8.3.1
a3470f