diff options
| author | Anuradha <atalur@redhat.com> | 2015-02-09 12:44:33 +0530 | 
|---|---|---|
| committer | Pranith Kumar Karampuri <pkarampu@redhat.com> | 2015-02-25 22:32:16 -0800 | 
| commit | 9112806b02b1c8668acff87af62553462aa7cf48 (patch) | |
| tree | cfe127f02b7b847e8cbbbdbdb7ec1e2f7bee2cb1 | |
| parent | 1fd540c386b3b4a99e3ee1b926a30f0992266983 (diff) | |
cluster/afr : provide split-brain info by using getxattr
This patch is one part to enable users analyze and resolve
split-brain.
Problem : To know if a file is in data/metadata split-brain
Solution : Performing "getfattr -n afr.split-brain-status
<path-to-file>" from the mount provides this information.
Also provides the list of afr children to analyse to
get more information.
Change-Id: I4d9b429794759a906371416cb84c84a212e2c7b9
BUG: 1191396
Signed-off-by: Anuradha <atalur@redhat.com>
Reviewed-on: http://review.gluster.org/9633
Reviewed-by: Ravishankar N <ravishankar@redhat.com>
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Krutika Dhananjay <kdhananj@redhat.com>
Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
Tested-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
| -rw-r--r-- | libglusterfs/src/glusterfs.h | 1 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-common.c | 134 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-inode-read.c | 4 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr.h | 2 | 
4 files changed, 141 insertions, 0 deletions
diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h index 8f993b2086a..1302a11d82b 100644 --- a/libglusterfs/src/glusterfs.h +++ b/libglusterfs/src/glusterfs.h @@ -139,6 +139,7 @@  #define GF_AFR_HEAL_INFO "glusterfs.heal-info"  #define GF_AFR_HEAL_SBRAIN "glusterfs.heal-sbrain" +#define GF_AFR_SBRAIN_STATUS "afr.split-brain-status"  #define GF_GFIDLESS_LOOKUP "gfidless-lookup"  /* replace-brick and pump related internal xattrs */ diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c index 0e321e620f7..333c2bda556 100644 --- a/xlators/cluster/afr/src/afr-common.c +++ b/xlators/cluster/afr/src/afr-common.c @@ -4537,6 +4537,140 @@ out:          return ret;  } +int +afr_set_split_brain_status (call_frame_t *frame, xlator_t *this, +                            struct afr_reply *replies, +                            afr_transaction_type type, +                            gf_boolean_t *spb) +{ +        afr_private_t    *priv              = NULL; +        uint64_t         *witness           = NULL; +        unsigned char    *sources           = NULL; +        unsigned char    *sinks             = NULL; +        int               sources_count     = 0; +        int               ret               = 0; + +        priv = this->private; + +        sources = alloca0 (priv->child_count); +        sinks = alloca0 (priv->child_count); +        witness = alloca0(priv->child_count * sizeof (*witness)); + +        ret = afr_selfheal_find_direction (frame, this, replies, +					   type, priv->child_up, sources, +                                           sinks, witness); +        if (ret) +                return ret; + +        sources_count = AFR_COUNT (sources, priv->child_count); +        if (!sources_count) +                *spb = _gf_true; + +        return ret; +} + +int +afr_get_split_brain_status (call_frame_t *frame, xlator_t *this, loc_t *loc) +{ +        gf_boolean_t      d_spb             = _gf_false; +        gf_boolean_t      m_spb             = _gf_false; +        int               ret               = -1; +        int               op_errno          = 0; +        int               i                 = 0; +        char             *choices           = NULL; +        char             *status            = NULL; +        dict_t           *dict              = NULL; +        struct afr_reply *replies           = NULL; +        inode_t          *inode             = NULL; +        afr_private_t    *priv              = NULL; +        xlator_t         **children         = NULL; + +        priv     = this->private; +        children = priv->children; + +        inode = afr_inode_find (this, loc->gfid); +        if (!inode) +                goto out; +        replies = alloca0 (sizeof (*replies) * priv->child_count); + +        /* Calculation for string length : +        * (child_count X length of child-name) + strlen ("    Choices :") +        * child-name consists of : +        * a) 256 = max characters for volname according to GD_VOLUME_NAME_MAX +        * b) strlen ("-client-00,") assuming 16 replicas +        */ +        choices = alloca0 (priv->child_count * (256 + strlen ("-client-00,")) + +                           strlen ("    Choices:")); +        ret = afr_selfheal_unlocked_discover (frame, inode, loc->gfid, replies); +        if (ret) { +                op_errno = -ret; +                ret = -1; +                goto out; +        } + +        ret = afr_set_split_brain_status (frame, this, replies, +                                          AFR_DATA_TRANSACTION, &d_spb); +        if (ret) { +                op_errno = -ret; +                ret = -1; +                goto out; +        } + +        ret = afr_set_split_brain_status (frame, this, replies, +                                          AFR_METADATA_TRANSACTION, &m_spb); +        if (ret) { +                op_errno = -ret; +                ret = -1; +                goto out; +        } + +        dict = dict_new (); +        if (!dict) { +                op_errno = ENOMEM; +                ret = -1; +                goto out; +        } + +        if (d_spb || m_spb) { +                sprintf (choices, "    Choices:"); +                for (i = 0; i < priv->child_count; i++) { +                        strcat (choices, children[i]->name); +                        strcat (choices, ","); +                } +                choices[strlen (choices) - 1] = '\0'; + +                ret = gf_asprintf (&status, "data-split-brain:%s    " +                                    "metadata-split-brain:%s%s", +                                    (d_spb) ? "yes" : "no", +                                    (m_spb) ? "yes" : "no", choices); + +                if (-1 == ret) { +                        op_errno = ENOMEM; +                        goto out; +                } +                ret = dict_set_dynstr (dict, GF_AFR_SBRAIN_STATUS, status); +                if (ret) +                        goto out; +        } else { +                ret = dict_set_str (dict, GF_AFR_SBRAIN_STATUS, +                                    "The file is not under data or" +                                    " metadata split-brain"); +                if (ret) +                        goto out; +        } + +        ret = 0; +out: +        AFR_STACK_UNWIND (getxattr, frame, ret, op_errno, dict, NULL); +        if (dict) +               dict_unref (dict); +        if (replies) +                afr_replies_wipe (replies, priv->child_count); +        if (inode) +                inode_unref (inode); +        return ret; +} +  int32_t  afr_heal_splitbrain_file(call_frame_t *frame, xlator_t *this, loc_t *loc)  { diff --git a/xlators/cluster/afr/src/afr-inode-read.c b/xlators/cluster/afr/src/afr-inode-read.c index 78dd65f30e7..e773f3284a6 100644 --- a/xlators/cluster/afr/src/afr-inode-read.c +++ b/xlators/cluster/afr/src/afr-inode-read.c @@ -1385,6 +1385,10 @@ afr_getxattr (call_frame_t *frame, xlator_t *this,                  return 0;          } +        if (!strcmp (name, GF_AFR_SBRAIN_STATUS)) { +                afr_get_split_brain_status (frame, this, loc); +                return 0; +        }          /*           * if we are doing getxattr with pathinfo as the key then we           * collect information from all childs diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h index 09821b724fe..d9233eedadc 100644 --- a/xlators/cluster/afr/src/afr.h +++ b/xlators/cluster/afr/src/afr.h @@ -1025,4 +1025,6 @@ afr_get_heal_info (call_frame_t *frame, xlator_t *this, loc_t *loc,  int  afr_heal_splitbrain_file(call_frame_t *frame, xlator_t *this, loc_t *loc); +int +afr_get_split_brain_status (call_frame_t *frame, xlator_t *this, loc_t *loc);  #endif /* __AFR_H__ */  | 
