diff options
Diffstat (limited to 'heal/src/glfs-heal.c')
| -rw-r--r-- | heal/src/glfs-heal.c | 180 | 
1 files changed, 151 insertions, 29 deletions
diff --git a/heal/src/glfs-heal.c b/heal/src/glfs-heal.c index 2a85e755151..94cb6b04c02 100644 --- a/heal/src/glfs-heal.c +++ b/heal/src/glfs-heal.c @@ -39,7 +39,7 @@ xmlDocPtr        glfsh_doc = NULL;                          ret = 0;                                \          } while (0)                                             \ -typedef void    (*print_status) (dict_t *, char *, uuid_t, uint64_t *, +typedef int    (*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, @@ -65,6 +65,11 @@ int32_t is_xml;                    "source-brick <HOSTNAME:BRICKNAME> [<FILE>] | "\                    "split-brain-info]\n" +typedef enum { +        GLFSH_MODE_CONTINUE_ON_ERROR = 1, +        GLFSH_MODE_EXIT_ON_FIRST_FAILURE, +} glfsh_fail_mode_t; +  int  glfsh_init ()  { @@ -72,6 +77,30 @@ glfsh_init ()  }  int +glfsh_end_op_granular_entry_heal (int op_ret, char *op_errstr) +{ +        /* If error sting is available, give it higher precedence.*/ + +        if (op_errstr) { +                printf ("%s\n", op_errstr); +        } else if (op_ret < 0) { +                if (op_ret == -EAGAIN) +                        printf ("One or more entries need heal. Please execute " +                                "the command again after there are no entries " +                                "to be healed\n"); +                else if (op_ret == -ENOTCONN) +                        printf ("One or more bricks could be down. Please " +                                "execute the command again after bringing all " +                                "bricks online and finishing any pending " +                                "heals\n"); +                else +                        printf ("Command failed - %s. Please check the logs for" +                                " more details\n", strerror (-op_ret)); +        } +        return 0; +} + +int  glfsh_end (int op_ret, char *op_errstr)  {          if (op_errstr) @@ -87,6 +116,12 @@ glfsh_print_hr_spb_status (char *path, uuid_t gfid, char *status)  }  void +glfsh_no_print_hr_heal_status (char *path, uuid_t gfid, char *status) +{ +        return; +} + +void  glfsh_print_hr_heal_status (char *path, uuid_t gfid, char *status)  {          printf ("%s%s\n", path, status); @@ -296,6 +331,12 @@ out:  }  int +glfsh_no_print_hr_heal_op_status (int ret, uint64_t num_entries, char *fmt_str) +{ +        return 0; +} + +int  glfsh_print_hr_heal_op_status (int ret, uint64_t num_entries, char *fmt_str)  {          if (ret < 0 && num_entries == 0) { @@ -422,7 +463,7 @@ glfsh_index_purge (xlator_t *subvol, inode_t *inode, char *name)          return ret;  } -void +int  glfsh_print_spb_status (dict_t *dict, char *path, uuid_t gfid,                          uint64_t *num_entries, gf_boolean_t flag)  { @@ -434,7 +475,7 @@ glfsh_print_spb_status (dict_t *dict, char *path, uuid_t gfid,          ret = dict_get_str (dict, "heal-info", &value);          if (ret) -                return; +                return 0;          if (!strcmp (value, "split-brain")) {                  split_b = _gf_true; @@ -456,10 +497,10 @@ glfsh_print_spb_status (dict_t *dict, char *path, uuid_t gfid,                                                  gfid, NULL);                  }          } -        return; +        return 0;  } -void +int  glfsh_print_heal_status (dict_t *dict, char *path, uuid_t gfid,                           uint64_t *num_entries, gf_boolean_t ignore_dirty)  { @@ -471,7 +512,7 @@ glfsh_print_heal_status (dict_t *dict, char *path, uuid_t gfid,          ret = dict_get_str (dict, "heal-info", &value);          if (ret || (!strcmp (value, "no-heal"))) -                return; +                return 0;          if (!strcmp (value, "heal")) {                  ret = gf_asprintf (&status, " "); @@ -514,7 +555,7 @@ out:                  if (pending) {                          GF_FREE (status);                          status = NULL; -                        return; +                        return 0;                  }          }          if (ret == -1) @@ -527,7 +568,21 @@ out:                                           status ? status : "");          GF_FREE (status); -        return; +        return 0; +} + +int +glfsh_heal_status_boolean (dict_t *dict, char *path, uuid_t gfid, +                           uint64_t *num_entries, gf_boolean_t ignore_dirty) +{ +        int             ret             = 0; +        char            *value          = NULL; + +        ret = dict_get_str (dict, "heal-info", &value); +        if ((!ret) && (!strcmp (value, "no-heal"))) +                return 0; +        else +                return -1;  }  static int @@ -561,11 +616,12 @@ 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, -                       gf_boolean_t ignore_dirty) +                       gf_boolean_t ignore_dirty, glfsh_fail_mode_t mode)  {          gf_dirent_t      *entry = NULL;          gf_dirent_t      *tmp = NULL;          int              ret = 0; +        int              print_status = 0;          char            *path = NULL;          uuid_t          gfid = {0};          xlator_t        *this = NULL; @@ -591,8 +647,13 @@ glfsh_process_entries (xlator_t *xl, fd_t *fd, gf_dirent_t *entries,                  gf_uuid_copy (loc.gfid, gfid);                  ret = syncop_getxattr (this, &loc, &dict, GF_HEAL_INFO, NULL,                                         NULL); -                if (ret) -                        continue; +                if (ret) { +                        if ((mode != GLFSH_MODE_CONTINUE_ON_ERROR) && +                            (ret == -ENOTCONN)) +                                goto out; +                        else +                                continue; +                }                  ret = syncop_gfid_to_path (this->itable, xl, gfid, &path); @@ -601,11 +662,19 @@ glfsh_process_entries (xlator_t *xl, fd_t *fd, gf_dirent_t *entries,                          ret = 0;                          continue;                  } -                if (dict) -                        glfsh_print_status (dict, path, gfid, -                                            num_entries, ignore_dirty); +                if (dict) { +                        print_status = glfsh_print_status (dict, path, gfid, +                                                           num_entries, +                                                           ignore_dirty); +                        if ((print_status) && +                            (mode != GLFSH_MODE_CONTINUE_ON_ERROR)) { +                                ret = -EAGAIN; +                                goto out; +                        } +                }          }          ret = 0; +out:          GF_FREE (path);          if (dict) {                  dict_unref (dict); @@ -620,17 +689,21 @@ glfsh_crawl_directory (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,                         dict_t *xattr_req, uint64_t *num_entries,                         gf_boolean_t ignore)  { -        uint64_t        offset = 0; +        int             ret          = 0; +        int             heal_op      = -1; +        uint64_t        offset       = 0;          gf_dirent_t     entries; -        int             ret = 0;          gf_boolean_t    free_entries = _gf_false; -        int             heal_op = -1; +        glfsh_fail_mode_t mode = GLFSH_MODE_CONTINUE_ON_ERROR;          INIT_LIST_HEAD (&entries.list);          ret = dict_get_int32 (xattr_req, "heal-op", &heal_op);          if (ret)                  return ret; +        if (heal_op == GF_SHD_OP_GRANULAR_ENTRY_HEAL_ENABLE) +                mode = GLFSH_MODE_EXIT_ON_FIRST_FAILURE; +          while (1) {                  ret = syncop_readdir (readdir_xl, fd, 131072, offset, &entries,                                        NULL, NULL); @@ -647,7 +720,7 @@ glfsh_crawl_directory (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,                                                       &entries, &offset,                                                       num_entries,                                                       glfsh_print_heal_status, -                                                     ignore); +                                                     ignore, mode);                          if (ret < 0)                                  goto out;                  } else if (heal_op == GF_SHD_OP_SPLIT_BRAIN_FILES) { @@ -655,13 +728,20 @@ glfsh_crawl_directory (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,                                                       &entries, &offset,                                                       num_entries,                                                       glfsh_print_spb_status, -                                                     ignore); +                                                     ignore, mode);                          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); +                } else if (heal_op == GF_SHD_OP_GRANULAR_ENTRY_HEAL_ENABLE) { +                        ret = glfsh_process_entries (readdir_xl, fd, &entries, +                                                     &offset, num_entries, +                                                     glfsh_heal_status_boolean, +                                                     ignore, mode); +                        if (ret < 0) +                                goto out;                  }                  gf_dirent_free (&entries);                  free_entries = _gf_false; @@ -674,6 +754,12 @@ out:  }  static int +glfsh_no_print_brick_from_xl (xlator_t *xl, loc_t *rootloc) +{ +        return 0; +} + +static int  glfsh_print_brick_from_xl (xlator_t *xl, loc_t *rootloc)  {          char    *remote_host = NULL; @@ -751,6 +837,13 @@ glfsh_print_pending_heals (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,          if (ret)                  goto out; +        if ((!is_parent_replicate) && +            ((heal_op == GF_SHD_OP_GRANULAR_ENTRY_HEAL_ENABLE) || +             (heal_op == GF_SHD_OP_GRANULAR_ENTRY_HEAL_DISABLE))) { +                ret = 0; +                goto out; +        } +          ret = glfsh_output->print_brick_from_xl (xl, rootloc);          if (ret < 0)                  goto out; @@ -758,6 +851,10 @@ glfsh_print_pending_heals (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,          ret = glfsh_print_pending_heals_type (fs, top_subvol, rootloc, xl,                                                heal_op, xattr_req,                                                GF_XATTROP_INDEX_GFID, &count); + +        if (ret < 0 && heal_op == GF_SHD_OP_GRANULAR_ENTRY_HEAL_ENABLE) +                goto out; +          total += count;          count = 0;          if (ret == -ENOTCONN) @@ -838,14 +935,14 @@ out:          return NULL;  } -  int  glfsh_gather_heal_info (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,                          gf_xl_afr_op_t heal_op)  { -        xlator_t  *xl       = NULL; +        int        ret       = 0; +        xlator_t  *xl        = NULL;          xlator_t  *heal_xl   = NULL; -        xlator_t  *old_THIS = NULL; +        xlator_t  *old_THIS  = NULL;          xl = top_subvol;          while (xl->next) @@ -856,20 +953,28 @@ glfsh_gather_heal_info (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,                          if (heal_xl) {                                  old_THIS = THIS;                                  THIS = heal_xl; -                                glfsh_print_pending_heals (fs, top_subvol, -                                                           rootloc, xl, -                                                           heal_op, -                                                           !strcmp -                                                           (heal_xl->type, -                                                           "cluster/replicate")); +                                ret = glfsh_print_pending_heals (fs, top_subvol, +                                                                 rootloc, xl, +                                                                 heal_op, +                                                                 !strcmp +                                                                (heal_xl->type, +                                                          "cluster/replicate"));                                  THIS = old_THIS; + +                                if ((ret < 0) && +                              (heal_op == GF_SHD_OP_GRANULAR_ENTRY_HEAL_ENABLE)) +                                        goto out;                          }                  }                  xl = xl->prev;          } -        return 0; +out: +        if (heal_op != GF_SHD_OP_GRANULAR_ENTRY_HEAL_ENABLE) +                ret = 0; + +        return ret;  }  int @@ -1107,6 +1212,15 @@ glfsh_info_t glfsh_human_readable = {          .end = glfsh_end  }; +glfsh_info_t glfsh_no_print = { +        .init = glfsh_init, +        .print_brick_from_xl = glfsh_no_print_brick_from_xl, +        .print_heal_op_status = glfsh_no_print_hr_heal_op_status, +        .print_heal_status = glfsh_no_print_hr_heal_status, +        .print_spb_status = glfsh_no_print_hr_heal_status, +        .end = glfsh_end_op_granular_entry_heal +}; +  #if (HAVE_LIB_XML)  glfsh_info_t glfsh_xml_output = {          .init = glfsh_xml_init, @@ -1150,6 +1264,8 @@ main (int argc, char **argv)                  } else if (!strcmp (argv[2], "xml")) {                          heal_op = GF_SHD_OP_INDEX_SUMMARY;                          is_xml = 1; +                } else if (!strcmp (argv[2], "granular-entry-heal-op")) { +                        heal_op = GF_SHD_OP_GRANULAR_ENTRY_HEAL_ENABLE;                  } else {                          printf (USAGE_STR, argv[0]);                          ret = -1; @@ -1206,6 +1322,9 @@ main (int argc, char **argv)          } +        if (heal_op == GF_SHD_OP_GRANULAR_ENTRY_HEAL_ENABLE) +                glfsh_output = &glfsh_no_print; +          ret = glfsh_output->init ();          if (ret)                  exit (EXIT_FAILURE); @@ -1282,6 +1401,7 @@ main (int argc, char **argv)          switch (heal_op) {          case GF_SHD_OP_INDEX_SUMMARY:          case GF_SHD_OP_SPLIT_BRAIN_FILES: +        case GF_SHD_OP_GRANULAR_ENTRY_HEAL_ENABLE:                  ret = glfsh_gather_heal_info (fs, top_subvol, &rootloc,                                                heal_op);                  break; @@ -1300,6 +1420,8 @@ main (int argc, char **argv)          }          glfsh_output->end (ret, NULL); +        if (ret < 0) +                ret = -ret;          loc_wipe (&rootloc);          glfs_subvol_done (fs, top_subvol);          cleanup (fs);  | 
