|
|
12a457 |
From ef36875cd4661de13b74225ac25e9c49914434bb Mon Sep 17 00:00:00 2001
|
|
|
12a457 |
From: Anuradha Talur <atalur@redhat.com>
|
|
|
12a457 |
Date: Tue, 22 Mar 2016 14:03:38 +0530
|
|
|
12a457 |
Subject: [PATCH 45/80] afr : Enable auto heal when replica count increases
|
|
|
12a457 |
|
|
|
12a457 |
Backport of: http://review.gluster.org/13807
|
|
|
12a457 |
|
|
|
12a457 |
This patch is part two change to prevent data loss
|
|
|
12a457 |
in a replicate volume on doing a add-brick operation.
|
|
|
12a457 |
|
|
|
12a457 |
Problem: After doing add-brick, there is a chance that
|
|
|
12a457 |
self heal might happen from the newly added brick rather
|
|
|
12a457 |
than the source brick, leading to data loss.
|
|
|
12a457 |
|
|
|
12a457 |
Solution: Mark pending changelogs on afr children for
|
|
|
12a457 |
the new afr-child so that heal is performed in the
|
|
|
12a457 |
correct direction.
|
|
|
12a457 |
|
|
|
12a457 |
>Change-Id: Iae6af44f97e612cb3ee8c642254ec3d15ac063f5
|
|
|
12a457 |
>BUG: 1320020
|
|
|
12a457 |
>Signed-off-by: Anuradha Talur <atalur@redhat.com>
|
|
|
12a457 |
>Reviewed-on: http://review.gluster.org/13807
|
|
|
12a457 |
>Smoke: Gluster Build System <jenkins@build.gluster.com>
|
|
|
12a457 |
>NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
|
|
|
12a457 |
>CentOS-regression: Gluster Build System <jenkins@build.gluster.com>
|
|
|
12a457 |
>Reviewed-by: Raghavendra G <rgowdapp@redhat.com>
|
|
|
12a457 |
>Signed-off-by: Anuradha Talur <atalur@redhat.com>
|
|
|
12a457 |
|
|
|
12a457 |
Change-Id: I216626f860e6e84e274479987216a6cf2d6e5834
|
|
|
12a457 |
Signed-off-by: Anuradha Talur <atalur@redhat.com>
|
|
|
12a457 |
Reviewed-on: https://code.engineering.redhat.com/gerrit/71426
|
|
|
12a457 |
Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
|
|
|
12a457 |
Tested-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
|
|
|
12a457 |
---
|
|
|
12a457 |
tests/basic/afr/add-brick-self-heal.t | 67 ++++++++++
|
|
|
12a457 |
xlators/cluster/afr/src/afr-common.c | 11 ++
|
|
|
12a457 |
xlators/cluster/afr/src/afr-inode-write.c | 187 +++++++++++++++++-----------
|
|
|
12a457 |
xlators/cluster/afr/src/afr-mem-types.h | 2 +-
|
|
|
12a457 |
xlators/cluster/afr/src/afr-messages.h | 16 ++-
|
|
|
12a457 |
xlators/cluster/afr/src/afr.h | 9 +-
|
|
|
12a457 |
6 files changed, 211 insertions(+), 81 deletions(-)
|
|
|
12a457 |
create mode 100644 tests/basic/afr/add-brick-self-heal.t
|
|
|
12a457 |
|
|
|
12a457 |
diff --git a/tests/basic/afr/add-brick-self-heal.t b/tests/basic/afr/add-brick-self-heal.t
|
|
|
12a457 |
new file mode 100644
|
|
|
12a457 |
index 0000000..748d367
|
|
|
12a457 |
--- /dev/null
|
|
|
12a457 |
+++ b/tests/basic/afr/add-brick-self-heal.t
|
|
|
12a457 |
@@ -0,0 +1,67 @@
|
|
|
12a457 |
+#!/bin/bash
|
|
|
12a457 |
+. $(dirname $0)/../../include.rc
|
|
|
12a457 |
+. $(dirname $0)/../../volume.rc
|
|
|
12a457 |
+cleanup;
|
|
|
12a457 |
+
|
|
|
12a457 |
+TEST glusterd
|
|
|
12a457 |
+TEST pidof glusterd
|
|
|
12a457 |
+TEST $CLI volume create $V0 replica 2 $H0:$B0/${V0}{0,1}
|
|
|
12a457 |
+TEST $CLI volume start $V0
|
|
|
12a457 |
+TEST $CLI volume set $V0 cluster.data-self-heal off
|
|
|
12a457 |
+TEST $CLI volume set $V0 cluster.metadata-self-heal off
|
|
|
12a457 |
+TEST $CLI volume set $V0 cluster.entry-self-heal off
|
|
|
12a457 |
+
|
|
|
12a457 |
+TEST $CLI volume set $V0 self-heal-daemon off
|
|
|
12a457 |
+TEST glusterfs --volfile-id=$V0 --volfile-server=$H0 $M0;
|
|
|
12a457 |
+
|
|
|
12a457 |
+# Create files
|
|
|
12a457 |
+for i in {1..5}
|
|
|
12a457 |
+do
|
|
|
12a457 |
+ echo $i > $M0/file$i.txt
|
|
|
12a457 |
+done
|
|
|
12a457 |
+
|
|
|
12a457 |
+# Metadata changes
|
|
|
12a457 |
+TEST setfattr -n user.test -v qwerty $M0/file5.txt
|
|
|
12a457 |
+
|
|
|
12a457 |
+# Add brick1
|
|
|
12a457 |
+TEST $CLI volume add-brick $V0 replica 3 $H0:$B0/${V0}2
|
|
|
12a457 |
+
|
|
|
12a457 |
+# New-brick should accuse the old-bricks (Simulating case for data-loss)
|
|
|
12a457 |
+TEST setfattr -n trusted.afr.$V0-client-0 -v 0x000000000000000000000001 $B0/${V0}2/
|
|
|
12a457 |
+TEST setfattr -n trusted.afr.$V0-client-1 -v 0x000000000000000000000001 $B0/${V0}2/
|
|
|
12a457 |
+
|
|
|
12a457 |
+# Check if pending xattr and dirty-xattr are set for newly-added-brick
|
|
|
12a457 |
+EXPECT "000000000000000100000001" get_hex_xattr trusted.afr.$V0-client-2 $B0/${V0}0
|
|
|
12a457 |
+EXPECT "000000000000000100000001" get_hex_xattr trusted.afr.$V0-client-2 $B0/${V0}1
|
|
|
12a457 |
+EXPECT "000000000000000000000001" get_hex_xattr trusted.afr.dirty $B0/${V0}2
|
|
|
12a457 |
+
|
|
|
12a457 |
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 0
|
|
|
12a457 |
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 1
|
|
|
12a457 |
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 2
|
|
|
12a457 |
+
|
|
|
12a457 |
+TEST $CLI volume set $V0 self-heal-daemon on
|
|
|
12a457 |
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "Y" glustershd_up_status
|
|
|
12a457 |
+EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_in_shd $V0 0
|
|
|
12a457 |
+EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_in_shd $V0 1
|
|
|
12a457 |
+EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_in_shd $V0 2
|
|
|
12a457 |
+TEST $CLI volume heal $V0
|
|
|
12a457 |
+
|
|
|
12a457 |
+# Wait for heal to complete
|
|
|
12a457 |
+EXPECT_WITHIN $HEAL_TIMEOUT "^0$" get_pending_heal_count $V0
|
|
|
12a457 |
+
|
|
|
12a457 |
+# Check if entry-heal has happened
|
|
|
12a457 |
+TEST diff <(ls $B0/${V0}0 | sort) <(ls $B0/${V0}2 | sort)
|
|
|
12a457 |
+TEST diff <(ls $B0/${V0}1 | sort) <(ls $B0/${V0}2 | sort)
|
|
|
12a457 |
+
|
|
|
12a457 |
+# Test if data was healed
|
|
|
12a457 |
+TEST diff $B0/${V0}0/file1.txt $B0/${V0}2/file1.txt
|
|
|
12a457 |
+
|
|
|
12a457 |
+# Test if metadata was healed and exists on both the bricks
|
|
|
12a457 |
+EXPECT "qwerty" get_text_xattr user.test $B0/${V0}2/file5.txt
|
|
|
12a457 |
+EXPECT "qwerty" get_text_xattr user.test $B0/${V0}0/file5.txt
|
|
|
12a457 |
+
|
|
|
12a457 |
+EXPECT "000000000000000000000000" get_hex_xattr trusted.afr.$V0-client-2 $B0/${V0}0
|
|
|
12a457 |
+EXPECT "000000000000000000000000" get_hex_xattr trusted.afr.$V0-client-2 $B0/${V0}1
|
|
|
12a457 |
+EXPECT "000000000000000000000000" get_hex_xattr trusted.afr.dirty $B0/${V0}2
|
|
|
12a457 |
+
|
|
|
12a457 |
+cleanup;
|
|
|
12a457 |
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c
|
|
|
12a457 |
index b5d07ac..6b393c7 100644
|
|
|
12a457 |
--- a/xlators/cluster/afr/src/afr-common.c
|
|
|
12a457 |
+++ b/xlators/cluster/afr/src/afr-common.c
|
|
|
12a457 |
@@ -5113,3 +5113,14 @@ afr_get_need_heal (xlator_t *this)
|
|
|
12a457 |
UNLOCK (&priv->lock);
|
|
|
12a457 |
return need_heal;
|
|
|
12a457 |
}
|
|
|
12a457 |
+
|
|
|
12a457 |
+int
|
|
|
12a457 |
+afr_get_msg_id (char *op_type)
|
|
|
12a457 |
+{
|
|
|
12a457 |
+
|
|
|
12a457 |
+ if (!strcmp (op_type, GF_AFR_REPLACE_BRICK))
|
|
|
12a457 |
+ return AFR_MSG_REPLACE_BRICK_STATUS;
|
|
|
12a457 |
+ else if (!strcmp (op_type, GF_AFR_ADD_BRICK))
|
|
|
12a457 |
+ return AFR_MSG_ADD_BRICK_STATUS;
|
|
|
12a457 |
+ return -1;
|
|
|
12a457 |
+}
|
|
|
12a457 |
diff --git a/xlators/cluster/afr/src/afr-inode-write.c b/xlators/cluster/afr/src/afr-inode-write.c
|
|
|
12a457 |
index 8069d6c..c86fb49 100644
|
|
|
12a457 |
--- a/xlators/cluster/afr/src/afr-inode-write.c
|
|
|
12a457 |
+++ b/xlators/cluster/afr/src/afr-inode-write.c
|
|
|
12a457 |
@@ -1014,14 +1014,15 @@ afr_setxattr_wind (call_frame_t *frame, xlator_t *this, int subvol)
|
|
|
12a457 |
}
|
|
|
12a457 |
|
|
|
12a457 |
int
|
|
|
12a457 |
-afr_rb_set_pending_changelog_cbk (call_frame_t *frame, void *cookie,
|
|
|
12a457 |
+afr_emptyb_set_pending_changelog_cbk (call_frame_t *frame, void *cookie,
|
|
|
12a457 |
xlator_t *this, int op_ret, int op_errno,
|
|
|
12a457 |
dict_t *xattr, dict_t *xdata)
|
|
|
12a457 |
|
|
|
12a457 |
{
|
|
|
12a457 |
afr_local_t *local = NULL;
|
|
|
12a457 |
afr_private_t *priv = NULL;
|
|
|
12a457 |
- int i = 0;
|
|
|
12a457 |
+ int i, ret = 0;
|
|
|
12a457 |
+ char *op_type = NULL;
|
|
|
12a457 |
|
|
|
12a457 |
local = frame->local;
|
|
|
12a457 |
priv = this->private;
|
|
|
12a457 |
@@ -1030,19 +1031,26 @@ afr_rb_set_pending_changelog_cbk (call_frame_t *frame, void *cookie,
|
|
|
12a457 |
local->replies[i].valid = 1;
|
|
|
12a457 |
local->replies[i].op_ret = op_ret;
|
|
|
12a457 |
local->replies[i].op_errno = op_errno;
|
|
|
12a457 |
+
|
|
|
12a457 |
+ ret = dict_get_str (local->xdata_req, "replicate-brick-op", &op_type);
|
|
|
12a457 |
+ if (ret)
|
|
|
12a457 |
+ goto out;
|
|
|
12a457 |
+
|
|
|
12a457 |
gf_msg (this->name, op_ret ? GF_LOG_ERROR : GF_LOG_INFO,
|
|
|
12a457 |
op_ret ? op_errno : 0,
|
|
|
12a457 |
- AFR_MSG_REPLACE_BRICK_STATUS, "Set of pending xattr %s on"
|
|
|
12a457 |
+ afr_get_msg_id (op_type),
|
|
|
12a457 |
+ "Set of pending xattr %s on"
|
|
|
12a457 |
" %s.", op_ret ? "failed" : "succeeded",
|
|
|
12a457 |
priv->children[i]->name);
|
|
|
12a457 |
|
|
|
12a457 |
+out:
|
|
|
12a457 |
syncbarrier_wake (&local->barrier);
|
|
|
12a457 |
return 0;
|
|
|
12a457 |
}
|
|
|
12a457 |
|
|
|
12a457 |
int
|
|
|
12a457 |
-afr_rb_set_pending_changelog (call_frame_t *frame, xlator_t *this,
|
|
|
12a457 |
- unsigned char *locked_nodes)
|
|
|
12a457 |
+afr_emptyb_set_pending_changelog (call_frame_t *frame, xlator_t *this,
|
|
|
12a457 |
+ unsigned char *locked_nodes)
|
|
|
12a457 |
{
|
|
|
12a457 |
afr_local_t *local = NULL;
|
|
|
12a457 |
afr_private_t *priv = NULL;
|
|
|
12a457 |
@@ -1051,9 +1059,9 @@ afr_rb_set_pending_changelog (call_frame_t *frame, xlator_t *this,
|
|
|
12a457 |
local = frame->local;
|
|
|
12a457 |
priv = this->private;
|
|
|
12a457 |
|
|
|
12a457 |
- AFR_ONLIST (locked_nodes, frame, afr_rb_set_pending_changelog_cbk,
|
|
|
12a457 |
+ AFR_ONLIST (locked_nodes, frame, afr_emptyb_set_pending_changelog_cbk,
|
|
|
12a457 |
xattrop, &local->loc, GF_XATTROP_ADD_ARRAY,
|
|
|
12a457 |
- local->xdata_req, NULL);
|
|
|
12a457 |
+ local->xattr_req, NULL);
|
|
|
12a457 |
|
|
|
12a457 |
/* It is sufficient if xattrop was successful on one child */
|
|
|
12a457 |
for (i = 0; i < priv->child_count; i++) {
|
|
|
12a457 |
@@ -1073,9 +1081,10 @@ out:
|
|
|
12a457 |
}
|
|
|
12a457 |
|
|
|
12a457 |
int
|
|
|
12a457 |
-_afr_handle_replace_brick_type (xlator_t *this, call_frame_t *frame,
|
|
|
12a457 |
- loc_t *loc, int rb_index,
|
|
|
12a457 |
- afr_transaction_type type)
|
|
|
12a457 |
+_afr_handle_empty_brick_type (xlator_t *this, call_frame_t *frame,
|
|
|
12a457 |
+ loc_t *loc, int empty_index,
|
|
|
12a457 |
+ afr_transaction_type type,
|
|
|
12a457 |
+ char *op_type)
|
|
|
12a457 |
{
|
|
|
12a457 |
afr_local_t *local = NULL;
|
|
|
12a457 |
afr_private_t *priv = NULL;
|
|
|
12a457 |
@@ -1096,13 +1105,21 @@ _afr_handle_replace_brick_type (xlator_t *this, call_frame_t *frame,
|
|
|
12a457 |
if (!local->pending)
|
|
|
12a457 |
goto out;
|
|
|
12a457 |
|
|
|
12a457 |
- local->pending[rb_index][idx] = hton32 (1);
|
|
|
12a457 |
+ local->pending[empty_index][idx] = hton32 (1);
|
|
|
12a457 |
|
|
|
12a457 |
local->xdata_req = dict_new ();
|
|
|
12a457 |
if (!local->xdata_req)
|
|
|
12a457 |
goto out;
|
|
|
12a457 |
|
|
|
12a457 |
- ret = afr_set_pending_dict (priv, local->xdata_req, local->pending);
|
|
|
12a457 |
+ ret = dict_set_str (local->xdata_req, "replicate-brick-op", op_type);
|
|
|
12a457 |
+ if (ret)
|
|
|
12a457 |
+ goto out;
|
|
|
12a457 |
+
|
|
|
12a457 |
+ local->xattr_req = dict_new ();
|
|
|
12a457 |
+ if (!local->xattr_req)
|
|
|
12a457 |
+ goto out;
|
|
|
12a457 |
+
|
|
|
12a457 |
+ ret = afr_set_pending_dict (priv, local->xattr_req, local->pending);
|
|
|
12a457 |
if (ret < 0)
|
|
|
12a457 |
goto out;
|
|
|
12a457 |
|
|
|
12a457 |
@@ -1123,7 +1140,7 @@ _afr_handle_replace_brick_type (xlator_t *this, call_frame_t *frame,
|
|
|
12a457 |
goto unlock;
|
|
|
12a457 |
}
|
|
|
12a457 |
|
|
|
12a457 |
- ret = afr_rb_set_pending_changelog (frame, this, locked_nodes);
|
|
|
12a457 |
+ ret = afr_emptyb_set_pending_changelog (frame, this, locked_nodes);
|
|
|
12a457 |
if (ret)
|
|
|
12a457 |
goto unlock;
|
|
|
12a457 |
ret = 0;
|
|
|
12a457 |
@@ -1139,33 +1156,41 @@ out:
|
|
|
12a457 |
return ret;
|
|
|
12a457 |
}
|
|
|
12a457 |
|
|
|
12a457 |
-int
|
|
|
12a457 |
-_afr_handle_replace_brick_cbk (int ret, call_frame_t *frame, void *opaque)
|
|
|
12a457 |
+void
|
|
|
12a457 |
+afr_brick_args_cleanup (void *opaque)
|
|
|
12a457 |
{
|
|
|
12a457 |
- afr_replace_brick_args_t *data = NULL;
|
|
|
12a457 |
+ afr_empty_brick_args_t *data = NULL;
|
|
|
12a457 |
|
|
|
12a457 |
data = opaque;
|
|
|
12a457 |
loc_wipe (&data->loc);
|
|
|
12a457 |
GF_FREE (data);
|
|
|
12a457 |
+}
|
|
|
12a457 |
+
|
|
|
12a457 |
+int
|
|
|
12a457 |
+_afr_handle_empty_brick_cbk (int ret, call_frame_t *frame, void *opaque)
|
|
|
12a457 |
+{
|
|
|
12a457 |
+ afr_brick_args_cleanup (opaque);
|
|
|
12a457 |
return 0;
|
|
|
12a457 |
}
|
|
|
12a457 |
|
|
|
12a457 |
int
|
|
|
12a457 |
-_afr_handle_replace_brick (void *opaque)
|
|
|
12a457 |
+_afr_handle_empty_brick (void *opaque)
|
|
|
12a457 |
{
|
|
|
12a457 |
|
|
|
12a457 |
afr_local_t *local = NULL;
|
|
|
12a457 |
afr_private_t *priv = NULL;
|
|
|
12a457 |
- int rb_index = -1;
|
|
|
12a457 |
+ int empty_index = -1;
|
|
|
12a457 |
int ret = -1;
|
|
|
12a457 |
int op_errno = ENOMEM;
|
|
|
12a457 |
call_frame_t *frame = NULL;
|
|
|
12a457 |
xlator_t *this = NULL;
|
|
|
12a457 |
- afr_replace_brick_args_t *data = NULL;
|
|
|
12a457 |
+ char *op_type = NULL;
|
|
|
12a457 |
+ afr_empty_brick_args_t *data = NULL;
|
|
|
12a457 |
|
|
|
12a457 |
data = opaque;
|
|
|
12a457 |
frame = data->frame;
|
|
|
12a457 |
- rb_index = data->rb_index;
|
|
|
12a457 |
+ empty_index = data->empty_index;
|
|
|
12a457 |
+ op_type = data->op_type;
|
|
|
12a457 |
this = frame->this;
|
|
|
12a457 |
priv = this->private;
|
|
|
12a457 |
|
|
|
12a457 |
@@ -1175,11 +1200,13 @@ _afr_handle_replace_brick (void *opaque)
|
|
|
12a457 |
|
|
|
12a457 |
loc_copy (&local->loc, &data->loc);
|
|
|
12a457 |
|
|
|
12a457 |
- gf_msg_debug (this->name, 0, "Child being replaced is : %s",
|
|
|
12a457 |
- priv->children[rb_index]->name);
|
|
|
12a457 |
+ gf_msg_debug (this->name, 0, "New brick is : %s",
|
|
|
12a457 |
+ priv->children[empty_index]->name);
|
|
|
12a457 |
|
|
|
12a457 |
- ret = _afr_handle_replace_brick_type (this, frame, &local->loc, rb_index,
|
|
|
12a457 |
- AFR_METADATA_TRANSACTION);
|
|
|
12a457 |
+ ret = _afr_handle_empty_brick_type (this, frame, &local->loc,
|
|
|
12a457 |
+ empty_index,
|
|
|
12a457 |
+ AFR_METADATA_TRANSACTION,
|
|
|
12a457 |
+ op_type);
|
|
|
12a457 |
if (ret) {
|
|
|
12a457 |
op_errno = -ret;
|
|
|
12a457 |
ret = -1;
|
|
|
12a457 |
@@ -1187,12 +1214,15 @@ _afr_handle_replace_brick (void *opaque)
|
|
|
12a457 |
}
|
|
|
12a457 |
|
|
|
12a457 |
dict_unref (local->xdata_req);
|
|
|
12a457 |
+ dict_unref (local->xattr_req);
|
|
|
12a457 |
afr_matrix_cleanup (local->pending, priv->child_count);
|
|
|
12a457 |
local->pending = NULL;
|
|
|
12a457 |
+ local->xattr_req = NULL;
|
|
|
12a457 |
local->xdata_req = NULL;
|
|
|
12a457 |
|
|
|
12a457 |
- ret = _afr_handle_replace_brick_type (this, frame, &local->loc, rb_index,
|
|
|
12a457 |
- AFR_ENTRY_TRANSACTION);
|
|
|
12a457 |
+ ret = _afr_handle_empty_brick_type (this, frame, &local->loc,
|
|
|
12a457 |
+ empty_index,
|
|
|
12a457 |
+ AFR_ENTRY_TRANSACTION, op_type);
|
|
|
12a457 |
if (ret) {
|
|
|
12a457 |
op_errno = -ret;
|
|
|
12a457 |
ret = -1;
|
|
|
12a457 |
@@ -1413,63 +1443,71 @@ afr_handle_spb_choice_timeout (xlator_t *this, call_frame_t *frame,
|
|
|
12a457 |
}
|
|
|
12a457 |
|
|
|
12a457 |
int
|
|
|
12a457 |
-afr_handle_replace_brick (xlator_t *this, call_frame_t *frame, loc_t *loc,
|
|
|
12a457 |
- dict_t *dict)
|
|
|
12a457 |
+afr_handle_empty_brick (xlator_t *this, call_frame_t *frame, loc_t *loc,
|
|
|
12a457 |
+ dict_t *dict)
|
|
|
12a457 |
{
|
|
|
12a457 |
int ret = -1;
|
|
|
12a457 |
- int rb_index = -1;
|
|
|
12a457 |
+ int ab_ret = -1;
|
|
|
12a457 |
+ int empty_index = -1;
|
|
|
12a457 |
int op_errno = EPERM;
|
|
|
12a457 |
- char *replace_brick = NULL;
|
|
|
12a457 |
- afr_replace_brick_args_t *data = NULL;
|
|
|
12a457 |
+ char *empty_brick = NULL;
|
|
|
12a457 |
+ char *op_type = NULL;
|
|
|
12a457 |
+ afr_empty_brick_args_t *data = NULL;
|
|
|
12a457 |
|
|
|
12a457 |
- ret = dict_get_str (dict, GF_AFR_REPLACE_BRICK, &replace_brick);
|
|
|
12a457 |
+ ret = dict_get_str (dict, GF_AFR_REPLACE_BRICK, &empty_brick);
|
|
|
12a457 |
+ if (!ret)
|
|
|
12a457 |
+ op_type = GF_AFR_REPLACE_BRICK;
|
|
|
12a457 |
|
|
|
12a457 |
- if (!ret) {
|
|
|
12a457 |
- if (frame->root->pid != GF_CLIENT_PID_SELF_HEALD) {
|
|
|
12a457 |
- gf_msg (this->name, GF_LOG_ERROR, EPERM,
|
|
|
12a457 |
- AFR_MSG_REPLACE_BRICK_STATUS, "'%s' is an "
|
|
|
12a457 |
- "internal extended attribute",
|
|
|
12a457 |
- GF_AFR_REPLACE_BRICK);
|
|
|
12a457 |
+ ab_ret = dict_get_str (dict, GF_AFR_ADD_BRICK, &empty_brick);
|
|
|
12a457 |
+ if (!ab_ret)
|
|
|
12a457 |
+ op_type = GF_AFR_ADD_BRICK;
|
|
|
12a457 |
+
|
|
|
12a457 |
+ if (ret && ab_ret)
|
|
|
12a457 |
+ goto out;
|
|
|
12a457 |
+
|
|
|
12a457 |
+ if (frame->root->pid != GF_CLIENT_PID_SELF_HEALD) {
|
|
|
12a457 |
+ gf_msg (this->name, GF_LOG_ERROR, EPERM,
|
|
|
12a457 |
+ afr_get_msg_id (op_type),
|
|
|
12a457 |
+ "'%s' is an internal extended attribute.",
|
|
|
12a457 |
+ op_type);
|
|
|
12a457 |
+ ret = 1;
|
|
|
12a457 |
+ goto out;
|
|
|
12a457 |
+ }
|
|
|
12a457 |
+ empty_index = afr_get_child_index_from_name (this, empty_brick);
|
|
|
12a457 |
+
|
|
|
12a457 |
+ if (empty_index < 0) {
|
|
|
12a457 |
+ /* Didn't belong to this replica pair
|
|
|
12a457 |
+ * Just do a no-op
|
|
|
12a457 |
+ */
|
|
|
12a457 |
+ AFR_STACK_UNWIND (setxattr, frame, 0, 0, NULL);
|
|
|
12a457 |
+ return 0;
|
|
|
12a457 |
+ } else {
|
|
|
12a457 |
+ data = GF_CALLOC (1, sizeof (*data),
|
|
|
12a457 |
+ gf_afr_mt_empty_brick_t);
|
|
|
12a457 |
+ if (!data) {
|
|
|
12a457 |
ret = 1;
|
|
|
12a457 |
+ op_errno = ENOMEM;
|
|
|
12a457 |
goto out;
|
|
|
12a457 |
}
|
|
|
12a457 |
- rb_index = afr_get_child_index_from_name (this, replace_brick);
|
|
|
12a457 |
-
|
|
|
12a457 |
- if (rb_index < 0) {
|
|
|
12a457 |
- /* Didn't belong to this replica pair
|
|
|
12a457 |
- * Just do a no-op
|
|
|
12a457 |
- */
|
|
|
12a457 |
- AFR_STACK_UNWIND (setxattr, frame, 0, 0, NULL);
|
|
|
12a457 |
- return 0;
|
|
|
12a457 |
- } else {
|
|
|
12a457 |
- data = GF_CALLOC (1, sizeof (*data),
|
|
|
12a457 |
- gf_afr_mt_replace_brick_t);
|
|
|
12a457 |
- if (!data) {
|
|
|
12a457 |
- ret = 1;
|
|
|
12a457 |
- op_errno = ENOMEM;
|
|
|
12a457 |
- goto out;
|
|
|
12a457 |
- }
|
|
|
12a457 |
- data->frame = frame;
|
|
|
12a457 |
- loc_copy (&data->loc, loc);
|
|
|
12a457 |
- data->rb_index = rb_index;
|
|
|
12a457 |
- ret = synctask_new (this->ctx->env,
|
|
|
12a457 |
- _afr_handle_replace_brick,
|
|
|
12a457 |
- _afr_handle_replace_brick_cbk,
|
|
|
12a457 |
- NULL, data);
|
|
|
12a457 |
- if (ret) {
|
|
|
12a457 |
- gf_msg (this->name, GF_LOG_ERROR, 0,
|
|
|
12a457 |
- AFR_MSG_REPLACE_BRICK_FAILED,
|
|
|
12a457 |
- "Failed to create synctask. Unable to "
|
|
|
12a457 |
- "perform replace-brick.");
|
|
|
12a457 |
- ret = 1;
|
|
|
12a457 |
- op_errno = ENOMEM;
|
|
|
12a457 |
- loc_wipe (&data->loc);
|
|
|
12a457 |
- GF_FREE (data);
|
|
|
12a457 |
- goto out;
|
|
|
12a457 |
- }
|
|
|
12a457 |
+ data->frame = frame;
|
|
|
12a457 |
+ loc_copy (&data->loc, loc);
|
|
|
12a457 |
+ data->empty_index = empty_index;
|
|
|
12a457 |
+ data->op_type = op_type;
|
|
|
12a457 |
+ ret = synctask_new (this->ctx->env,
|
|
|
12a457 |
+ _afr_handle_empty_brick,
|
|
|
12a457 |
+ _afr_handle_empty_brick_cbk,
|
|
|
12a457 |
+ NULL, data);
|
|
|
12a457 |
+ if (ret) {
|
|
|
12a457 |
+ gf_msg (this->name, GF_LOG_ERROR, 0,
|
|
|
12a457 |
+ afr_get_msg_id (op_type),
|
|
|
12a457 |
+ "Failed to create synctask.");
|
|
|
12a457 |
+ ret = 1;
|
|
|
12a457 |
+ op_errno = ENOMEM;
|
|
|
12a457 |
+ afr_brick_args_cleanup (data);
|
|
|
12a457 |
+ goto out;
|
|
|
12a457 |
}
|
|
|
12a457 |
- ret = 0;
|
|
|
12a457 |
}
|
|
|
12a457 |
+ ret = 0;
|
|
|
12a457 |
out:
|
|
|
12a457 |
if (ret == 1) {
|
|
|
12a457 |
AFR_STACK_UNWIND (setxattr, frame, -1, op_errno, NULL);
|
|
|
12a457 |
@@ -1492,7 +1530,8 @@ afr_handle_special_xattr (xlator_t *this, call_frame_t *frame, loc_t *loc,
|
|
|
12a457 |
if (ret == 0)
|
|
|
12a457 |
goto out;
|
|
|
12a457 |
|
|
|
12a457 |
- ret = afr_handle_replace_brick (this, frame, loc, dict);
|
|
|
12a457 |
+ /* Applicable for replace-brick and add-brick commands */
|
|
|
12a457 |
+ ret = afr_handle_empty_brick (this, frame, loc, dict);
|
|
|
12a457 |
out:
|
|
|
12a457 |
return ret;
|
|
|
12a457 |
}
|
|
|
12a457 |
diff --git a/xlators/cluster/afr/src/afr-mem-types.h b/xlators/cluster/afr/src/afr-mem-types.h
|
|
|
12a457 |
index 6f1eee9..7f79620 100644
|
|
|
12a457 |
--- a/xlators/cluster/afr/src/afr-mem-types.h
|
|
|
12a457 |
+++ b/xlators/cluster/afr/src/afr-mem-types.h
|
|
|
12a457 |
@@ -45,7 +45,7 @@ enum gf_afr_mem_types_ {
|
|
|
12a457 |
gf_afr_mt_subvol_healer_t,
|
|
|
12a457 |
gf_afr_mt_spbc_timeout_t,
|
|
|
12a457 |
gf_afr_mt_spb_status_t,
|
|
|
12a457 |
- gf_afr_mt_replace_brick_t,
|
|
|
12a457 |
+ gf_afr_mt_empty_brick_t,
|
|
|
12a457 |
gf_afr_mt_end
|
|
|
12a457 |
};
|
|
|
12a457 |
#endif
|
|
|
12a457 |
diff --git a/xlators/cluster/afr/src/afr-messages.h b/xlators/cluster/afr/src/afr-messages.h
|
|
|
12a457 |
index d07c7bc..1fb5b51 100644
|
|
|
12a457 |
--- a/xlators/cluster/afr/src/afr-messages.h
|
|
|
12a457 |
+++ b/xlators/cluster/afr/src/afr-messages.h
|
|
|
12a457 |
@@ -341,11 +341,21 @@
|
|
|
12a457 |
|
|
|
12a457 |
/*!
|
|
|
12a457 |
* @messageid 108039
|
|
|
12a457 |
- * @diagnosis
|
|
|
12a457 |
- * @recommendedaction
|
|
|
12a457 |
+ * @diagnosis Setting of pending xattrs succeeded/failed during add-brick
|
|
|
12a457 |
+ * operation.
|
|
|
12a457 |
+ * @recommendedaction In case of failure, error number in the log should give
|
|
|
12a457 |
+ * the reason why it failed. Also observe brick logs for more information.
|
|
|
12a457 |
*/
|
|
|
12a457 |
-#define AFR_MSG_REPLACE_BRICK_FAILED (GLFS_COMP_BASE_AFR + 39)
|
|
|
12a457 |
+#define AFR_MSG_ADD_BRICK_STATUS (GLFS_COMP_BASE_AFR + 39)
|
|
|
12a457 |
|
|
|
12a457 |
+/*!
|
|
|
12a457 |
+ * @messageid 108040
|
|
|
12a457 |
+ * @diagnosis AFR was unable to be loaded because the pending-changelog xattrs
|
|
|
12a457 |
+ * were not found in the volfile.
|
|
|
12a457 |
+ * @recommendedaction Please ensure cluster op-version is atleast 30707 and the
|
|
|
12a457 |
+ * volfiles are regenerated.
|
|
|
12a457 |
+*/
|
|
|
12a457 |
+#define AFR_MSG_NO_CHANGELOG (GLFS_COMP_BASE_AFR + 40)
|
|
|
12a457 |
|
|
|
12a457 |
#define glfs_msg_end_x GLFS_MSGID_END, "Invalid: End of messages"
|
|
|
12a457 |
#endif /* !_AFR_MESSAGES_H_ */
|
|
|
12a457 |
diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h
|
|
|
12a457 |
index 9915344..dec4eaa 100644
|
|
|
12a457 |
--- a/xlators/cluster/afr/src/afr.h
|
|
|
12a457 |
+++ b/xlators/cluster/afr/src/afr.h
|
|
|
12a457 |
@@ -777,11 +777,12 @@ typedef struct afr_spb_status {
|
|
|
12a457 |
loc_t *loc;
|
|
|
12a457 |
} afr_spb_status_t;
|
|
|
12a457 |
|
|
|
12a457 |
-typedef struct afr_replace_brick_args {
|
|
|
12a457 |
+typedef struct afr_empty_brick_args {
|
|
|
12a457 |
call_frame_t *frame;
|
|
|
12a457 |
loc_t loc;
|
|
|
12a457 |
- int rb_index;
|
|
|
12a457 |
-} afr_replace_brick_args_t;
|
|
|
12a457 |
+ int empty_index;
|
|
|
12a457 |
+ char *op_type;
|
|
|
12a457 |
+} afr_empty_brick_args_t;
|
|
|
12a457 |
|
|
|
12a457 |
typedef struct afr_read_subvol_args {
|
|
|
12a457 |
ia_type_t ia_type;
|
|
|
12a457 |
@@ -1117,4 +1118,6 @@ afr_set_need_heal (xlator_t *this, afr_local_t *local);
|
|
|
12a457 |
int
|
|
|
12a457 |
afr_selfheal_data_open (xlator_t *this, inode_t *inode, fd_t **fd);
|
|
|
12a457 |
|
|
|
12a457 |
+int
|
|
|
12a457 |
+afr_get_msg_id (char *op_type);
|
|
|
12a457 |
#endif /* __AFR_H__ */
|
|
|
12a457 |
--
|
|
|
12a457 |
1.7.1
|
|
|
12a457 |
|