887953
From 7e7ffc4cc56b6b6ed460a49344082c3c25c1a23d Mon Sep 17 00:00:00 2001
887953
From: Kotresh HR <khiremat@redhat.com>
887953
Date: Mon, 5 Nov 2018 11:46:41 +0530
887953
Subject: [PATCH 435/444] geo-rep: Fix traceback with symlink metadata sync
887953
887953
While syncing metadata, 'os.chmod', 'os.chown',
887953
'os.utime' should be used without de-reference.
887953
But python supports only 'os.chown' without
887953
de-reference. That's mostly because Linux
887953
doesn't support 'chmod' on symlink file itself
887953
but it does support 'chown'.
887953
887953
So while syncing metadata ops, if it's symlink
887953
we should only sync 'chown' and not do 'chmod'
887953
and 'utime'. It will lead to tracebacks with
887953
errors like EROFS, EPERM, ACCESS, ENOENT.
887953
All the three errors (EPERM, ACCESS, ENOENT)
887953
were handled except EROFS. But the way it was
887953
handled was not fool proof. The operation is
887953
tried and failure was handled based on the errors.
887953
All the errors with symlink file for 'chown',
887953
'utime' had to be passed to safe errors list of
887953
'errno_wrap'. This patch handles it better by
887953
avoiding 'chmod' and 'utime' if it's symlink
887953
file.
887953
887953
Backport of:
887953
 > Patch: https://review.gluster.org/21546
887953
 > fixes: bz#1646104
887953
 > Change-Id: Ic354206455cdc7ab2a87d741d81f4efe1f19d77d
887953
 > Signed-off-by: Kotresh HR <khiremat@redhat.com>
887953
887953
BUG: 1645916
887953
Change-Id: Ic354206455cdc7ab2a87d741d81f4efe1f19d77d
887953
Signed-off-by: Kotresh HR <khiremat@redhat.com>
887953
Reviewed-on: https://code.engineering.redhat.com/gerrit/155049
887953
Tested-by: RHGS Build Bot <nigelb@redhat.com>
887953
Reviewed-by: Aravinda Vishwanathapura Krishna Murthy <avishwan@redhat.com>
887953
Reviewed-by: Sunny Kumar <sunkumar@redhat.com>
887953
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
887953
---
887953
 geo-replication/syncdaemon/resource.py | 26 +++++++++++---------------
887953
 1 file changed, 11 insertions(+), 15 deletions(-)
887953
887953
diff --git a/geo-replication/syncdaemon/resource.py b/geo-replication/syncdaemon/resource.py
887953
index eb696f3..b289b3b 100644
887953
--- a/geo-replication/syncdaemon/resource.py
887953
+++ b/geo-replication/syncdaemon/resource.py
887953
@@ -790,10 +790,8 @@ class Server(object):
887953
             # 'lchown' 'lchmod' 'utime with no-deference' blindly.
887953
             # But since 'lchmod' and 'utime with no de-reference' is
887953
             # not supported in python3, we have to rely on 'chmod'
887953
-            # and 'utime with de-reference'. But 'chmod'
887953
-            # de-reference the symlink and gets ENOENT, EACCES,
887953
-            # EPERM errors, hence ignoring those errors if it's on
887953
-            # symlink file.
887953
+            # and 'utime with de-reference'. Hence avoiding 'chmod'
887953
+            # and 'utime' if it's symlink file.
887953
 
887953
             is_symlink = False
887953
             cmd_ret = errno_wrap(os.lchown, [go, uid, gid], [ENOENT],
887953
@@ -801,19 +799,17 @@ class Server(object):
887953
             if isinstance(cmd_ret, int):
887953
                 continue
887953
 
887953
-            cmd_ret = errno_wrap(os.chmod, [go, mode],
887953
-                                 [ENOENT, EACCES, EPERM], [ESTALE, EINVAL])
887953
-            if isinstance(cmd_ret, int):
887953
-                is_symlink = os.path.islink(go)
887953
-                if not is_symlink:
887953
+            is_symlink = os.path.islink(go)
887953
+
887953
+            if not is_symlink:
887953
+                cmd_ret = errno_wrap(os.chmod, [go, mode],
887953
+                                     [ENOENT, EACCES, EPERM], [ESTALE, EINVAL])
887953
+                if isinstance(cmd_ret, int):
887953
                     failures.append((e, cmd_ret, "chmod"))
887953
 
887953
-            cmd_ret = errno_wrap(os.utime, [go, (atime, mtime)],
887953
-                                 [ENOENT, EACCES, EPERM], [ESTALE, EINVAL])
887953
-            if isinstance(cmd_ret, int):
887953
-                if not is_symlink:
887953
-                    is_symlink = os.path.islink(go)
887953
-                if not is_symlink:
887953
+                cmd_ret = errno_wrap(os.utime, [go, (atime, mtime)],
887953
+                                     [ENOENT, EACCES, EPERM], [ESTALE, EINVAL])
887953
+                if isinstance(cmd_ret, int):
887953
                     failures.append((e, cmd_ret, "utime"))
887953
         return failures
887953
 
887953
-- 
887953
1.8.3.1
887953