From fa08597a004b591afbeb478d0a736ec09066f648 Mon Sep 17 00:00:00 2001 From: Anuradha Talur Date: Fri, 11 Sep 2015 18:43:36 +0530 Subject: afr : get split-brain-status in a synctask On executing `getfattr -n replica.split-brain-status ` on mount, there is a possibility that the mount hangs. To avoid this hang, fetch the split-brain-status of a file in synctask. Change-Id: I87b781419ffc63248f915325b845e3233143d385 BUG: 1262345 Signed-off-by: Anuradha Talur Reviewed-on: http://review.gluster.org/12163 Reviewed-by: Pranith Kumar Karampuri Tested-by: NetBSD Build System Tested-by: Gluster Build System Reviewed-by: Ravishankar N --- xlators/cluster/afr/src/afr-common.c | 32 ++++++++++++--- xlators/cluster/afr/src/afr-inode-read.c | 67 +++++++++++++++++++++++++------ xlators/cluster/afr/src/afr-inode-write.c | 3 ++ xlators/cluster/afr/src/afr-mem-types.h | 1 + xlators/cluster/afr/src/afr-messages.h | 9 ++++- xlators/cluster/afr/src/afr.h | 13 ++++-- 6 files changed, 103 insertions(+), 22 deletions(-) (limited to 'xlators') diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c index 66d04b7c8c5..ce9c1ce110a 100644 --- a/xlators/cluster/afr/src/afr-common.c +++ b/xlators/cluster/afr/src/afr-common.c @@ -4583,8 +4583,7 @@ out: } int -afr_get_heal_info (call_frame_t *frame, xlator_t *this, loc_t *loc, - dict_t *xdata) +afr_get_heal_info (call_frame_t *frame, xlator_t *this, loc_t *loc) { gf_boolean_t data_selfheal = _gf_false; gf_boolean_t metadata_selfheal = _gf_false; @@ -4709,7 +4708,14 @@ out: } int -afr_get_split_brain_status (call_frame_t *frame, xlator_t *this, loc_t *loc) +afr_get_split_brain_status_cbk (int ret, call_frame_t *frame, void *opaque) +{ + GF_FREE (opaque); + return 0; +} + +int +afr_get_split_brain_status (void *opaque) { gf_boolean_t d_spb = _gf_false; gf_boolean_t m_spb = _gf_false; @@ -4722,7 +4728,15 @@ afr_get_split_brain_status (call_frame_t *frame, xlator_t *this, loc_t *loc) inode_t *inode = NULL; afr_private_t *priv = NULL; xlator_t **children = NULL; - + call_frame_t *frame = NULL; + xlator_t *this = NULL; + loc_t *loc = NULL; + afr_spb_status_t *data = NULL; + + data = opaque; + frame = data->frame; + this = frame->this; + loc = data->loc; priv = this->private; children = priv->children; @@ -4772,14 +4786,20 @@ afr_get_split_brain_status (call_frame_t *frame, xlator_t *this, loc_t *loc) goto out; } ret = dict_set_dynstr (dict, GF_AFR_SBRAIN_STATUS, status); - if (ret) + if (ret) { + op_errno = -ret; + ret = -1; goto out; + } } else { ret = dict_set_str (dict, GF_AFR_SBRAIN_STATUS, "The file is not under data or" " metadata split-brain"); - if (ret) + if (ret) { + op_errno = -ret; + ret = -1; goto out; + } } ret = 0; diff --git a/xlators/cluster/afr/src/afr-inode-read.c b/xlators/cluster/afr/src/afr-inode-read.c index d430f98b9c7..234f1d0c918 100644 --- a/xlators/cluster/afr/src/afr-inode-read.c +++ b/xlators/cluster/afr/src/afr-inode-read.c @@ -1424,6 +1424,59 @@ afr_marker_populate_args (call_frame_t *frame, int type, int *gauge, return priv->child_count; } +static int +afr_handle_heal_xattrs (call_frame_t *frame, xlator_t *this, loc_t *loc, + const char *heal_op) +{ + int ret = -1; + afr_spb_status_t *data = NULL; + + if (!strcmp (heal_op, GF_HEAL_INFO)) { + afr_get_heal_info (frame, this, loc); + ret = 0; + goto out; + } + + if (!strcmp (heal_op, GF_AFR_HEAL_SBRAIN)) { + afr_heal_splitbrain_file (frame, this, loc); + ret = 0; + goto out; + } + + if (!strcmp (heal_op, GF_AFR_SBRAIN_STATUS)) { + data = GF_CALLOC (1, sizeof (*data), gf_afr_mt_spb_status_t); + if (!data) { + ret = 1; + goto out; + } + data->frame = frame; + data->loc = loc; + ret = synctask_new (this->ctx->env, + afr_get_split_brain_status, + afr_get_split_brain_status_cbk, + NULL, data); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, 0, + AFR_MSG_SPLIT_BRAIN_STATUS, + "Failed to create" + " synctask. Unable to fetch split-brain status" + " for %s.", loc->name); + ret = 1; + goto out; + } + goto out; + } + +out: + if (ret == 1) { + AFR_STACK_UNWIND (getxattr, frame, -1, ENOMEM, NULL, NULL); + if (data) + GF_FREE (data); + ret = 0; + } + return ret; +} + int32_t afr_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) @@ -1473,20 +1526,10 @@ afr_getxattr (call_frame_t *frame, xlator_t *this, afr_marker_populate_args) == 0) return 0; - if (!strcmp (name, GF_HEAL_INFO)) { - afr_get_heal_info (frame, this, loc, xdata); + ret = afr_handle_heal_xattrs (frame, this, &local->loc, name); + if (ret == 0) return 0; - } - if (!strcmp (name, GF_AFR_HEAL_SBRAIN)) { - afr_heal_splitbrain_file (frame, this, loc); - return 0; - } - - if (!strcmp (name, GF_AFR_SBRAIN_STATUS)) { - afr_get_split_brain_status (frame, this, loc); - return 0; - } /* * Special xattrs which need responses from all subvols */ diff --git a/xlators/cluster/afr/src/afr-inode-write.c b/xlators/cluster/afr/src/afr-inode-write.c index 0601b89090c..44ac01ade5a 100644 --- a/xlators/cluster/afr/src/afr-inode-write.c +++ b/xlators/cluster/afr/src/afr-inode-write.c @@ -1337,6 +1337,7 @@ afr_handle_split_brain_commands (xlator_t *this, call_frame_t *frame, " synctask. Aborting split-brain choice set" " for %s", loc->name); ret = 1; + op_errno = ENOMEM; goto out; } ret = 0; @@ -1360,6 +1361,8 @@ out: /* key was correct but value was invalid when ret == 1 */ if (ret == 1) { AFR_STACK_UNWIND (setxattr, frame, -1, op_errno, NULL); + if (data) + GF_FREE (data); ret = 0; } return ret; diff --git a/xlators/cluster/afr/src/afr-mem-types.h b/xlators/cluster/afr/src/afr-mem-types.h index a11063c1f25..fd484e4f1fd 100644 --- a/xlators/cluster/afr/src/afr-mem-types.h +++ b/xlators/cluster/afr/src/afr-mem-types.h @@ -44,6 +44,7 @@ enum gf_afr_mem_types_ { gf_afr_mt_reply_t, gf_afr_mt_subvol_healer_t, gf_afr_mt_spbc_timeout_t, + gf_afr_mt_spb_status_t, gf_afr_mt_end }; #endif diff --git a/xlators/cluster/afr/src/afr-messages.h b/xlators/cluster/afr/src/afr-messages.h index 83cfef9ceef..ede88674a10 100644 --- a/xlators/cluster/afr/src/afr-messages.h +++ b/xlators/cluster/afr/src/afr-messages.h @@ -40,7 +40,7 @@ */ #define GLFS_COMP_BASE_AFR GLFS_MSGID_COMP_AFR -#define GLFS_NUM_MESSAGES 37 +#define GLFS_NUM_MESSAGES 38 #define GLFS_MSGID_END (GLFS_COMP_BASE_AFR + GLFS_NUM_MESSAGES + 1) #define glfs_msg_start_x GLFS_COMP_BASE_AFR, "Invalid: Start of messages" @@ -328,6 +328,13 @@ #define AFR_MSG_SELF_HEAL_FAILED (GLFS_COMP_BASE_AFR + 37) +/*! + * @messageid 108038 + * @diagnosis + * @recommendedaction +*/ +#define AFR_MSG_SPLIT_BRAIN_STATUS (GLFS_COMP_BASE_AFR + 38) + #define glfs_msg_end_x GLFS_MSGID_END, "Invalid: End of messages" #endif /* !_AFR_MESSAGES_H_ */ diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h index 3a4a8794698..bae20e5bf79 100644 --- a/xlators/cluster/afr/src/afr.h +++ b/xlators/cluster/afr/src/afr.h @@ -750,6 +750,11 @@ typedef struct afr_spbc_timeout { int spb_child_index; } afr_spbc_timeout_t; +typedef struct afr_spb_status { + call_frame_t *frame; + loc_t *loc; +} afr_spb_status_t; + typedef struct afr_read_subvol_args { ia_type_t ia_type; uuid_t gfid; @@ -1045,14 +1050,16 @@ gf_boolean_t afr_is_xattr_ignorable (char *key); int -afr_get_heal_info (call_frame_t *frame, xlator_t *this, loc_t *loc, - dict_t *xdata); +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); +afr_get_split_brain_status (void *opaque); + +int +afr_get_split_brain_status_cbk (int ret, call_frame_t *frame, void *opaque); int afr_inode_split_brain_choice_set (inode_t *inode, xlator_t *this, -- cgit