summaryrefslogtreecommitdiffstats
path: root/geo-replication
diff options
context:
space:
mode:
authorAravinda VK <avishwan@redhat.com>2019-08-05 19:00:21 +0530
committerAmar Tumballi <amarts@redhat.com>2019-08-06 09:33:47 +0000
commitb1acf275a0779542d0ad1362e926658c037c94d8 (patch)
treed10ccb0af34c0dc580e0cb1d52bb79321cd6547a /geo-replication
parent30e42d14d8d1bec1883f1b7921d01b3117b1eed8 (diff)
geo-rep: Fix Config Get Race
When two threads(sync jobs) in Geo-rep worker calls `gconf.get` and `gconf.getr`(realtime) at the sametime, `getr` resets the conf object and other one gets None. Thread Lock is introduced to fix the issue. ``` File "/usr/libexec/glusterfs/python/syncdaemon/syncdutils.py", line 368, in twrap tf(*aargs) File "/usr/libexec/glusterfs/python/syncdaemon/master.py", line 1987, in syncjob po = self.sync_engine(pb, self.log_err) File "/usr/libexec/glusterfs/python/syncdaemon/resource.py", line 1444, in rsync rconf.ssh_ctl_args + \ AttributeError: 'NoneType' object has no attribute 'split' ``` Change-Id: I9c245e5c36338265354e158f5baa32b119eb2da5 Updates: bz#1737484 Signed-off-by: Aravinda VK <avishwan@redhat.com>
Diffstat (limited to 'geo-replication')
-rw-r--r--geo-replication/syncdaemon/gsyncdconfig.py27
1 files changed, 21 insertions, 6 deletions
diff --git a/geo-replication/syncdaemon/gsyncdconfig.py b/geo-replication/syncdaemon/gsyncdconfig.py
index 0476d5ec05c..61f91f7b727 100644
--- a/geo-replication/syncdaemon/gsyncdconfig.py
+++ b/geo-replication/syncdaemon/gsyncdconfig.py
@@ -17,6 +17,7 @@ import os
import shutil
from string import Template
from datetime import datetime
+from threading import Lock
# Global object which can be used in other modules
@@ -35,6 +36,7 @@ class GconfInvalidValue(Exception):
class Gconf(object):
def __init__(self, default_conf_file, custom_conf_file=None,
args={}, extra_tmpl_args={}, override_from_args=False):
+ self.lock = Lock()
self.default_conf_file = default_conf_file
self.custom_conf_file = custom_conf_file
self.tmp_conf_file = None
@@ -163,6 +165,11 @@ class Gconf(object):
if value is not None and not self._is_valid_value(name, value):
raise GconfInvalidValue()
+
+ def _load_with_lock(self):
+ with self.lock:
+ self._load()
+
def _load(self):
self.gconf = {}
self.template_conf = []
@@ -230,12 +237,19 @@ class Gconf(object):
self._tmpl_substitute()
self._do_typecast()
- def reload(self):
+ def reload(self, with_lock=True):
if self._is_config_changed():
- self._load()
+ if with_lock:
+ self._load_with_lock()
+ else:
+ self._load()
- def get(self, name, default_value=None):
- return self.gconf.get(name, default_value)
+ def get(self, name, default_value=None, with_lock=True):
+ if with_lock:
+ with self.lock:
+ return self.gconf.get(name, default_value)
+ else:
+ return self.gconf.get(name, default_value)
def getall(self, show_defaults=False, show_non_configurable=False):
cnf = {}
@@ -276,8 +290,9 @@ class Gconf(object):
return cnf
def getr(self, name, default_value=None):
- self.reload()
- return self.get(name, default_value)
+ with self.lock:
+ self.reload(with_lock=False)
+ return self.get(name, default_value, with_lock=False)
def get_help(self, name=None):
pass