diff options
| author | Anuradha Talur <atalur@redhat.com> | 2015-11-23 15:56:28 +0530 | 
|---|---|---|
| committer | Pranith Kumar Karampuri <pkarampu@redhat.com> | 2015-12-21 01:19:05 -0800 | 
| commit | fbcd691b593cba29ba9c54d3da2c685787f719be (patch) | |
| tree | 8c6fb950f79f261e7c61e849045ddd8e85062af9 /heal/src | |
| parent | cf1667cf2fdc9306ae23db1c171b6bdb225153d7 (diff) | |
heal : Changed heal info to process all indices directories
        Backport of http://review.gluster.org/#/c/12658/
Change-Id: Ida863844e14309b6526c1b8434273fbf05c410d2
BUG: 1287531
Signed-off-by: Anuradha Talur <atalur@redhat.com>
Reviewed-on: http://review.gluster.org/12854
Tested-by: NetBSD Build System <jenkins@build.gluster.org>
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
Diffstat (limited to 'heal/src')
| -rw-r--r-- | heal/src/glfs-heal.c | 343 | 
1 files changed, 237 insertions, 106 deletions
diff --git a/heal/src/glfs-heal.c b/heal/src/glfs-heal.c index 2f120c9bd3d..ce9ffbbc70b 100644 --- a/heal/src/glfs-heal.c +++ b/heal/src/glfs-heal.c @@ -26,7 +26,8 @@                    "source-brick <HOSTNAME:BRICKNAME> [<FILE>] | "\                    "split-brain-info]\n" -typedef void    (*print_status) (dict_t *, char *, uuid_t, uint64_t *); +typedef void    (*print_status) (dict_t *, char *, uuid_t, uint64_t *, +                 gf_boolean_t flag);  int glfsh_heal_splitbrain_file (glfs_t *fs, xlator_t *top_subvol,                                  loc_t *rootloc, char *file, dict_t *xattr_req); @@ -49,9 +50,30 @@ out:  } +void +glfsh_print_heal_op_status (int ret, uint64_t num_entries, +                            gf_xl_afr_op_t heal_op) +{ + +        if (ret < 0) { +                printf ("Failed to process entries completely. " +                         "Number of entries so far: %"PRIu64"\n", num_entries); +        } else { +                if (heal_op == GF_SHD_OP_INDEX_SUMMARY) +                        printf ("Number of entries: %"PRIu64"\n", num_entries); +                else if (heal_op == GF_SHD_OP_SPLIT_BRAIN_FILES) +                        printf ("Number of entries in split-brain: %"PRIu64"\n" +                                , num_entries); +                else if (heal_op == GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK) +                        printf ("Number of healed entries: %"PRIu64"\n", +                                num_entries); +        } +        return; +} +  int  glfsh_get_index_dir_loc (loc_t *rootloc, xlator_t *xl, loc_t *dirloc, -                         int32_t *op_errno) +                         int32_t *op_errno, char *vgfid)  {          void      *index_gfid = NULL;          int       ret = 0; @@ -59,14 +81,13 @@ glfsh_get_index_dir_loc (loc_t *rootloc, xlator_t *xl, loc_t *dirloc,          struct iatt   iattr = {0};          struct iatt   parent = {0}; -        ret = syncop_getxattr (xl, rootloc, &xattr, GF_XATTROP_INDEX_GFID, -                               NULL, NULL); +        ret = syncop_getxattr (xl, rootloc, &xattr, vgfid, NULL, NULL);          if (ret < 0) {                  *op_errno = -ret;                  goto out;          } -        ret = dict_get_ptr (xattr, GF_XATTROP_INDEX_GFID, &index_gfid); +        ret = dict_get_ptr (xattr, vgfid, &index_gfid);          if (ret < 0) {                  *op_errno = EINVAL;                  goto out; @@ -137,53 +158,105 @@ glfsh_index_purge (xlator_t *subvol, inode_t *inode, char *name)  void  glfsh_print_spb_status (dict_t *dict, char *path, uuid_t gfid, -                        uint64_t *num_entries) +                        uint64_t *num_entries, gf_boolean_t flag)  { -       char *value  = NULL; -       int   ret    = 0; +        int   ret    = 0; +        gf_boolean_t    pending         = _gf_false; +        gf_boolean_t    split_b         = _gf_false; +        char            *value          = NULL; -       ret = dict_get_str (dict, "heal-info", &value); -       if (ret) -               return; +        ret = dict_get_str (dict, "heal-info", &value); +        if (ret) +                return; -       if (!strcmp (value, "split-brain")) { -                (*num_entries)++; -                printf ("%s\n", +        if (!strcmp (value, "split-brain")) { +                split_b = _gf_true; +        } else if (!strcmp (value, "split-brain-pending")) { +                split_b = _gf_true; +                pending = _gf_true; +        } +        /* Consider the entry only iff : +         * 1) The dir being processed is not indices/dirty, indicated by +         *    flag == _gf_false +         * 2) The dir being processed is indices/dirty but the entry also +         *    exists in indices/xattrop dir and has already been processed. +         */ +        if (split_b) { +                if (!flag || (flag && !pending)) { +                        (*num_entries)++; +                        printf ("%s\n",                          path ? path : uuid_utoa (gfid)); -       } -       return; +                } +        } +        return;  }  void  glfsh_print_heal_status (dict_t *dict, char *path, uuid_t gfid, -                         uint64_t *num_entries) +                         uint64_t *num_entries, gf_boolean_t ignore_dirty)  { -       char *value  = NULL; -       int   ret    = 0; -       char *status = NULL; - -       ret = dict_get_str (dict, "heal-info", &value); -       if (ret || (!strcmp (value, "no-heal"))) -               return; - -       (*num_entries)++; -       if (!strcmp (value, "heal")) { -               ret = gf_asprintf (&status, " "); -       } else if (!strcmp (value, "possibly-healing")) { -               ret = gf_asprintf (&status, " - Possibly undergoing heal\n"); -       } else if (!strcmp (value, "split-brain")) { -               ret = gf_asprintf (&status, " - Is in split-brain\n"); -       } -       if (ret == -1) -               status = NULL; - -       printf ("%s%s\n", -               path ? path : uuid_utoa (gfid), -               status); - -       if (status) -               GF_FREE (status); -       return; +        int             ret             = 0; +        gf_boolean_t    pending         = _gf_false; +        char            *status         = NULL; +        char            *value          = NULL; + +        ret = dict_get_str (dict, "heal-info", &value); +        if (ret || (!strcmp (value, "no-heal"))) +                return; + +        if (!strcmp (value, "heal")) { +                ret = gf_asprintf (&status, " "); +                if (ret < 0) +                        goto out; +        } else if (!strcmp (value, "possibly-healing")) { +                ret = gf_asprintf (&status, +                                   " - Possibly undergoing heal\n"); +                if (ret < 0) +                        goto out; +        } else if (!strcmp (value, "split-brain")) { +                ret = gf_asprintf (&status, " - Is in split-brain\n"); +                if (ret < 0) +                        goto out; +        } else if (!strcmp (value, "heal-pending")) { +                pending = _gf_true; +                ret = gf_asprintf (&status, " "); +                if (ret < 0) +                        goto out; +        } else if (!strcmp (value, "split-brain-pending")) { +                pending = _gf_true; +                ret = gf_asprintf (&status, " - Is in split-brain\n"); +                if (ret < 0) +                        goto out; +        } else if (!strcmp (value, "possibly-healing-pending")) { +                pending = _gf_true; +                ret = gf_asprintf (&status, +                                   " - Possibly undergoing heal\n"); +                if (ret < 0) +                        goto out; +        } +out: +        /* If ignore_dirty is set, it means indices/dirty directory is +         * being processed. Ignore the entry if it also exists in +         * indices/xattrop. +         * Boolean pending is set to true if the entry also exists in +         * indices/xattrop directory. +         */ +        if (ignore_dirty) { +                if (pending) { +                        GF_FREE (status); +                        status = NULL; +                        return; +                } +        } +        if (ret == -1) +                status = NULL; + +        (*num_entries)++; +        printf ("%s%s\n", +                path ? path : uuid_utoa (gfid), status ? status : ""); + +        GF_FREE (status); +        return;  }  static int @@ -216,7 +289,8 @@ glfsh_heal_entries (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,  static int  glfsh_process_entries (xlator_t *xl, fd_t *fd, gf_dirent_t *entries,                         uint64_t *offset, uint64_t *num_entries, -                       print_status glfsh_print_status) +                       print_status glfsh_print_status, +                       gf_boolean_t ignore_dirty)  {          gf_dirent_t      *entry = NULL;          gf_dirent_t      *tmp = NULL; @@ -258,7 +332,7 @@ glfsh_process_entries (xlator_t *xl, fd_t *fd, gf_dirent_t *entries,                  }                  if (dict)                          glfsh_print_status (dict, path, gfid, -                                            num_entries); +                                            num_entries, ignore_dirty);          }          ret = 0;          GF_FREE (path); @@ -272,13 +346,13 @@ glfsh_process_entries (xlator_t *xl, fd_t *fd, gf_dirent_t *entries,  static int  glfsh_crawl_directory (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,                         xlator_t *readdir_xl, fd_t *fd, loc_t *loc, -                       dict_t *xattr_req) +                       dict_t *xattr_req, uint64_t *num_entries, +                       gf_boolean_t ignore)  {          uint64_t        offset = 0;          gf_dirent_t     entries;          int             ret = 0;          gf_boolean_t    free_entries = _gf_false; -        uint64_t        num_entries = 0;          int             heal_op = -1;          INIT_LIST_HEAD (&entries.list); @@ -300,21 +374,23 @@ glfsh_crawl_directory (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,                  if (heal_op == GF_SHD_OP_INDEX_SUMMARY) {                          ret = glfsh_process_entries (readdir_xl, fd,                                                       &entries, &offset, -                                                     &num_entries, -                                                     glfsh_print_heal_status); +                                                     num_entries, +                                                     glfsh_print_heal_status, +                                                     ignore);                          if (ret < 0)                                  goto out;                  } else if (heal_op == GF_SHD_OP_SPLIT_BRAIN_FILES) {                          ret = glfsh_process_entries (readdir_xl, fd,                                                       &entries, &offset, -                                                     &num_entries, -                                                     glfsh_print_spb_status); +                                                     num_entries, +                                                     glfsh_print_spb_status, +                                                     ignore);                          if (ret < 0)                                  goto out;                  } else if (heal_op == GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK) {                          ret = glfsh_heal_entries (fs, top_subvol, rootloc,                                                    &entries, &offset, -                                                  &num_entries, xattr_req); +                                                  num_entries, xattr_req);                  }                  gf_dirent_free (&entries);                  free_entries = _gf_false; @@ -323,19 +399,6 @@ glfsh_crawl_directory (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,  out:          if (free_entries)                  gf_dirent_free (&entries); -        if (ret < 0) { -                printf ("Failed to complete gathering info. " -                         "Number of entries so far: %"PRIu64"\n", num_entries); -        } else { -                if (heal_op == GF_SHD_OP_INDEX_SUMMARY) -                        printf ("Number of entries: %"PRIu64"\n", num_entries); -                else if (heal_op == GF_SHD_OP_SPLIT_BRAIN_FILES) -                        printf ("Number of entries in split-brain: %"PRIu64"\n" -                                , num_entries); -                else if (heal_op == GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK) -                        printf ("Number of healed entries: %"PRIu64"\n", -                                num_entries); -        }          return ret;  } @@ -361,14 +424,53 @@ out:          return ret;  } -void -glfsh_print_pending_heals (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc, -                           xlator_t *xl, gf_xl_afr_op_t heal_op) +int +glfsh_print_pending_heals_type (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc, +                                xlator_t *xl, gf_xl_afr_op_t heal_op, +                                dict_t *xattr_req, char *vgfid, +                                uint64_t *num_entries)  {          int ret = 0;          loc_t   dirloc = {0};          fd_t    *fd = NULL;          int32_t op_errno = 0; +        gf_boolean_t ignore = _gf_false; + +        if (!strcmp(vgfid, GF_XATTROP_DIRTY_GFID)) +                ignore = _gf_true; + +        ret = glfsh_get_index_dir_loc (rootloc, xl, &dirloc, &op_errno, +                                       vgfid); +        if (ret < 0) { +                if (op_errno == ESTALE || op_errno == ENOENT) { +                        ret = 0; +                } else { +                        printf ("Status: %s\n", strerror (op_errno)); +                        ret = -op_errno; +                } +                goto out; +        } + +        ret = syncop_dirfd (xl, &dirloc, &fd, GF_CLIENT_PID_GLFS_HEAL); +        if (ret) +                goto out; + +        ret = glfsh_crawl_directory (fs, top_subvol, rootloc, xl, fd, &dirloc, +                                     xattr_req, num_entries, ignore); +        if (fd) +                fd_unref (fd); +out: +        loc_wipe (&dirloc); +        return ret; +} + +void +glfsh_print_pending_heals (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc, +                           xlator_t *xl, gf_xl_afr_op_t heal_op) +{ +        int ret = 0; +        uint64_t count = 0, total = 0; +          dict_t *xattr_req = NULL;          xattr_req = dict_new(); @@ -378,38 +480,31 @@ glfsh_print_pending_heals (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,          ret = dict_set_int32 (xattr_req, "heal-op", heal_op);          if (ret)                  goto out; +          ret = glfsh_print_brick_from_xl (xl);          if (ret < 0)                  goto out; -        ret = glfsh_get_index_dir_loc (rootloc, xl, &dirloc, &op_errno); -        if (ret < 0) { -                if (op_errno == ESTALE || op_errno == ENOENT) -                        printf ("Number of entries: 0\n"); -                else -                        printf ("Status: %s\n", strerror (op_errno)); -                goto out; -        } - -        ret = syncop_dirfd (xl, &dirloc, &fd, GF_CLIENT_PID_GLFS_HEAL); -        if (ret) +        ret = glfsh_print_pending_heals_type (fs, top_subvol, rootloc, xl, +                                              heal_op, xattr_req, +                                              GF_XATTROP_INDEX_GFID, &count); +        total += count; +        count = 0; +        if (ret == -ENOTCONN)                  goto out; -        ret = glfsh_crawl_directory (fs, top_subvol, rootloc, xl, fd, &dirloc, -                                     xattr_req); -        if (fd) -                fd_unref (fd); -        if (xattr_req) -                dict_unref (xattr_req); -        if (ret < 0) { -                if (heal_op == GF_SHD_OP_INDEX_SUMMARY) -                        printf ("Failed to find entries with pending" -                                " self-heal\n"); -                if (heal_op == GF_SHD_OP_SPLIT_BRAIN_FILES) -                        printf ("Failed to find entries in split-brain\n"); +        if (!strcmp (xl->type, "cluster/replicate")) { +                ret = glfsh_print_pending_heals_type (fs, top_subvol, +                                                      rootloc, xl, +                                                      heal_op, xattr_req, +                                                      GF_XATTROP_DIRTY_GFID, +                                                      &count); +                total += count;          }  out: -        loc_wipe (&dirloc); +        if (xattr_req) +                dict_unref (xattr_req); +        glfsh_print_heal_op_status (ret, total, heal_op);          return;  } @@ -598,15 +693,43 @@ out:  }  int +glfsh_heal_from_brick_type (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc, +                            char *hostname, char *brickpath, xlator_t *client, +                            dict_t *xattr_req, char *vgfid, +                            uint64_t *num_entries) +{ +        fd_t     *fd        = NULL; +        loc_t     dirloc    = {0}; +        int32_t   op_errno  = 0; +        int       ret       = -1; + +        ret = glfsh_get_index_dir_loc (rootloc, client, &dirloc, +                                       &op_errno, vgfid); +        if (ret < 0) +                goto out; + +        ret = syncop_dirfd (client, &dirloc, &fd, +                            GF_CLIENT_PID_GLFS_HEAL); +        if (ret) +                goto out; +        ret = glfsh_crawl_directory (fs, top_subvol, rootloc, client, +                                     fd, &dirloc, xattr_req, num_entries, +                                     _gf_false); +        if (fd) +                fd_unref (fd); +out: +        loc_wipe (&dirloc); +        return ret; +} + +int  glfsh_heal_from_brick (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,                        char *hostname, char *brickpath, char *file)  {          int       ret       = -1; +        uint64_t   count     = 0, total = 0;          dict_t   *xattr_req = NULL;          xlator_t *client    = NULL; -        fd_t     *fd        = NULL; -        loc_t     dirloc    = {0}; -        int32_t   op_errno  = 0;          xattr_req = dict_new();          if (!xattr_req) @@ -627,23 +750,31 @@ glfsh_heal_from_brick (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,                  goto out;          if (file)                  ret = glfsh_heal_splitbrain_file (fs, top_subvol, rootloc, file, -                                                 xattr_req); +                                                  xattr_req);          else { -                ret = glfsh_get_index_dir_loc (rootloc, client, &dirloc, -                                               &op_errno); -                ret = syncop_dirfd (client, &dirloc, &fd, -                                    GF_CLIENT_PID_GLFS_HEAL); -                if (ret) +                ret = glfsh_heal_from_brick_type (fs, top_subvol, rootloc, +                                                  hostname, brickpath, +                                                  client, xattr_req, +                                                  GF_XATTROP_INDEX_GFID, +                                                  &count); +                total += count; +                count = 0; +                ret = glfsh_heal_from_brick_type (fs, top_subvol, rootloc, +                                                  hostname, brickpath, +                                                  client, xattr_req, +                                                  GF_XATTROP_DIRTY_GFID, +                                                  &count); +                total += count; +                if (ret < 0)                          goto out; -                ret = glfsh_crawl_directory (fs, top_subvol, rootloc, client, -                                             fd, &dirloc, xattr_req); -                if (fd) -                        fd_unref (fd);          }  out:          if (xattr_req)                  dict_unref (xattr_req); -        loc_wipe (&dirloc); +        if (!file) +                glfsh_print_heal_op_status (ret, total, +                                            GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK); +          return ret;  }  | 
