From 5af5b953a69a7b9ae8ba698fd36ff4df2a4e6dfe Mon Sep 17 00:00:00 2001 From: Aravinda VK Date: Wed, 25 Nov 2015 18:34:29 +0530 Subject: geo-rep: fd close and fcntl issue When any of the open fd of a file is closed on which fcntl lock is taken even though another fd of the same file is open on which lock is taken, all fcntl locks will be released. This causes both replica workers to be ACTIVE sometimes. This patche fixes that issue. BUG: 1287456 Change-Id: I8f113230d16075f18020044898a7eda5e2a5a0ac Original-Author: Aravinda VK Signed-off-by: Kotresh HR Reviewed-on: http://review.gluster.org/12752 Tested-by: Gluster Build System Reviewed-by: Milind Changire Tested-by: NetBSD Build System Reviewed-by: Aravinda VK Reviewed-by: Venky Shankar Reviewed-on: http://review.gluster.org/12842 --- geo-replication/syncdaemon/master.py | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) (limited to 'geo-replication') diff --git a/geo-replication/syncdaemon/master.py b/geo-replication/syncdaemon/master.py index 55226bdf94f..eadf51d3e5b 100644 --- a/geo-replication/syncdaemon/master.py +++ b/geo-replication/syncdaemon/master.py @@ -443,6 +443,24 @@ class GMasterCommon(object): def mgmt_lock(self): """Take management volume lock """ + if gconf.mgmt_lock_fd: + try: + fcntl.lockf(gconf.mgmt_lock_fd, fcntl.LOCK_EX | fcntl.LOCK_NB) + if not gconf.active_earlier: + gconf.active_earlier = True + logging.info("Got lock : %s : Becoming ACTIVE" + % gconf.local_path) + return True + except: + ex = sys.exc_info()[1] + if isinstance(ex, IOError) and ex.errno in (EACCES, EAGAIN): + if not gconf.passive_earlier: + gconf.passive_earlier = True + logging.info("Didn't get lock : %s : Becoming PASSIVE" + % gconf.local_path) + return False + raise + fd = None bname = str(self.uuid) + "_" + str(gconf.slave_id) + "_subvol_" \ + str(gconf.subvol_num) + ".lock" @@ -468,31 +486,17 @@ class GMasterCommon(object): raise try: fcntl.lockf(fd, fcntl.LOCK_EX | fcntl.LOCK_NB) - # Close the previously acquired lock so that - # fd will not leak. Reset fd to None - if gconf.mgmt_lock_fd: - os.close(gconf.mgmt_lock_fd) - gconf.mgmt_lock_fd = None - # Save latest FD for future use gconf.mgmt_lock_fd = fd except: ex = sys.exc_info()[1] - if fd: - os.close(fd) - - # When previously Active becomes Passive, Close the - # fd of previously acquired lock - if gconf.mgmt_lock_fd: - os.close(gconf.mgmt_lock_fd) - gconf.mgmt_lock_fd = None - if isinstance(ex, IOError) and ex.errno in (EACCES, EAGAIN): # cannot grab, it's taken if not gconf.passive_earlier: gconf.passive_earlier = True logging.info("Didn't get lock : %s : Becoming PASSIVE" % gconf.local_path) + gconf.mgmt_lock_fd = fd return False raise -- cgit