summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnoop C S <anoopcs@redhat.com>2016-03-18 10:32:09 +0530
committerPranith Kumar Karampuri <pkarampu@redhat.com>2016-05-03 04:22:48 -0700
commitd250a81c0aba677e1858a1f83337603bd94b3d90 (patch)
treef0138a29554c6ae88aa016f3e84ed357c09ec3d5
parentbe41e31fefb92bf09c23efdb228000a2a1de28b5 (diff)
features/trash: wind mkdir with special pid
Recent changes done w.r.t handling of mkdir calls in posix translator resulted in crashing the brick process from trash translator. This was due to the changes made in posix translator to return EPERM for every mkdir calls without 'gfid-req' set in dictionary. In order to avoid gfid mismatches during directory creation from brick side trash translator does not set 'gfid-req'. This patch is to have an exemption for trash based on a special pid set for those mkdir calls originating from trash translator and to reset it in callback. This patch also includes a small optimization to the existing test case for trash feature. > Reviewed-on: http://review.gluster.org/13776 > Smoke: Gluster Build System <jenkins@build.gluster.com> > NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> > CentOS-regression: Gluster Build System <jenkins@build.gluster.com> > Reviewed-by: Jeff Darcy <jdarcy@redhat.com> (cherry picked from commit b5cfe948cb3569f034da80ac97b5d2f028b3b0e5) Change-Id: I59f084ac875e54342ecf2bffa6e43ebd84814153 BUG: 1332372 Signed-off-by: Anoop C S <anoopcs@redhat.com> Reviewed-on: http://review.gluster.org/14173 Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com> Tested-by: Pranith Kumar Karampuri <pkarampu@redhat.com> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> CentOS-regression: Gluster Build System <jenkins@build.gluster.com> Smoke: Gluster Build System <jenkins@build.gluster.com>
-rw-r--r--libglusterfs/src/common-utils.h3
-rwxr-xr-xtests/features/trash.t20
-rw-r--r--xlators/features/trash/src/trash.c20
-rw-r--r--xlators/features/trash/src/trash.h21
4 files changed, 48 insertions, 16 deletions
diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h
index 76952d5e14b..0ae575bce11 100644
--- a/libglusterfs/src/common-utils.h
+++ b/libglusterfs/src/common-utils.h
@@ -129,7 +129,8 @@ enum _gf_special_pid
GF_CLIENT_PID_GLFS_HEAL = -7,
GF_CLIENT_PID_BITD = -8,
GF_CLIENT_PID_SCRUB = -9,
- GF_CLIENT_PID_TIER_DEFRAG = -10
+ GF_CLIENT_PID_TIER_DEFRAG = -10,
+ GF_SERVER_PID_TRASH = -11
};
enum _gf_xlator_ipc_targets {
diff --git a/tests/features/trash.t b/tests/features/trash.t
index 268baac570f..620b84f0da1 100755
--- a/tests/features/trash.t
+++ b/tests/features/trash.t
@@ -93,11 +93,6 @@ wildcard_not_exists() {
if [ $? -eq 0 ]; then echo "Y"; else echo "N"; fi
}
-heal_ready() {
- $CLI volume heal $1 info | grep -q '^Brick'
- if [ $? -eq 0 ]; then echo "Y"; else echo "N"; fi
-}
-
# testing glusterd [1-3]
TEST glusterd
TEST pidof glusterd
@@ -227,26 +222,23 @@ EXPECT_WITHIN ${PROCESS_UP_TIMEOUT} "1" online_brick_count
rm -f $M1/self
EXPECT "Y" wildcard_exists $B0/${V1}2/.trashcan/self*
-# force start the volume and trigger the self-heal manually [55-59]
+# force start the volume and trigger the self-heal manually [55-57]
TEST $CLI volume start $V1 force
EXPECT_WITHIN $PROCESS_UP_TIMEOUT "2" online_brick_count
EXPECT_WITHIN $PROCESS_UP_TIMEOUT "Y" glustershd_up_status
-# volume heal one sometimes fail with "Launching heal operation to
-# perform index self heal on volume patchy1 has been unsuccessful"
-# Hence firt check heal is really functionnal.
-EXPECT_WITHIN $PROCESS_UP_TIMEOUT "Y" heal_ready $V1
-TEST $CLI volume heal $V1
+# Since we created the file under root of the volume, it will be
+# healed automatically
-# check for the removed file in trashcan [60]
+# check for the removed file in trashcan [58]
EXPECT_WITHIN $HEAL_TIMEOUT "Y" wildcard_exists $B0/${V1}1/.trashcan/internal_op/self*
-# check renaming of trash directory through cli [61-64]
+# check renaming of trash directory through cli [59-62]
TEST $CLI volume set $V0 trash-dir abc
TEST start_vol $V0 $M0 $M0/abc
TEST [ -e $M0/abc -a ! -e $M0/.trashcan ]
EXPECT "Y" wildcard_exists $B0/${V0}1/abc/internal_op/rebal2*
-# ensure that rename and delete operation on trash directory fails [65-67]
+# ensure that rename and delete operation on trash directory fails [63-65]
rm -rf $M0/abc/internal_op
TEST [ -e $M0/abc/internal_op ]
rm -rf $M0/abc/
diff --git a/xlators/features/trash/src/trash.c b/xlators/features/trash/src/trash.c
index 665737389b9..e14edf0eea7 100644
--- a/xlators/features/trash/src/trash.c
+++ b/xlators/features/trash/src/trash.c
@@ -602,6 +602,8 @@ trash_unlink_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local = frame->local;
GF_VALIDATE_OR_GOTO ("trash", local, out);
+ TRASH_UNSET_PID (frame, local);
+
tmp_str = gf_strdup (local->newpath);
if (!tmp_str) {
gf_log (this->name, GF_LOG_ERROR, "out of memory");
@@ -649,6 +651,9 @@ trash_unlink_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
remove_trash_path (tmp_path, (frame->root->pid < 0), &tmp_stat);
if (tmp_stat)
strcat (real_path, tmp_stat);
+
+ TRASH_SET_PID (frame, local);
+
STACK_WIND_COOKIE (frame, trash_unlink_mkdir_cbk, tmp_path,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->mkdir,
@@ -720,6 +725,8 @@ trash_unlink_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (tmp_stat)
strcat (real_path, tmp_stat);
+ TRASH_SET_PID (frame, local);
+
STACK_WIND_COOKIE (frame, trash_unlink_mkdir_cbk, tmp_path,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->mkdir, &tmp_loc,
@@ -791,6 +798,9 @@ trash_unlink_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
remove_trash_path (tmp_str, (frame->root->pid < 0), &tmp_stat);
if (tmp_stat)
strcat (real_path, tmp_stat);
+
+ TRASH_SET_PID (frame, local);
+
/* create the directory with proper permissions */
STACK_WIND_COOKIE (frame, trash_unlink_mkdir_cbk, tmp_cookie,
FIRST_CHILD(this),
@@ -1309,6 +1319,9 @@ trash_truncate_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
remove_trash_path (tmp_path, (frame->root->pid < 0), &tmp_stat);
if (tmp_stat)
strcat (real_path, tmp_stat);
+
+ TRASH_SET_PID (frame, local);
+
/* create the directory with proper permissions */
STACK_WIND_COOKIE (frame, trash_truncate_mkdir_cbk,
tmp_path, FIRST_CHILD(this),
@@ -1387,6 +1400,8 @@ trash_truncate_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
loop_count = local->loop_count;
+ TRASH_UNSET_PID (frame, local);
+
tmp_str = gf_strdup (local->newpath);
if (!tmp_str) {
gf_log (this->name, GF_LOG_DEBUG, "out of memory");
@@ -1432,6 +1447,9 @@ trash_truncate_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
remove_trash_path (tmp_path, (frame->root->pid < 0), &tmp_stat);
if (tmp_stat)
strcat (real_path, tmp_stat);
+
+ TRASH_SET_PID (frame, local);
+
STACK_WIND_COOKIE (frame, trash_truncate_mkdir_cbk,
tmp_path, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->mkdir,
@@ -1503,6 +1521,8 @@ trash_truncate_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (tmp_stat)
strcat (real_path, tmp_stat);
+ TRASH_SET_PID (frame, local);
+
STACK_WIND_COOKIE (frame, trash_truncate_mkdir_cbk, tmp_path,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->mkdir, &tmp_loc,
diff --git a/xlators/features/trash/src/trash.h b/xlators/features/trash/src/trash.h
index 37d8f7b3d85..cac7e5f02c4 100644
--- a/xlators/features/trash/src/trash.h
+++ b/xlators/features/trash/src/trash.h
@@ -44,10 +44,12 @@ struct trash_struct {
loc_t newloc; /* to store the location for the new file */
size_t fsize; /* for keeping the size of existing file */
off_t cur_offset; /* current offset for read and write ops */
- off_t fop_offset;
+ off_t fop_offset; /* original offset received with the fop */
+ pid_t pid;
char origpath[PATH_MAX];
char newpath[PATH_MAX];
int32_t loop_count;
+ gf_boolean_t is_set_pid;
struct iatt preparent;
struct iatt postparent;
gf_boolean_t ctr_link_count_req;
@@ -73,6 +75,23 @@ struct trash_priv {
};
typedef struct trash_priv trash_private_t;
+#define TRASH_SET_PID(frame, local) do { \
+ GF_ASSERT (!local->is_set_pid); \
+ if (!local->is_set_pid) { \
+ local->pid = frame->root->pid; \
+ frame->root->pid = GF_SERVER_PID_TRASH; \
+ local->is_set_pid = _gf_true; \
+ } \
+} while (0)
+
+#define TRASH_UNSET_PID(frame, local) do { \
+ GF_ASSERT (local->is_set_pid); \
+ if (local->is_set_pid) { \
+ frame->root->pid = local->pid; \
+ local->is_set_pid = _gf_false; \
+ } \
+} while (0)
+
#define TRASH_STACK_UNWIND(op, frame, params ...) do { \
trash_local_t *__local = NULL; \
__local = frame->local; \