|
|
50dc83 |
From f40570f2f784dc61edb061a4931dcfc16bf51e7e Mon Sep 17 00:00:00 2001
|
|
|
50dc83 |
From: Aravinda VK <avishwan@redhat.com>
|
|
|
50dc83 |
Date: Mon, 5 Aug 2019 19:00:21 +0530
|
|
|
50dc83 |
Subject: [PATCH 277/284] geo-rep: Fix Config Get Race
|
|
|
50dc83 |
|
|
|
50dc83 |
When two threads(sync jobs) in Geo-rep worker calls `gconf.get` and
|
|
|
50dc83 |
`gconf.getr`(realtime) at the sametime, `getr` resets the conf object
|
|
|
50dc83 |
and other one gets None. Thread Lock is introduced to fix the issue.
|
|
|
50dc83 |
|
|
|
50dc83 |
```
|
|
|
50dc83 |
File "/usr/libexec/glusterfs/python/syncdaemon/syncdutils.py",
|
|
|
50dc83 |
line 368, in twrap
|
|
|
50dc83 |
tf(*aargs)
|
|
|
50dc83 |
File "/usr/libexec/glusterfs/python/syncdaemon/master.py", line 1987,
|
|
|
50dc83 |
in syncjob
|
|
|
50dc83 |
po = self.sync_engine(pb, self.log_err)
|
|
|
50dc83 |
File "/usr/libexec/glusterfs/python/syncdaemon/resource.py",
|
|
|
50dc83 |
line 1444, in rsync
|
|
|
50dc83 |
rconf.ssh_ctl_args + \
|
|
|
50dc83 |
AttributeError: 'NoneType' object has no attribute 'split'
|
|
|
50dc83 |
```
|
|
|
50dc83 |
|
|
|
50dc83 |
Backport of:
|
|
|
50dc83 |
> Patch: https://review.gluster.org/#/c/glusterfs/+/23158/
|
|
|
50dc83 |
> Change-Id: I9c245e5c36338265354e158f5baa32b119eb2da5
|
|
|
50dc83 |
> Updates: bz#1737484
|
|
|
50dc83 |
> Signed-off-by: Aravinda VK <avishwan@redhat.com>
|
|
|
50dc83 |
|
|
|
50dc83 |
Change-Id: I9c245e5c36338265354e158f5baa32b119eb2da5
|
|
|
50dc83 |
BUG: 1729915
|
|
|
50dc83 |
Signed-off-by: Kotresh HR <khiremat@redhat.com>
|
|
|
50dc83 |
Reviewed-on: https://code.engineering.redhat.com/gerrit/178960
|
|
|
50dc83 |
Tested-by: RHGS Build Bot <nigelb@redhat.com>
|
|
|
50dc83 |
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
|
|
|
50dc83 |
---
|
|
|
50dc83 |
geo-replication/syncdaemon/gsyncdconfig.py | 27 +++++++++++++++++++++------
|
|
|
50dc83 |
1 file changed, 21 insertions(+), 6 deletions(-)
|
|
|
50dc83 |
|
|
|
50dc83 |
diff --git a/geo-replication/syncdaemon/gsyncdconfig.py b/geo-replication/syncdaemon/gsyncdconfig.py
|
|
|
50dc83 |
index 1fc451f..38f3594 100644
|
|
|
50dc83 |
--- a/geo-replication/syncdaemon/gsyncdconfig.py
|
|
|
50dc83 |
+++ b/geo-replication/syncdaemon/gsyncdconfig.py
|
|
|
50dc83 |
@@ -17,6 +17,7 @@ import os
|
|
|
50dc83 |
import shutil
|
|
|
50dc83 |
from string import Template
|
|
|
50dc83 |
from datetime import datetime
|
|
|
50dc83 |
+from threading import Lock
|
|
|
50dc83 |
|
|
|
50dc83 |
|
|
|
50dc83 |
# Global object which can be used in other modules
|
|
|
50dc83 |
@@ -35,6 +36,7 @@ class GconfInvalidValue(Exception):
|
|
|
50dc83 |
class Gconf(object):
|
|
|
50dc83 |
def __init__(self, default_conf_file, custom_conf_file=None,
|
|
|
50dc83 |
args={}, extra_tmpl_args={}, override_from_args=False):
|
|
|
50dc83 |
+ self.lock = Lock()
|
|
|
50dc83 |
self.default_conf_file = default_conf_file
|
|
|
50dc83 |
self.custom_conf_file = custom_conf_file
|
|
|
50dc83 |
self.tmp_conf_file = None
|
|
|
50dc83 |
@@ -163,6 +165,11 @@ class Gconf(object):
|
|
|
50dc83 |
if value is not None and not self._is_valid_value(name, value):
|
|
|
50dc83 |
raise GconfInvalidValue()
|
|
|
50dc83 |
|
|
|
50dc83 |
+
|
|
|
50dc83 |
+ def _load_with_lock(self):
|
|
|
50dc83 |
+ with self.lock:
|
|
|
50dc83 |
+ self._load()
|
|
|
50dc83 |
+
|
|
|
50dc83 |
def _load(self):
|
|
|
50dc83 |
self.gconf = {}
|
|
|
50dc83 |
self.template_conf = []
|
|
|
50dc83 |
@@ -230,12 +237,19 @@ class Gconf(object):
|
|
|
50dc83 |
self._tmpl_substitute()
|
|
|
50dc83 |
self._do_typecast()
|
|
|
50dc83 |
|
|
|
50dc83 |
- def reload(self):
|
|
|
50dc83 |
+ def reload(self, with_lock=True):
|
|
|
50dc83 |
if self._is_config_changed():
|
|
|
50dc83 |
- self._load()
|
|
|
50dc83 |
+ if with_lock:
|
|
|
50dc83 |
+ self._load_with_lock()
|
|
|
50dc83 |
+ else:
|
|
|
50dc83 |
+ self._load()
|
|
|
50dc83 |
|
|
|
50dc83 |
- def get(self, name, default_value=None):
|
|
|
50dc83 |
- return self.gconf.get(name, default_value)
|
|
|
50dc83 |
+ def get(self, name, default_value=None, with_lock=True):
|
|
|
50dc83 |
+ if with_lock:
|
|
|
50dc83 |
+ with self.lock:
|
|
|
50dc83 |
+ return self.gconf.get(name, default_value)
|
|
|
50dc83 |
+ else:
|
|
|
50dc83 |
+ return self.gconf.get(name, default_value)
|
|
|
50dc83 |
|
|
|
50dc83 |
def getall(self, show_defaults=False, show_non_configurable=False):
|
|
|
50dc83 |
cnf = {}
|
|
|
50dc83 |
@@ -276,8 +290,9 @@ class Gconf(object):
|
|
|
50dc83 |
return cnf
|
|
|
50dc83 |
|
|
|
50dc83 |
def getr(self, name, default_value=None):
|
|
|
50dc83 |
- self.reload()
|
|
|
50dc83 |
- return self.get(name, default_value)
|
|
|
50dc83 |
+ with self.lock:
|
|
|
50dc83 |
+ self.reload(with_lock=False)
|
|
|
50dc83 |
+ return self.get(name, default_value, with_lock=False)
|
|
|
50dc83 |
|
|
|
50dc83 |
def get_help(self, name=None):
|
|
|
50dc83 |
pass
|
|
|
50dc83 |
--
|
|
|
50dc83 |
1.8.3.1
|
|
|
50dc83 |
|