diff options
author | Venkatesh Somyajulu <vsomyaju@redhat.com> | 2014-01-03 13:54:25 +0530 |
---|---|---|
committer | Niels de Vos <ndevos@redhat.com> | 2014-05-08 06:31:35 -0700 |
commit | f46a3198b1a3d794c23b8ac2ab9334326c4918c8 (patch) | |
tree | 4ddbfce73d6a3bb53a1c740a0eacfc8ecc2a7e0a | |
parent | d8014f53c22a7da2d7b38e7d3215aa83e3e51d0d (diff) |
cluster/afr: Unable to self heal symbolic links
Problem:
Under the entry self heal, readlink is done at the
source and sink. When readlink is done at the sink,
because link is not present at the sink, afr expects
ENOENT. AFR translator takes decisions for new link
creation based on ENOENT but server translator is modified
to return ESTALE because of which afr xlator is not able
to heal.
Fix:
The check for inode absence at server includes ESTALE as
well.
Change-Id: I9218da214ed44f7219570ad9dae298d6b5cbded9
BUG: 1046624
Signed-off-by: Venkatesh Somyajulu <vsomyaju@redhat.com>
Reviewed-on: http://review.gluster.org/6600
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Niels de Vos <ndevos@redhat.com>
-rwxr-xr-x | tests/bugs/bug-1046624.t | 49 | ||||
-rw-r--r-- | xlators/cluster/afr/src/afr-self-heal-entry.c | 4 | ||||
-rw-r--r-- | xlators/cluster/afr/src/afr.h | 2 |
3 files changed, 53 insertions, 2 deletions
diff --git a/tests/bugs/bug-1046624.t b/tests/bugs/bug-1046624.t new file mode 100755 index 00000000000..bd46b5eafea --- /dev/null +++ b/tests/bugs/bug-1046624.t @@ -0,0 +1,49 @@ +#!/bin/bash + +. $(dirname $0)/../include.rc +. $(dirname $0)/../volume.rc + +cleanup; +TEST glusterd +TEST pidof glusterd +TEST $CLI volume info; + +## Start and create a volume +mkdir -p ${B0}/${V0}-0 +mkdir -p ${B0}/${V0}-1 +TEST $CLI volume create $V0 replica 2 $H0:$B0/${V0}-{0,1} + +## Verify volume is created +EXPECT "$V0" volinfo_field $V0 'Volume Name'; +EXPECT 'Created' volinfo_field $V0 'Status'; + + +## Make sure automatic self-heal doesn't perturb our results. +TEST $CLI volume set $V0 cluster.self-heal-daemon off + +TEST $CLI volume set $V0 background-self-heal-count 0 + +## Start volume and verify +TEST $CLI volume start $V0; +EXPECT 'Started' volinfo_field $V0 'Status'; + +## Mount native +TEST glusterfs --volfile-server=$H0 --volfile-id=$V0 $M0 + +TEST `echo "TEST-FILE" > $M0/File` +TEST `mkdir $M0/Dir` +TEST kill_brick $V0 $H0 $B0/${V0}-0 + +TEST `ln -s $M0/File $M0/Link1` +TEST `ln -s $M0/Dir $M0/Link2` + +TEST $CLI volume start $V0 force + +TEST `find $M0/ | xargs stat 2>/dev/null 1>/dev/null` + +sleep 60 + +TEST stat $B0/${V0}-0/Link1 +TEST stat $B0/${V0}-0/Link2 + +cleanup; diff --git a/xlators/cluster/afr/src/afr-self-heal-entry.c b/xlators/cluster/afr/src/afr-self-heal-entry.c index 1ea957ad042..97f0d68b9f6 100644 --- a/xlators/cluster/afr/src/afr-self-heal-entry.c +++ b/xlators/cluster/afr/src/afr-self-heal-entry.c @@ -1530,7 +1530,7 @@ afr_sh_entry_impunge_readlink_sink_cbk (call_frame_t *impunge_frame, void *cooki child_index = (long) cookie; - if ((op_ret == -1) && (op_errno != ENOENT)) { + if ((op_ret == -1) && (!afr_inode_missing(op_errno))) { gf_log (this->name, GF_LOG_INFO, "readlink of %s on %s failed (%s)", impunge_local->loc.path, @@ -1541,7 +1541,7 @@ afr_sh_entry_impunge_readlink_sink_cbk (call_frame_t *impunge_frame, void *cooki /* symlink doesn't exist on the sink */ - if ((op_ret == -1) && (op_errno == ENOENT)) { + if ((op_ret == -1) && (afr_inode_missing(op_errno))) { afr_sh_entry_impunge_symlink (impunge_frame, this, child_index, impunge_sh->linkname); return 0; diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h index cad5de3986a..e86300d0a22 100644 --- a/xlators/cluster/afr/src/afr.h +++ b/xlators/cluster/afr/src/afr.h @@ -33,6 +33,8 @@ #define AFR_LOCKEE_COUNT_MAX 3 #define AFR_DOM_COUNT_MAX 3 +#define afr_inode_missing(op_errno) (op_errno == ENOENT || op_errno == ESTALE) + struct _pump_private; typedef int (*afr_expunge_done_cbk_t) (call_frame_t *frame, xlator_t *this, |