From 478203fd9447cbc67c7cdc2980d6bdf4881984bf Mon Sep 17 00:00:00 2001 From: Saravanakumar Arumugam Date: Fri, 22 Jan 2016 16:58:13 +0530 Subject: geo-rep: Handle hardlink in Tiering based volume Problem: Hardlinks are synced as Sticky bit files to Slave in a Tiering based volume. In a Tiering based volume, cold tier is hashed subvolume and geo-rep captures all namespace operations in cold tier. While syncing a file and its corresponding hardlink, it is recorded as MKNOD in cold tier(for both) and We end up creating two different files in Slave. Solution: If MKNOD with Sticky bit set is present, record it as LINK. This way it will create a HARDLINK if source file exists (on slave), else it will create a new file. This way, Slave can create Hardlink file itself (instead of creating a new file) in case of hardlink. Change-Id: Ic50dc6e64df9ed01799c30539a33daace0abe6d4 BUG: 1302979 Signed-off-by: Saravanakumar Arumugam Signed-off-by: Aravinda VK Reviewed-on: http://review.gluster.org/13281 Reviewed-on: http://review.gluster.org/13315 Smoke: Gluster Build System NetBSD-regression: NetBSD Build System CentOS-regression: Gluster Build System --- geo-replication/syncdaemon/master.py | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) (limited to 'geo-replication') diff --git a/geo-replication/syncdaemon/master.py b/geo-replication/syncdaemon/master.py index f318e7901f8..e743fdf2e50 100644 --- a/geo-replication/syncdaemon/master.py +++ b/geo-replication/syncdaemon/master.py @@ -24,7 +24,7 @@ from datetime import datetime from gconf import gconf from syncdutils import Thread, GsyncdError, boolify, escape from syncdutils import unescape, gauxpfx, md5hex, selfkill -from syncdutils import lstat, errno_wrap +from syncdutils import lstat, errno_wrap, FreeObject from syncdutils import NoPurgeTimeAvailable, PartialHistoryAvailable URXTIME = (-1, 0) @@ -865,19 +865,34 @@ class GMasterChangelogMixin(GMasterCommon): entries.append(edct(ty, gfid=gfid, entry=en)) elif ty in ['CREATE', 'MKDIR', 'MKNOD']: entry_update() - # stat information present in the changelog itself - entries.append(edct(ty, gfid=gfid, entry=en, - mode=int(ec[2]), - uid=int(ec[3]), gid=int(ec[4]))) - # Special case: add DATA in case of tier linkto file, - # Here, we have the assumption that only tier-gfid.linkto - # causes this mknod + # Special case: record mknod as link if ty in ['MKNOD']: mode = int(ec[2]) if mode & 01000: - datas.add(os.path.join(pfx, ec[0])) - + # Avoid stat'ing the file as it + # may be deleted in the interim + st = FreeObject(st_mode=int(ec[2]), + st_uid=int(ec[3]), + st_gid=int(ec[4]), + st_atime=0, + st_mtime=0) + + # So, it may be deleted, but still we are + # append LINK? Because, the file will be + # CREATED if source not exists. + entries.append(edct('LINK', stat=st, entry=en, + gfid=gfid)) + + # Here, we have the assumption that only + # tier-gfid.linkto causes this mknod. Add data + datas.add(os.path.join(pfx, ec[0])) + continue + + # stat info. present in the changelog itself + entries.append(edct(ty, gfid=gfid, entry=en, + mode=int(ec[2]), + uid=int(ec[3]), gid=int(ec[4]))) elif ty == "RENAME": go = os.path.join(pfx, gfid) st = lstat(go) -- cgit