summaryrefslogtreecommitdiffstats
path: root/geo-replication
diff options
context:
space:
mode:
authorKotresh HR <khiremat@redhat.com>2017-05-25 07:28:07 -0400
committerAravinda VK <avishwan@redhat.com>2017-06-04 08:27:19 +0000
commit324e81d6fea324d512431a2604086326b8848e9b (patch)
treeab0fa555e0b8fa162a736ff565c18dc3a3e3d48b /geo-replication
parentbe28cbc5f8d3a78f6968b0307d001a5c0f0d8b31 (diff)
geo-rep: Fix meta data sync on symlink
chmod doesn't support 'no dereference' option. It always deference the symlink. But 'chown' does support metadata changes on symlink itself, which was not taken care while syncing. This patch fixes the same. Change-Id: Ic9985f4e39d15b5a9deb379841bcfb2c263d3e6c BUG: 1455559 Signed-off-by: Kotresh HR <khiremat@redhat.com> Reviewed-on: https://review.gluster.org/17389 NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> Reviewed-by: Aravinda VK <avishwan@redhat.com> Smoke: Gluster Build System <jenkins@build.gluster.org> Reviewed-by: Amar Tumballi <amarts@redhat.com> CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
Diffstat (limited to 'geo-replication')
-rw-r--r--geo-replication/syncdaemon/resource.py48
1 files changed, 37 insertions, 11 deletions
diff --git a/geo-replication/syncdaemon/resource.py b/geo-replication/syncdaemon/resource.py
index 9cbe92a93c5..5d7234358fb 100644
--- a/geo-replication/syncdaemon/resource.py
+++ b/geo-replication/syncdaemon/resource.py
@@ -23,8 +23,8 @@ import logging
import tempfile
import threading
import subprocess
-from errno import EEXIST, ENOENT, ENODATA, ENOTDIR, ELOOP
-from errno import EISDIR, ENOTEMPTY, ESTALE, EINVAL, EBUSY
+from errno import EEXIST, ENOENT, ENODATA, ENOTDIR, ELOOP, EACCES
+from errno import EISDIR, ENOTEMPTY, ESTALE, EINVAL, EBUSY, EPERM
from select import error as SelectError
import shutil
@@ -880,17 +880,43 @@ class Server(object):
atime = e['stat']['atime']
mtime = e['stat']['mtime']
go = e['go']
- cmd_ret = errno_wrap(os.chmod, [go, mode],
- [ENOENT], [ESTALE, EINVAL])
- # This is a fail fast mechanism
- # We do this for failing fops on Slave
- # Master should be logging this
+ # Linux doesn't support chmod on symlink itself.
+ # It is always applied to the target file. So
+ # changelog would record target file's gfid
+ # and we are good. But 'chown' is supported on
+ # symlink file. So changelog would record symlink
+ # gfid in such cases. Since we do 'chown' 'chmod'
+ # 'utime' for each gfid recorded for metadata, and
+ # we know from changelog the metadata is on symlink's
+ # gfid or target file's gfid, we should be doing
+ # 'lchown' 'lchmod' 'utime with no-deference' blindly.
+ # But since 'lchmod' and 'utime with no de-reference' is
+ # not supported in python3, we have to rely on 'chmod'
+ # and 'utime with de-reference'. But 'chmod'
+ # de-reference the symlink and gets ENOENT, EACCES,
+ # EPERM errors, hence ignoring those errors if it's on
+ # symlink file.
+
+ is_symlink = False
+ cmd_ret = errno_wrap(os.lchown, [go, uid, gid], [ENOENT],
+ [ESTALE, EINVAL])
if isinstance(cmd_ret, int):
- failures.append((e, cmd_ret))
continue
- errno_wrap(os.chown, [go, uid, gid], [ENOENT], [ESTALE, EINVAL])
- errno_wrap(os.utime, [go, (atime, mtime)],
- [ENOENT], [ESTALE, EINVAL])
+
+ cmd_ret = errno_wrap(os.chmod, [go, mode],
+ [ENOENT, EACCES, EPERM], [ESTALE, EINVAL])
+ if isinstance(cmd_ret, int):
+ is_symlink = os.path.islink(go)
+ if not is_symlink:
+ failures.append((e, cmd_ret, "chmod"))
+
+ cmd_ret = errno_wrap(os.utime, [go, (atime, mtime)],
+ [ENOENT, EACCES, EPERM], [ESTALE, EINVAL])
+ if isinstance(cmd_ret, int):
+ if not is_symlink:
+ is_symlink = os.path.islink(go)
+ if not is_symlink:
+ failures.append((e, cmd_ret, "utime"))
return failures
@classmethod