summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnuradha Talur <atalur@redhat.com>2015-09-11 18:43:36 +0530
committerPranith Kumar Karampuri <pkarampu@redhat.com>2015-09-15 19:22:58 -0700
commit57dfa97d4f84d426969591d3c0c674bdd54de450 (patch)
tree4113e9d980021daee61df39f3c53338a832f74cc
parent2e65b7aa6fe8fd03c1bea83d8b1d81ed4a774207 (diff)
afr : get split-brain-status in a synctask
Backport of: http://review.gluster.org/#/c/12163/ On executing `getfattr -n replica.split-brain-status <file>` 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 <atalur@redhat.com> Change-Id: I9f4f4b54e108d3a0017264353b8272e072170c16 BUG: 1262547 Signed-off-by: Anuradha Talur <atalur@redhat.com> Reviewed-on: http://review.gluster.org/12166 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>
-rw-r--r--xlators/cluster/afr/src/afr-common.c32
-rw-r--r--xlators/cluster/afr/src/afr-inode-read.c67
-rw-r--r--xlators/cluster/afr/src/afr-inode-write.c3
-rw-r--r--xlators/cluster/afr/src/afr-mem-types.h1
-rw-r--r--xlators/cluster/afr/src/afr-messages.h9
-rw-r--r--xlators/cluster/afr/src/afr.h13
6 files changed, 103 insertions, 22 deletions
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c
index 2eb3946ab7c..1c652f41e88 100644
--- a/xlators/cluster/afr/src/afr-common.c
+++ b/xlators/cluster/afr/src/afr-common.c
@@ -4588,8 +4588,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;
@@ -4714,7 +4713,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;
@@ -4727,7 +4733,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;
@@ -4777,14 +4791,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 1ebe5e5caf8..6afd51dfb4e 100644
--- a/xlators/cluster/afr/src/afr-inode-read.c
+++ b/xlators/cluster/afr/src/afr-inode-read.c
@@ -1429,6 +1429,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)
@@ -1478,20 +1531,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 84876503e22..18dd5529fb4 100644
--- a/xlators/cluster/afr/src/afr-inode-write.c
+++ b/xlators/cluster/afr/src/afr-inode-write.c
@@ -1342,6 +1342,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;
@@ -1365,6 +1366,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 e4bf85b769f..4793413ed83 100644
--- a/xlators/cluster/afr/src/afr-messages.h
+++ b/xlators/cluster/afr/src/afr-messages.h
@@ -45,7 +45,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"
@@ -333,6 +333,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 008839a7312..870d26b7689 100644
--- a/xlators/cluster/afr/src/afr.h
+++ b/xlators/cluster/afr/src/afr.h
@@ -755,6 +755,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;
@@ -1050,14 +1055,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,