summaryrefslogtreecommitdiffstats
path: root/geo-replication/syncdaemon
diff options
context:
space:
mode:
authorMilind Changire <mchangir@redhat.com>2016-01-06 21:23:51 +0530
committerAravinda VK <avishwan@redhat.com>2016-03-09 00:26:27 -0800
commit0cb6e6e7020c5a4f2e5c34c6b8cbfa4fdeb45191 (patch)
tree2f2bd9ec7f1b6eabd3e3098b493345e81045eddd /geo-replication/syncdaemon
parent3122e47e70494fd224f764f86fae29eca16ac06b (diff)
geo-rep: hard-link rename issues on changelog replay
Problem: LINK + RENAME changelog when replayed after worker restart causes stale hard-links to persist since VFS returns success for RENAME if hard-links point to same inode. Solution: Worker detects RENAME being issued on hard-links to the same inode and unlinks the source file-name. Conditionally rename by verifying that the source gfid matches with the on-disk gfid on the slave. Change-Id: I3ff1c30ef79e77503c8b246d46dab8ac3059ccf2 BUG: 1296175 Reviewed-on: http://review.gluster.org/13189 Signed-off-by: Milind Changire <mchangir@redhat.com> Reviewed-on: http://review.gluster.org/13638 Smoke: Gluster Build System <jenkins@build.gluster.com> Tested-by: Aravinda VK <avishwan@redhat.com> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> CentOS-regression: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Aravinda VK <avishwan@redhat.com>
Diffstat (limited to 'geo-replication/syncdaemon')
-rw-r--r--geo-replication/syncdaemon/resource.py28
1 files changed, 24 insertions, 4 deletions
diff --git a/geo-replication/syncdaemon/resource.py b/geo-replication/syncdaemon/resource.py
index c26054ad9df..81edfaa4a49 100644
--- a/geo-replication/syncdaemon/resource.py
+++ b/geo-replication/syncdaemon/resource.py
@@ -670,6 +670,21 @@ class Server(object):
errno_wrap(os.rmdir, [path], [ENOENT, ESTALE])
+ def rename_with_disk_gfid_confirmation(gfid, entry, en):
+ if not matching_disk_gfid(gfid, entry):
+ logging.error("RENAME ignored: "
+ "source entry:%s(gfid:%s) does not match with "
+ "on-disk gfid(%s), when attempting to rename "
+ "to %s" %
+ (entry, gfid, cls.gfid_mnt(entry), en))
+ return
+
+ cmd_ret = errno_wrap(os.rename,
+ [entry, en],
+ [ENOENT, EEXIST], [ESTALE])
+ collect_failure(e, cmd_ret)
+
+
for e in entries:
blob = None
op = e['op']
@@ -738,10 +753,15 @@ class Server(object):
(pg, bname) = entry2pb(en)
blob = entry_pack_reg_stat(gfid, bname, e['stat'])
else:
- cmd_ret = errno_wrap(os.rename,
- [entry, en],
- [ENOENT, EEXIST], [ESTALE])
- collect_failure(e, cmd_ret)
+ st1 = lstat(en)
+ if isinstance(st1, int):
+ rename_with_disk_gfid_confirmation(gfid, entry, en)
+ else:
+ if st.st_ino == st1.st_ino:
+ # we have a hard link, we can now unlink source
+ os.unlink(entry)
+ else:
+ rename_with_disk_gfid_confirmation(gfid, entry, en)
if blob:
cmd_ret = errno_wrap(Xattr.lsetxattr,
[pg, 'glusterfs.gfid.newfile', blob],