|
|
50dc83 |
From 161a039f8088bf8ce7000d8175e3793219525179 Mon Sep 17 00:00:00 2001
|
|
|
50dc83 |
From: Kotresh HR <khiremat@redhat.com>
|
|
|
50dc83 |
Date: Thu, 28 Mar 2019 07:17:16 -0400
|
|
|
50dc83 |
Subject: [PATCH 50/52] geo-rep: Fix syncing multiple rename of symlink
|
|
|
50dc83 |
|
|
|
50dc83 |
Problem:
|
|
|
50dc83 |
Geo-rep fails to sync rename of symlink if it's
|
|
|
50dc83 |
renamed multiple times if creation and rename
|
|
|
50dc83 |
happened successively
|
|
|
50dc83 |
|
|
|
50dc83 |
Worker crash at slave:
|
|
|
50dc83 |
Traceback (most recent call last):
|
|
|
50dc83 |
File "/usr/libexec/glusterfs/python/syncdaemon/repce.py", in worker
|
|
|
50dc83 |
res = getattr(self.obj, rmeth)(*in_data[2:])
|
|
|
50dc83 |
File "/usr/libexec/glusterfs/python/syncdaemon/resource.py", in entry_ops
|
|
|
50dc83 |
[ESTALE, EINVAL, EBUSY])
|
|
|
50dc83 |
File "/usr/libexec/glusterfs/python/syncdaemon/syncdutils.py", in errno_wrap
|
|
|
50dc83 |
return call(*arg)
|
|
|
50dc83 |
File "/usr/libexec/glusterfs/python/syncdaemon/libcxattr.py", in lsetxattr
|
|
|
50dc83 |
cls.raise_oserr()
|
|
|
50dc83 |
File "/usr/libexec/glusterfs/python/syncdaemon/libcxattr.py", in raise_oserr
|
|
|
50dc83 |
raise OSError(errn, os.strerror(errn))
|
|
|
50dc83 |
OSError: [Errno 12] Cannot allocate memory
|
|
|
50dc83 |
|
|
|
50dc83 |
Geo-rep Behaviour:
|
|
|
50dc83 |
1. SYMLINK doesn't record target path in changelog.
|
|
|
50dc83 |
So while syncing SYMLINK, readlink is done on
|
|
|
50dc83 |
master to get target path.
|
|
|
50dc83 |
|
|
|
50dc83 |
2. Geo-rep will create destination if source is not
|
|
|
50dc83 |
present while syncing RENAME. Hence while syncing
|
|
|
50dc83 |
RENAME of SYMLINK, target path is collected from
|
|
|
50dc83 |
destination.
|
|
|
50dc83 |
|
|
|
50dc83 |
Cause:
|
|
|
50dc83 |
If symlink is created and renamed multiple times, creation of
|
|
|
50dc83 |
symlink is ignored, as it's no longer present on master at
|
|
|
50dc83 |
that path. While symlink is renamed multiple times at master,
|
|
|
50dc83 |
when syncing first RENAME of SYMLINK, both source and destination
|
|
|
50dc83 |
is not present, hence target path is not known. In this case,
|
|
|
50dc83 |
while creating destination directly at slave, regular file
|
|
|
50dc83 |
attributes were encoded into blob instead of symlink,
|
|
|
50dc83 |
causing failure in gfid-access translator while decoding
|
|
|
50dc83 |
blob.
|
|
|
50dc83 |
|
|
|
50dc83 |
Solution:
|
|
|
50dc83 |
While syncing of RENAME of SYMLINK, when target is not known
|
|
|
50dc83 |
and when src and destination is not present on the master,
|
|
|
50dc83 |
don't create destination. Ignore the rename. It's ok to ignore.
|
|
|
50dc83 |
If it's unliked, it's fine. If it's renamed to something else,
|
|
|
50dc83 |
it will be synced then.
|
|
|
50dc83 |
|
|
|
50dc83 |
Backport of:
|
|
|
50dc83 |
> Patch: https://review.gluster.org/22438
|
|
|
50dc83 |
> Change-Id: Ibdfa495513b7c05b5370ab0b89c69a6802338d87
|
|
|
50dc83 |
> BUG: 1693648
|
|
|
50dc83 |
> Signed-off-by: Kotresh HR <khiremat@redhat.com>
|
|
|
50dc83 |
|
|
|
50dc83 |
Change-Id: Ibdfa495513b7c05b5370ab0b89c69a6802338d87
|
|
|
50dc83 |
fixes: bz#1670429
|
|
|
50dc83 |
Signed-off-by: Kotresh HR <khiremat@redhat.com>
|
|
|
50dc83 |
Reviewed-on: https://code.engineering.redhat.com/gerrit/167122
|
|
|
50dc83 |
Tested-by: RHGS Build Bot <nigelb@redhat.com>
|
|
|
50dc83 |
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
|
|
|
50dc83 |
---
|
|
|
50dc83 |
geo-replication/syncdaemon/resource.py | 23 ++++++++++++++---------
|
|
|
50dc83 |
tests/00-geo-rep/georep-basic-dr-rsync.t | 1 +
|
|
|
50dc83 |
tests/geo-rep.rc | 12 ++++++++++++
|
|
|
50dc83 |
3 files changed, 27 insertions(+), 9 deletions(-)
|
|
|
50dc83 |
|
|
|
50dc83 |
diff --git a/geo-replication/syncdaemon/resource.py b/geo-replication/syncdaemon/resource.py
|
|
|
50dc83 |
index a2d0b16..c290d86 100644
|
|
|
50dc83 |
--- a/geo-replication/syncdaemon/resource.py
|
|
|
50dc83 |
+++ b/geo-replication/syncdaemon/resource.py
|
|
|
50dc83 |
@@ -625,15 +625,20 @@ class Server(object):
|
|
|
50dc83 |
# exist with different gfid.
|
|
|
50dc83 |
if not matching_disk_gfid(gfid, entry):
|
|
|
50dc83 |
if e['stat'] and not stat.S_ISDIR(e['stat']['mode']):
|
|
|
50dc83 |
- if stat.S_ISLNK(e['stat']['mode']) and \
|
|
|
50dc83 |
- e['link'] is not None:
|
|
|
50dc83 |
- st1 = lstat(en)
|
|
|
50dc83 |
- if isinstance(st1, int):
|
|
|
50dc83 |
- (pg, bname) = entry2pb(en)
|
|
|
50dc83 |
- blob = entry_pack_symlink(cls, gfid, bname,
|
|
|
50dc83 |
- e['link'], e['stat'])
|
|
|
50dc83 |
- elif not matching_disk_gfid(gfid, en):
|
|
|
50dc83 |
- collect_failure(e, EEXIST, uid, gid, True)
|
|
|
50dc83 |
+ if stat.S_ISLNK(e['stat']['mode']):
|
|
|
50dc83 |
+ # src is not present, so don't sync symlink as
|
|
|
50dc83 |
+ # we don't know target. It's ok to ignore. If
|
|
|
50dc83 |
+ # it's unliked, it's fine. If it's renamed to
|
|
|
50dc83 |
+ # something else, it will be synced then.
|
|
|
50dc83 |
+ if e['link'] is not None:
|
|
|
50dc83 |
+ st1 = lstat(en)
|
|
|
50dc83 |
+ if isinstance(st1, int):
|
|
|
50dc83 |
+ (pg, bname) = entry2pb(en)
|
|
|
50dc83 |
+ blob = entry_pack_symlink(cls, gfid, bname,
|
|
|
50dc83 |
+ e['link'],
|
|
|
50dc83 |
+ e['stat'])
|
|
|
50dc83 |
+ elif not matching_disk_gfid(gfid, en):
|
|
|
50dc83 |
+ collect_failure(e, EEXIST, uid, gid, True)
|
|
|
50dc83 |
else:
|
|
|
50dc83 |
slink = os.path.join(pfx, gfid)
|
|
|
50dc83 |
st = lstat(slink)
|
|
|
50dc83 |
diff --git a/tests/00-geo-rep/georep-basic-dr-rsync.t b/tests/00-geo-rep/georep-basic-dr-rsync.t
|
|
|
50dc83 |
index 4a03930..8b64370 100644
|
|
|
50dc83 |
--- a/tests/00-geo-rep/georep-basic-dr-rsync.t
|
|
|
50dc83 |
+++ b/tests/00-geo-rep/georep-basic-dr-rsync.t
|
|
|
50dc83 |
@@ -110,6 +110,7 @@ EXPECT_WITHIN $GEO_REP_TIMEOUT 0 chown_file_ok ${slave_mnt}/hybrid_chown_f1
|
|
|
50dc83 |
#Check History Crawl.
|
|
|
50dc83 |
TEST $GEOREP_CLI $master $slave stop
|
|
|
50dc83 |
TEST create_data "history"
|
|
|
50dc83 |
+TEST create_rename_symlink_case
|
|
|
50dc83 |
TEST $GEOREP_CLI $master $slave start
|
|
|
50dc83 |
EXPECT_WITHIN $GEO_REP_TIMEOUT 2 check_status_num_rows "Active"
|
|
|
50dc83 |
EXPECT_WITHIN $GEO_REP_TIMEOUT 2 check_status_num_rows "Passive"
|
|
|
50dc83 |
diff --git a/tests/geo-rep.rc b/tests/geo-rep.rc
|
|
|
50dc83 |
index 396b4c4..d723129 100644
|
|
|
50dc83 |
--- a/tests/geo-rep.rc
|
|
|
50dc83 |
+++ b/tests/geo-rep.rc
|
|
|
50dc83 |
@@ -19,6 +19,18 @@ function check_common_secret_file()
|
|
|
50dc83 |
echo $?
|
|
|
50dc83 |
}
|
|
|
50dc83 |
|
|
|
50dc83 |
+function create_rename_symlink_case()
|
|
|
50dc83 |
+{
|
|
|
50dc83 |
+ mkdir ${mastermnt}/MUL_REN_SYMLINK
|
|
|
50dc83 |
+ cd ${mastermnt}/MUL_REN_SYMLINK
|
|
|
50dc83 |
+ mkdir sym_dir1
|
|
|
50dc83 |
+ ln -s "sym_dir1" sym1
|
|
|
50dc83 |
+ mv sym1 sym2
|
|
|
50dc83 |
+ mv sym2 sym3
|
|
|
50dc83 |
+ mv sym3 sym4
|
|
|
50dc83 |
+ cd -
|
|
|
50dc83 |
+}
|
|
|
50dc83 |
+
|
|
|
50dc83 |
function create_data()
|
|
|
50dc83 |
{
|
|
|
50dc83 |
prefix=$1
|
|
|
50dc83 |
--
|
|
|
50dc83 |
1.8.3.1
|
|
|
50dc83 |
|