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